Correction: my earlier version attribution was inaccurate. I initially treated this as an ECharts 6.1.0 regression, but that comparison changed both ECharts and echarts-gl versions, so it did not isolate ECharts 6.1.0 as the cause.
The failing behavior is more likely caused by the high-pixel-ratio export path in zrender, where non-builtin layers such as echarts-gl LayerGL are omitted. The proposed upstream fix is ecomfe/zrender#1164 <https://github.com/ecomfe/zrender/pull/1164>. Sorry for the earlier misclassification. bryan yang <[email protected]> 于2026年7月22日周三 16:11写道: > Hi ECharts community, > > I am working on apache/echarts#21700, where exporting an echarts-gl chart > at a pixel ratio higher than the painter DPR produces an image without the > WebGL content, while 2D components such as visualMap are still included. > > Issue: > https://github.com/apache/echarts/issues/21700 > > I traced the problem to CanvasPainter.getRenderedCanvas in zrender 6.1.0. > > When the requested pixel ratio is less than or equal to the painter DPR, > getRenderedCanvas composites all painter layers and invokes renderToCanvas > for non-builtin layers. > > When the requested pixel ratio is greater than the painter DPR, it > repaints only the zrender storage display list through brush(...). LayerGL > is a custom, non-builtin layer and is not part of that display list, so its > WebGL content is omitted from the exported image. > > Therefore, the exact trigger is: > > requested pixel ratio > painter DPR > > This regression became visible with ECharts 6.1.0 and echarts-gl 2.1.0. > echarts-gl 2.1.0 removed its previous getRenderedCanvas override because > zrender's native export path was expected to support non-builtin layers. > That works in the normal compositing branch, but not in the > high-pixel-ratio branch. > > I have submitted the following zrender PR: > > https://github.com/ecomfe/zrender/pull/1164 > > The proposed change: > > 1. Includes non-builtin layers in the high-pixel-ratio export path through > their renderToCanvas hooks. > 2. Preserves z-level ordering between custom layers and built-in > displayables. > 3. Finalizes the current brush scope before rendering a custom layer, so > pending path batches and clipping state do not leak across the composition > boundary. > 4. Restarts the brush scope after each custom layer. > 5. Adds a regression test with custom layers below and above a built-in > displayable, using painter DPR 1 and export pixel ratio 2. > > The unit tests, type check, lint check, and library build pass locally. > > I chose to fix this in zrender rather than reintroducing an > echarts-gl-specific workaround because the current behavior can affect any > custom painter layer. > > I would appreciate feedback on whether the zrender-level approach and the > proposed layer-ordering behavior are consistent with the expected design. I > am happy to adjust the implementation based on the community's suggestions. > > Best regards, > Bryan > GitHub: DaZuiZui https://github.com/DaZuiZui >
