Chartjs-Draw line between starting point and Ending point in semi doughnut chart in chart js

4👍

This is not war movie material. This is not justice-gone-wrong documentary material. But it should give you a thrill or two.

This is a plugin that works as follows. It draws The Thin Green Line along the start side of the first slice of the doughnut up to the center, and then continues along the end side of the last slice of the doughnut. It does so, in order to be able to use whatever doughnut circumference one would wish, e.g. 5/8 of the circle:

The Thin Green Line

Some (8 pixels) padding has been used, so that The Thin Green Line will have some room to extend a bit (4 pixels) beyond the slice. A working fiddle is here. The code (commented enough) is also available below.

var theThinGreenLinePlugin = {
  afterDatasetsDraw: function(chartInstance, easing) {
    // The context, needed for drawing.
    var ctx = chartInstance.chart.ctx;
    // The first (and, assuming, only) dataset.
    var dataset = chartInstance.data.datasets[0];
    // The dataset's data length.
    var datasetDataLength = dataset.data.length;
    // The model of the first slice.
    var firstDatumModel = dataset._meta[Object.keys(dataset._meta)[0]].data[0]._model;
    // The model of the last slice.
    var lastDatumModel = dataset._meta[Object.keys(dataset._meta)[0]].data[datasetDataLength - 1]._model;
    // The Thin Green Line's radius (measured from the center of the doughnut).
    // Add a few pixels to make the line extend a bit from the slice's outer radius.
    var lineRadius = firstDatumModel.outerRadius + 4;
    // The first point of The Thin Green Line (for the first slice).
    var firstSliceStartX = firstDatumModel.x + lineRadius * Math.cos(firstDatumModel.startAngle);
    var firstSliceStartY = firstDatumModel.y + lineRadius * Math.sin(firstDatumModel.startAngle);
    // The last point of The Thin Green Line (for the last slice).
    var lastSliceEndX = lastDatumModel.x + lineRadius * Math.cos(lastDatumModel.endAngle);
    var lastSliceEndY = lastDatumModel.y + lineRadius * Math.sin(lastDatumModel.endAngle);

    // Save the context, in order to mess with it. We will restore it later.
    ctx.save();

    // Green
    ctx.strokeStyle = '#3db24b';
    // Thin
    ctx.lineWidth = 4.0;
    ctx.beginPath();
    ctx.moveTo(firstSliceStartX, firstSliceStartY);
    // Go through the center, so that other doughnuts (e.g. 3/4 doughnuts) will make sense.
    ctx.lineTo(firstDatumModel.x, firstDatumModel.y);
    ctx.lineTo(lastSliceEndX, lastSliceEndY);
    ctx.stroke();

    // Restore the context.
    ctx.restore();
  }
};

Chart.pluginService.register(theThinGreenLinePlugin);

var ctx = document.getElementById("myChart");

var myChart = new Chart(ctx, {
  type: 'doughnut',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
      data: [12, 19, 3, 5, 2, 3],
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)',
        'rgba(75, 192, 192, 0.2)',
        'rgba(153, 102, 255, 0.2)',
        'rgba(255, 159, 64, 0.2)'
      ],
      borderColor: [
        'rgba(255,99,132,1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)',
        'rgba(153, 102, 255, 1)',
        'rgba(255, 159, 64, 1)'
      ],
      borderWidth: 1
    }]
  },
  options: {
    circumference: 1.0 * Math.PI,
    rotation: 1.0 * Math.PI,
    layout: {
      padding: 8
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>

Leave a comment