Highcharts单折线图页面缩放时数值消失报错问题排查
I’ve run into this exact issue before with Highstock’s dynamic legend formatting—let’s break down why this happens and how to fix it.
Why the points Variable Turns Null on Resize
When you resize the page (or switch to mobile), Highcharts triggers a redraw event to re-render the chart with the new dimensions. Here’s what’s going wrong in your current setup:
- Your
updateLegendLabelfunction only runs on theloadevent, but doesn’t account for subsequent redraws during resizing. - During a redraw, Highstock temporarily resets or reinitializes series data. When the legend’s
labelFormatterruns mid-redraw, thethis.pointsproperty (which references the series’ current rendered points) might not be fully populated yet, resulting innull. - Calling
chart.update()inside theloadevent overrides the legend configuration, but this update isn’t re-run during redraws, leading to stale or broken references.
Fixes to Resolve the Issue
1. Move the Legend Formatter Directly to Initial Configuration
Instead of updating the legend via chart.update() on load, define the labelFormatter directly in your initial chart config. This ensures it runs every time the legend renders (including during redraws) and has access to the latest state.
Highcharts.stockChart('nav-chart', { tooltip: { pointFormat:"{point.y:.3f}€" }, chart: { type: 'line', zoomType: 'x', pinchType: 'x', panning: false, <?php if (is_front_page()){ ?> height: 700, <?php } else { ?> height: 500 <?php } ?> }, legend: { useHTML: true, symbolPadding: 0, symbolWidth: 0, symbolHeight: 0, symbolRadius: 0, labelFormatter: function() { // Add a guard clause to handle null points if (!this.points || this.points.length === 0) { return ''; // Or return a default label like "Loading..." } var lastVal = this.yData[this.yData.length - 1], chart = this.chart, xAxis = this.xAxis, points = this.points, avg = 0, counter = 0, min, max; // Your existing business logic here // ... } } });
2. Listen to Redraw Events for Dynamic Updates
If you need to update the legend dynamically after load (e.g., based on user interactions), add a redraw event listener alongside load. This ensures your formatter refreshes every time the chart resizes or redraws:
Highcharts.stockChart('nav-chart', { // ... other config ... chart: { // ... other chart options ... <?php if (!is_front_page()){ ?> height: 500, events: { load: updateLegendLabel, redraw: updateLegendLabel // Trigger on resize/redraw } <?php } ?> }, }); function updateLegendLabel() { var chrt = this.chart || this; chrt.update({ legend: { useHTML: true, symbolPadding: 0, symbolWidth: 0, symbolHeight: 0, symbolRadius: 0, labelFormatter: function() { // Guard clause to avoid null errors if (!this.points) return ''; // Your business logic here // ... } } }, false); // Pass false to avoid immediate redraw chrt.redraw(); // Trigger redraw once update is complete }
3. Use yData Instead of points (If Possible)
You’re already using this.yData for the last value—if your business logic doesn’t need direct access to point objects (like coordinates), stick to yData (an array of raw values) instead of points. yData is more reliably available during redraws because it’s tied to the series’ raw data, not the rendered DOM elements.
Key Takeaways
- Always add guard clauses for
nullvalues in formatters to prevent console errors. - Prefer defining formatters in the initial config over post-load updates for consistency across redraws.
- Listen to
redrawevents if you need dynamic updates to handle resize and zoom scenarios.
内容的提问来源于stack exchange,提问作者Danyal Sandeelo

