在 chartjs 中绘制混合堆叠水平 bar/line
Drawing a mixed stacked horizontal bar/line in chartjs
我查看了 chartjs 的 docs/examples,但有谁知道执行以下操作的方法吗?
- 创建宽度(x 轴)可变但高度始终为满(也就是整个 y 轴)的条形?
- 一个图表中可以有 x 个柱状图
- 创建一条横跨 x 轴但可以更改其 y 轴的线(也不是直线,而是曲线)。
我这里有一张粗略的图,黄色是条,黑色是线
我有点使用堆叠条和交换轴来完成第一部分,但 y 轴(条高度)仅设置为 1。在混合模式下尝试绘制曲线时出现问题,因为只有一个y轴点(而不是很多y轴点):
这是另一个具有多个 y 轴点的尝试,但我无法控制条形宽度:
如果有人能提供帮助(或者至少告诉我我的方向是否正确),我们将不胜感激!
Please see code in the jsfiddle link
嗯,这很难...我唯一的解决方案是创建一个包含很多非常小的条形图的条形图。
I made a JSBin with my solution 但它 远非完美 ,但在 chart.js 中实现它的唯一方法。我没有测试性能,因为我不知道你的数据,但这将是非常重要的,也是最大的问题。
目前只有一个矩形是可能的,但改进为多个矩形并不难。
这是我所有的代码,和 JSBin 一样:
var chartData = {
datasets: [{
type: 'line',
label: 'Dataset 1',
borderColor: 'blue',
borderWidth: 2,
fill: false,
data: []
}, {
type: 'bar',
label: 'Dataset 2',
backgroundColor: 'red',
data: [],
}]
};
var newData0 = []
var newData1 = []
var labels = []
var counter = 50
// Rectangle between two random Integers
var rectangleBetween = [Math.round(Math.random()*counter), Math.round(Math.random()*counter)]
rectangleBetween.sort(function(a, b){return a - b})
for (var i = 0; i < counter; i++) {
labels.push(i)
// Data for Dataset 1 (line):
var newObj0 = {}
newObj0.x = i
// 50/50 chance of data
if (Math.random()<0.5) {
newObj0.y = Math.round(Math.random()*100)
} else {
newObj0.y = null
}
newData0.push(newObj0)
// Data for Dataset 2 (bar):
var newObj1 = {}
if (i >= rectangleBetween[0] && i <= rectangleBetween[1]) {
newObj1.x = i
newObj1.y = 100
} else {
newObj1.x = i
newObj1.y = 0
}
newData1.push(newObj1)
}
chartData.datasets[0].data = newData0
chartData.datasets[1].data = newData1
chartData.labels = labels
var ctx = document.getElementById('chart').getContext('2d');
myMixedChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
responsive: true,
spanGaps: true,
title: {
display: true,
text: 'Chart.js Combo Bar Line Chart'
},
tooltips: {
mode: 'index',
intersect: true
},
scales: {
xAxes: [{
//barThickness: 80, // number (pixels) or 'flex'
//maxBarThickness: 100, // number (pixels)
barPercentage: 1.0,
categoryPercentage: 1.0,
gridLines: {
display: false
}
}]
}
}
});
看起来这是最好的解决方案:
https://codepen.io/kurkle/pen/ExxdyXQ
var ctx = document.getElementById("chart").getContext("2d");
var chart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
datasets: [
{
label: "Bar1",
data: [[2.5, 5.7]],
},
{
label: "Bar2",
data: [[6, 8]],
},
{
label: "Bar3",
data: [[9,10]],
},
{
label: "Line",
type: "line",
backgroundColor: "rgb(75, 192, 192, 0.5)",
borderColor: "rgb(75, 192, 192)",
fill: false,
tension: 0,
data: [11, 10, 9, 8, 7, 6, 5, 4, 3, 2],
yAxisID: "line"
}
]
},
options: {
datasets: {
horizontalBar: {
backgroundColor: "rgb(255, 99, 132, 0.5)",
borderColor: "rgb(255, 99, 132)",
borderWidth: 1,
barPercentage: 1,
categoryPercentage: 1,
yAxisID: "bar"
}
},
scales: {
yAxes: [
{
id: "bar",
type: 'category',
stacked: true,
labels: ['bar'],
offset: true
},
{
id: "line",
position: 'right',
ticks: {
min: 0,
stepSize: 1
}
}
]
}
}
});
感谢此代码的原作者(Jukka Kurkela aka kurkle)。他在 chart.js GitHub issues page.
上回答了这个问题
我查看了 chartjs 的 docs/examples,但有谁知道执行以下操作的方法吗?
- 创建宽度(x 轴)可变但高度始终为满(也就是整个 y 轴)的条形?
- 一个图表中可以有 x 个柱状图
- 创建一条横跨 x 轴但可以更改其 y 轴的线(也不是直线,而是曲线)。
我这里有一张粗略的图,黄色是条,黑色是线
我有点使用堆叠条和交换轴来完成第一部分,但 y 轴(条高度)仅设置为 1。在混合模式下尝试绘制曲线时出现问题,因为只有一个y轴点(而不是很多y轴点):
这是另一个具有多个 y 轴点的尝试,但我无法控制条形宽度:
如果有人能提供帮助(或者至少告诉我我的方向是否正确),我们将不胜感激!
Please see code in the jsfiddle link
嗯,这很难...我唯一的解决方案是创建一个包含很多非常小的条形图的条形图。
I made a JSBin with my solution 但它 远非完美 ,但在 chart.js 中实现它的唯一方法。我没有测试性能,因为我不知道你的数据,但这将是非常重要的,也是最大的问题。
目前只有一个矩形是可能的,但改进为多个矩形并不难。
这是我所有的代码,和 JSBin 一样:
var chartData = {
datasets: [{
type: 'line',
label: 'Dataset 1',
borderColor: 'blue',
borderWidth: 2,
fill: false,
data: []
}, {
type: 'bar',
label: 'Dataset 2',
backgroundColor: 'red',
data: [],
}]
};
var newData0 = []
var newData1 = []
var labels = []
var counter = 50
// Rectangle between two random Integers
var rectangleBetween = [Math.round(Math.random()*counter), Math.round(Math.random()*counter)]
rectangleBetween.sort(function(a, b){return a - b})
for (var i = 0; i < counter; i++) {
labels.push(i)
// Data for Dataset 1 (line):
var newObj0 = {}
newObj0.x = i
// 50/50 chance of data
if (Math.random()<0.5) {
newObj0.y = Math.round(Math.random()*100)
} else {
newObj0.y = null
}
newData0.push(newObj0)
// Data for Dataset 2 (bar):
var newObj1 = {}
if (i >= rectangleBetween[0] && i <= rectangleBetween[1]) {
newObj1.x = i
newObj1.y = 100
} else {
newObj1.x = i
newObj1.y = 0
}
newData1.push(newObj1)
}
chartData.datasets[0].data = newData0
chartData.datasets[1].data = newData1
chartData.labels = labels
var ctx = document.getElementById('chart').getContext('2d');
myMixedChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
responsive: true,
spanGaps: true,
title: {
display: true,
text: 'Chart.js Combo Bar Line Chart'
},
tooltips: {
mode: 'index',
intersect: true
},
scales: {
xAxes: [{
//barThickness: 80, // number (pixels) or 'flex'
//maxBarThickness: 100, // number (pixels)
barPercentage: 1.0,
categoryPercentage: 1.0,
gridLines: {
display: false
}
}]
}
}
});
看起来这是最好的解决方案:
https://codepen.io/kurkle/pen/ExxdyXQ
var ctx = document.getElementById("chart").getContext("2d");
var chart = new Chart(ctx, {
type: "horizontalBar",
data: {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
datasets: [
{
label: "Bar1",
data: [[2.5, 5.7]],
},
{
label: "Bar2",
data: [[6, 8]],
},
{
label: "Bar3",
data: [[9,10]],
},
{
label: "Line",
type: "line",
backgroundColor: "rgb(75, 192, 192, 0.5)",
borderColor: "rgb(75, 192, 192)",
fill: false,
tension: 0,
data: [11, 10, 9, 8, 7, 6, 5, 4, 3, 2],
yAxisID: "line"
}
]
},
options: {
datasets: {
horizontalBar: {
backgroundColor: "rgb(255, 99, 132, 0.5)",
borderColor: "rgb(255, 99, 132)",
borderWidth: 1,
barPercentage: 1,
categoryPercentage: 1,
yAxisID: "bar"
}
},
scales: {
yAxes: [
{
id: "bar",
type: 'category',
stacked: true,
labels: ['bar'],
offset: true
},
{
id: "line",
position: 'right',
ticks: {
min: 0,
stepSize: 1
}
}
]
}
}
});
感谢此代码的原作者(Jukka Kurkela aka kurkle)。他在 chart.js GitHub issues page.
上回答了这个问题