Chartjs-Chart.js (v3) Doughnut with rounded edges, but not everywhere

2๐Ÿ‘

โœ…

I have modified your code and made changes for roundedCornersFor. It will now take an object structure which will define take start and end as keys and the values will be the arc positions which are according to labels.

Chart.defaults.elements.arc.roundedCornersFor = {
  "start": 0, //0th position of Label 1
  "end": 2 //2nd position of Label 2
};

Below is the entire code snippet:

Chart.defaults.elements.arc.borderWidth = 0;
Chart.defaults.elements.arc.roundedCornersFor = {
  "start": 0, //0th position of Label 1
  "end": 2 //2nd position of Label 2
};

//Can be provided as array:
//Chart.defaults.elements.arc.roundedCornersFor = {
//  "start": [0,1,2],
//  "end": 3
//};

Chart.defaults.elements.arc.hoverBorderColor = 'white';

Chart.defaults.datasets.doughnut.cutout = '85%';

var chartInstance = new Chart(document.getElementById("chartJSContainer"), {
  type: 'doughnut',

  // The data for our dataset
  data: {
    labels: [
      'Label 1',
      'Label 2',
      'Label 3',
      'Label 4'
    ],
    datasets: [{
      label: 'My First Dataset',
      data: [22, 31, 26, 19],
      backgroundColor: [
        '#000000',
        '#ffff00',
        '#aaaaaa',
        '#ff0000'
      ]
    }]
  },
  //Inline Options...
  /*  options: {
    elements: {
      arc: {
        roundedCornersFor: {
          "start": 1, //0th position of Label 1
          "end": 1 //2nd position of Label 2
        }
      }
    }
  }, */
  plugins: [{
    afterUpdate: function(chart) {
      if (chart.options.elements.arc.roundedCornersFor !== undefined) {
        var arcValues = Object.values(chart.options.elements.arc.roundedCornersFor);

        arcValues.forEach(function(arcs) {
          arcs = Array.isArray(arcs) ? arcs : [arcs];
          arcs.forEach(function(i) {
            var arc = chart.getDatasetMeta(0).data[i];
            arc.round = {
              x: (chart.chartArea.left + chart.chartArea.right) / 2,
              y: (chart.chartArea.top + chart.chartArea.bottom) / 2,
              radius: (arc.outerRadius + arc.innerRadius) / 2,
              thickness: (arc.outerRadius - arc.innerRadius) / 2,
              backgroundColor: arc.options.backgroundColor
            }
          });
        });
      }
    },
    afterDraw: (chart) => {

      if (chart.options.elements.arc.roundedCornersFor !== undefined) {
        var {
          ctx,
          canvas
        } = chart;
        var arc,
          roundedCornersFor = chart.options.elements.arc.roundedCornersFor;
        for (var position in roundedCornersFor) {
          var values = Array.isArray(roundedCornersFor[position]) ? roundedCornersFor[position] : [roundedCornersFor[position]];
          values.forEach(p => {
            arc = chart.getDatasetMeta(0).data[p];
            var startAngle = Math.PI / 2 - arc.startAngle;
            var endAngle = Math.PI / 2 - arc.endAngle;
            ctx.save();
            ctx.translate(arc.round.x, arc.round.y);
            ctx.fillStyle = arc.options.backgroundColor;
            ctx.beginPath();
            if (position == "start") {
              ctx.arc(arc.round.radius * Math.sin(startAngle), arc.round.radius * Math.cos(startAngle), arc.round.thickness, 0, 2 * Math.PI);
            } else {
              ctx.arc(arc.round.radius * Math.sin(endAngle), arc.round.radius * Math.cos(endAngle), arc.round.thickness, 0, 2 * Math.PI);
            }
            ctx.closePath();
            ctx.fill();
            ctx.restore();
          });

        };
      }
    }
  }]
});
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.3.1/dist/chart.js"></script>

<body>
  <canvas id="chartJSContainer" width="200" height="200"></canvas>
</body>

Leave a comment