막대 그래프, 선 그래프, 거미줄 그래프, 파이 그래프 등등..
chart.js를 이용하여 그래프 만들기
chart.js 공식 문서
사실 공식 문서만 봐도 어려울 게 없다.
그렇지만 처음 써봤으니까 기록을 남긴다.
공식 문서의 samples 에 들어가면 그래프 모양 별로 샘플을 다양하게 볼 수 있고,
해당 샘플에서 페이지 소스를 보면 코드도 다~ 볼 수 있다.
나는 이 중에서 line chart
, pie chart
, bar chart
를 만들었다.
요로코롬.
프로젝트 상황: django를 쓰고 있고, js와 html파일은 분리되어 있음
# django views.py
# pie chart
pie_chart_vpn = []
# vpn pie chart 데이터
today_vpn = Vpn.objects.filter(time__range=[today_start,today_end])
today_vpn_success = today_vpn.filter(result="Success").count()
today_vpn_fail = today_vpn.filter(result="Failure").count()
pie_chart_vpn = [ today_vpn_success, today_vpn_fail ]
날짜가 오늘
인 데이터 중에 result
값이 Success
인 데이터 갯수와, result
값이 Failure
인 데이터의 갯수를 chart
의 데이터로 넣어줄 거다.
# html
<div class="access-chart__card">
<div class="card__title">
<h4>1️⃣ VPN 오늘 접근 결과</h4>
</div>
<div class="card__chartWrapper">
<canvas id="vpnPieChart"></canvas>
</div>
</div>
...
<script>
var pie_chart_vpn = {{pie_chart_vpn}}
</script>
id를 지정한 canvas
태그만 넣어주면 되고, django views.py
에서 넘어온 데이터를 변수로 지정하기 위해 script
태그 안에 템플릿 태그로 변수를 선언해준다.
# js 파일
var vpn_pie = document.getElementById('vpnPieChart').getContext('2d');
var vpnPieChart = new Chart(vpn_pie, {
type: 'pie',
data:{
labels: [ 'Success', 'Failure' ],
datasets: [{
data: pie_chart_vpn,
backgroundColor: [
"#f7323f",
"#673ba7"
],
borderWidth: 0
}]
}
});
이렇게만 해주면 끝 !
# django views.py
# line chart
# 시간 설정
now = datetime.datetime.now()
# line chart - 그래프 라벨 (x축)
h_labels = []
for i in range(9):
h = now - timedelta(hours=i+1)
h_labels.append(h.hour)
h_labels.reverse()
# line chart - 그래프 데이터 (접근 명수 count)
chart_vpn_suc = []
chart_vpn_fail = []
for i in range(10):
h = now - timedelta(hours=i)
hour_start = h.strftime("%Y-%m-%d %H:00:00")
hour_end = h.strftime("%Y-%m-%d %H:59:59")
hour_vpn = Vpn.objects.filter(time__range=[hour_start, hour_end])
hour_vpn_success = hour_vpn.filter(result="Success").count()
hour_vpn_fail = hour_vpn.filter(result="Failure").count()
chart_vpn_suc.append(hour_vpn_success)
chart_vpn_fail.append(hour_vpn_fail)
chart_vpn_success.reverse()
chart_vpn_fail.reverse()
line_chart_vpn = [ chart_vpn_success, chart_vpn_fail ]
10시간 동안의 접근 명수를 각각 성공 데이터, 실패 데이터로 나눠서 저장한다.
# html
<div class="access-chart__card">
<div class="card__title">
<h4>2️⃣ VPN 오늘 하루 접속자 수</h4>
</div>
<div class="card__chartWrapper">
<canvas id="vpnLineChart"></canvas>
</div>
</div>
...
<script>
var h_labels = {{h_labels}};
h_labels.push("현재");
var line_chart_vpn = {{line_chart_vpn}};
</script>
똑같이 id를 지정한 canvas
태그만 넣어주면 되고, django views.py
에서 넘어온 데이터를 변수로 지정하기 위해 script
태그 안에 템플릿 태그로 변수를 선언해준다. line그래프는 x축에 들어갈 labels
값들도 리스트로 불러온다.
# js 파일
var vpn_line = document.getElementById('vpnLineChart').getContext('2d');
var vpnLineChart = new Chart(vpn_line, {
type: 'line',
data: {
labels: h_labels,
datasets: [{ //첫 번째 데이터 셋 (성공 데이터)
label: 'vpn접속',
data: line_chart_vpn[0],
backgroundColor: 'rgba(247,50,63,0.1)',
borderColor: 'rgba(247,50,63,1)',
},{ //두 번째 데이터 셋 (실패 데이터)
label: 'vpn접속실패',
data: line_chart_vpn[1],
backgroundColor: 'rgba(103,59,167,0.1)',
borderColor: '#673ba7'
}]
},
options: {
maintainAspectRatio: false,
responsive: true,
legend: false, //범례 표시 안함
tooltips: {
mode: 'index',
intersect: false
},
hover: { //마우스를 근처에 가져갔을 때, 데이터 값 표시
mode: 'nearest',
intersect: true
},
scales: {
yAxes: [{
ticks: {
stepSize: 1, //y축의 숫자가 1단위로 커진다는 뜻
beginAtZero: true
},
gridLines: {
lineWidth: 0 //y축 격자선 없애기
}
}]
}
}
});
# django views.py
# bar chart
# 시간 설정
today = datetime.date.today()
yesterday = today - datetime.timedelta(days=1)
weekdays = today.weekday() + 1
this_week_start = today - datetime.timedelta(days=weekdays % 7)
last_week_start = this_week_start - datetime.timedelta(days=7)
this_month = today.month
last_month = this_month - 1
# bar chart 데이터 (지난 성공 수, 이번 성공 수)
vpn_success = Vpn.objects.filter(result='Success')
today_vpn_count = vpn_success.filter(time__date=today)
yesterday_vpn = vpn_success.filter(time__date=yesterday)
yesterday_vpn_count = yesterday_vpn.count()
this_week_vpn = vpn_success.filter(time__date__gte=this_week_start)
this_week_vpn_count = this_week_vpn.count()
last_week_vpn = vpn_success.filter(time__date__gte=last_week_start, time__date__lt=this_week_start)
last_week_vpn_count = last_week_vpn.count()
this_month_vpn = vpn_success.filter(time__month=this_month)
this_month_vpn_count = this_month_vpn.count()
last_month_vpn = vpn_success.filter(time__month=last_month)
last_month_vpn_count = last_month_vpn.count()
this_vpn_counts = [today_vpn_count, this_week_vpn_count, this_month_vpn_count]
last_vpn_counts = [yesterday_vpn_count, last_week_vpn_count, last_month_vpn_count]
bar_chart_vpn = [last_vpn_counts, this_vpn_counts]
# html
<div class="access-chart__card">
<div class="card__title">
<h4>3️⃣ VPN 접근 비교</h4>
</div>
<div class="card__chartWrapper">
<canvas id="vpnBarChart"></canvas>
</div>
</div>
...
<script>
var bar_chart_vpn = {{bar_chart_vpn}};
</script>
# js 코드
var vpn_bar = document.getElementById('vpnBarChart').getContext('2d');
var vpnBarChart = new Chart(vpn_bar, {
type: 'bar',
data: {
labels: ['DAY', 'WEEK', 'MONTH'],
datasets: [{
label: '지난 합계',
backgroundColor: 'rgba(103,59,167,0.1)',
hoverBackgroundColor: 'rgba(103,59,167,0.5)',
borderColor: 'rgba(103,59,167,1)',
borderWidth: 1,
data: bar_chart_vpn[0]
},
{
label: '이번 합계',
backgroundColor: 'rgba(247,50,63,0.1)',
hoverBackgroundColor: 'rgba(247,50,63,0.5)',
borderColor: 'rgba(247,50,63,1)',
borderWidth: 1,
data: bar_chart_vpn[1]
}]
},
options: {
responsive: true,
tooltips: {
mode: 'index',
intersect: false
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
yAxes: [{
ticks: {
stepSize: 1,
beginAtZero: true
},
gridLines: {
lineWidth: 0
}
}]
}
}
});
성공 ~