This is an automated email from the ASF dual-hosted git repository. sushuang pushed a commit to branch PR/plainheart_fix/alignTicks-precision in repository https://gitbox.apache.org/repos/asf/echarts.git
commit 9335851264c527001c8978d0005ed9f385670295 Author: 100pah <[email protected]> AuthorDate: Sun Mar 15 22:06:51 2026 +0800 fix: (1) Previously hoverLayerThreshold modification does not work. (2) Restrict the triggering of hoverLayer to only canvas renderer. --- src/chart/custom/CustomView.ts | 4 ++-- src/chart/heatmap/HeatmapView.ts | 2 +- src/chart/helper/LineDraw.ts | 2 +- src/chart/helper/SymbolDraw.ts | 2 +- src/component/legend/LegendView.ts | 17 ++--------------- src/core/ExtensionAPI.ts | 8 ++++++++ src/core/Scheduler.ts | 5 +++-- src/core/echarts.ts | 28 ++++++++++++++++++++++++---- src/util/graphic.ts | 8 ++++++++ src/view/Chart.ts | 3 +++ 10 files changed, 53 insertions(+), 26 deletions(-) diff --git a/src/chart/custom/CustomView.ts b/src/chart/custom/CustomView.ts index fe50f12ce..e8f30d648 100644 --- a/src/chart/custom/CustomView.ts +++ b/src/chart/custom/CustomView.ts @@ -94,7 +94,6 @@ import CustomSeriesModel, { CustomRootElementOption, CustomSeriesOption, CustomCompoundPathOption, - CustomSeriesRenderItemCoordinateSystemAPI } from './CustomSeries'; import { PatternObject } from 'zrender/src/graphic/Pattern'; import { @@ -110,6 +109,7 @@ import type SeriesModel from '../../model/Series'; import { getCustomSeries } from './customSeriesRegister'; import tokens from '../../visual/tokens'; + const EMPHASIS = 'emphasis' as const; const NORMAL = 'normal' as const; const BLUR = 'blur' as const; @@ -290,7 +290,7 @@ export default class CustomChartView extends ChartView { function setIncrementalAndHoverLayer(el: Displayable) { if (!el.isGroup) { el.incremental = true; - el.ensureState('emphasis').hoverLayer = true; + el.ensureState('emphasis').hoverLayer = graphicUtil.HOVER_LAYER_FOR_INCREMENTAL; } } for (let idx = params.start; idx < params.end; idx++) { diff --git a/src/chart/heatmap/HeatmapView.ts b/src/chart/heatmap/HeatmapView.ts index a58406bb4..403332025 100644 --- a/src/chart/heatmap/HeatmapView.ts +++ b/src/chart/heatmap/HeatmapView.ts @@ -346,7 +346,7 @@ class HeatmapView extends ChartView { // PENDING if (incremental) { // Rect must use hover layer if it's incremental. - rect.states.emphasis.hoverLayer = true; + rect.states.emphasis.hoverLayer = graphic.HOVER_LAYER_FOR_INCREMENTAL; } group.add(rect); diff --git a/src/chart/helper/LineDraw.ts b/src/chart/helper/LineDraw.ts index 94c417f4f..4e0a83ee1 100644 --- a/src/chart/helper/LineDraw.ts +++ b/src/chart/helper/LineDraw.ts @@ -172,7 +172,7 @@ class LineDraw { function updateIncrementalAndHover(el: Displayable) { if (!el.isGroup && !isEffectObject(el)) { el.incremental = true; - el.ensureState('emphasis').hoverLayer = true; + el.ensureState('emphasis').hoverLayer = graphic.HOVER_LAYER_FOR_INCREMENTAL; } } diff --git a/src/chart/helper/SymbolDraw.ts b/src/chart/helper/SymbolDraw.ts index 93e13848e..5889b1af6 100644 --- a/src/chart/helper/SymbolDraw.ts +++ b/src/chart/helper/SymbolDraw.ts @@ -292,7 +292,7 @@ class SymbolDraw { function updateIncrementalAndHover(el: Displayable) { if (!el.isGroup) { el.incremental = true; - el.ensureState('emphasis').hoverLayer = true; + el.ensureState('emphasis').hoverLayer = graphic.HOVER_LAYER_FOR_INCREMENTAL; } } for (let idx = taskParams.start; idx < taskParams.end; idx++) { diff --git a/src/component/legend/LegendView.ts b/src/component/legend/LegendView.ts index 2dc195fca..142bb32d6 100644 --- a/src/component/legend/LegendView.ts +++ b/src/component/legend/LegendView.ts @@ -724,25 +724,13 @@ function dispatchSelectAction( dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId); } -function isUseHoverLayer(api: ExtensionAPI) { - const list = api.getZr().storage.getDisplayList(); - let emphasisState: DisplayableState; - let i = 0; - const len = list.length; - while (i < len && !(emphasisState = list[i].states.emphasis)) { - i++; - } - return emphasisState && emphasisState.hoverLayer; -} - function dispatchHighlightAction( seriesName: string, dataName: string, api: ExtensionAPI, excludeSeriesId: string[] ) { - // If element hover will move to a hoverLayer. - if (!isUseHoverLayer(api)) { + if (!api.usingTHL()) { api.dispatchAction({ type: 'highlight', seriesName: seriesName, @@ -758,8 +746,7 @@ function dispatchDownplayAction( api: ExtensionAPI, excludeSeriesId: string[] ) { - // If element hover will move to a hoverLayer. - if (!isUseHoverLayer(api)) { + if (!api.usingTHL()) { api.dispatchAction({ type: 'downplay', seriesName: seriesName, diff --git a/src/core/ExtensionAPI.ts b/src/core/ExtensionAPI.ts index cfba0a270..5e615c9ea 100644 --- a/src/core/ExtensionAPI.ts +++ b/src/core/ExtensionAPI.ts @@ -73,6 +73,14 @@ abstract class ExtensionAPI { abstract getViewOfSeriesModel(seriesModel: SeriesModel): ChartView; abstract getModel(): GlobalModel; abstract getECMainCycleVersion(): number; + /** + * PENDING: a temporary method - may be refactored. + * Whether a "threshold hoverLayer" is used. + * `true` means using hover layer due to over `hoverLayerThreshold`. + * Otherwise, if `false`, hover layer may be still used due to progressive (incremental), + * but this method does not need to cover this case. + */ + abstract usingTHL(): boolean; } export default ExtensionAPI; diff --git a/src/core/Scheduler.ts b/src/core/Scheduler.ts index c87690e95..f902f9f01 100644 --- a/src/core/Scheduler.ts +++ b/src/core/Scheduler.ts @@ -34,6 +34,7 @@ import { EChartsType } from './echarts'; import SeriesModel from '../model/Series'; import ChartView from '../view/Chart'; import SeriesData from '../data/SeriesData'; +import { ZRenderType } from 'zrender/src/zrender'; export type GeneralTask = Task<TaskContext>; export type SeriesTask = Task<SeriesTaskContext>; @@ -233,12 +234,12 @@ class Scheduler { }; } - restorePipelines(ecModel: GlobalModel): void { + restorePipelines(zr: ZRenderType, ecModel: GlobalModel): void { const scheduler = this; const pipelineMap = scheduler._pipelineMap = createHashMap(); ecModel.eachSeries(function (seriesModel) { - const progressive = seriesModel.getProgressive(); + const progressive = zr.painter.type === 'canvas' && seriesModel.getProgressive(); const pipelineId = seriesModel.uid; pipelineMap.set(pipelineId, { diff --git a/src/core/echarts.ts b/src/core/echarts.ts index b2a887293..fc1add4b7 100644 --- a/src/core/echarts.ts +++ b/src/core/echarts.ts @@ -310,6 +310,11 @@ interface PostIniter { (chart: EChartsType): void } +const ecInner = modelUtil.makeInner<{ + // Using hoverLayer due to over hoverLayerThreshold. + usingTHL: boolean; +}, ECharts>(); + type EventMethodName = 'on' | 'off'; function createRegisterEventWithLowercaseECharts(method: EventMethodName) { return function (this: ECharts, ...args: any): ECharts { @@ -1638,7 +1643,7 @@ class ECharts extends Eventful<ECEventDefinition> { const scheduler = ecIns._scheduler; - scheduler.restorePipelines(ecIns._model); + scheduler.restorePipelines(ecIns._zr, ecIns._model); scheduler.prepareStageTasks(); prepareView(ecIns, true); @@ -2538,6 +2543,11 @@ class ECharts extends Eventful<ECEventDefinition> { function updateHoverLayerStatus(ecIns: ECharts, ecModel: GlobalModel): void { const zr = ecIns._zr; + + if (zr.painter.type !== 'canvas') { + return; + } + const storage = zr.storage; let elCount = 0; @@ -2547,7 +2557,10 @@ class ECharts extends Eventful<ECEventDefinition> { } }); - if (elCount > ecModel.get('hoverLayerThreshold') && !env.node && !env.worker) { + const inner = ecInner(ecIns); + const shouldUseHoverLayer = elCount > ecModel.get('hoverLayerThreshold') && !env.node && !env.worker; + + if (inner.usingTHL || shouldUseHoverLayer) { ecModel.eachSeries(function (seriesModel) { if (seriesModel.preventUsingHoverLayer) { return; @@ -2555,12 +2568,16 @@ class ECharts extends Eventful<ECEventDefinition> { const chartView = ecIns._chartsMap[seriesModel.__viewId]; if (chartView.__alive) { chartView.eachRendered((el: ECElement) => { - if (el.states.emphasis) { - el.states.emphasis.hoverLayer = true; + const emphasis = el.states.emphasis; + if (emphasis && emphasis.hoverLayer !== graphic.HOVER_LAYER_FOR_INCREMENTAL) { + emphasis.hoverLayer = shouldUseHoverLayer + ? graphic.HOVER_LAYER_FROM_THRESHOLD + : graphic.HOVER_LAYER_NO; } }); } }); + inner.usingTHL = shouldUseHoverLayer; } }; @@ -2726,6 +2743,9 @@ class ECharts extends Eventful<ECEventDefinition> { getECMainCycleVersion(): number { return ecIns[EC_MAIN_CYCLE_VERSION_KEY]; } + usingTHL(): boolean { + return ecInner(ecIns).usingTHL; + } })(ecIns); }; diff --git a/src/util/graphic.ts b/src/util/graphic.ts index 45bf8b556..ef104b7fd 100644 --- a/src/util/graphic.ts +++ b/src/util/graphic.ts @@ -97,6 +97,14 @@ type ExtendShapeReturn = ReturnType<typeof Path.extend>; export const XY = ['x', 'y'] as const; export const WH = ['width', 'height'] as const; +/** + * NOTICE: Only canvas renderer can set these hoverLayer flags. + * @see ElementCommonState['hoverLayer'] + */ +export const HOVER_LAYER_NO = 0; +export const HOVER_LAYER_FROM_THRESHOLD = 1; +export const HOVER_LAYER_FOR_INCREMENTAL = 2; + /** * Extend shape with parameters */ diff --git a/src/view/Chart.ts b/src/view/Chart.ts index 734dece86..a3b9b726c 100644 --- a/src/view/Chart.ts +++ b/src/view/Chart.ts @@ -249,6 +249,9 @@ function toggleHighlight(data: SeriesData, payload: Payload, state: DisplayState }); } else { + // In progressive mode, `data._graphicEls` has typically no items, + // thereby skipping this hover style changing. + // PENDING: more robust approaches? data.eachItemGraphicEl(function (el) { elSetState(el, state, highlightDigit); }); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
