16

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 + '%' %>"
});
c0d3appl3
  • 163
  • 1
  • 1
  • 5
  • Pretty good, clear and concise first question. It is only missing a little info about what you've already tried (i.e. looking in documentation, reading through properties, or changing some of them) – jumps4fun Jul 23 '15 at 08:58
  • Well I did check the documentation [here](http://www.chartjs.org/docs/) and there does not seem to be anything that allows me to alter the shape of the bars, except in size and width. As I am quite new to javascript, I am not sure what else to tell you – c0d3appl3 Jul 23 '15 at 09:03
  • hmmm... I've worked a little with Highcharts before, and it renders the charts as a collection of html elements. There I can edit the css of the individual displayed elements, but that seems not to be the case here. It is simply displayed as an image.... – jumps4fun Jul 23 '15 at 09:29
  • @c0d3appl3 - it's possible to draw rounded rectangles in chartjs (there is no configuration, but you can extend an existing chart to do this). There is a helper method and you can see it when in action on tooltips. – potatopeelings Jul 24 '15 at 09:32
  • No more pain. This will be added in the next major release. https://www.chartjs.org/docs/master/charts/bar#borderradius – Rem Dec 09 '20 at 01:15

2 Answers2

20

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

potatopeelings
  • 40,709
  • 7
  • 95
  • 119
  • 1
    No worries. It was fun figuring it out :-) – potatopeelings Jul 27 '15 at 12:49
  • what would I do if the chart was too low a value. I am finding that the rounded rectangle either hovers just above the bar or goes through the bottom of the chart? – c0d3appl3 Jul 27 '15 at 13:26
  • Wow, great job. I had to check if my answer was wrong. I see that it is not, yours is just better ;) – jumps4fun Jul 27 '15 at 13:30
  • All credit to nnnick who developed Chartjs - it is amazingly flexible and the code is extremely readable. Cheers! – potatopeelings Jul 27 '15 at 13:41
  • @c0d3appl3 - could you update the fiddle with the data causing that problem? – potatopeelings Jul 27 '15 at 13:47
  • @c0d3appl3 - I think I see what you mean - the scale is off if the value is low and the curvature is high. I've edited a couple of lines in the answer so that the curvature adjusts itself for the lower values and updated the fiddle. Check it out. Cheers! – potatopeelings Jul 27 '15 at 13:56
  • Would there be a way so that when a value of a bar is 0 the bar disappears instead of being a very small bar? Every time I try to achieve this the curvature gets removed. – c0d3appl3 Jul 29 '15 at 08:24
  • I removed the -1 from the self.scale.endPoint and it worked :) – c0d3appl3 Jul 29 '15 at 09:37
  • Cheers! I was going to suggest setting the color to transparent but removing the -1 is better. – potatopeelings Jul 29 '15 at 09:55
  • 1
    Does anyone know how to use this with angular-chart? (Wrapper for chartjs) – Peheje Jul 12 '16 at 08:42
  • 1
    @potatopeelings your answer is fantastic! I would love to apply your junk of code to extend my bar chart using chart.js v2.0. Any idea how to do this ? See here http://stackoverflow.com/questions/38633014/extending-existing-chart-types-angular-chart-js-using-chart-js-2-0 – Jibeee Jul 28 '16 at 16:57
  • @potatopeelings - Could you please let me know what plugin do I need to install in order to use above code, is that free? Currently I am using `chart.js": "^2chart.js.9.3` plugin. I am using VS code with Angular. Thank you. – R15 Jul 07 '20 at 14:58
  • 1
    Rounded corners are natively implemented on v3 https://stackoverflow.com/a/68778432/1922733 – Franco Altuna Nov 24 '21 at 18:35
6

Starting on Chart.js v3 you can just specify borderRadius: NUMBER on the dataset.

new Chart(document.querySelector('canvas').getContext('2d'), {
        type: 'bar',
        data: {
            labels: ['1','2','3','4','5','6'],
            datasets: [{
                label: 'Sales',
                data: [20,30,10,20,30,10],
                fill: true,
                borderRadius: 15,
                borderColor: '#5eb8ff',
                backgroundColor: '#5eb8ff',
                datalabels: {
                    display: false
                }
            }]
        }
    });
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <canvas></canvas>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/chart.js@3.0.0/dist/chart.min.js"></script>
</body>
</html>
Franco Altuna
  • 188
  • 1
  • 3
  • 12