Search code examples
javascriptecharts

Use of echartsInstance.getModel() with setOption()


I have a question about option update with setOption() using getModel().

Consider this code with getModel():

const optionSeries = myChart.getModel().option.series[0];
optionSeries.axisLabel.color = "#f00";
myChart.setOption(optionSeries);

And this with setOption():

myChart.setOption({
  series: [
    {
      axisLabel: "#f00"
    }
  ]
});

myChart.setOption(option);

And this with getOption():

const option = myChart.getOption();
option.series[0].axisLabel.color = "#f00";
myChart.setOption(option);

According to the getOption() documentation:

Besides, the following style is not recommended:

var option = myChart.getOption(); 
option.visualMap[0].inRange.color = ...;
myChart.setOption(option);

This is because getOption contains merged values which could be default values, and may overlaps future values. So, we recommend the following style when update part of configuration.

I would like to know if using getModel() as I showed in the example above is as harmful as using getOption() or can you use it normally with setOption without restrictions or penalties?

Also, are there any additional restrictions with using getModel(), i.e. reasons to avoid it?


Solution

  • ECharts#getModel() and the Model class, as well as anything under them are undocumented, and as such are not supposed to be accessed in userland.

    You may look at the typescript type definitions for echarts file you referenced in a previous post. You can see that Echarts#getModel (line 2554) is marked as private, which says a lot about what the developers think about its being accessed by users.

    We gain information about these methods and classes by looking into the source code and by inspecting the datastructures our code creates in console. The main issue with that is the fact that anything we find out that way about an undocumented feature might change without notice in any future updates to echarts library. So, we either tie our code to a specific version of echarts, or, theoretically, whenever there's a minor update, we'll have to repeat our fact gathering procedure to make sure that the structures our code relies on are still valid.

    As for Model#option (or Model#getOption), in theory, it presents the same dangers as Echarts#getOption: the option object is not guaranteed to be fully deep-cloned, so by assigning a value deep inside the live option object you may change a default property, unwillingly affecting new series added to the current chart or other chart instances.

    As a non-essential observation, in practice, I failed to create an example where this happens for neither Echarts#getOption, nor Model#option, not even the visualMap example that is sketched in the docs you referenced doesn't produce any unwanted side-effects. The series model defaultOptions are loaded (see Series.ts#L264) via zrender#merge using zrender#clone, both performing fully recursive deep-copy for object-array structures as the options are. Only Dates are not cloned, but I don't know of any default series option in the form of a Date.

    In any case, the warning stands, as the developers don't intentionally ensure there are no mix-ups, so setting options for Echarts#setOption as well as Model#setOption should better use fresh objects, not live ones acquired by getOption methods.