chartjs / chartjs/chartjs-plugin-datalabels

[BUG] Weird behavior with labels

Open
#368 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
920
Forks
507
PR merge metrics
No merged PRs in 30d

Description

Hello,

I experienced a really weird behavior with my labels and don't know why. Im using this package in combination with `chartjs-node-canvas`.

## Description

The provided example code has three different for loop heads which work/don't work.

```ts
// run only for top=60 => perfect result
for (let top = 60; top <= 60; top += 5) {

// run a few values for top more => only a few bad
for (let top = 40; top < 70; top += 5) {

// run from 0 to 100 in 5er steps => everything bad
for (let top = 0; top < 100; top += 5) {
```

The weird part is, that it works if the for loop only runs one iteration. If it runs only a few iterations, it's sometimes correct and if its runs 20 iterations nothing is correct.

## Screenshots

Correct:
![working](https://user-images.githubusercontent.com/76838159/215261689-f29d7e4b-14e0-45f1-afb3-072b88087a02.png)

Wrong:
![not-working](https://user-images.githubusercontent.com/76838159/215261696-9c80c6a2-6b21-45d3-bda4-bb65b6f6a98d.png)

Look at the placement of the labels. In the correct one, the labels are placed ontop of the bars, in the wrong one they are wrapped somehow.

## Steps to reproduce

1. Create a folder and add the example code provided below
2. Create a folder next to the `index.ts` file called `a`.
3. Run the file with `npx ts-node index.ts` and try all 3 for heads. (Remember to remove all files in `a/` first to have no conflicts)
4. Compare the results

Example code

`package.json`:
```json
{
"name": "typescript-node",
"version": "1.0.0",
"scripts": {},
"dependencies": {
"@types/node": "14.14.29",
"ts-node": "9.1.1",
"typescript": "4.1.5",
"chart.js": "^3.9.1",
"chartjs-node-canvas": "^4.1.6",
"chartjs-plugin-datalabels": "^2.2.0"
}
}
```

```ts
import { ChartJSNodeCanvas } from "chartjs-node-canvas";
import { ChartConfiguration } from "chart.js";
import "chartjs-plugin-datalabels"; // to fix types
import { writeFileSync } from "fs";

const abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const srcData = new Array(100)
.fill(0)
.map((_, i) => ({ x: abc[i % (abc.length - 1)], y: i }));

(async () => {
// run only for top=60 => perfect result
// for (let top = 60; top <= 60; top += 5) {

// run a few values for top more => only a few bad
for (let top = 40; top < 70; top += 5) {

// run from 0 to 100 in 5er steps => everything bad
// for (let top = 0; top < 100; top += 5) {

const sliced = srcData.slice(0, top);

// import via require as it doesnt work otherwise
// eslint-disable-next-line @typescript-eslint/no-var-requires
const ChartDataLabels = require("chartjs-plugin-datalabels");

const scale = 2;
const chartRenderer = new ChartJSNodeCanvas({
width: scale * Math.max(400, 40 * sliced.length),
height: scale * 400,
chartCallback: async (ChartJS) => {
ChartJS.register(ChartDataLabels);
},
});

const chart: ChartConfiguration = {
type: "bar",
data: {
labels: sliced.map((x) => x.x),
datasets: [
{
label: "ABC",
data: sliced.map((x) => x.y * 2),
backgroundColor: "#f43543",
datalabels: {
labels: {
relative: {
align: "end",
anchor: "end",
color: "#ffffff",
offset: scale * 12,
font: {
size: scale * 10,
weight: "bold",
},
formatter: (_value, ctx) =>
`${~~(sliced[ctx.dataIndex].y * 10 ** 3) / 10}%`,
},
},
},
},
],
},
};
const pictureBuffer = await chartRenderer.renderToBuffer(chart);
writeFileSync(`./a/chart${top}.png`, pictureBuffer);
}
})();
```

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.