Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chart.js Legend Customization

I was having some problem with self-customized chart legend for chart.js. This is how my doughtnut chart looks like:

As you can see, the legend at the side is not showing the colored-square icon. By right, it should look like this:

My HTML for the chart:

<canvas id="merchantChart" height="660" width="330"></canvas>
<div id="merchantLegend" class="chart-legend"></div>

This is the part where I set the color for each slice and override the default chart legend provided by chart.js:

var opt = {
      type: "doughnut",
      data: { 
        labels: labelData, 
        datasets: [{ 
        data: priceData, 
        backgroundColor:  "rgba(220,220,220,0)",
        borderColor: colorArr,
        borderWidth: 1.5,
        hoverBackgroundColor: colorArr
        }] 
      }, 
      options: options
    };

    if (merchantChart) merchantChart.destroy();
    merchantChart = new Chart(ctx, opt);

    merchantChart.update(); 
    merchantLegend.innerHTML = merchantChart.generateLegend();

As you can see, because I am setting the backgroundColor for each slice to be transparent, is there any way to generateLegend() based on the borderColor of each slice?

Thanks!

like image 936
BlackMamba Avatar asked Sep 23 '17 15:09

BlackMamba


People also ask

What is legend in ChartJS?

The chart legend displays data about the datasets that are appearing on the chart.

How do you wrap a legend text in ChartJS?

To make this behave the same as standard Chart. js charts, the function onLegendClicked is invoked when a mouse click occurs on a legend label. This function toggles the hidden state of individual datasets and changes label text style between normal and strike-through.


2 Answers

legendCallback method can be used to manipulate how legend­'s labels are generated. so, using this you can customize legend­'s box-color as well (such as, using datasets border-color instead of background-color), like so :

legendCallback: function(chart) {
   var ul = document.createElement('ul');
   var borderColor = chart.data.datasets[0].borderColor;
   chart.data.labels.forEach(function(label, index) {
      ul.innerHTML += `
        <li>
            <span style="background-color: ${borderColor[index]}"></span>
            ${label}
         </li>
      `; // ^ ES6 Template String
   });
   return ul.outerHTML;
}

ᴅᴇᴍᴏ ⧩

var chart = new Chart(ctx, {
   type: 'doughnut',
   data: {
      labels: ['Jan', 'Feb', 'Mar'],
      datasets: [{
         data: [1, 1, 1],
         backgroundColor: 'rgba(0, 0, 0, 0)',
         borderColor: ['#ff9800', '#e91e63', '#2196f3']
      }]
   },
   options: {
      responsive: false,
      legend: false,
      legendCallback: function(chart) {
         var ul = document.createElement('ul');
         var borderColor = chart.data.datasets[0].borderColor;
         chart.data.labels.forEach(function(label, index) {
            ul.innerHTML += `
            	<li>
               	<span style="background-color: ${borderColor[index]}"></span>
                  ${label}
               </li>
            `; // ^ ES6 Template String
         });
         return ul.outerHTML;
      }
   }
});

legend.innerHTML = chart.generateLegend();
.chart-container {
   display: flex;
}

#legend ul {
   list-style: none;
   font: 12px Verdana;
   white-space: nowrap;
}

#legend li span {
   width: 36px;
   height: 12px;
   display: inline-block;
   margin: 0 5px 8px 0;
   vertical-align: -9.4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<div class="chart-container">
   <canvas id="ctx"></canvas>
   <div id="legend"></div>
</div>
like image 127
ɢʀᴜɴᴛ Avatar answered Oct 20 '22 06:10

ɢʀᴜɴᴛ


legend customize with table to display multiple values

var data = [{
    value: 2755,
    usedValue:100,
    color: "#FFE135",
    label: "Bare Pipe"
}, {
    value: 2256,
    usedValue:200,
    color: "#3B5323",
    label: "Coated Pipe"
}, {
    value: 1637,
    usedValue:300,
    color: "#fc6c85",
    label: "Cement Lining"
}];
var str=""
str+='<table>';
str+='<thead><tr><td>Item Name</td><td>Scope</td><td>Used in Construction</td></tr></thead>';
str+='<tbody>';
$.each(data, function(k,v){
    if(k =>0){
      str+='<tr><td>'+ v.label +'</td><td style="background-color:'+v.color+'">'+v.value+'</td><td style="background-color:'+v.color+'">'+v.usedValue+'</td></tr>';  
    }
});
str+='</tbody></table>';
//debigger;
    var optionsPie = {
        scaleBeginAtZero: false,
        legendTemplate: str
    }

    var ctx = $("#top10ItemsChart").get(0).getContext("2d");
    var top10PieChart = new Chart(ctx).Pie(data, optionsPie);
$("#top10Legend").html(top10PieChart.generateLegend());
    .topleft {
        margin-top: -4px;
        margin-left: 16px;
        margin-bottom: 16px;
        padding: 16px;
        border: 1px solid black;
    }

canvas {
    width: 100% !important;
    height: auto !important;
    margin-left: -25%;
}

.chart {
    border: 1px solid forestgreen;
    width: 100%;
    overflow: hidden;
    position: relative;
}

.pie {
    position: relative;
    padding: 10px 0;
    // adjust as necessary
    padding-left: 10px;
    padding-right: 0;
}

table td{border:1px solid #ddd; text-align:center; padding:5px}
.legend {
    position: absolute;
    right: 10px;
    top: 10px;
    height: 100%;
    // adjust as necessary:
    width: 48%;
}

@media (max-width: 480px) {
    .legend {
        position: relative;
        width: 100%;
    }
    .pie {
        margin: 0;
    }
}

.pie-legend ul {
    list-style: none;
    margin: 0;
    padding: 0;
    width: 300px;
}

.pie-legend span {
    display: inline-block;
    width: 14px;
    height: 12px;
    border-radius: 100%;
    margin-right: 4px;
    margin-bottom: -2px;
}

.pie-legend li {
    margin-bottom: 4px;
    display: inline-block;
    margin-right: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.1.0/Chart.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-6">
    <div class="topleft">
        <h2 class="sectiontext">Top 10 Items</h2>
        <br />
        <div class="chart">
            <div class="pie">
                <canvas id="top10ItemsChart" class="pie"></canvas>
            </div>
            <div class="legend" id="top10Legend">
            </div>
        </div>
    </div>
</div>
</div>
</div>
Working Example : https://codepen.io/santosh-k1/pen/jOEXdZOenter code here
like image 32
SantoshK Avatar answered Oct 20 '22 08:10

SantoshK