Chartjs-Adjust legend element alignment for chart.js

0👍

After having received not feedback on this issue, I guess this example may help others to get a quick solution, too, on how to create a sorted and much better looking legend for chart.js with keeping all interactions available.

This example generates fixed boxes for each item. It will break the legend items into a second row – keeping the colums width – while minimizing the width of the chart.

function updateLegendAction(e, datasetIndex) {
	var index = datasetIndex;
    var ci = e.view.chart;
    var meta = ci.getDatasetMeta(index);
    // See controller.isDatasetVisible comment
    meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
	document.getElementById("label"+index).style.opacity = document.getElementById("label"+index).style.opacity === '0.2' ? '1' : '0.2';
	// We hid a dataset ... rerender the chart
     ci.update();                                                                                      
};    

Chart.defaults.global.defaultFontFamily = 'Helvetica', 'Helvetica Neue', 'Arial', 'sans-serif';
Chart.defaults.global.defaultFontColor = 'grey';

var chart = new Chart(myChart, {
  type: 'line',
  data: {
  labels: ["January", "February", "March", "April"],
  datasets: [{
    label: "First dataset",
    fillColor: "rgba(220,220,220,0.2)",
    borderColor: "rgba(220,20,20,1)",
    pointColor: "rgba(220,20,20,1)",
    pointStrokeColor: "#fff",
    borderWidth: 3,
    pointHighlightFill: "#fff",
    pointHighlightStroke: "rgba(220,220,220,1)",
    data: [65, 59, 80, 81]
  }, {
    label: "Second dataset",
    fillColor: "rgba(151,187,205,0.2)",
    borderColor: "rgba(15,187,25,1)",
    pointColor: "rgba(15,187,25,1)",
    pointStrokeColor: "#fff",
    borderWidth: 3,
    pointHighlightFill: "#fff",
    pointHighlightStroke: "rgba(151,187,205,1)",
    data: [38, 55, 50, 65]
  },{
    label: "Third dataset",
    fillColor: "rgba(220,220,220,0.2)",
    borderColor: "rgba(220,20,20,1)",
    pointColor: "rgba(220,20,20,1)",
    pointStrokeColor: "#fff",
    borderWidth: 3,
    pointHighlightFill: "#fff",
    pointHighlightStroke: "rgba(220,220,220,1)",
    data: [4, 56, 34, 21]
  },{
    label: "And so on...",
    fillColor: "rgba(220,220,220,0.2)",
    borderColor: "rgba(220,20,20,1)",
    pointColor: "rgba(220,20,20,1)",
    pointStrokeColor: "#fff",
    borderWidth: 3,
    pointHighlightFill: "#fff",
    pointHighlightStroke: "rgba(220,220,220,1)",
    data: [25, 13, 11, 5]
  }]
  },
  options: {
      responsive: false,
      //Define a new HTML Legend
      legendCallback: function(legendarray) {
            var legendHtml = [];
			legendHtml.push('<div class="boxxcontainer">');
            for (var i=0; i<legendarray.data.datasets.length; i++) {
                legendHtml.push('<div id="label' + i + '" class="containerItem" style="width:' + (100/(legendarray.data.datasets.length)-1) +'%;"> <div class="boxx" style="background-color:' + legendarray.data.datasets[i].fillColor + '; border-top:' + legendarray.data.datasets[i].borderWidth +'px solid ' + legendarray.data.datasets[i].borderColor +';"></div>');                    
                if (legendarray.data.datasets[i].label) {
                    legendHtml.push('<div class="boxxlabel" onclick="updateLegendAction(event, ' + '\'' + legendarray.legend.legendItems[i].datasetIndex + '\'' + ')">&nbsp;' + legendarray.data.datasets[i].label + '</div></div>');
                }                                                                              
            }      			
			legendHtml.push('</div>');                                                   
            return legendHtml.join("");                                                        
        }, 
      legend: {
		   display: false,
	   },
     scales: {
      yAxes: [{
        ticks:{
          min: 0,
          max: 100,
         }
      }]
     }
      },
}, newlegend);
var newlegend = document.getElementById("htmllegend").innerHTML = chart.generateLegend();
div {
  font-family: 'Helvetica', 'Helvetica Neue', 'Arial', 'sans-serif';
}

.boxxcontainer {
  margin-left:30px;
  width: 90%;
  float: left;
}

.boxx {
  background-color: green;
  width: 10%;
  height: 15px;
  margin-left: 0%;
  float: left;
  line-height: 100%;
  display: block;
  border-top: 1px solid white;
}

.boxxlabel {
  color: grey;
  font-size: 13px;
  width: 86%;
  margin-left: 2%;
  float: left;
  line-height: 125%;
  display: block;
  cursor: pointer;
  -webkit-touch-callout: none;
  /* iOS Safari */
  -webkit-user-select: none;
  /* Safari */
  -khtml-user-select: none;
  /* Konqueror HTML */
  -moz-user-select: none;
  /* Firefox */
  -ms-user-select: none;
  /* Internet Explorer/Edge */
  user-select: none;
  /* Non-prefixed version, currently
                                  supported by Chrome and Opera */
}

.containerItem {
  height: 30px;
  min-width:150px;
  float: left;
  opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<div id="htmllegend"></div>
<canvas id="myChart" width="600" height="400"></canvas>

Leave a comment