Search code examples
javascriptchartsbar-chartrounded-cornerschart.js

How to put rounded corners on a Chart.js Bar chart


I have created a bar chart in chart.js using the below code. However I want to give the bars rounded corners instead of edged ones at the top of the bars. I can't find any way to do this using the global settings of chart.js. Is there any way to achieve the effect I want?

var barContext = document.getElementById("canvas").getContext("2d");

var barGradientFirst = barContext.createLinearGradient(0, 0, 0, 450);
barGradientFirst.addColorStop(0, 'rgba(112,122,157, 0.1)');   
barGradientFirst.addColorStop(1, 'rgba(112,122,157, 1)');

var barGradientSecond = barContext.createLinearGradient(0, 0, 0, 450);
barGradientSecond.addColorStop(0, 'rgba(151,122,208, 0.1 )');  
barGradientSecond.addColorStop(1, 'rgba(151,122,208, 1)');


var barChartData = {
labels: ["High", "Med", "Low", "None"],
datasets : [
    {
        fillColor : barGradientFirst,
        strokeColor: "rgb(112,122,200)",
        data: [30, 40, 70, 90]
    }, {
        fillColor : barGradientSecond,
        strokeColor: "rgba(220,100,80,0.8)",
        data: [50, 60, 65, 20]
    }]  
};

new Chart(barContext).Bar(barChartData, {
    responsive : true,
    scaleOverride : true,
    scaleBeginAtZero : true,
    scaleSteps : 2,
    scaleLineWidth: 3,
    scaleStepWidth : 50,
    scaleShowLabels : true,
    scaleShowVerticalLines: false,
    scaleShowHorizontalLines: false,
    scaleFontSize: 30,
    barValueSpacing : 40,
    barDatasetSpacing : 3,
    scaleLabel: "<%= value + '%' %>"
});

Solution

  • As pointed out in https://stackoverflow.com/a/68778432/360067, this is natively implemented in v3.


    Original Answer

    Here is how you extend Chart.js to draw a bar chart with rounded corners.

    Chart.types.Bar.extend({
        name: "BarAlt",
        initialize: function (data) {
            Chart.types.Bar.prototype.initialize.apply(this, arguments);
                
            if (this.options.curvature !== undefined && this.options.curvature <= 1) {
                var rectangleDraw = this.datasets[0].bars[0].draw;
                var self = this;
                var radius = this.datasets[0].bars[0].width * this.options.curvature * 0.5;
    
                // override the rectangle draw with ours
                this.datasets.forEach(function (dataset) {
                    dataset.bars.forEach(function (bar) {
                        bar.draw = function () {
                            // draw the original bar a little down (so that our curve brings it to its original position)
                            var y = bar.y;
                            // the min is required so animation does not start from below the axes
                            bar.y = Math.min(bar.y + radius, self.scale.endPoint - 1);
                            // adjust the bar radius depending on how much of a curve we can draw
                            var barRadius = (bar.y - y);
                            rectangleDraw.apply(bar, arguments);
    
                            // draw a rounded rectangle on top
                            Chart.helpers.drawRoundedRectangle(self.chart.ctx, bar.x - bar.width / 2, bar.y - barRadius + 1, bar.width, bar.height, barRadius);
                            ctx.fill();
    
                            // restore the y value
                            bar.y = y;
                        }
                    })
                })
            }
        }
    });
    
    
    var lineChartData = {
        labels: ["January", "February", "March", "April", "May", "June"],
        datasets: [
            {
                fillColor: "#79D1CF",
                strokeColor: "#79D1CF",
                data: [60, 80, 81, 56, 55, 40]
            },
            {
                fillColor: "#D1CF79",
                strokeColor: "#D1CF79",
                data: [34, 43, 43, 12, 65, 65]
            }
        ]
    };
    
    var ctx = document.getElementById("myChart").getContext("2d");
    var myLine = new Chart(ctx).BarAlt(lineChartData, {
        // 0 (flat) to 1 (more curvy)
        curvature: 1
    });
    

    You could simplify the code a bit if you don't need the animation.


    Fiddle - http://jsfiddle.net/0dzp3jxw/


    enter image description here