chartjs / chartjs/Chart.js

Stacked bars are rendered with wrong colors when using custom plugin

Open
#10,838 0 comments 0 reactions 0 assignees View on GitHub
type: bug
Dominant language
JavaScript
Stars
67.7k
Forks
11.9k
Avg merge
7h 39m
Merged PRs (30d)
5

Description

### Expected behavior

I added custom plugin for sorting sections inside stacked bar depends on value. In two words - it fills `sortedData` at `beforeDraw`, then at `beforeDatasetDraw` it changes Y and BASE of section bar due to `sortedData` (just swaps sections) . Additionally at `beforeDatasetDraw` I try to paint sections to grey color, if there are more than 10 sections, so 10, 11, etc would be grey.

Screenshot 2022-10-28 at 10 07 02

### Current behavior

For now depends of datasets (for some datasets it works properly, for some don't) some bar's sections filled already with grey color despite that there are less than 10 sections in a bar. It started to colorise with right color on hover.
Screenshot 2022-10-28 at 10 22 24

### Reproducible sample

https://codepen.io/mi1ord/pen/qBKdRvp

### Optional extra steps/info to reproduce

custom plugin

```javascript
const stackedBarSorterPlugin = {
id: 'stackedBarSorter',

sortedData: {},

/*
* Sorts data by value and calculates values for bar stacks
*/
beforeDraw(chart: Chart) {
this.sortedData = {};
// iterate over datasets
chart.data.datasets.forEach((dataset, datasetIndex) => {
// iterate over dataset records
dataset.data.forEach((_, index) => {
// create data container for bar stack data
if (!this.sortedData[index]) {
this.sortedData[index] = {
data: [],
};
}

const datasetMeta = chart.getDatasetMeta(datasetIndex);

// save data
this.sortedData[index].data[datasetIndex] = {
color: dataset.backgroundColor,
datasetIndex,
hidden: datasetMeta.hidden,
value: dataset.data[index],
y: datasetMeta.data[index].y,
base: datasetMeta.data[index].base,
};

this.sortedData[index].data = this.sortedData[index].data.filter(({ value }) => value > 0);
});
});

const chartTop = chart.scales.y.top;
const { max } = chart.scales.y;
const h = chart.scales.y.height / max;

// iterate over datasets
chart.data.datasets.forEach((dataset) => {
// iterate over dataset records
dataset.data.forEach((_, index) => {
// sort data in bar stack by value
this.sortedData[index].data = Object.keys(this.sortedData[index].data)
.map((k) => this.sortedData[index].data[k])
.sort((a, b) => b.value - a.value);

this.sortedData[index].data = this.sortedData[index].data.map((dataItem, idx) => {
// calculate base value
let base =
chartTop +
(max -
Object.keys(this.sortedData[index].data)
.map((k) => this.sortedData[index].data[k].value)
.reduce((a, b) => a + b, 0)) *
h +
Object.keys(this.sortedData[index].data)
.map((k) => this.sortedData[index].data[k])
.filter((d) => d.hidden)
.reduce((a, b) => a + b.value, 0) *
h;

// increase base value with values of previous records
for (let i = 0; i < idx; i += 1) {
const { hidden, value } = this.sortedData[index].data[i];
base += hidden ? 0 : h * value;
}

return {
...dataItem,
base,
y: base + h * dataItem.value,
};
});
});
});
},

/*
* Sets values for base and y
*/
beforeDatasetDraw(chart, args) {
chart.getDatasetMeta(args.index).data.forEach((barElement, index) => {
const data = this.sortedData[index].data.filter(({ value }) => value > 0);

const storedElementIndex = data.findIndex(
(el) => el.datasetIndex === args.index,
);

if (storedElementIndex === -1) {
return;
}

const storedElement = data[storedElementIndex];

// !!!!!!!!!!!!!!!!!
// for somehow barElement.options.backgroundColor in some sections already has grey color
// !!!!!!!!!!!!!!!!!

if (storedElementIndex > 9) {
barElement.options.backgroundColor = 'grey';
}
if (storedElementIndex > 10) {
barElement.options.borderWidth = 0;
}
// swaps sections
barElement.y = storedElement.y;
barElement.base = storedElement.base;
});
},
};

```

### Possible solution

_No response_

### Context

_No response_

### chart.js version

v3.9.1

### Browser name and version

tried in chrome, safari, firefox

### Link to your project

_No response_

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.