| name | chartjs-graphs |
| description | Chart.js integration patterns for creating interactive statistical graphs in Django templates. Covers HTML setup, data injection, and JavaScript chart rendering with datalabels plugin.
|
| license | Apache-2.0 |
| metadata | {"author":"Carlos","version":"1.0","scope":["root"],"auto_invoke":["Creating Chart.js graphs in Django","Implementing statistical dashboards with charts"]} |
| allowed-tools | Read, Edit, Write, Glob, Grep, Bash |
Chart.js Setup
CDN Includes (in template head):
{% block extra_css %}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0/dist/chartjs-plugin-datalabels.min.js"></script>
{% endblock %}
HTML Template Pattern
Canvas element with data attributes:
<canvas id="surveysChart" data-timeline='{{ timeline_data_json|safe }}'></canvas>
<canvas id="complaintsChart" data-complaints='{{ complaints_data_json|safe }}'></canvas>
<canvas id="chart-{{ forloop.counter }}"
data-question="{{ question_text }}"
data-type="{{ data.type }}"
data-summary='{{ data.summary|safe }}'></canvas>
Key Points:
- Use
data-* attributes to pass JSON from Django context
- Always use
|safe filter for JSON data
- Unique
id for each canvas (use forloop.counter in loops)
JavaScript Chart Patterns
1. Line Chart (Time Series)
document.addEventListener('DOMContentLoaded', function() {
const canvas = document.getElementById('surveysChart');
if (!canvas) return;
const timelineDataRaw = canvas.getAttribute('data-timeline');
const timelineData = JSON.parse(timelineDataRaw);
if (!timelineData || !timelineData.dates || timelineData.dates.length === 0) {
console.warn('No data available');
return;
}
new Chart(canvas.getContext('2d'), {
type: 'line',
data: {
labels: timelineData.dates,
datasets: [{
label: 'Survey Submissions',
data: timelineData.counts,
borderColor: 'rgba(52, 152, 219, 1)',
: ,
: ,
: ,
: ,
: ,
: ,
}]
},
: {
: ,
: ,
: {
: { : },
: { : }
},
: {
: {
: ,
: { : }
}
}
}
});
});
2. Horizontal Bar Chart
document.addEventListener('DOMContentLoaded', function() {
const canvas = document.getElementById('complaintsChart');
if (!canvas) return;
const complaintsDataRaw = canvas.getAttribute('data-complaints');
const complaintsData = JSON.parse(complaintsDataRaw);
const labels = Object.keys(complaintsData);
const counts = Object.values(complaintsData);
new Chart(canvas.getContext('2d'), {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Number of Complaints',
data: counts,
backgroundColor: 'rgba(231, 76, 60, 0.7)',
borderColor: 'rgba(231, 76, 60, 1)',
borderWidth: 2,
borderRadius: 6,
maxBarThickness: ,
}]
},
: {
: ,
: ,
: {
: { : },
: {
: ,
: ,
: ,
: ,
: { : , : },
: value
}
},
: {
: {
: ,
: { : }
}
}
},
: []
});
});
3. Pie Chart
document.addEventListener('DOMContentLoaded', function() {
if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') {
Chart.register(ChartDataLabels);
}
const canvas = document.getElementById('pieChart');
const summaryData = JSON.parse(canvas.dataset.summary);
const labels = Object.keys(summaryData);
const values = Object.values(summaryData);
const colors = [
'rgba(52, 152, 219, 0.7)',
'rgba(46, 204, 113, 0.7)',
'rgba(241, 196, 15, 0.7)',
'rgba(231, 76, 60, 0.7)',
'rgba(155, 89, 182, 0.7)',
];
new Chart(canvas.getContext('2d'), {
: ,
: {
: labels,
: [{
: values,
: colors,
: ,
:
}]
},
: {
: ,
: {
: {
: ,
: { : , : { : } }
},
: {
: ,
: {
total = ctx...( a + b, );
pct = (value / total) * ;
;
},
: { : , : }
}
}
}
});
});
4. Vertical Bar Chart
new Chart(canvas.getContext('2d'), {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Number of Responses',
data: values,
backgroundColor: 'rgba(52, 152, 219, 0.7)',
}]
},
options: {
responsive: true,
plugins: {
legend: { display: false },
datalabels: {
anchor: 'end',
align: 'end',
color: '#000',
formatter: (value) => value
}
},
scales: {
y: {
beginAtZero: true,
ticks: { stepSize: 1, precision: 0 }
}
}
},
plugins: [ChartDataLabels]
});
Data Injection from Django
In Django view (CBV):
import json
from django.views.generic import TemplateView
class DashboardView(TemplateView):
template_name = "dashboard.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
timeline_data = {
'dates': ['2024-01-01', '2024-01-02', '2024-01-03'],
'counts': [5, 8, 12]
}
complaints_data = {
'Bad Service': 10,
'Late Arrival': 5,
'Dirty Vehicle': 3
}
context['timeline_data_json'] = json.dumps(timeline_data)
context['complaints_data_json'] = json.dumps(complaints_data)
return context
Dynamic Color Palette
const chartColors = {
primary: '#3498db',
success: '#2ecc71',
warning: '#f39c12',
danger: '#e74c3c',
info: '#1abc9c',
purple: '#9b59b6',
pink: '#e91e63',
orange: '#ff5722',
};
const colorPalette = Object.values(chartColors);
backgroundColor: labels.map((_, i) => colorPalette[i % colorPalette.length])
Best Practices
ALWAYS:
- ✅ Wrap code in
DOMContentLoaded event listener
- ✅ Check if canvas exists before creating chart
- ✅ Validate parsed JSON data before using
- ✅ Use
try-catch when parsing JSON
- ✅ Set
responsive: true and maintainAspectRatio: true
- ✅ Use
beginAtZero: true for bar/line charts
- ✅ Set
stepSize: 1 for integer-only data
- ✅ Register
ChartDataLabels plugin when using datalabels
- ✅ Use
|safe filter in Django template for JSON data
NEVER:
- ❌ Forget to check if canvas element exists
- ❌ Skip JSON parsing error handling
- ❌ Hard-code chart data in JavaScript (use Django context)
- ❌ Create charts without validating data first
- ❌ Forget to include Chart.js CDN in template
File Structure
app/
├── templates/
│ └── app/
│ └── dashboard.html # Canvas elements with data-* attributes
├── static/
│ └── app/
│ ├── js/
│ │ ├── line_chart.js # One file per chart type
│ │ ├── bar_chart.js
│ │ └── pie_chart.js
│ └── css/
│ └── dashboard.css
└── views.py # JSON data preparation
Common Issues
Chart not rendering:
- Check if canvas ID matches JavaScript selector
- Verify Chart.js CDN loaded before custom scripts
- Check browser console for JavaScript errors
- Validate JSON data structure
DataLabels not showing:
- Include chartjs-plugin-datalabels CDN
- Register plugin:
Chart.register(ChartDataLabels)
- Add plugin to chart config:
plugins: [ChartDataLabels]
- Set
datalabels: { display: true } in options
Data not updating:
- Clear browser cache
- Check Django context data in view
- Verify
|safe filter used in template
- Inspect canvas
data-* attributes in browser DevTools