I have a bar chart with multiple datasets which include empty values. I use skipNull
to hide the empty values. Currently each group (month) has the same width, and the width of the bars is inversely proportional to the number of bars in a group. I’d like all bars in the chart to have the same width, and the groups to have variable widths.
This is my current code:
const data = {
labels: ['January', 'February', 'March'],
datasets: [
{
label: 'Dataset 1',
data: [3, null, null],
skipNull: true,
},
{
label: 'Dataset 2',
data: [1, 2, null],
skipNull: true,
},
{
label: 'Dataset 3',
data: [4, 1, 3],
skipNull: true,
},
],
};
new Chart(
document.querySelector('#chart'),
{
type: 'bar',
data: data,
}
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js"></script>
<canvas width="500" height="100" id="chart"></canvas>
This is more or less how I’d like the chart to look (excuse my poor Photoshop skills):
I tried barPercentage
and barThickness
, but they don’t affect the group width.
2
Answers
Use
maxBarThickness
property:Bar charts with variable category or bar widths can be obtained in chart.js using
barThicknes: "flex"
,however, it is not simple to set the widths according to predefined numeric data.
I gave a simple example of such an application in a comment,
but that post was abandoned and I haven’t had the chance to refine the code.
This question poses a supplemental challenge – obviously, the category width has to be proportional to
the number of non-null data points in that category; however, the width of each bar is modified
by
categoryPercent
option; this will create a different spacing of a three-bar category from a one-bar categoryand results in visually defective charts.
The only solution I found was to recenter the bars and the axis labels with a plugin, in the
afterUpdate
callback.
This is a rather lengthy piece of code, and explaining it in detail makes little sense. The central part
is changing the x axis to a linear type and positioning the categories to exact values computed by
"reverse engineering" the function
computeFlexCategoryTraits
of chart.js source. This also involves adding an invisible category by pushing a
null
to each of thedatasets data; that is because the number of parameters required to position
n
categorieswith
computeFlexCategoryTraits
isn
+1.Here’s a snippet using this contraption for the original example data: