ayanami
Posts: 9
Joined: Tue Jun 28, 2022 9:39 am

Highcharts: The problem of slow response in line graph rendering

hi team , i have a question for you, my english is not good, so i use google translation. well, this is my question.
I wrote a demo using highcharts, communicated with the backend through websocket, set a frame of 100ms to get data, made a limit, turned off all animations, and configured boost in options: { useGPUTranslations: true}, use series[0].setData(data, true, false) renders, and it is found that the data transmitted from the backend in a group of 3000 points is very smooth, the data in a group of 8000 points is a little stuck, and when it reaches a group of 20000 points, It is particularly stuck, and the interaction cannot be completed, and the business requirements cannot be realized.
May I ask if there is any solution that can achieve the requirements or what can be improved to achieve smooth rendering at 20,000 points, thank you all.
kamil.m
Posts: 892
Joined: Thu May 19, 2022 1:33 pm

Re: Highcharts: The problem of slow response in line graph rendering

Hello,

Welcome to our forum and thank you for contacting us with your question!

You have done everything correctly to improve the chart performance, but remember that it also depends on the client-side machine, so if you have less computing power on the machine you are using to display the chart then you will have worse performance than on a more powerful device.

In general, when the density of data is higher than the pixel resolution of the chart then it is pointless to show all the points because they will overlap and will not be visible anyway - they will only consume processing power and slow rendering down. Suggested performance tips could be found in our general documentation here: https://www.highcharts.com/docs/getting ... highcharts
And here: https://www.highcharts.com/blog/tutoria ... st-module/

Do not hesitate to contact us with any further questions,
Best regards!
Kamil Musiałowski
Highcharts Developer
ayanami
Posts: 9
Joined: Tue Jun 28, 2022 9:39 am

Re: Highcharts: The problem of slow response in line graph rendering

First of all,thank you very much for your answer :D ,I don't think it has much to do with the performance of my computer. I have a 32G memory stick, an Intel 9th generation i7 processor, and a gtx-2070ti, which should be enough to run this program.

Secondly, Mr. kamil.m, I have already checked the document you sent. My boost configuration is learned from the document, but I feel that the performance improvement is only effective within a few thousand points.

The question now is that the company needs to achieve ten frames per second in one chart, and the received data is a group of 20k. Can the highcharts component meet this requirement? Do you have any other good solutions?



Looking forward to your answer
kamil.m
Posts: 892
Joined: Thu May 19, 2022 1:33 pm

Re: Highcharts: The problem of slow response in line graph rendering

Unfortunately, I can't do much without looking at your code, since there are too many variables that can impact the chart performance. If you could reproduce your issue in an online editor (i.e JSFiddle or Stackblitz) that would allow me to inspect your issue a bit further.

Could you also explain what you mean by "ten frames per second"? Also, are you using any framework or just plain JavaScript?

Regards!
Kamil Musiałowski
Highcharts Developer
ayanami
Posts: 9
Joined: Tue Jun 28, 2022 9:39 am

Re: Highcharts: The problem of slow response in line graph rendering

Good morning., Mr. kamil.m.


Thank you so much for your reply :) ,"ten frames per second" means that when I receive data and render the chart, I set it to render ten times a second, which means that the method is executed once every 100ms.

The framework I use is Vue, with highcharts and highcharts-vue.

This is my configuration in the page:

Code: Select all

      <highcharts
        id="chart"
        class="chart"
        :constructor-type="constructorType"
        :options="chartOptions"
        :updateArgs="updateArgs"
        :deepCopyOnUpdate='true'
      ></highcharts>

Code: Select all

   
      constructorType: 'chart',
      updateArgs: [true, true, {duration: 1000}],
      hcInstance: Highcharts,

