question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG] Updating scales/axes breaks

See original GitHub issue

Expected Behavior

The scales/axes are updated

Current Behavior

An error is thrown Uncaught TypeError: Cannot set property 'options' of undefined

Steps to Reproduce (for bugs)

  1. http://plnkr.co/edit/YEunkUileubTZiv6rauM?p=preview
  2. Click Update

Context

I’m trying to have dynamic charts where configuration (not just data) is fed from an external source.

Environment

  • Chart.js version: 2.6.0
  • Browser name and version: Chrome 59.0.3071.115

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
mMerlincommented, Jul 26, 2017

Using Developer tools with Firefox, clicking update on your example, I get

TypeError: t.scales[e.id] is undefined.

Somewhat browser specific error message. The cause though, appears to be that you are wiping out some of the internals of what chartjs setup during the initialization / creation of the original chart object. Add

console.log(JSON.stringify(chart.options.scales.yAxes));

to see what is already there before modifying the options. Way more than what you see in the creation options passed to the constructor. To do what you want, you need to merge your new settings. Not just overwrite with them.

Have a look at jQuery.extend(true, …) for one way to do this. Other implementations are around, including one in the internals of chartjs. Something like (with jQuery)

chart.options.scales.yAxes = $.extend({}, chart.options.scales.yAxes, {[{
  id: 'y-axis-1',
  position: 'right',
  ticks: {
    min: 0
  }
}]};

will probably do what you want. For this case. More complex situations are going to need more involved manipulation, to explicitly remove pieces that are not wanted in the update.

In this case, directly adding the new values should work fine. But that needs to be things like

chart.options.scales.yAxes[0].id =  'y-axis-1';

etc.

For the general case, generate the chart with the minimal options, save the section that is to be manipulated, then use a deep merge.

chart.options.scales.yAxes = $.extend( {}, savedBaseYaxes, newYaxesOptions );

Make sure that the save is a deep copy too, and there is always going to be the risk that the externally supplied options are going to be invalid, or inconsistent with the previous state of the chart instance. chart.update is intended for relatively small changes. Normally chart.update would be called just after modifying the object. So the settings change would be inside your update function. That is really the only safe way, since other things can trigger an update as well. Like resizing the browser, which changes the chart dimensions.

1reaction
etimbergcommented, Jul 27, 2017

@mMerlin is definitely on the right track with extending this rather than replacing the array. The items in this array are merged with the axis type defaults during initialization and replacing it means that that is lost.

However, simply changing the logic to push another object onto the array also doesn’t work. The error that currently appears probably comes from https://github.com/chartjs/Chart.js/blob/master/src/core/core.controller.js#L53 because the updateConfig function is not currently designed to add or remove scales. I think with some modification it could easily work, but it would require changes elsewhere in update() to ensure that the necessary parts of buildScales() run.

As an aside, we want to get rid of the xAxes and yAxes arrays at the next major version and replace them with a map by axis ID. That will simplify a lot of the internal code and ensure that IDs are always present. It will also make updates like this a lot nicer to work with.

Read more comments on GitHub >

github_iconTop Results From Across the Web

brokenaxes - PyPI
Break x and y axes. Supports multiple breaks on a single axis. Automatically scales axes according to relative ranges. Plot multiple lines.
Read more >
ggplot - Ch6 Scales, axes and legends - RPubs
The breaks argument controls which values appear as tick marks on axes and keys on legends. Each break has an associated label, controlled...
Read more >
Scales, Axes & Coordinate systems
9.1 Scales. Within ggplot there are a bunch of scale s that control how a plot maps data values to the visual values...
Read more >
Adjusting scales on axes - TIBCO Product Documentation
By default, there is only one scale on an axis, and all measures are shown on this scale. If the measures are of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found