highcharts / highcharts-vue

Other
685 stars 150 forks source link

Highcharts Maps initializing Question #228

Closed fzc-seaside-villager closed 1 year ago

fzc-seaside-villager commented 1 year ago

I try to initialize a mapChart.

Context:

  1. There is a chartOptions state in the data property and the default value is an empty object chartOptions: { };
  2. In the mounted(), a simple but complete map option will be loaded and it will be assigned to the chartOptions state. But it fails to show the map, here is the live demo link
    https://codesandbox.io/s/sweet-sammet-s42sp1?file=/src/components/Chart.vue

However, if a default value like below given to the chartOptions state

chartOptions: {
    chart: {
        map: worldMap,
    },
},

It will work, here is the demo link https://codesandbox.io/s/red-cdn-pfl7xh?file=/src/components/Chart.vue

Obviously, in both two demos, after loading the map option in the mounted(), the chartOptions state will be the same.

Then why the first demo fails to initialize the map view? (so far, from my testing experience, it doesn't happen on other normal types of charts, but only happens when initializing mapChart)

jszuminski commented 1 year ago

Hi,

Thanks for the question!

I understand your question, but it is not related to the Highcharts-Vue wrapper, it's just how Highcharts works.

It doesn't seem to work in with Vanilla JS in either normal charts: https://jsfiddle.net/BlackLabel/xny05arq/ nor map charts: https://jsfiddle.net/BlackLabel/ekbm2qnh/

As you can read in the API (https://api.highcharts.com/class-reference/Highcharts.Chart#update):

A special case is configuration objects that take arrays, for example xAxis, yAxis or series.

So chart.update works for updating the chart config, but does not work for adding/modifying series. That's why nothing shows up in your demo.

I'd recommend you use chart.addSeries() to add a new series to the chart on mounted().

Demo for a standard chart: https://jsfiddle.net/BlackLabel/bv59r8ze/ Demo for a map chart: https://jsfiddle.net/BlackLabel/3a756quz/

Let me know if that helps!

fzc-seaside-villager commented 1 year ago

Hi,

It's interesting, the vanilla js demos you provided match the below concept

So chart.update works for updating the chart config, but does not work for adding/modifying series. That's why nothing shows up in your demo.

and seems it also matches the explanation for the special cases from https://api.highcharts.com/class-reference/Highcharts.Chart#update

Then, a new question, is the chart updating logic behind highcharts-vue wrapper <highcharts></highcharts> completely equal to Highchart.chart.update() when the :options prop is changed? I will give it a question mark for now, coz I got a few 'highcharts-vue' wrapper-based demos to show you.

Here are the links 1.https://codesandbox.io/s/cranky-mclaren-dts4ju?file=/src/components/Chart.vue:0-419 (line chart) 2.https://codesandbox.io/s/intelligent-ardinghelli-v630i3?file=/src/components/Chart.vue:0-458 (pie chart) 3.https://codesandbox.io/s/determined-snow-rso769?file=/src/components/Chart.vue (stock chart) For these demos, they all have a chartOptions state with the default value - chartOptions: { }, and after loading/fetching in the mounted(), a new non-empty chart option will be assigned to the state, basically the same logic to the first failed map demo I showed above (https://codesandbox.io/s/sweet-sammet-s42sp1?file=/src/components/Chart.vue), but they all have the expected charts showed instead of failed rendering.

So I feel the test results have some conflicts with the concept you mentioned, and it only happens to the map chart. What's your opinion on this?

jszuminski commented 1 year ago

Hi,

You're right!

If you take a look at line 52 of highcharts-vue/src/component.js you'll find that 2 additional arguments are passed to chart.update(config, true, true).

As you can read in the API (https://api.highcharts.com/class-reference/Highcharts.Chart#update), the third argument is oneToOne which determines if the series is updated from the config passed to chart.update or not. The Highcharts-Vue wrapper makes all updates based on props changes with oneToOne = true

Here's how it works for a normal chart: https://jsfiddle.net/BlackLabel/pwnm93gj/

However, I've taken a closer look to what happens to mapChart and you're right - it seems to be a bug. I've reported it here: https://github.com/highcharts/highcharts/issues/18648

So until it gets solved, I would recommend you use series.mapData instead of chart.map when you perform an update on the chart. Here's a demo: https://jsfiddle.net/BlackLabel/6gtxfrz9/

Let me know if you have any more questions!

jszuminski commented 1 year ago

Closed as it will be solved within the Highcharts repo.

fzc-seaside-villager commented 1 year ago

Hi,

Thank you for your response and recommendation.

What I wanted was to share some of my findings that might confuse highchart-vue users when they're using this wrapper to create a mapChart. With the above demos and our discussion, I think highchart-vue users will have a better understanding of creating mapChart via this wrapper when they find this issue content.

I also found another alternative which is different to your recommendation. I will share it here. https://codesandbox.io/s/nice-silence-lepkj6?file=/src/components/Chart.vue

Anyone who is interested in it could compare it with the above failed one (https://codesandbox.io/s/sweet-sammet-s42sp1?file=/src/components/Chart.vue).

jszuminski commented 1 year ago

Thank you for your detailed descriptions!

We appreciate that.

Feel free to post any questions on our forum or GitHub if they arise.