Code: Select all

      chartOptions: {
        chart: {
          type: 'spline',
          animation: false,
          showAxes: true,
          zoomType: 'x',
          events: {
            selection: function (event) {},
            click: (event) => {}
          }
        },
        credits: {
          enabled: false
        },
        exporting: { enabled:false },
        plotOptios: {
          series: {
            animation: false
          }
        },
        boost: {
          useGPUTranslations: true,
          usePreallocated: false,
          seriesThreshold: 1,
          allowForce: true
        },
        scrollbar:{
          enabled: true,
          height: 8,
          barBackgroundColor: "#d1d1d1",
          barBorderColor: "#d1d1d1",
          rifleColor: "#d1d1d1",
          barBorderRadius: 5,
          buttonBorderWidth: 0,
          buttonArrowColor: "rgba(0,0,0,0)",
        },
        xAxis: {
          gridLineWidth: 0,
          opposite: true,
          labels: {
            format: '{value} hz'
          },
          minorGridLineWidth: 0,
          minorTickInterval: 'auto',
          minorTickColor: 'rgb(230, 230, 230)',
          minorTickWidh: 1,
          minorTickLength: 10,
          tickPosition: 'outside'
        },
        yAxis: {
            max: 30000,
            min: -2000,
            title: {
                text: null
            },
            labels: {
              format: '{value} hz'
            },
            lineWidth: 0,
            minorTickInterval: 'auto',
            minorTickColor: 'rgb(230, 230, 230)',
            minorTickWidh: 1,
            minorTickLength: 10
        },
        title: {
          text: null
        },
        mapNavigation: {
          enabled: true,
          enableButtons: false
        },
        subtitle: {
          text: null
        },
        legend: {
          enabled: false
        },
        tooltip: {
          valueDecimals: 2
        },
        series: [{
          boostThreshold: 1,
          data: [],
          color: '#6fcd98',
          lineWidth: 0.5,
          point: {
            events: {
              click: (event) => {}
            }
          },
          states: {
            hover: {
              animation: false,
              marker: {
                enabled: false
              }
            }
          }
        }]
      }
This is my configuration in the main.js:

Code: Select all

import HighchartsVue from 'highcharts-vue'
import Highcharts from 'highcharts'
import stockInit from 'highcharts/modules/stock'
import mapInit from 'highcharts/modules/map'

import boostInt  from 'highcharts/modules/boost'

Highcharts.setOptions({
  plotOptions: {
    series: {
      animation: false
    }
  }
})

stockInit(Highcharts)
mapInit(Highcharts)

boostInt(Highcharts)
This is all my configuration about highchart data rendering. The method of data rendering is to use setInterval() to execute the setData() method every 100ms.

When the length of the array of data received from the database is about 3k-6k, there is no problem in rendering it ten times in one second. When the length of the array reaches 15k, it may only be executed 4-5 times a second, you see Is it a problem with my configuration or something else?


Looking forward to your reply, wish you a happy life
kamil.m
Posts: 892
Joined: Thu May 19, 2022 1:33 pm

Re: Highcharts: The problem of slow response in line graph rendering

Hi,

Thank you for providing the code - and a detailed explanation.

From what I can see in your config, I would set the :deepCopyOnUpdate to false. That's quite heavy on performance when using larger datasets.
You can read about it at the very bottom of the official GitHub Highcharts Vue wrapper page.
GitHub: https://github.com/highcharts/highcharts-vue
Then, disable the animation in :updateArgs.
And also please remember, that boost does not work with spline type of charts. You can read more about it down below (and check which series types work with boost module).
Docs: https://www.highcharts.com/docs/advance ... ost-module

Let me know if those tips have improved your chart performance,
Best regards!
Kamil Musiałowski
Highcharts Developer
ayanami
Posts: 9
Joined: Tue Jun 28, 2022 9:39 am

Re: Highcharts: The problem of slow response in line graph rendering

Hello.Mr. kamil.m.

Thank you so much for your advice, it helped me a lot.
I checked the related boost configuration documents and highcharts-vue configuration documents you posted, and made corresponding changes in the options.
The performance improvement of changing 'spline' to 'line' is obvious.
From the previous 4-5 times in one second, it reached 8-9 times, but it still did not fully reach the 100ms rendering time I set, that is, 10 times in one second.
The goal is to render once 100ms of data of 20k length.
Do you have a look at what might be possible to improve?


