Search code examples
javascriptjqueryhtml5-canvaschart.js

ChartJs - Round borders on a doughnut chart with multiple datasets


I have a regular Chartjs doughnut chart with multiple datasets, using this code for the dataset:

datasets: 
    [
        {
            label: 'Bugs',
            data: [ 60 , 6.6666666666667 , 33.333333333333 ],
            backgroundColor: ['#25CFE4', '#92E7F1', '#eeeeee'],
        }, {
            label: 'Fixes',
            data: [ 60 , 0.44444444444444 , 39.555555555556 ],
            backgroundColor: ['#514463', '#8C75AB', '#eeeeee'],
        }, {
            label: 'Redesigns',
            data: [
            33.333333333333 , 10.37037037037 , 56.296296296296 ],
            backgroundColor: ['#1B745F', '#40C1A0', '#eeeeee'],
        }
    ]
};

I am trying to implement rounded edges on the scales, I manage to make the first one round, but no luck with the others.

Basically, this is what I have now

enter image description here

And this is what I am trying to achieve (sorry for the poor photoshop)

enter image description here

I don't mind if the start of the scale is also round or the grey area (which I painted grey just to give the impression of something not yet filled) gas round edges too.

Thanks


Solution

  • Made a few more adjustments and finally got it.This does exactly what you want:

        Chart.pluginService.register({
            afterUpdate: function (chart) {
                    var a=chart.config.data.datasets.length -1;
                    for (let i in chart.config.data.datasets) {
                        for(var j = chart.config.data.datasets[i].data.length - 1; j>= 0;--j) { 
                            if (Number(j) == (chart.config.data.datasets[i].data.length - 1))
                                continue;
                            var arc = chart.getDatasetMeta(i).data[j];
                            arc.round = {
                                x: (chart.chartArea.left + chart.chartArea.right) / 2,
                                y: (chart.chartArea.top + chart.chartArea.bottom) / 2,
                                radius: chart.innerRadius + chart.radiusLength / 2 + (a * chart.radiusLength),
                                thickness: chart.radiusLength / 2 - 1,
                                backgroundColor: arc._model.backgroundColor
                            }
                        }
                        a--;
                    }
            },
    
            afterDraw: function (chart) {
                    var ctx = chart.chart.ctx;
                    for (let i in chart.config.data.datasets) {
                        for(var j = chart.config.data.datasets[i].data.length - 1; j>= 0;--j) { 
                            if (Number(j) == (chart.config.data.datasets[i].data.length - 1))
                                continue;
                            var arc = chart.getDatasetMeta(i).data[j];
                            var startAngle = Math.PI / 2 - arc._view.startAngle;
                            var endAngle = Math.PI / 2 - arc._view.endAngle;
    
                            ctx.save();
                            ctx.translate(arc.round.x, arc.round.y);
                            console.log(arc.round.startAngle)
                            ctx.fillStyle = arc.round.backgroundColor;
                            ctx.beginPath();
                            //ctx.arc(arc.round.radius * Math.sin(startAngle), arc.round.radius * Math.cos(startAngle), arc.round.thickness, 0, 2 * Math.PI);
                            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();
                        }
                    }
            },
        });
    

    Fiddle - http://jsfiddle.net/tgyxmkLj/1/