How to create rounded bars for Bar Chart.js v2?
Asked Answered
E

6

17

Trying to round the bars on bar chart as found in this post that works as displayed in the jsFiddle provided. This is for version 1.

In the chart that I am using, it fails to load for the reference to extend in Chart.types.Bar.extend crashes the script.

If I use the default option, the chart loads no problems. I had to place the Chart.types.Bar.extend at the end for the default option to load correctly. Run and View this in Full Screen.

I tried implementing this with my version of Chart.js 2.4.0.

Chrome reports:

Uncaught TypeError: Cannot read property 'extend' of undefined chart.js

This code will not even run here. Why is this occurring? Could someone please assist me.

This code works with an older version of Chart.js 1.0. Could anyone please further display how this could work with version Chart.js 2.0? Thank you.

$(document).ready(function(){

	var myBarChart1 = new Chart($('#appBarChart2_NoRound'), {
		type: 'bar',
		data: dataBar2,
		options: optionsBar
	});
  
  var ctx = $("#appBarChart2").getContext("2d");

  	var myBarChart2 = new Chart(ctx).BarAlt(dataBarAlt2, {
		// 0 (flat) to 1 (more curvy)
		curvature: 1
	});
});

var dataBarAlt2 = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
        {
            fillColor: "#1A9BFC",
            strokeColor: "#1A9BFC",
            data: [65, 59, 80, 81, 56, 55, 40],
        }
    ]
};

var dataBar2 = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
        {
            label: "My First dataset",
            backgroundColor: '#1A9BFC',
            borderColor:'#1A9BFC',
            borderWidth: 1,
            data: [65, 59, 80, 81, 56, 55, 40],
        }
    ]
};

var optionsBar =
		{
        scales: {
            xAxes: [{
                stacked: true,
				barThickness: 20,
				gridLines:{
					display:false,
				}
//				barPercentage:0.5,
            }],
            yAxes: [{
                stacked: true,
				
//				barPercentage:0.5,
            }]
        },
		legend: {
			display: false,
//			position: 'left'
		 }
    };


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;
                    }
                })
            })
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<p>Bar Chart - Working</p>
<canvas id="appBarChart2_NoRound" height="100" >
</div>
<div>
<p>Rounded Bar Chart - Not Working</p>
<canvas id="appBarChart2" height="100" >
</div>
Eula answered 6/4, 2017 at 11:39 Comment(5)
The reason this code won't work is because its for chart.js v1. Chart.js v2 is a major re-factor and there isn't even a Chart.types namespace anymore. So that answers your question for "why doesn't this work"? Maybe you want to ask a new question for how to create rounded bars in chart.js 2.0?Silvana
@Silvana When I hold shift and click on types it brings me to the core.controller.js. I know this snippet when running reports a different issue. It could be related to online version I included in the example which 2.5.0Eula
Maybe they kept the namespace for posterity or something then. But the bottom line is that v2 is very different from v1 and you will need to re-write the code you are trying to use for v2. Let me know if you would like me to provide an answer for a similar capability but for v2?Silvana
@Silvana I would be forever grateful if you could provide a rounded bar chart example. :)Eula
Rem posted an Answer saying "This will be added in next major release. chartjs.org/docs/master/charts/bar#borderradius"Harker
S
22

The code that you were trying to use is actually for chart.js v1 and, as you discovered, does not work for chart.js v2 (which is almost a full chart.js re-write).

To achieve the same results in chart.js v2, you need to extend Chart.elements.Rectangle and overwrite it's draw method in order to paint the rounded top. There is already a chart.js helper method that will draw a rounded rectangle (Chart.helpers.drawRoundedRectangle), so we will modify it slightly and create a new helper method that will only draw a rounded top (instead of all sides).