This is all the code of my vue single page demo

template:

Code: Select all

<template>
  <div class="chartElem">
    <highcharts
      id="chart"
      class="chart"
      :highcharts="hcInstance"
      :constructor-type="constructorType"
      :options="chartOptions"
      :updateArgs="updateArgs"
      :deepCopyOnUpdate="false"
    ></highcharts>
    <div>
      <div class="display: flex;">
        <button @click="reset()">reset</button>
        <button @click="stop()">stop</button>
        <button @click="start()">start</button>
      </div>
    </div>
  </div>
</template>
config;

Code: Select all

      constructorType: 'chart',
      updateArgs: [false, false, false],
      hcInstance: Highcharts,
      chartOptions: {
        chart: {
          // type: 'spline',
          animation: false,
          showAxes: true,
          zoomType: 'x',
          events: {
            selection: function (event) {},
            click: (event) => {}
          }
        },
        credits: {
          enabled: false
        },
        exporting: { enabled: false },
        plotOptios: {
          series: {
            animation: false
          }
        },
        boost: {
          useGPUTranslations: true,
          usePreallocated: false,
          seriesThreshold: 1,
          allowForce: true,
          pixelRatio: 0
        },
        scrollbar: {
          enabled: true,
          height: 8,
          barBackgroundColor: '#d1d1d1',
          barBorderColor: '#d1d1d1',
          rifleColor: '#d1d1d1',
          barBorderRadius: 5,
          buttonBorderWidth: 0,
          buttonArrowColor: 'rgba(0,0,0,0)'
        },
        xAxis: {
          gridLineWidth: 0,
          opposite: true,
          labels: {
            format: '{value} hz'
          },
          minorGridLineWidth: 0,
          minorTickInterval: 'auto',
          minorTickColor: 'rgb(230, 230, 230)',
          minorTickWidh: 1,
          minorTickLength: 10,
          tickPosition: 'outside'
        },
        yAxis: {
            max: 30000,
            min: -2000,
            title: {
                text: null
            },
            labels: {
              format: '{value} hz'
            },
            lineWidth: 0,
            minorTickInterval: 'auto',
            minorTickColor: 'rgb(230, 230, 230)',
            minorTickWidh: 1,
            minorTickLength: 10
        },
        title: {
          text: null
        },
        mapNavigation: {
          enabled: true,
          enableButtons: false
        },
        subtitle: {
          text: null
        },
        legend: {
          enabled: false
        },
        tooltip: {
          valueDecimals: 2
        },
        series: [{
          boostThreshold: 1,
          data: [],
          color: '#6fcd98',
          lineWidth: 0.5,
          point: {
            events: {
              click: (event) => {}
            }
          },
          states: {
            hover: {
              animation: false,
              marker: {
                enabled: false
              }
            }
          }
        }]
      }
The websocket is not connected for the time being, I wrote a 'for' locally to simulate the data

function:

Code: Select all

    reset () {
      Highcharts.charts[0].xAxis[0].setExtremes(undefined, undefined)
      Highcharts.charts[0].yAxis[0].setExtremes(undefined, undefined)
    },
    start () {
      this.timer = setInterval(() => {
        this.payNewData()
      }, 100)
    },
    stop () {
      clearInterval(this.timer)
    },
    payNewData () {
      console.log('go', this.intervalNum++, new Date())
      Highcharts.charts[0].series[0].setData(this.getData(20000))
    },
    getData (n) {
      const arr = []
      for (let i = 0; i < n; i++) {
        arr.push([
          i,
          2 * Math.random() * i
        ])
      }
      return arr
    }
Looking forward to your reply, the first day of July, I wish you a happy day :)
kamil.m
Posts: 892
Joined: Thu May 19, 2022 1:33 pm

Re: Highcharts: The problem of slow response in line graph rendering

Hi there,

We've spent some time testing and improving the performance of your code. In general, on our machines (M1 Pro, intel i5 10th gen) we are getting times around 50-80ms per update on your chart configuration. So as I said before, this really depends on a client's computing power.

