Skip to content

Upgrade Highcharts to 13.x in the next major version #12213

Description

@DiegoCardoso

Describe your motivation

@vaadin/charts is pinned to Highcharts 12.2.0 since it was last upgraded (#10010). Highcharts 13.0.0 was released on 2026-06-11, and we are now five releases behind (12.3.0–12.6.0, 13.0.0). Staying on 12.2.0 means missing, among other things, local (in-browser) image export, which is the default since 12.3.0, the new palette options with colors exposed as CSS custom properties, and the DataTable-based data input.

The original blocker that kept us on 12.2.0 is still not fixed: solid gauge loses its highcharts-color-{n} classes in styled mode when yAxis.stops is set (highcharts/highcharts#23279, tracked in #10104). The regression code is still present in the 13.0.0 sources. A fix was proposed in highcharts/highcharts#23831, but it has not been reviewed yet.

Describe the solution you'd like

Upgrade highcharts to the latest 13.x for the next Vaadin major version. Based on an audit of the 13.0.0 changelog and sources against our integration code:

Blocker handling (one of):

Note

Update (2026-08-31): We can consider this no longer a blocker after the research shared in the comment below showed that we can implement a workaround while the fix doesn't land in Highcharts.

Known work items:

  • Re-check the two full-method overrides (Pointer.prototype.onDocumentMouseMove, KeyboardNavigation.prototype.onMouseUp) against the 13 implementations. Both upstream issues they work around (Wrong click behavior in drilldown series when a chart is placed in a shadow root highcharts/highcharts#23490, Data labels misaligned in Organization chart in styled mode highcharts/highcharts#23443) are still open, so the workarounds stay.
  • Move the export monkeypatches (exportChart, exportChartLocal, getSVG) to the new Highcharts.Exporting class API. The chart-level methods still exist in 13 but only as deprecated proxies, and exportChart is now async.
  • Add the new modules/data-sorting.js import so that series.dataSorting passed through the configuration keeps working (moved out of core in 13).
  • Update visual test baselines: gauges and polar charts have a new default pane design, and default data label positions changed (new dataLabels.distance option).
  • Check the base styles for useHTML content, which is now wrapped in <div> instead of <span>.
  • Evaluate adopting the new palette CSS custom properties instead of the manual --highcharts-* bridging in the base styles.
  • Coordinate with the Flow integration: vaadin-charts-flow-svg-generator has its own highcharts: 12.2.0 pin that must be bumped together, and the migration guide must document the behavioral changes (solid gauge radius/innerRadius numbers are now pixels instead of percent, data label positions changed). No Flow Java API removals are required.

Describe alternatives you've considered

  • Upgrading only to 12.6.0: still contains the solid gauge regression, so it does not avoid the blocker and misses the 13 features.
  • Staying on 12.2.0: not sustainable; chart-level export APIs we patch are deprecated and will likely be removed in Highcharts 14.

Additional context

Supersedes #10104. Highcharts 13.0.0 changelog: https://www.highcharts.com/changelog/#highcharts-v13.0.0

Activity

  1. DiegoCardoso commented on Aug 31, 2026

    @DiegoCardoso
    ContributorAuthor

    Solid gauge blocker: workaround verified

    Prototype branch: proto/hc-solidgauge-colorindex — highcharts bumped to 12.6.0 to reproduce, plus workaround, unit tests, and a dev-page reproduction of the upstream config.

    Root cause. SolidGaugeSeries#drawPoints removes the highcharts-color-{n} classes whenever series.yAxis.stops is truthy. But ColorAxisBase.initStops always assigns axis.stops, falling back to [[0, minColor || ''], [1, maxColor || '']] — undefined in styled mode. So stops is a truthy array of invalid colors, toColor() returns 'none', no fill is written, and the class is removed anyway. The point ends up with neither a class nor a fill and renders fill: none, fully invisible. Identical in 12.3.0 through 13.0.2, and the only such site in the source.

    Workaround (in vaadin-chart-mixin.js, next to the existing monkeypatches):

    Highcharts.wrap(Highcharts.seriesTypes.solidgauge.prototype, 'drawPoints', function (proceed, ...args) {
      proceed.apply(this, args);
    
      const stops = this.yAxis?.stops;
      if (!this.chart.styledMode || (stops && stops.every((stop) => stop.color?.get('rgb') !== ''))) {
        return;
      }
    
      this.points.forEach((point) => {
        if (point.graphic) {
          point.graphic.addClass(point.getClassName(), true);
        }
      });
    });

    Verified on the composed gauge from highcharts/highcharts#23279:

    Variant Before After
    Point colorIndex: 0, series colorIndex: 0 highcharts-point, fill none highcharts-point highcharts-color-0
    Point colorIndex: 3, series colorIndex: 0 highcharts-point, fill none highcharts-point highcharts-color-3
    Same, with yAxis.stops gradient fill attribute unchanged

    Also holds after point.update({ colorIndex }), series.setData() and chart.redraw().

    It wraps instead of overriding, so it does not duplicate the ~90-line drawPoints body. The guard is the same condition as highcharts/highcharts#23831, so once that is merged the wrap writes the identical class list and removing it is never urgent.

    Effect on the plan. "Blocker handling" is resolved: no need to wait for #23831, and point-level colorIndex does not have to be documented as unsupported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions