기능

- 라인 다중 차트(line multiple chart)

- 다중 차트 클릭 이벤트 제어(multiple chart click event control)

- 상시 레이블 출력( show label without mouseover)

html

canvas에 cMultiLineChart 생성

<canvas id="cMultiLineChart" style="min-height: 400px; height: 400px; max-height: 1000px; width: 700px; max-width: 100%;"></canvas>

javascript

chart.min.js : chart.js 3.x 사용을 위해 추가

chartjs-plugin-datalabels@2.0.0 : 마우스 오버없이 레이블을 항상 표시하기 위해 추가 ( chart.js 3.x 버전 부터는 2.0.0 사용)

 

[상시 레이블 출력 로직]

chart.js 3.x 버전에서 datalabels을 사용하기 위해서 반드시 chart config에 plugins: [ChartDataLabels] 추가 (중요)

plugins: [ChartDataLabels]를 추가하지 않는 경우, CDN을 추가하더라도 datalabels 인식이 되지 않음

 

data의 labels를 외부에서 입력 하는 경우

MultiLineChart.data.labels.push('월');

MultiLineChart.data.labels.push('화');

...

MultiLineChart.data.labels.push('일');

MultiLineChart.update();

 

group별 datasets의 data는 일반적으로 외부(DB)에서 조회 후 아래 형태로 입력

Chart_config.data.datasets[0].data.push(11);

Chart_config.data.datasets[0].data.push(22);

Chart_config.data.datasets[1].data.push(33);

Chart_config.data.datasets[1].data.push(44);

Chart_config.data.datasets[2].data.push(55);

Chart_config.data.datasets[2].data.push(66);

MultiLineChart.update();

 

datasets의 datalabels Color는 function을 사용하여 ctx값 추출하여 처리

예제는 value가 5 이상인 경우만 Color를 적용

function(ctx) {
    var value = ctx.dataset.data[ctx.dataIndex];
    return value > 5 ? ctx.dataset.backgroundColor : null;
}

color : label의 색상

backgroundColor : label 배경 색상

formatter : label 출력값

 

[클릭 이벤트 로직]

이벤트 발생 정보 조회

chart.js 3.x 이후 버전부터 getElementsAtEventForMode를 사용

var activePoints = C_Issue_analysis_range.getElementsAtEventForMode(evt, 'point', C_Issue_analysis_range.options);

chart.js 공식 가이드

 

클릭한 Chart의 그룹 인덱스 정보 ( 예제 에서는 Group 1, Group 2, Group 3 의 인덱스)
var datasetIndex = activePoints[0].datasetIndex

 

클릭한 그룹의 Value를 참조하기 위한 Index
var index = activePoints[0].index

 

Group label 정보

var label = MultiLineChart.data.datasets[datasetIndex].label;

 

클릭한 x좌표의 값 정보

var xlavel = MultiLineChart.scales["x"]._labelItems[index].label;

 

클릭한 Group의 Value값

var value = MultiLineChart.data.datasets[datasetIndex].data[index];

<script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.0/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>

// Chart ctx Create
var Chart_ctx = document.getElementById('cMultiLineChart').getContext('2d');

