ChartJs Legend

by ellisdod

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>


<head></head>
<body>
  <div id="chart-container">
    <canvas id="line-chart"></canvas>
  </div>
  <div id="chart-legend">
  </div>
</body>

CSS

body {
  display:flex;
}
#chart-container {
  height: 35vh !important;
  flex:1;
  min-width:60%;
}

#chart-legend {
  width: 40%;
  flex:0;
  min-width:40px;
}

.legend-item div {
  display:inline-block;
  vertical-align: middle;
  margin-top:5px;
}
.legend-symbol {
  width:20px;
  height:20px;
}
.legend-label {
  font-family:sans-serif;
  font-size:10px;
  line-height:20px;
  margin-left:5px;
}

JavaScript

function legendBuilder (chart) {
      return chart.data.datasets.map((x,i)=>{
      
      const symbol = '<div class="legend-symbol" style="background-color:'+x.backgroundColor+'"></div>'
  
      const label = '<div class="legend-label">'+(x.label || '') + '</div>'
      
      return '<div onclick="toggleDataset('+i+')" class="legend-item">'+symbol+label+'</div>'
      }).join('')
      
}

function toggleDataset (index) {
  const dataset = myChart.data.datasets[index]
  dataset.hidden = !dataset.hidden
  myChart.update()
  const legendItem = document.getElementsByClassName('legend-item')[index]
  legendItem.style.opacity = dataset.hidden ? 0.4 : 1; 
}

console.log(Chart.prototype)
const myChart = new Chart(document.getElementById("line-chart"), {
        type: "line",
        data: {
          labels: ["Label1", "Label2", "Label3", "Label4"],
          datasets: [
            {
              label: "A",
              fill: false,
              data: [10, 30, 60, 100],
              borderWidth: 1,
              backgroundColor: "red",
              borderColor: "red",
            },
            {
              label: "B",
              fill: false,
              data: [28, 80, 60, 60],
              borderWidth: 1,
              backgroundColor: "green",
              borderColor: "green",
            },
          ],
        },
        options: {
          legendCallback : legendBuilder,
          legend: {
            display:false,
          },
          elements: {
            line: {
              tension: 0,
            },
          },
          responsive: true,
          maintainAspectRatio: false,
        },
      });
      

var myLegend = document.getElementById("chart-legend");
myLegend.innerHTML = myChart.generateLegend();