// draws a rectangle with a rounded top
Chart.helpers.drawRoundedTopRectangle = function(ctx, x, y, width, height, radius) {
  ctx.beginPath();
  ctx.moveTo(x + radius, y);
  // top right corner
  ctx.lineTo(x + width - radius, y);
  ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
  // bottom right   corner
  ctx.lineTo(x + width, y + height);
  // bottom left corner
  ctx.lineTo(x, y + height);
  // top left   
  ctx.lineTo(x, y + radius);
  ctx.quadraticCurveTo(x, y, x + radius, y);
  ctx.closePath();
};

Chart.elements.RoundedTopRectangle = Chart.elements.Rectangle.extend({
  draw: function() {
    var ctx = this._chart.ctx;
    var vm = this._view;
    var left, right, top, bottom, signX, signY, borderSkipped;
    var borderWidth = vm.borderWidth;

    if (!vm.horizontal) {
      // bar
      left = vm.x - vm.width / 2;
      right = vm.x + vm.width / 2;
      top = vm.y;
      bottom = vm.base;
      signX = 1;
      signY = bottom > top? 1: -1;
      borderSkipped = vm.borderSkipped || 'bottom';
    } else {
      // horizontal bar
      left = vm.base;
      right = vm.x;
      top = vm.y - vm.height / 2;
      bottom = vm.y + vm.height / 2;
      signX = right > left? 1: -1;
      signY = 1;
      borderSkipped = vm.borderSkipped || 'left';
    }

    // Canvas doesn't allow us to stroke inside the width so we can
    // adjust the sizes to fit if we're setting a stroke on the line
    if (borderWidth) {
      // borderWidth shold be less than bar width and bar height.
      var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
      borderWidth = borderWidth > barSize? barSize: borderWidth;
      var halfStroke = borderWidth / 2;
      // Adjust borderWidth when bar top position is near vm.base(zero).
      var borderLeft = left + (borderSkipped !== 'left'? halfStroke * signX: 0);
      var borderRight = right + (borderSkipped !== 'right'? -halfStroke * signX: 0);
      var borderTop = top + (borderSkipped !== 'top'? halfStroke * signY: 0);
      var borderBottom = bottom + (borderSkipped !== 'bottom'? -halfStroke * signY: 0);
      // not become a vertical line?
      if (borderLeft !== borderRight) {
        top = borderTop;
        bottom = borderBottom;
      }
      // not become a horizontal line?
      if (borderTop !== borderBottom) {
        left = borderLeft;
        right = borderRight;
      }
    }

    // calculate the bar width and roundess
    var barWidth = Math.abs(left - right);
    var roundness = this._chart.config.options.barRoundness || 0.5;
    var radius = barWidth * roundness * 0.5;

    // keep track of the original top of the bar
    var prevTop = top;

    // move the top down so there is room to draw the rounded top
    top = prevTop + radius;
    var barRadius = top - prevTop;

    ctx.beginPath();
    ctx.fillStyle = vm.backgroundColor;
    ctx.strokeStyle = vm.borderColor;
    ctx.lineWidth = borderWidth;

    // draw the rounded top rectangle
    Chart.helpers.drawRoundedTopRectangle(ctx, left, (top - barRadius + 1), barWidth, bottom - prevTop, barRadius);

    ctx.fill();
    if (borderWidth) {
      ctx.stroke();
    }

    // restore the original top value so tooltips and scales still work
    top = prevTop;
  },
});

Next, you will also have to extend the bar chart controller (Chart.controllers.bar) and overwrite dataElementType to use the new "rounded rectangle" for the chart instead of a regular rectangle.

Chart.defaults.roundedBar = Chart.helpers.clone(Chart.defaults.bar);

Chart.controllers.roundedBar = Chart.controllers.bar.extend({
  dataElementType: Chart.elements.RoundedTopRectangle
});

Lastly, we will modify the chart's config to use the new chart type created above and add a new options property called barRoundness to control how round the top is (0 is flat, 1 is a semi-circle).