// Chart Config Set
Chart_config = {
    plugins: [ChartDataLabels],
    type: 'line',
    data: {
        labels: ['월','화','수','목','금','토','일'],
        datasets: [
            {
                label: 'Group 1',
                data: [1,1,2,2,3,3,4],
                backgroundColor: 'rgba(255, 99, 132, 0.2)',
                borderColor: 'rgba(255, 99, 132, 1)',
                borderWidth: 3,
                datalabels: {
                    labels: {
                        value: {
                            align: 'top',
                            backgroundColor: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 0 ? ctx.dataset.backgroundColor : null;
                            },
                            borderWidth: 2,
                            borderRadius: 4,
                            color: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 0 ? 'black' : null;
                            },
                            padding: 4
                        }
                    }
                }
            },
            {
                label: 'Group 2',
                data: [4,4,5,5,0,0,1],
                backgroundColor: 'rgba(54, 162, 235, 0.2)',
                borderColor: 'rgba(54, 162, 235, 1)',
                borderWidth: 3,
                datalabels: {
                    labels: {
                        value: {
                            align: 'top',
                            backgroundColor: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 0 ? ctx.dataset.backgroundColor : null;
                            },
                            borderWidth: 2,
                            borderRadius: 4,
                            color: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 0 ? 'black' : null;
                            },
                            padding: 4
                        }
                    }
                }
            },
            {
                label: 'Group 3',
                data: [0,0,7,8,9,4,1],
                backgroundColor: 'rgba(50, 220, 20, 0.2)',
                borderColor: 'rgba(50, 220, 20, 1)',
                borderWidth: 3,
                datalabels: {
                    labels: {
                        value: {
                            align: 'top',
                            backgroundColor: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 5 ? ctx.dataset.backgroundColor : null;
                            },
                            borderWidth: 2,
                            borderRadius: 4,
                            color: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 5 ? 'black' : null;
                            },
                            padding: 4
                        }
                    }
                }
            }
        ]
    },
    options: {
        responsive: true,
        scales: {
            y: { 
                beginAtZero: true
            }
        },
        plugins: {
            legend: {
                position: 'left',
            },
            title: {
                display: true,
                text: '그룹별 주간 카운트',
                font: {
                    size: 30
                }
            }
       }
    }
};

// Chart Create
var MultiLineChart = new Chart(Chart_ctx, Chart_config);

// Chart Click Event
document.getElementById("cMultiLineChart").onclick = function(evt) {

    var activePoints = MultiLineChart.getElementsAtEventForMode(evt, 'point', MultiLineChart.options);

    var datasetIndex = activePoints[0].datasetIndex
    var index = activePoints[0].index

    var label = C_Issue_analysis_interval.data.datasets[datasetIndex].label;
    var xlavel = C_Issue_analysis_interval.scales["x"]._labelItems[index].label
    var value = C_Issue_analysis_interval.data.datasets[datasetIndex].data[index]
    
    //alert(label + "  :  " + value + "  :  " + xlavel);

    //Process
};

참고

https://v2_0_0--chartjs-plugin-datalabels.netlify.app/guide/getting-started.html#installation

 

Getting Started | chartjs-plugin-datalabels

Getting Started Installation npm (opens new window) (opens new window) CDN (opens new window) (opens new window) By default, https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels returns the latest (minified) version, however it's highly recommended (open

v2_0_0--chartjs-plugin-datalabels.netlify.app

https://www.chartjs.org/docs/3.2.1/samples/tooltip/interactions.html

https://www.chartjs.org/docs/latest/getting-started/v3-migration.html

https://www.chartjs.org/docs/latest/developers/api.html

https://stackoverflow.com/questions/50515985/get-ylabel-value-onclick-chart-js

기능

1. Chart.js 2.x 버전 Pie Chart

2. 파이 차트 클릭 이벤트 ( Pie Chart Click Event ) - label 및 value 조회

3. 마우스 오버없이 레이블을 항상 백분율(%)값을 표시

 

html

* chart를 그리기 위한 canvas를 생성

* 다른 로직에서 canvas를 참고하기 위해 id를 지정 ( 예제는 cPieChart 으로 생성 )

<canvas id="cPieChart" style="min-height: 500px; height: 500px; max-height: 1000px; width: 700px; max-width: 100%;"></canvas>

javascript

* chart.js를 사용하기 위해 Chart.min.js 를 추가

* 마우스 오버없이 레이블을 항상 표시하기 위한 chartjs-plugin-datalabels@0.7.0 추가

 

* config의 data -> datasets -> datalabels 부분에 설정값을 지정

   align : 레이블 위치

   backgroundColor : ctx 정보를 가져와서 value가 0 이상인 경우만 출력

   color : ctx 정보를 가져와서 value가 0 이상인 경우만 출력

   formatter : value, ctx 정보를 가져와서 0 이상인 경우 백분율값을 구하여 리턴

 

