달력

11

« 2024/11 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
반응형

※ 해당 글은 아래 글과 연결되어 있습니다.

혹시 잘 안되거나 이해 안 되는 부분이 있으시면 아래 글을 참조하여 주세요.

http://risha-lee.tistory.com/18?category=764955

 

 

 

앞서 말했다시피 사용자 범례를 이전 글처럼 만들기만 해서는 

위 그림처럼 범례 클릭 시 해당 데이터셋의 숨김/보이기 토글 기능을 사용할 수 없다.

 

해당 기능을 만들려면 이전 글의 코드에 다음과 같이 추가로 코드를 작성해주어야 한다.

 

<script>
	 window.onload = function() {
		$("#chartLegend li").click(function(){
			updateDataset(event, $(this).attr("datasetIndex"), "theChart");
			if($(this).css("text-decoration").indexOf("line-through")<0){
				$(this).css("text-decoration", "line-through");
			} else{
				$(this).css("text-decoration", "none");
			}
		});
	 }

	 //범례 클릭시 해당 데이터셋이 숨김/보이기 토글 기능 함수
	 function updateDataset(e, datasetIndex, chartId) {
		var index = datasetIndex;
		var ci = e.view[chartId];
		var meta = ci.getDatasetMeta(index);
		var scaleList = ci.options.scales["yAxes"];
        
		meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
		ci.update();
	 }
</script>

 

참고 : https://github.com/chartjs/Chart.js/issues/2565

 

반응형
:
Posted by 리샤씨
반응형

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>

 

그러나 이것만 해서는.. 기본 범례에서 제공하는 범례를 클릭하면 

해당 데이터셋의 숨김/보이기 토글이 작동하지 않아 다소 불편했다.

그래서 나는 사용자 범례에 해당 기능도 추가했었다.

 

다음 글에서 설명하도록 하겠다.

반응형
:
Posted by 리샤씨


반응형
반응형