问题描述
尝试,如中所示。这适用于版本1.
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.
在我使用的图表中,无法加载参考 extend
in Chart.types.Bar.extend
崩溃脚本。
In the chart that I am using, it fails to load for the reference to extend
in Chart.types.Bar.extend
crashes the script.
如果我使用默认选项,则图表加载没有问题。我必须在最后放置 Chart.types.Bar.extend
,以便正确加载默认选项。在全屏幕中运行并查看此内容。
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.
我尝试使用我的Chart.js 2.4.0版本实现此功能。
I tried implementing this with my version of Chart.js 2.4.0.
Chrome报告:
此代码甚至不会在这里运行。为什么会这样?有人可以帮助我吗。
This code will not even run here. Why is this occurring? Could someone please assist me.
此代码适用于旧版本的Chart.js 1.0。有谁可以请进一步展示如何使用版本Chart.js 2.0?谢谢。
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>
推荐答案
你试图使用的实际上是chart.js v1,并且正如你所发现的那样,对于chart.js v2(这几乎是一个完整的chart.js重写)不起作用。
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).
要在chart.js v2中获得相同的结果,您需要扩展 Chart.elements.Rectangle
并覆盖它的 draw
方法以绘制圆角 最佳。已经有一个chart.js帮助器方法将绘制一个圆角矩形( Chart.helpers.drawRoundedRectangle
),所以我们将稍微修改它并创建一个新的辅助方法,只绘制一个圆形顶部(而不是所有边)。
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;
},
});
接下来,您还需要扩展条形图控制器(图表。 controllers.bar
)并覆盖 dataElementType
以使用图表的新圆角矩形而不是常规矩形。
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
});
最后,我们将修改图表的配置以使用上面创建的新图表类型并添加新选项名为 barRoundness
的属性,用于控制顶部的圆度(0为平面,1为半圆)。
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).
这篇关于如何为Bar Chart.js v2创建圆角条?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!