[BUG] Updating scales/axes breaks

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

Author: Fantashit

1 thought on “[BUG] Updating scales/axes breaks

  1. 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.

Comments are closed.