chart.js 그래프 만들기

파오리·2021년 2월 19일
1

아주 작은 기록

목록 보기
3/13

막대 그래프, 선 그래프, 거미줄 그래프, 파이 그래프 등등..
chart.js를 이용하여 그래프 만들기
chart.js 공식 문서

사실 공식 문서만 봐도 어려울 게 없다.
그렇지만 처음 써봤으니까 기록을 남긴다.

공식 문서의 samples 에 들어가면 그래프 모양 별로 샘플을 다양하게 볼 수 있고,
해당 샘플에서 페이지 소스를 보면 코드도 다~ 볼 수 있다.

나는 이 중에서 line chart, pie chart, bar chart를 만들었다.

요로코롬.

프로젝트 상황: django를 쓰고 있고, js와 html파일은 분리되어 있음

pie chart

# 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
        }]
    }
});

이렇게만 해주면 끝 !

line chart

# 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축 격자선 없애기
                }
            }]
        }
    }
});

bar chart

# 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
                }
            }]
        }
    }
});

성공 ~

profile
경험 == 배움

0개의 댓글