var ctx = document.getElementById("canvas").getContext("2d");
var myBar = new Chart(ctx, {
  type: 'roundedBar',
  data: {
    labels: ["Car", "Bike", "Walking"],
    datasets: [{
      label: 'Students',
      backgroundColor: chartColors.blue,
      data: [
        randomScalingFactor(), 
        randomScalingFactor(), 
        randomScalingFactor(), 
      ]
    }, {
      label: 'Teachers',
      backgroundColor: chartColors.red,
      data: [
        randomScalingFactor(), 
        randomScalingFactor(), 
        randomScalingFactor(), 
      ]
    }, {
      label: 'Visitors',
      backgroundColor: chartColors.green,
      data: [
        randomScalingFactor(), 
        randomScalingFactor(), 
        randomScalingFactor(), 
      ]
    }]
  },
  options: {
    responsive: true,
    barRoundness: 1,
    title: {
      display: true,
      text: "Chart.js - Bar Chart with Rounded Tops (drawRoundedTopRectangle Method)"
    },
  }
});

You can see a full working example at this codepen.

Also, in case you want a slightly different "rounded top" look, here is another codepen that uses a different approach to drawing the top (a single quadratic curve).

Silvana answered 7/4, 2017 at 14:54 Comment(6)
Once I have a moment to go back to this I will totally close this item. and of course remove this useless comment! :) Thank you very much for your assistance! :)Eula
I'm trying to do this in angular 6 but it's not working. it doesn't recognize chart.elements! it says elements doesn't exist on type chartCoulson
Great answer, thanks! How would one modify this for the following two cases: 1. horizontal bar chart, 2. stacked bar chart (it rounds each in the stack; should just round top corners of whole stack bar (or right-most corners of whole stack if its a horizontal bar chart))?Korikorie
Update: found very helpful fiddle that worked well for me here - jsfiddle.net/uffo/5oty49r3/6Korikorie
@PatrickBassut I also faced with that issue and fixed it. Works with 2.9.3 https://mcmap.net/q/691947/-how-to-create-rounded-bars-for-bar-chart-js-v2Biggerstaff
Tried to use this code with ng2-charts but couldn't get it to work :(Roughish
K
8

The following only customizes the Chart.elements.Rectangle.prototype.draw - no need to create an entirely new chart type.

Other pros:

  • It works well with both vertical & horizontal bar charts
  • It works well with both vertical & horizontal stacked bar charts - it only rounds the last box in the series

Noted issue: because this only rounds the box in the last dataset, if the value of the datapoint in the last dataset is < either of the previous data points, the visual top-most box will not be rounded. However, if the last data point is negative and the lowest value, it will round that box on the bottom corners.

Credit: original code belongs to https://github.com/uffo. Code below and linked fiddle demonstrate increasing positive values in each dataset for each stack, and also modifies some of the default radius options.

