如何为Bar Chart.js v2创建圆角条?

试图在条形图上围绕条形图,如在此post中找到的那样工作,如提供的jsFiddle中所示 。 这是针对版本1的。

在我使用的图表中,无法加载Chart.types.Bar.extend extend引用,导致脚本崩溃。

如果我使用默认选项,图表不会加载任何问题。 我必须将Chart.types.Bar.extend放在最后,以便正确加载默认选项。 在全屏幕中运行并查看此内容。

我尝试使用我的Chart.js 2.4.0版本实现这一点。

Chrome报告:

未捕获的TypeError:无法读取未定义的chart.js的属性“extend”

此代码甚至不会在这里运行。 为什么会这样? 有人可以帮助我。

此代码适用于旧版本的Chart.js 1.0。 有谁可以请进一步展示如何使用版本Chart.js 2.0? 谢谢。

 $(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; } }) }) } } }); 
   

Bar Chart - Working

Rounded Bar Chart - Not Working

您尝试使用的代码实际上是用于chart.js v1,并且正如您所发现的那样,对于chart.js v2(这几乎是一个完整的chart.js重写)不起作用。

要在chart.js v2中获得相同的结果,您需要扩展Chart.elements.Rectangle并覆盖它的draw方法以绘制圆顶。 已经有一个chart.js辅助方法将绘制一个圆角矩形( Chart.helpers.drawRoundedRectangle ),所以我们将稍微修改它并创建一个新的辅助方法,只绘制一个圆形顶部(而不是所有边)。

 // 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; }, }); 

接下来,您还必须扩展条形图控制器( Chart.controllers.bar )并覆盖dataElementType以使用图表的新“圆角矩形”而不是常规矩形。

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

最后,我们将修改图表的配置以使用上面创建的新图表类型,并添加一个名为barRoundness的新选项属性来控制顶部的圆度(0表示平坦,1表示半圆)。

 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)" }, } }); 

您可以在此codepen中看到完整的工作示例。

此外,如果您想要略微不同的“圆顶”外观,这里是另一个使用不同方法绘制顶部的编码器 (单个二次曲线)。