javascript - How to create rounded bars for Bar Chart.js v2? -


trying round bars on bar chart found in post works displayed in jsfiddle provided. version 1.

in chart using, fails load reference extend in chart.types.bar.extend crashes script.

if use default option, chart loads no problems. had place chart.types.bar.extend @ end default option load correctly. run , view in full screen.

i tried implementing version of chart.js 2.4.0.

chrome reports:

uncaught typeerror: cannot read property 'extend' of undefined chart.js

this code not run here. why occurring? please assist me.

this code works older version of chart.js 1.0. please further display how work 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) 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 rectangle draw ours              this.datasets.foreach(function (dataset) {                  dataset.bars.foreach(function (bar) {                      bar.draw = function () {                          // draw original bar little down (so our curve brings original position)                          var y = bar.y;                          // min required animation not start below axes                          bar.y = math.min(bar.y + radius, self.scale.endpoint - 1);                          // adjust bar radius depending on how of curve can draw                          var barradius = (bar.y - y);                          rectangledraw.apply(bar, arguments);                            // draw 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 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>

the code trying use chart.js v1 and, discovered, not work chart.js v2 (which full chart.js re-write).

to achieve same results in chart.js v2, need extend chart.elements.rectangle , overwrite it's draw method in order paint rounded top. there chart.js helper method draw rounded rectangle (chart.helpers.drawroundedrectangle), modify , create new helper method draw rounded top (instead of sides).

// draws rectangle 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 stroke inside width can     // adjust sizes fit if we're setting stroke on line     if (borderwidth) {       // borderwidth shold less bar width , 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 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 vertical line?       if (borderleft !== borderright) {         top = bordertop;         bottom = borderbottom;       }       // not become horizontal line?       if (bordertop !== borderbottom) {         left = borderleft;         right = borderright;       }     }      // calculate bar width , 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 original top of bar     var prevtop = top;      // move top down there room draw rounded top     top = prevtop + radius;     var barradius = top - prevtop;      ctx.beginpath();     ctx.fillstyle = vm.backgroundcolor;     ctx.strokestyle = vm.bordercolor;     ctx.linewidth = borderwidth;      // draw rounded top rectangle     chart.helpers.drawroundedtoprectangle(ctx, left, (top - barradius + 1), barwidth, bottom - prevtop, barradius);      ctx.fill();     if (borderwidth) {       ctx.stroke();     }      // restore original top value tooltips , scales still work     top = prevtop;   }, }); 

next, have extend bar chart controller (chart.controllers.bar) , overwrite dataelementtype use new "rounded rectangle" chart instead of regular rectangle.

chart.defaults.roundedbar = chart.helpers.clone(chart.defaults.bar);  chart.controllers.roundedbar = chart.controllers.bar.extend({   dataelementtype: chart.elements.roundedtoprectangle }); 

lastly, modify chart's config use new chart type created above , add new options property called barroundness control how round top (0 flat, 1 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 rounded tops (drawroundedtoprectangle method)"     },   } }); 

you can see full working example @ codepen.

also, in case want different "rounded top" look, here codepen uses different approach drawing top (a single quadratic curve).


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

thorough guide for profiling racket code -