2019. 1. 9. 13:53
Chart.js에서 사용자 범례 만드는 법 개발/Chart.js2019. 1. 9. 13:53
반응형
Chart.js가 기본적으로 제공하는 범례는 그냥 위치를 위나 아래로 정하면 무조건 가운데 정렬만 할 뿐,
왼쪽 위. 오른쪽 위, 오른쪽 아래, 왼쪽 아래 등 위치를 자유자재로 변경할 수 없어서
오른쪽 위에 범례를 두기 위해 사용자 범례를 사용했었다.
물론 디자인도 자유자재로 변경할 수 있다는 점이 마음에 들어서 위치를 바꿀 겸 범례의 디자인도 조정하였다.
추가로 덧붙이자면 Chart.js에서 제공하는 기본 범례를 사용하면 그래프가 길어져 스크롤이 생겼을 때,
스크롤 위치에 따라 어떤 부분에서는 범례가 보이지만 어떤 부분에서는 범례가 보이지 않을 수 있다.
사용자 범례를 사용하면 위의 문제점도 해결해준다. (차트를 좌우로 스크롤해도 범례의 위치는 고정된다)
1. 막대 차트&막대 라인 차트 - 막대 형식 데이터셋 원형, 라인 형식 데이터셋 선형 범례
2. 라인 차트 - 라인 형식 데이터셋 사각형 범례
별다른 설정 없이 막대 차트냐, 라인 차트냐, 해당 데이터셋의 형식이 라인이냐 바이냐에 따라 자동으로 class를 입히도록 작성하였다.
아래의 코드를 사용하면 위와 같은 범례를 만들 수 있다. 예제는 막대 라인 차트이다.
<style type="text/css">
.chartjs-legend ol,
.chartjs-legend ul {
list-style: none;
margin:0;
padding:0;
text-align:right;
}
.chartjs-legend li {
cursor:pointer;
display: inline-table;
margin: 10px 4px;
}
.chartjs-legend li span.bar{
position:relative;
padding: 0px 10px;
margin: 5px;
border-radius:100px;
color:white;
}
.chartjs-legend li span.line{
position:relative;
padding: 1px 10px;
margin: 5px;
color:white;
}
.chartjs-legend li div.line{
float:left;
height:2px;
background:#000;
font-size:0;
line-height:0;
width:25px;
padding:1px 0px;
border-radius:100px;
margin: 9px 5px;
}
</style>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.bundle.min.js"></script>
<script>
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
type: 'line',
label: 'line',
borderColor: "#1E90FF",
fill: false,
data: [
Math.random()*90000,
Math.random()*90000,
Math.random()*90000,
Math.random()*90000,
Math.random()*90000,
Math.random()*90000,
Math.random()*90000
]
},
{
type: 'bar',
label: 'bar',
backgroundColor: "#F7464A",
data: [
Math.random()*90000,
Math.random()*90000,
Math.random()*90000,
Math.random()*90000,
Math.random()*90000,
Math.random()*90000,
Math.random()*90000
]
}]
};
window.onload = function() {
var ctx = $('#chart').get(0).getContext("2d");
window.theChart = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
legend: false,
legendCallback: function(chart){
return drawCustomLegend(chart);
}// 사용자 범례를 만들 때 쓰는 함수를 지정하거나 작성한다.
}
});
$('#chartLegend').html(window.theChart.generateLegend());//사용자 범례 자리에 해당 차트에 대한 사용자 범례 코드를 넣는다.
}
function drawCustomLegend(chart){
var text = [];
text.push('<ul class="' + chart.id + '-legend">');
if(chart.config.type == 'bar'){//막대차트, 막대라인차트일 경우
var barIndex = chart.data.datasets.length;
for (var i = 0; i <chart.data.datasets.length; i++) {
if(chart.data.datasets[i].type == 'line' == false){
barIndex = i;
break;
}
}//라인 형식 데이터셋이 어디까지인지 확인
// -> 막대 형식의 데이터셋을 라인 형식의 데이터셋보다 앞에 둘 경우 라인이 막대에 묻히기 때문에 라인 형식이 먼저 올 수 밖에 없다.
//그러나 막대 형식의 데이터셋의 범례를 먼저 그리고 싶었기 때문에 해당 작업을 했다.
for (i = barIndex; i <chart.data.datasets.length; i++) {
if(!(chart.data.datasets[i].hideLegend) && chart.data.datasets[i].label){
text.push('<li datasetIndex="'+i+'"><span class="bar" style="background-color:' + chart.data.datasets[i].backgroundColor + '" ></span>');
text.push('<span>'+chart.data.datasets[i].label+'</span>');
text.push('</li>');
}
}//막대 형식 데이터셋의 범례를 먼저 그림
for (i = 0; i <barIndex; i++) {
if(!(chart.data.datasets[i].hideLegend) && chart.data.datasets[i].label){
text.push('<li datasetIndex="'+i+'"><div class="line" style="background:' + chart.data.datasets[i].borderColor + '"></div>');
text.push('<span>'+chart.data.datasets[i].label+'</span>');
text.push('</li>');
}
}//막대 형식 데이터셋의 범례를 그린 후 라인 형식 데이터셋의 범례를 그림.
} else if(chart.config.type == 'line'){//라인 차트일 경우
for (i = 0; i <chart.data.datasets.length; i++) {
if(!(chart.data.datasets[i].hideLegend) && chart.data.datasets[i].label){
text.push('<li datasetIndex="'+i+'"><span class="line" style="background-color:' + chart.data.datasets[i].borderColor + '"></span>');
text.push('<span>'+chart.data.datasets[i].label+'</span>');
text.push('</li>');
}
}
}
text.push('</ul>');
return text.join("");
}
</script>
<div id="chartArea" style="width:700px;">
<div id="chartLegend" class="chartjs-legend"></div>
<canvas id="chart"></canvas>
</div>
그러나 이것만 해서는.. 기본 범례에서 제공하는 범례를 클릭하면
해당 데이터셋의 숨김/보이기 토글이 작동하지 않아 다소 불편했다.
그래서 나는 사용자 범례에 해당 기능도 추가했었다.
다음 글에서 설명하도록 하겠다.
반응형
'개발 > Chart.js' 카테고리의 다른 글
Chart.js Pie 데이터 값 출력 (0) | 2020.01.03 |
---|---|
Chart.js에서 사용자 범례에 기존 범례기능(누르면 숨김/보이기 토글) 넣기 (0) | 2019.01.09 |
Chart.js에서 그래프 위에 값 그리는 법 (2) | 2017.12.12 |
Chart.js에서 도넛/반도넛 차트 가운데에 숫자 적는 법 (0) | 2017.12.12 |
Chart.js에서 반도넛 그래프 그리는 법 (9) | 2017.12.12 |