我使用 Chart.js 在同一个条形图上绘制两个数据集,以进行基于时间的比较(x 轴)。然而,我遇到了一个问题,一个图形的高度会被压缩或扩展以适应另一个图形的高度,从而很难有效地比较它们。
例如,下面的紫色图增加了 26 倍,而蓝色图仅增加了 5 倍。由于缩放,很难评估这些变化的影响,因为紫色图被挤压到蓝色图的高度。
我认为在第一个数据点处与蓝色图处于同一水平可能会有所帮助,但我担心数据仍然会被压缩以适合蓝色图的高度。
我可以调整特定的 Chart.js 设置或配置来提高这些数据集的可比性吗?
我的图表比例代码如下:
y: {
beginAtZero: true,
grid: {
display: false,
drawBorder: false,
drawOnChartArea: false,
},
ticks: {
display: true,
},
},
},
y1: {
beginAtZero: true,
position: 'right',
grid: {
display: false,
drawBorder: false,
drawOnChartArea: false,
},
ticks: {
display: true,
},
},
}
当前图表
预期图表
没有一个 Chart.js 选项可以排列这些值,使得第一个柱形图 两个数据集高度相等,但可以通过计算轴的值来排列
max
动态:
function computeMax(which, data){
// computes max for scale `which` (0 -> 'y', 1 -> 'y1') such that the first
// bars of the two datasets have the same height
const other = 1 - which,
dataValues = data.datasets.map(dataset=>dataset.data),
dataMax = dataValues.map(data => Math.max(...data)),
firstToMax = dataValues.map((data, i) => data[0] / dataMax[i])
if(firstToMax[which] > firstToMax[other]){
return firstToMax[which]/firstToMax[other] * dataMax[which];
}
else{
return dataMax[which];
}
}
为
scriptable调用函数
computeMax
max
每个轴的属性,如下所示:
options: {
........... other options
scales: {
y: {
.......... other y axis options
ticks: {
display: true,
includeBounds: false
},
max: ({chart}) => computeMax(0, chart.data)
},
y1: {
.......... other y1 axis options
ticks: {
display: true,
includeBounds: false
},
max: ({chart}) => computeMax(1, chart.data)
}
}
}
这是包含该代码段的片段:
function computeMax(which, data){
// computes max for scale `which` (0 -> 'y', 1 -> 'y1') such that the first
// bars of the two datasets have the same height
const other = 1 - which,
dataValues = data.datasets.map(dataset=>dataset.data),
dataMax = dataValues.map(data => Math.max(...data)),
firstToMax = dataValues.map((data, i) => data[0] / dataMax[i])
if(firstToMax[which] > firstToMax[other]){
return firstToMax[which]/firstToMax[other] * dataMax[which];
}
else{
return dataMax[which];
}
}
const config = {
type: "bar",
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
{
label: 2023,
data: [20, 65, 80, 102, 55, 56, 65, 59, 80, 81, 56, 55],
},
{
label: 2024,
data: [50, 59, 80, 81, 56, 55, 65, 108, 80, 81, 56, 55].map(x => x * 10),
yAxisID: 'y1'
},
]
},
options: {
maintainAspectRatio: false,
scales: {
y: {
grid: {
display: false,
drawBorder: false,
drawOnChartArea: false
},
ticks: {
display: true,
includeBounds: false
},
max: ({chart}) => computeMax(0, chart.data)
},
y1: {
beginAtZero: true,
position: 'right',
grid: {
display: false,
drawBorder: false,
drawOnChartArea: false,
},
ticks: {
display: true,
includeBounds: false
},
max: ({chart}) => computeMax(1, chart.data)
},
}
}
};
new Chart('myChart', config);
<div style="height: 300px">
<canvas id="myChart">
</canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
由于轴已设置
beginAtZero
true
,很明显,所有值都是
积极的。具有多个数据集并包含负值的概括
可以在这个小提琴中找到。