/**Customize the Rectangle.prototype draw method**/
Chart.elements.Rectangle.prototype.draw = function() {
  var ctx = this._chart.ctx;
  var vm = this._view;
  var left, right, top, bottom, signX, signY, borderSkipped, radius;
  var borderWidth = vm.borderWidth;

  // If radius is less than 0 or is large enough to cause drawing errors a max
  //      radius is imposed. If cornerRadius is not defined set it to 0.
  var cornerRadius = this._chart.config.options.cornerRadius;
  var fullCornerRadius = this._chart.config.options.fullCornerRadius;
  var stackedRounded = this._chart.config.options.stackedRounded;
  var typeOfChart = this._chart.config.type;

  if (cornerRadius < 0) {
    cornerRadius = 0;
  }
  if (typeof cornerRadius == 'undefined') {
    cornerRadius = 0;
  }
  if (typeof fullCornerRadius == 'undefined') {
    fullCornerRadius = false;
  }
  if (typeof stackedRounded == 'undefined') {
    stackedRounded = false;
  }

  if (!vm.horizontal) {
    // bar
    left = vm.x - vm.width / 2;
    right = vm.x + vm.width / 2;
    top = vm.y;
    bottom = vm.base;
    signX = 1;
    signY = bottom > top ? 1 : -1;
    borderSkipped = vm.borderSkipped || 'bottom';
  } else {
    // horizontal bar
    left = vm.base;
    right = vm.x;
    top = vm.y - vm.height / 2;
    bottom = vm.y + vm.height / 2;
    signX = right > left ? 1 : -1;
    signY = 1;
    borderSkipped = vm.borderSkipped || 'left';
  }

  // Canvas doesn't allow us to stroke inside the width so we can
  // adjust the sizes to fit if we're setting a stroke on the line
  if (borderWidth) {
    // borderWidth shold be less than bar width and bar height.
    var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
    borderWidth = borderWidth > barSize ? barSize : borderWidth;
    var halfStroke = borderWidth / 2;
    // Adjust borderWidth when bar top position is near vm.base(zero).
    var borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0);
    var borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0);
    var borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0);
    var borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0);
    // not become a vertical line?
    if (borderLeft !== borderRight) {
      top = borderTop;
      bottom = borderBottom;
    }
    // not become a horizontal line?
    if (borderTop !== borderBottom) {
      left = borderLeft;
      right = borderRight;
    }
  }

  ctx.beginPath();
  ctx.fillStyle = vm.backgroundColor;
  ctx.strokeStyle = vm.borderColor;
  ctx.lineWidth = borderWidth;

  // Corner points, from bottom-left to bottom-right clockwise
  // | 1 2 |
  // | 0 3 |
  var corners = [
    [left, bottom],
    [left, top],
    [right, top],
    [right, bottom]
  ];

  // Find first (starting) corner with fallback to 'bottom'
  var borders = ['bottom', 'left', 'top', 'right'];
  var startCorner = borders.indexOf(borderSkipped, 0);
  if (startCorner === -1) {
    startCorner = 0;
  }

  function cornerAt(index) {
    return corners[(startCorner + index) % 4];
  }

  // Draw rectangle from 'startCorner'
  var corner = cornerAt(0);
  ctx.moveTo(corner[0], corner[1]);


  var nextCornerId, nextCorner, width, height, x, y;
  for (var i = 1; i < 4; i++) {
    corner = cornerAt(i);
    nextCornerId = i + 1;
    if (nextCornerId == 4) {
      nextCornerId = 0
    }

    nextCorner = cornerAt(nextCornerId);

    width = corners[2][0] - corners[1][0];
    height = corners[0][1] - corners[1][1];
    x = corners[1][0];
    y = corners[1][1];

    var radius = cornerRadius;
    // Fix radius being too large
    if (radius > Math.abs(height) / 2) {
      radius = Math.floor(Math.abs(height) / 2);
    }
    if (radius > Math.abs(width) / 2) {
      radius = Math.floor(Math.abs(width) / 2);
    }

      var x_tl, x_tr, y_tl, y_tr, x_bl, x_br, y_bl, y_br;
      if (height < 0) {
        // Negative values in a standard bar chart
        x_tl = x;
        x_tr = x + width;
        y_tl = y + height;
        y_tr = y + height;

        x_bl = x;
        x_br = x + width;
        y_bl = y;
        y_br = y;

        // Draw
        ctx.moveTo(x_bl + radius, y_bl);

        ctx.lineTo(x_br - radius, y_br);

        // bottom right
        ctx.quadraticCurveTo(x_br, y_br, x_br, y_br - radius);


        ctx.lineTo(x_tr, y_tr + radius);

        // top right
        fullCornerRadius ? ctx.quadraticCurveTo(x_tr, y_tr, x_tr - radius, y_tr) : ctx.lineTo(x_tr, y_tr, x_tr - radius, y_tr);


        ctx.lineTo(x_tl + radius, y_tl);

        // top left
        fullCornerRadius ? ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl + radius) : ctx.lineTo(x_tl, y_tl, x_tl, y_tl + radius);


        ctx.lineTo(x_bl, y_bl - radius);

        //  bottom left
        ctx.quadraticCurveTo(x_bl, y_bl, x_bl + radius, y_bl);

      } else if (width < 0) {
        // Negative values in a horizontal bar chart
        x_tl = x + width;
        x_tr = x;
        y_tl = y;
        y_tr = y;

        x_bl = x + width;
        x_br = x;
        y_bl = y + height;
        y_br = y + height;

        // Draw
        ctx.moveTo(x_bl + radius, y_bl);

        ctx.lineTo(x_br - radius, y_br);

        //  Bottom right corner
        fullCornerRadius ? ctx.quadraticCurveTo(x_br, y_br, x_br, y_br - radius) : ctx.lineTo(x_br, y_br, x_br, y_br - radius);

        ctx.lineTo(x_tr, y_tr + radius);

        // top right Corner
        fullCornerRadius ? ctx.quadraticCurveTo(x_tr, y_tr, x_tr - radius, y_tr) : ctx.lineTo(x_tr, y_tr, x_tr - radius, y_tr);

        ctx.lineTo(x_tl + radius, y_tl);

        // top left corner
        ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl + radius);

        ctx.lineTo(x_bl, y_bl - radius);

        //  bttom left corner
        ctx.quadraticCurveTo(x_bl, y_bl, x_bl + radius, y_bl);

      } else {
      
          var lastVisible = 0;
        for (var findLast = 0, findLastTo = this._chart.data.datasets.length; findLast < findLastTo; findLast++) {
          if (!this._chart.getDatasetMeta(findLast).hidden) {
            lastVisible = findLast;
          }
        }
        var rounded = this._datasetIndex === lastVisible;

        if (rounded) {
        //Positive Value
          ctx.moveTo(x + radius, y);

          ctx.lineTo(x + width - radius, y);

          // top right
          ctx.quadraticCurveTo(x + width, y, x + width, y + radius);


          ctx.lineTo(x + width, y + height - radius);

          // bottom right
          if (fullCornerRadius || typeOfChart == 'horizontalBar')
            ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
          else
            ctx.lineTo(x + width, y + height, x + width - radius, y + height);


          ctx.lineTo(x + radius, y + height);

          // bottom left
          if (fullCornerRadius)
            ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
          else
            ctx.lineTo(x, y + height, x, y + height - radius);


          ctx.lineTo(x, y + radius);

          // top left
          if (fullCornerRadius || typeOfChart == 'bar')
            ctx.quadraticCurveTo(x, y, x + radius, y);
          else
            ctx.lineTo(x, y, x + radius, y);
        }else {
          ctx.moveTo(x, y);
          ctx.lineTo(x + width, y);
          ctx.lineTo(x + width, y + height);
          ctx.lineTo(x, y + height);
          ctx.lineTo(x, y);
        }
      }
    
  }

  ctx.fill();
  if (borderWidth) {
    ctx.stroke();
  }
};