I have reproduced your demo in Vue.js, and included a console.time method in it to measure the chart render time. On that demo, we are averaging around 50-80ms per update (see console).
DEMO: https://codesandbox.io/s/highcharts-vue ... ked-sltlb8

And honestly, it is pretty hard to improve that time without sacrificing some features. You could for example turn off the xAxis visibility. That would give you an extra -20ms down, but I guess it is necessary to leave it on.

There is another workaround, but it won't work in Vue.js since as you can read in our GitHub documentation -
it is not supported to update the chart using its built-in functions, because that could cause problems with data synchronization between your app and the chart itself
GitHub: https://github.com/highcharts/highchart ... -reference

This workaround updates the series on data updates, instead of reading and recalculating the whole chart options. See demo below.
DEMO: https://jsfiddle.net/BlackLabel/qtrwva90/

On that JavaScript configuration, we are getting values around 20-25ms for the update, which is the lowest value we were able to get.

We have achieved an update time below 100ms, which was the main goal - and the rest of it is up to the clients computing power, and your chart configuration.

I hope that you will find those solutions useful and will implement them in your final code,
Have a good day!
Kamil Musiałowski
Highcharts Developer
ayanami
Posts: 9
Joined: Tue Jun 28, 2022 9:39 am

Re: Highcharts: The problem of slow response in line graph rendering

Hello mr kamil.m


As you can see, I wrote back to you again, and again, thank you very much for taking the time to help me.

I've made sure I read the documentation you posted about rendering highcharts charts in vue.js and native JavaScript. I've tried both solutions locally. I've tested them on different computers.It does have something to do with the performance of the computer.

Code: Select all

      redraw() {
        // we need to count the time on the redraw
        // console.timeEnd("line");
        console.log(new Date());
      },

Code: Select all

    updateData() {
      // start counting
      // console.time("line");
      this.chartOptions = {
        ...chartOptions,
        series: [
          {
            data: getData(n),
          },
        ],
      };
    },
    setTimer() {
      this.timer = setInterval(() => {
        this.updateData();
      }, 100);
    },
The laptop I use is Razer Blade 15(2021). I modified your online demo and added a setInterval(()=>{}, 100) function. The time of printing and rendering on my computer is almost 60ms. -80ms or so, but what I don't understand is that when I print new Date() in the redraw() function, I find that it is only executed about 8-9 times in a second. Since each rendering time is less than 100ms, Shouldn't that be printed 10 times in 1s? And the chart refreshed by my naked eye does not have ten frames per second. I don't know if you print it in the redraw() function, whether it will output ten times per second, you can open that directly Link to test and see.

I just want to achieve that ten pieces of data can be rendered and refreshed within 1s
https://codesandbox.io/s/highcharts-vue ... :1135-1280

Looking forward to your reply :)
Attachments
test_2.png
test_2.png (63.21 KiB) Viewed 1900 times
test_1.png
test_1.png (95.64 KiB) Viewed 1900 times
ayanami
Posts: 9
Joined: Tue Jun 28, 2022 9:39 am

Re: Highcharts: The problem of slow response in line graph rendering

Hi, mr kamil.m

You can ignore my last message
I have just implemented a 20ms - 30ms rendering refresh on the host computer, and the problem that has been bothering me for a long time has been solved! Thank you very much for your help.

I'm going to read the code and the differences between my two machines and try to find out what the problem is and what changes have been made. Any help would be greatly appreciated,

But I don't just use highcharts as a dynamic display of data. On the basis that there is no problem with data rendering, I will add some interactive operations. If there are new problems, I will start a new post to ask new questions. Hope you will still help me then.
I think this question should be over here.

Thank you so much! Have a nice day :D
kamil.m
Posts: 892
Joined: Thu May 19, 2022 1:33 pm

Re: Highcharts: The problem of slow response in line graph rendering

Hi there!

I'm really glad that you were able to find a solution for that.

In case of any further questions, simply create a new topic and our support team will be more than happy to help you,
Thank you, and have a great day too!
Kamil Musiałowski
Highcharts Developer

Return to “Highcharts Usage”