* Pie Chart 생성 후 onClick Event 값을 가져와서 이벤트 처리

  getElementsAtEvent(evt) 함수로 클릭 이벤트 값을 조회

  activePoints[0]["_index"] 로 클릭한 차트의 위치값을 조회

   >> 만약 하나의 canvas에 여러개의 chart가 있는 경우 아래 형태로 조회

        activePoints[0]["_index"]

        activePoints[1]["_index"]

        activePoints[2]["_index"]

 

<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@0.7.0"></script>

// Pie Chart ctx Get
var PieChart_ctx = document.getElementById('cPieChart').getContext('2d');

// Pie Chart Config Set
PieChart_config = {
    type: 'pie',
    data: {
        labels: ['OPEN', 'PROGRESSING', 'COMPLETE'],
        data: [13,11,14],
        datasets: [{
            label: 'Pie Chart Count',
            backgroundColor: [
                        'rgba(255, 99, 132, 0.2)',
                        'rgba(54, 162, 235, 0.2)',
                        'rgba(75, 192, 192, 0.2)'
                        ],
            borderColor: [
                        'rgba(255, 99, 132, 1)',
                        'rgba(54, 162, 235, 1)',
                        'rgba(75, 192, 192, 1)'
                        ],
            borderWidth: 1,
            datalabels: {
                labels: {
                    value: {
                        borderWidth: 2,
                        borderRadius: 4,
                        font: {size: 15},
                        formatter: function(value, ctx) {
                            var value = ctx.dataset.data[ctx.dataIndex];
                            return value > 0 ? Math.round(value / (ctx.dataset.data[0] + ctx.dataset.data[1] + ctx.dataset.data[2]) * 100) + ' %' : null;
                        },
                        color: function(ctx) {
                            var value = ctx.dataset.data[ctx.dataIndex];
                            return value > 0 ? 'white' : null;
                        },
                        backgroundColor:function(ctx) {
                            var value = ctx.dataset.data[ctx.dataIndex];
                            return value > 0 ? 'gray' : null;
                        },
                        padding: 4
                    }
                }
            }
        }]
    },
    options: {
        responsive: true,
        maintainAspectRatio : false,
        animation: false,
        legend: {
            position: 'left',
            display: true
        },
        title: {
            display: false,
            text: 'Pie Chart - Count',
            font: {
                size: 50
            },
            fontstyle: 'bold',
            position: 'top'
        }, 
        plugins: {
            legend: {
                position: 'left',
            },
            title: {
                display: true,
                text: 'Pie Chart - Count',
                font: { 
                    size: 25
                }
            }
        }
    }
};


// Pie Chart Create
var PieChart = new Chart(PieChart_ctx, PieChart_config);

// Pie Chart Event Set
document.getElementById("cPieChart").onclick = function(evt) {

    var activePoints = PieChart.getElementsAtEvent(evt);

    if(activePoints.length > 0)
    {
        //get the internal index of slice in pie chart
        var clickedElementindex = activePoints[0]["_index"];

        //get specific label by index 
        var label = PieChart.data.labels[clickedElementindex];

        //get value by index      
        var value = PieChart.data.datasets[0].data[clickedElementindex];

        // label and value Process
        
   }
};

참고

https://stackoverflow.com/questions/26257268/click-events-on-pie-charts-in-chart-js

https://chartjs-plugin-datalabels.netlify.app/samples/charts/line.html

https://chartjs-plugin-datalabels.netlify.app/samples/advanced/multiple-labels.html

 

Multiple Labels | chartjs-plugin-datalabels

Multiple Labels Use multiple labels configuration to display 3 labels per data, one for the index, one for the label and one for the value. Move the mouse over the chart to display label ids. { type: 'doughnut', data: { labels: labels, datasets: [{ backgro

chartjs-plugin-datalabels.netlify.app

 


to Top