/**Chart Data**/
var data = {
  labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
  datasets: [{
    label: 'data 0',
    data: [12, 19, 3, 5, 2, 3],
    backgroundColor: [
      '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: 0
  }, {
    label: 'data 1',
    data: [20, 24, 10, 15, 12, 13],
    backgroundColor: [
      'rgba(255, 159, 64, 1)',
      'rgba(255, 99, 132, 1)',
      'rgba(255, 206, 86, 1)',

      'rgba(54, 162, 235, 1)',
      'rgba(153, 102, 255, 1)',
      'rgba(75, 192, 192, 1)'

    ],
    borderWidth: 0
  }, {
    label: 'data 2',
    data: [20, 30, 30, 20, 14, 20],
    backgroundColor: [
      'rgba(75, 192, 192, 1)',
      'rgba(255, 159, 64, 1)',
      'rgba(255, 99, 132, 1)',
      'rgba(255, 206, 86, 1)',

      'rgba(54, 162, 235, 1)',
      'rgba(153, 102, 255, 1)'


    ],
    borderWidth: 0
  }]
};

/**Chart Options - Radius options are here**/
var options = {
	//Border radius; Default: 0; If a negative value is passed, it will overwrite to 0;
  cornerRadius: 10, 
  //Default: false; if true, this would round all corners of final box;
  fullCornerRadius: false, 
  //Default: false; if true, this rounds each box in the stack instead of only final box;
  stackedRounded: false,
	elements: {
    point: {
      radius: 25,
      hoverRadius: 35,
      pointStyle: 'rectRounded',

    }
  },
  scales: {
    yAxes: [{
      ticks: {
        beginAtZero: true
      },
      stacked: true,
      radius: 25
    }],
    xAxes: [{
      ticks: {
        beginAtZero: true
      },
      stacked: true,

    }]
  }
};

/**Generate Chart**/
var ctxBar = document.getElementById("myChart");
var myBarChart = new Chart(ctxBar, {
  type: 'bar',
  data: data,
  options: options
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.js"></script>
<canvas id="myChart" height="300" width="800"></canvas>

Fiddle: https://jsfiddle.net/adammoisa/v0dthnyr/7/

Korikorie answered 2/5, 2019 at 19:1 Comment(4)
What needs to be done if i want to create the round edges at the bottom bar ?Explicate
there is is a bug. it doesn't work if you have two negative values stacked in the same bar.Hudspeth
this answer works with non-stacked negative values which is all I need, thank youColonize
I like this solution the best but found two issues. One is that the stackedRounded option is not implemented. This option is handy if you unstack your bars and they become grouped and you want each bar to be rounded in the group, not just the last one. The second is that if the top data point on the stack has a value of 0 this script will still try to round it, making it appear as if the stack didn't get rounded. I've addressed both of these issues in a modified version. Cheers: jsfiddle.net/JLamb99/f25zdxjq/8Somatist
O
3

Also worth a mention is this solution which takes you 30 seconds to implement:

https://github.com/jedtrow/Chart.js-Rounded-Bar-Charts

Download and put the .js file into your projects folder, load it and use
var options = { cornerRadius: 20, };

to get rounded bars.

Credits: https://github.com/jedtrow

Orfinger answered 24/11, 2019 at 7:21 Comment(0)
B
3

Solution by @jordanwillis doesn't work with chart.js version after 2.8.0.

To make it work just add following code before drawRoundedTopRectangle definition

Chart.helpers.merge(Chart.defaults.global, {
    datasets: {
        roundedBar: {
            categoryPercentage: 0.8,
            barPercentage: 0.9
        }
    }
});
Biggerstaff answered 10/7, 2020 at 14:7 Comment(2)
Could you elaborate more on this why was this needed? It worked for me but I have no idea why it worked.Michelinamicheline
Could please explain more ? ThanksOrestes
C
3

Got this working in Angular 11 and Charts.js version 2.9.4 (might work in other versions too)

Add this at the very end of your .component.ts file after export class { .. }

Chart['elements'].Rectangle.prototype.draw = function() {
    
    let ctx = this._chart.ctx;
    let view = this._view;

    //////////////////// edit this to change how rounded the edges are /////////////////////
                                    let borderRadius = 10;


    let left = view.x - view.width / 2;
    let right = view.x + view.width / 2;
    let top = view.y;
    let bottom = view.base;

    ctx.beginPath();
    ctx.fillStyle = view.backgroundColor;
    ctx.strokeStyle = view.borderColor;
    ctx.lineWidth = view.borderWidth;

    let barCorners = [
        [left, bottom],
        [left, top],
        [right, top],
        [right, bottom]
    ];

    //start in bottom-left
    ctx.moveTo(barCorners[0][0], barCorners[0][1]);

    for (let i = 1; i < 4; i++) {
        let x = barCorners[1][0];
        let y = barCorners[1][1];
        let width = barCorners[2][0] - barCorners[1][0];
        let height = barCorners[0][1] - barCorners[1][1];

        
        //Fix radius being too big for small values
        if(borderRadius > width/2){
            borderRadius = width/2;
        }
        if(borderRadius > height/2){
            borderRadius = height/2;
        }



        // DRAW THE LINES THAT WILL BE FILLED - REPLACING lineTo with quadraticCurveTo CAUSES MORE EDGES TO BECOME ROUNDED
        ctx.moveTo(x + borderRadius, y);
        ctx.lineTo(x + width - borderRadius, y);
        ctx.quadraticCurveTo(x + width, y, x + width, y + borderRadius);
        ctx.lineTo(x + width, y + height - borderRadius);
        ctx.lineTo(x + width, y + height, x + width - borderRadius, y + height);
        ctx.lineTo(x + borderRadius, y + height);
        ctx.lineTo(x, y + height, x, y + height - borderRadius);
        ctx.lineTo(x, y + borderRadius);
        ctx.quadraticCurveTo(x, y, x + borderRadius, y);

    }
    //FILL THE LINES
    ctx.fill();
}; 

example ngOnInit method:

ngOnInit() {
console.log("asdf entering getChart");
this.canvas = document.getElementById('NumberOfSessionsChart');
this.ctx = this.canvas.getContext('2d');

this.myChart = new Chart(this.ctx, {
  type: 'bar',
  data: {
    labels: ['Jan 20', 'Feb 20', 'Mar 20', 'Apr 20', 'May 20', 'Jun 20', 'Jul 20', 'Aug 20', 'Sept 20'],
    datasets: [{
      label: 'vVals',
      backgroundColor: 'blue',
      data: [0, 50, 20, 30, 40, 50, 60, 70, 80, 90, 100],
    }]
  },
  options: {
    devicePixelRatio: 2.2,
    //tooltips are the things that appear when you hover over the data that show the counts.
    //for some reason we can't choose where the tooltip is oriented.
    tooltips: {
        enabled: false
    },
    onClick: (e) => {
        console.log("asdf entering on click");  
    },
    
    legend: {
        display: true,
        position: 'right',
        reverse: true,
        labels: {
            fontColor: 'black',
            fontSize: 15,
            padding: 20,
            usePointStyle: true,
            //width of circles in legend
            boxWidth: 9
        }
    },
    scales: {
        
        xAxes: [{  
            ticks: {
                padding: 10,
                fontSize: 13,
                fontFamily: 'Roboto',
                fontColor: 'black',
                beginAtZero: true
            },
               gridLines: {
                tickMarkLength: 0,
                color: '#9da0a2',
                drawOnChartArea: false,
               },
        }],
        yAxes: [{ 
            ticks: {
                padding: 10,
                fontSize: 13,
                fontFamily: 'Roboto',
                fontColor: 'black',
                beginAtZero: true,
                precision:0
            },
               gridLines: {
                tickMarkLength: 0,
                color: '#9da0a2',
                drawOnChartArea: false,
               },
        }],
      },
    responsive: false,
}
});



    }
}
Connotative answered 8/4, 2021 at 1:12 Comment(2)
The only thing that works! And a major helpful point being Chart['elements'] ... Thank you!!Circumstantiate
This is the answer that works for me in the same moment I pasted Thanks a lot!!Tripletail
A
0

Checkout chartjs-top-round-bar a usefull

You just need to

import 'chartjs-top-round-bar';

...

new Chart('myChart', 
{ 
    options: { 
        barRoundness: 0.3
    }
}
Annmarie answered 5/7, 2019 at 22:48 Comment(3)
I get this Error Object literal may only specify known properties, and 'barRoundness' does not exist in type 'ChartOptions'.ts(2322)Slapdash
chartjs 2.9 angular 8Slapdash
A diagram is loaded, but the bars in the diagram are not displayedFetial

© 2022 - 2024 — McMap. All rights reserved.