我正在使用Chart.js构建一个堆积条形图来显示软件产品的销售数据。堆叠的条形代表我们销售的两种不同类型的许可证:完整许可证或升级许可证。但并非所有产品都有升级许可证,这就是问题所在。
我的销售数据采用以下格式:
const product_variant_sales = {
"Product One": { Full: 234, Upgrade: 987 },
"Product Two": { Full: 456, Upgrade: 895 },
"Product Three": { Full: 3456 },
};
因此,对于产品 3,我们只销售完整许可证,而不是升级许可证(因为它是版本 1)。
我正在使用以下代码将此数据转换为数据集:
const products = Object.keys(product_variant_sales);
const variants = ["Full", "Upgrade"];
const product_variant_sales_datasets = variants.map(variant => {
return {
label: variant,
data: products.map(product => {
return product_variant_sales[product][variant] ?? 0;
}),
backgroundColor: `rgb(38,96,137,${variant === "Full" ? 1 : 0.8})`,
}
});
生成的条形图看起来很棒!
但是,有一个问题。当您将鼠标悬停在没有升级许可证的产品之一上时,它确实显示为 0 销售额:
这是误导性的。我们的升级许可证的销售量并非为零。根本就没有升级许可证。如何获得堆叠条形图,其中并非每个条形都具有相同数量的元素?由于两个数据集中的数据数组需要具有相同数量的元素,因此我不能将它们排除在外。我尝试用
?? 0
和 ?? null
替换 ?? undefined
,但这也没有任何作用。
为了更好地衡量,这是我的图表代码:
new Chart(document.getElementById("product_sales"), {
type: 'bar',
data: {
labels: products,
datasets: product_variant_sales_datasets,
},
options: {
interaction: {
intersect: false,
mode: 'x',
position: 'nearest',
},
plugins: {
legend: {
display: false
},
},
scales: {
x: {
stacked: true,
border: {
color: "#254b5d",
},
grid: {
color: "#254b5d",
}
},
y: {
stacked: true
}
},
}
});
好的,当值为
null
时,我设法隐藏标签,如下所示:
function productsChartLabel(context) {
if (context.raw === null) {
return null;
}
return `${context.dataset.label}: ${context.formattedValue}`;
}
然后在插件选项中我添加了这个:
tooltip: {
callbacks: {
label: productsChartLabel,
}
}
这解决了我的问题。我确实发现数据集使用起来有点烦人,我必须提供 2 个相等长度的数组,而不是代表堆栈的对象数组,但它就是这样:)