chart.js - 当 ChartJS 中没有重叠数据时,以全宽渲染来自多个数据集的条形图
问题描述
内的例子。作为参考,我使用的是最新版本的 ChartJS (3.2.1) 和最新版本的 react-chartjs-2 (3.0.3)。
我想知道如何在给定多个不同数据集的情况下以特定方式显示我的条形图。我希望图表上的条以标准宽度呈现,同时在必要时允许并排重叠。
当您使用一个数据集时,ChartJS 将以我的“理想”方式处理这个问题,该数据集可能有两个值落在同一个 X 轴坐标上,但在使用多个数据集时我似乎无法模仿这种行为。
似乎每当两个数据集共享一个轴时,条形宽度要么调整以适应两组数据,即使它们不占用相同的空间,或者它们在它们应该占用相同空间时堆叠在一起。我的目标是只在必要时让条“缩小”它们的宽度,否则保持它们的全宽。
这是我希望看到的多个数据集的示例(这就是 ChartJS 在有一个带有barThickness: "flex"
集合的数据集时处理渲染的方式):
这是我使用两个没有任何重叠点的数据集时得到的示例(barThickness: "flex"
两者都设置了):
到目前为止,我什至找到解决此问题的唯一方法是创建多个 x 轴,一个用于一个数据集,一个用于另一个数据集,一个用于重叠。然后,通过操作我的数据结构,为每个轴创建数据集,其中包含与所需条形宽度相对应的数据点。
这当然是一个解决方案,但我正在处理一个生产代码库、数千行数据和几个额外的数据集(所有这些数据集都有不同的状态、可见性条件和规则)。像这样一起管理所有这些几乎是不可能的,更不用说以可维护的方式了。我已经浏览了绝大多数 StackOverflow 问题和 ChartJS 文档,试图找到一个更清洁的解决方案,但到目前为止还不够,希望能得到您的帮助。
以下代码的简化版本。我已经包含了一些未使用的零碎(大部分被注释掉)只是为了展示我迄今为止尝试过的东西:
var ctx1 = document.getElementById("canvas1").getContext("2d");
var ctx2 = document.getElementById("canvas2").getContext("2d");
var ctx3 = document.getElementById("canvas3").getContext("2d");
function getBackgroundColor(data) {
const bar = data.dataset.data[data.dataIndex];
return bar.projection ? "green" : "black";
}
const dataset1Labels = ['Mar 2021', 'Apr 2021', 'May 2021', 'Jun 2021', 'Jul 2021', 'Aug 2021']
const dataset2Labels = ['Jan 2020', 'Feb 2020', 'Mar 2020', 'Apr 2020', ...dataset1Labels]
const dataset3Labels = ['Jan 2020', 'Feb 2020', 'Mar 2020', 'Apr 2020', 'May 2020', 'Jun 2020', 'Jul 2020', 'Aug 2020', ...dataset1Labels]
const dataset1 = [
{ x: "Mar 2021", y: 1, projection: false },
{ x: "Apr 2021", y: 4, projection: false },
{ x: "May 2021", y: 6, projection: false },
{ x: "May 2021", y: 9, projection: true },
{ x: "Jun 2021", y: 11, projection: true },
{ x: "Jul 2021", y: 13, projection: true },
{ x: "Aug 2021", y: 16, projection: true },
]
const dataset2 = [
{ x: "Jan 2020", y: 1 },
{ x: "Feb 2020", y: 4 },
{ x: "Mar 2020", y: 6 },
{ x: "Apr 2020", y: 8 },
{ x: "Mar 2021", y: 6 },
{ x: "Apr 2021", y: 8 },
]
const dataset3 = [
{ x: "Jan 2020", y: 1 },
{ x: "Feb 2020", y: 4 },
{ x: "Mar 2020", y: 6 },
{ x: "Apr 2020", y: 8 },
{ x: "May 2020", y: 10 },
{ x: "Jun 2020", y: 12 },
{ x: "Jul 2020", y: 12 },
{ x: "Aug 2020", y: 16 },
{ x: "Mar 2021", y: 1 },
{ x: "Apr 2021", y: 4 },
{ x: "May 2021", y: 6 },
]
var myChart = new Chart(ctx1, {
type: 'bar',
data: {
labels: dataset1Labels,
datasets: [{
label: "2 data types, distinguished by color",
data: dataset1,
backgroundColor: getBackgroundColor,
barThickness: "flex",
}]
},
options: {
plugins: {
title: {
display: true,
text: '1 dataset. Can Overlap. Full width bars.'
},
legend: {
position: "bottom",
},
},
scales: {
x: {
id: "dates",
offset: true,
},
}
}
});
var myChart2 = new Chart(ctx2, {
type: 'bar',
data: {
labels: dataset2Labels,
datasets: [
{
label: "previous year",
data: dataset2,
backgroundColor: "blue",
xAxisID: "dates",
},
{
label: "current year",
data: dataset1,
backgroundColor: "green",
},
]},
options: {
plugins: {
title: {
display: true,
text: '2 datasets. Cannot Overlap. Full width bars.'
},
legend: {
position: "bottom",
},
},
scales: {
x: {
id: "dates2",
display: false,
stacked: false,
bounds: "ticks",
grid: {
offset: true,
},
},
}
}
});
var myChart3 = new Chart(ctx3, {
type: 'bar',
data: {
labels: dataset3Labels,
datasets: [
{
label: "previous year",
data: dataset3,
backgroundColor: "blue",
// group: false,
// barThickness: "flex",
// categoryPercentage: 1,
// barPercentage: 1,
},
{
label: "current year",
data: dataset1,
backgroundColor: "green",
// group: false,
// categoryPercentage: 1,
// barThickness: "flex",
// barPercentage: 1,
},
]},
options: {
plugins: {
title: {
display: true,
text: '2 datasets. Can overlap. Half-width bars.'
},
legend: {
position: "bottom",
},
},
scales: {
x: {
id: "dates3",
display: false,
grid: {
offset: true,
},
},
}
}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"></script>
<h2>Chart #1</h2>
<canvas id="canvas1"></canvas>
<h2>Chart #2</h2>
<p>Note that March and April 2021 both have data from both datasets, but only one dataset is visible</p>
<canvas id="canvas2"></canvas>
<h2>Chart #3</h2>
<canvas id="canvas3"></canvas>
解决方案
推荐阅读
- date - 从工作表中提取该数据并使用该数据创建一个 PDF
- python - 如何定义新类型()
- css - XSL:when - 应用多个属性
- react-native - React-Native-无法读取未定义的属性“0”
- google-apps-script - 如何获得两列等于特定值的行
- node.js - 在 OSX 上安装 Node 时遇到这些错误时我错过了什么?
- ruby-on-rails - VSCode 抱怨 Ruby UTF-8 文件具有无效的多字节字符(US-ASCII)
- dart - 如何在服务器上部署 Flutter Web?
- swagger - 如何使用 swagger-ui?
- python-3.x - 如何在没有数字系统的情况下使用海龟在 Python 中制作井字游戏?