What does redraw exactly do?

2019-08-07 02:28发布

问题:

When changing somthing on the chart, like myChart.addSeries(mySeriesObj) or

myChart.get("myPointId').update(50); the default behavior is calling the redraw function.

now, suppose i have 3 series on that chart (seriesA, seriesB, seriesC), and i just updated 1 point in seriesA. would it redraw all the chart (seriesA, seriesB, seriesC, axises, labels, etc...) very fast, or just the new point?

Does Highchart works with layers, or all in the same "frame"?

I am asking this because i am going to work with serieses larger then 1,000 points and i know that there can be some issues with performence when using large data on Highchart.( i already saw that the performance slows when enabling the marker.states.hover option or the tooltip option )

回答1:

To my understanding, Highcharts would most likely only redraw the dirty components (in your case the series to which that point belongs to).

Some bits and pieces of the chart.redraw() source looks like

// redraw affected series
each(series, function (serie) {
    if (serie.isDirty && serie.visible &&
            (!serie.isCartesian || serie.xAxis)) { // issue #153
        serie.redraw();
    }
});

When you call the point.update(), only the serie that the point belongs to is marked dirty. Hence is redrawn on the next chart.redraw() call, whereas other series whose points haven't been updated won't be redrawn.

Having said that, there are other bits and pieces of code in chart.redraw() apart from the above. Mainly for redrawing axes and legends and other stuff. Appears that most of those are also redrawn based on a similar isDirty logic, and hence should not be performance deterrents. But if performance is really a critical factor you can call the point.update() with a second parameter as false, this would skip the implicit chart.redraw() call and hence everything inside it. Then you can explicitly make a call to the series.redraw() method on the particular serie that you wish to update (the one that the point belongs to).
Caution: This won't redraw the axes (and other stuffs), which may need to be redrawn if the updated value of the point is outside the extremes of the current axes. Also the series.redraw() is not listed in the documentation, possibly indicating that using it is discouraged and may produce unexpected results.
I would go with the chart.redraw() way in 99% of cases, as the performance is highly acceptable most of the time.

References:
point.update() api reference
Demo @ JsFiddle



回答2:

From the source code:

/**
 * Redraw legend, axes or series based on updated data
 *
 * @param {Boolean|Object} animation Whether to apply animation, and optionally animation
 *    configuration
 */
 redraw: function (animation) {


回答3:

I have had some trouble with Highchart performance loading > 1000 points fitness data series (like heart rate, speed etc.). I found that disabling marker in plot Highcharts example, gave quite significant performance boost. I've also disabled animation.

I ran the chrome profiler on my solution and found that the each function in highcharts.src.js is called during preparation for rendering.

    this.each =
            //Array.prototype.forEach ?
        //  function (arr, fn) { // modern browsers
        //      return Array.prototype.forEach.call(arr, fn);

        //  } : 
            function (arr, fn) { // legacy
                var i = 0, 
                    len = arr.length;
                for (; i < len; i++) {
                    if (fn.call(arr[i], arr[i], i, arr) === false) {
                        return i;
                    }
                }
            };

I've heard that forEach is slower than for loop, so I've commented out the default selection of forEach. Testing on jsperf for vs foreach, shows on my machine environment that foreach is 85% slower than the fastest reverse for loop



回答4:

You can also use point update() function http://api.highcharts.com/highstock#Point.update()



标签: highcharts