chartjs / Chart.js

Simple HTML5 Charts using the <canvas> tag
https://www.chartjs.org/
MIT License
64.5k stars 11.89k forks source link

Update dataset to default values from array not working #11679

Open ipax77 opened 7 months ago

ipax77 commented 7 months ago

Expected behavior

When deleting a dataset property (or setting it to null) it should have its default values after chart.update(), independent if it was a single value or an array.

Current behavior

When deleting a dataset property (or setting it to null) when it was an array does not reset its default value.

Reproducible sample

https://codepen.io/Ipax77-the-flexboxer/pen/jOJoWqJ

Optional extra steps/info to reproduce

Click "Update Test Arrays" then "Reset" ("Update Test Single" then "Reset" is working as expected)

Possible solution

It is working when you do a chart.update() after setting each property to null (codepen line 43), but then you have multiple animations (or none with chart.update('none')).

Context

I want to be able to update datasets with animations for my Blazor wrapper library.

chart.js version

v4.4.1

Browser name and version

Chrome 121.0.6167.185

Link to your project

https://github.com/ipax77/pax.BlazorChartJs

kurkle commented 7 months ago

In the pen, you are changing the colors from string to array, why?

ipax77 commented 7 months ago

The scenario is resetting the dataset. Base dataset:

{
  id: '1',
  label: 'Dataset 1',
  data: [1, 2, 3],
}

Update dataset - e.g. when you hover a custom html legend

{
  id: '1',
  label: 'Dataset 1',
  data: [3, 2, 1],
  backgroundColor: ["red", "lightblue", "lightyellow"],
  borderColor: ["darkred", "blue", "yellow"],
  borderWidth: 3
}

And then I want to revert it to the base dataset - e.g. when you move out a custom html legend. As mentioned deleting the additional properties or setting them to null is not working. (Replacing the entire dataset would prevent the update animation)

When using this 'Update dataset' with single values, the revert to base is working as expected:

{
  id: '1',
  label: 'Dataset 1',
  data: [3, 2, 1],
  backgroundColor: "red",
  borderColor: "darkred",
  borderWidth: 3
}
annelibogren commented 7 months ago

Hi, we are a group of students at the KTH Royal Institute of Technology and are taking a course in software engineering. We would like to work on this issue in one of our upcoming assignments and are therefore wondering if we could be assigned to it? Thanks!

paultisaw commented 7 months ago

Hi, I noticed something in your codepen example. When you click the Update Test Arrays button then reset, as you mentioned the colors aren't reset to default as they should. However, if you hover the bars with your mouse, then the correct color gets set back and it is blue again. I tried to look into how how the hovering is handled to understand why it manages to get the correct background value but not the update function, but I haven't found anything yet, I still struggle to understand how the whole resolver thing works. Anyway I hope this might help !

paultisaw commented 7 months ago

Here is something else that I noticed. I added a print in the update function of the Config class like so:

update() {
    const config = this._config;
    console.dir("_config", this._config.data.datasets[0]);
    this.clearCache();
    initOptions(config);
  }

And when I click Update Test Arrays and then Reset, I get this in the console image As you can see, on top it says that borderColor and backgroundColor are null, but in the expanded view we can see that they are set to the correct value (the default blue). In my understanding, the collapsed version is the state when the console.log call is made, and the expanded values are dynamically updated.

So could it be that the attributes set to null are handled correctly, but that the render is too fast or doesn't wait for the updated values to be completely retrieved ?

WarlCang commented 7 months ago

In controller.update(), if the line const animsDisabled = this._animationsDisabled = !options.animation; is modified to const animsDisabled = this._animationsDisabled = options.animation;. The bars are correctly displayed. However, this would make many tests fail. I hope this discovery could help someone who knows the project well.

ipax77 commented 7 months ago

I realized, that updating from array to single values (Update Test Array => Update Test Single) is producing the same behavior, the 'chart object' is in the correct state (hovering the bars updates the expected color), but the visible state is not.

paultisaw commented 7 months ago

Here is a summary of what my team worked on and observed while trying to resolve this issue.

@etimberg sorry for pinging you, but do you maybe have an insight about this situation ? Thanks a lot in advance and we hope this helps !