You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2020/03/29 14:30:41 UTC

[incubator-echarts] branch next updated: refact: add hover event handler on the view group to save memory. fix states bugs.

This is an automated email from the ASF dual-hosted git repository.

shenyi pushed a commit to branch next
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git


The following commit(s) were added to refs/heads/next by this push:
     new 32a6f76  refact: add hover event handler on the view group to save memory. fix states bugs.
32a6f76 is described below

commit 32a6f76a8713e8c6f2a5079def13c632016dd9fe
Author: pissang <bm...@gmail.com>
AuthorDate: Sun Mar 29 22:30:07 2020 +0800

    refact: add hover event handler on the view group to save memory. fix states bugs.
---
 src/chart/bar/PictorialBarView.ts |  8 ++--
 src/chart/helper/EffectSymbol.ts  |  6 +--
 src/chart/helper/Line.ts          |  4 +-
 src/chart/helper/Symbol.ts        |  8 ++--
 src/chart/line/LineView.ts        |  3 ++
 src/chart/sankey/SankeyView.ts    |  8 ++--
 src/component/helper/MapDraw.ts   |  5 +-
 src/echarts.ts                    | 31 ++++++++++++-
 src/util/graphic.ts               | 96 ++++++++++++++++++++-------------------
 src/view/Chart.ts                 |  5 +-
 10 files changed, 107 insertions(+), 67 deletions(-)

diff --git a/src/chart/bar/PictorialBarView.ts b/src/chart/bar/PictorialBarView.ts
index e52ffbc..743ab47 100644
--- a/src/chart/bar/PictorialBarView.ts
+++ b/src/chart/bar/PictorialBarView.ts
@@ -621,13 +621,13 @@ function createOrUpdateRepeatSymbols(
 
     function onMouseOver() {
         eachPath(bar, function (path) {
-            path.trigger('emphasis');
+            graphic.enterEmphasis(path);
         });
     }
 
     function onMouseOut() {
         eachPath(bar, function (path) {
-            path.trigger('normal');
+            graphic.leaveEmphasis(path);
         });
     }
 }
@@ -685,11 +685,11 @@ function createOrUpdateSingleSymbol(
     updateHoverAnimation(mainPath, symbolMeta);
 
     function onMouseOver(this: typeof mainPath) {
-        this.trigger('emphasis');
+        graphic.enterEmphasis(this);
     }
 
     function onMouseOut(this: typeof mainPath) {
-        this.trigger('normal');
+        graphic.leaveEmphasis(this);
     }
 }
 
diff --git a/src/chart/helper/EffectSymbol.ts b/src/chart/helper/EffectSymbol.ts
index 17381ad..f6fb57c 100644
--- a/src/chart/helper/EffectSymbol.ts
+++ b/src/chart/helper/EffectSymbol.ts
@@ -19,7 +19,7 @@
 
 import * as zrUtil from 'zrender/src/core/util';
 import {createSymbol} from '../../util/symbol';
-import {Group, Path} from '../../util/graphic';
+import {Group, Path, enterEmphasis, leaveEmphasis} from '../../util/graphic';
 import {parsePercent} from '../../util/number';
 import SymbolClz from './Symbol';
 import List from '../../data/List';
@@ -151,14 +151,14 @@ class EffectSymbol extends Group {
      * Highlight symbol
      */
     highlight() {
-        this.trigger('emphasis');
+        enterEmphasis(this);
     }
 
     /**
      * Downplay symbol
      */
     downplay() {
-        this.trigger('normal');
+        leaveEmphasis(this);
     }
 
     /**
diff --git a/src/chart/helper/Line.ts b/src/chart/helper/Line.ts
index ca3bc51..1f7109b 100644
--- a/src/chart/helper/Line.ts
+++ b/src/chart/helper/Line.ts
@@ -303,11 +303,11 @@ class Line extends graphic.Group {
     }
 
     highlight() {
-        this.trigger('emphasis');
+        graphic.enterEmphasis(this);
     }
 
     downplay() {
-        this.trigger('normal');
+        graphic.leaveEmphasis(this);
     }
 
     updateLayout(lineData: List, idx: number) {
diff --git a/src/chart/helper/Symbol.ts b/src/chart/helper/Symbol.ts
index ddffc18..a4c46df 100644
--- a/src/chart/helper/Symbol.ts
+++ b/src/chart/helper/Symbol.ts
@@ -131,14 +131,14 @@ class Symbol extends graphic.Group {
      * Highlight symbol
      */
     highlight() {
-        this.childAt(0).trigger('emphasis');
+        graphic.enterEmphasis(this.childAt(0));
     }
 
     /**
      * Downplay symbol
      */
     downplay() {
-        this.childAt(0).trigger('normal');
+        graphic.leaveEmphasis(this.childAt(0));
     }
 
     /**
@@ -363,8 +363,8 @@ function highDownOnUpdate(this: ECSymbol, fromState: DisplayState, toState: Disp
     if (toState === 'emphasis') {
         const ratio = scale[1] / scale[0];
         const emphasisOpt = {
-            x: Math.max(scale[0] * 1.1, scale[0] + 3),
-            y: Math.max(scale[1] * 1.1, scale[1] + 3 * ratio)
+            scaleX: Math.max(scale[0] * 1.1, scale[0] + 3),
+            scaleY: Math.max(scale[1] * 1.1, scale[1] + 3 * ratio)
         };
         // FIXME
         // modify it after support stop specified animation.
diff --git a/src/chart/line/LineView.ts b/src/chart/line/LineView.ts
index a2e27bb..c829293 100644
--- a/src/chart/line/LineView.ts
+++ b/src/chart/line/LineView.ts
@@ -365,6 +365,7 @@ class LineView extends ChartView {
     }
 
     render(seriesModel: LineSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
+
         const coordSys = seriesModel.coordinateSystem;
         const group = this.group;
         const data = seriesModel.getData();
@@ -655,6 +656,7 @@ class LineView extends ChartView {
             shape: {
                 points: points
             },
+            segmentIgnoreThreshold: 2,
             silent: true,
             z2: 10
         });
@@ -678,6 +680,7 @@ class LineView extends ChartView {
                 points: points,
                 stackedOnPoints: stackedOnPoints
             },
+            segmentIgnoreThreshold: 2,
             silent: true
         });
 
diff --git a/src/chart/sankey/SankeyView.ts b/src/chart/sankey/SankeyView.ts
index 492358b..f102fcd 100644
--- a/src/chart/sankey/SankeyView.ts
+++ b/src/chart/sankey/SankeyView.ts
@@ -156,11 +156,11 @@ class SankeyPath extends graphic.Path<SankeyPathProps> {
     }
 
     highlight() {
-        this.trigger('emphasis');
+        graphic.enterEmphasis(this);
     }
 
     downplay() {
-        this.trigger('normal');
+        graphic.leaveEmphasis(this);
     }
 }
 
@@ -346,11 +346,11 @@ class SankeyView extends ChartView {
             }
 
             el.highlight = function () {
-                this.trigger('emphasis');
+                graphic.enterEmphasis(this);
             };
 
             el.downplay = function () {
-                this.trigger('normal');
+                graphic.leaveEmphasis(this);
             };
 
             el.focusNodeAdjHandler && el.off('mouseover', el.focusNodeAdjHandler);
diff --git a/src/component/helper/MapDraw.ts b/src/component/helper/MapDraw.ts
index 4a653f7..21ce559 100644
--- a/src/component/helper/MapDraw.ts
+++ b/src/component/helper/MapDraw.ts
@@ -237,6 +237,9 @@ class MapDraw {
             compoundPath.style.strokeNoScale = true;
             compoundPath.culling = true;
 
+            const compoundPathEmphasisState = compoundPath.ensureState('emphasis');
+            compoundPathEmphasisState.style = hoverItemStyle;
+
             // Label
             const showLabel = labelModel.get('show');
             const hoverShowLabel = hoverLabelModel.get('show');
@@ -311,7 +314,7 @@ class MapDraw {
 
             // @ts-ignore FIXME:TS fix the "compatible with each other"?
             regionGroup.highDownSilentOnTouch = !!mapOrGeoModel.get('selectedMode');
-            graphic.enableHoverEmphasis(regionGroup, hoverItemStyle);
+            graphic.enableHoverEmphasis(regionGroup);
 
             regionsGroup.add(regionGroup);
         });
diff --git a/src/echarts.ts b/src/echarts.ts
index 679d646..ff4709e 100644
--- a/src/echarts.ts
+++ b/src/echarts.ts
@@ -61,7 +61,8 @@ import {
     ECUnitOption,
     ZRColor,
     ComponentMainType,
-    ComponentSubType
+    ComponentSubType,
+    ZRElementEvent
 } from './util/types';
 import Displayable from 'zrender/src/graphic/Displayable';
 import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable';
@@ -1602,6 +1603,7 @@ class ECharts extends Eventful {
                 componentView.render(componentModel, ecModel, api, payload);
 
                 updateZ(componentModel, componentView);
+                updateHoverEmphasisHandler(componentView);
             });
         };
 
@@ -1636,6 +1638,8 @@ class ECharts extends Eventful {
                 updateZ(seriesModel, chartView);
 
                 updateBlend(seriesModel, chartView);
+
+                updateHoverEmphasisHandler(chartView);
             });
             scheduler.unfinished |= unfinished;
 
@@ -1712,6 +1716,7 @@ class ECharts extends Eventful {
                     z != null && (el.z = z);
                     zlevel != null && (el.zlevel = zlevel);
 
+                    // TODO if textContent is on group.
                     const textContent = el.getTextContent();
                     if (textContent) {
                         textContent.z = el.z;
@@ -1723,6 +1728,29 @@ class ECharts extends Eventful {
             });
         };
 
+        function getHighDownDispatcher(target: Element) {
+            while (target && !graphic.isHighDownDispatcher(target)) {
+                target = target.parent;
+            }
+            return target;
+        }
+        function onMouseOver(e: ZRElementEvent) {
+            const dispatcher = getHighDownDispatcher(e.target);
+            if (dispatcher) {
+                graphic.enterEmphasisWhenMouseOver(dispatcher, e);
+            }
+        }
+        function onMouseOut(e: ZRElementEvent) {
+            const dispatcher = getHighDownDispatcher(e.target);
+            if (dispatcher) {
+                graphic.leaveEmphasisWhenMouseOut(dispatcher, e);
+            }
+        }
+        updateHoverEmphasisHandler = function (view: ComponentView | ChartView): void {
+            view.group.on('mouseover', onMouseOver)
+                .on('mouseout', onMouseOut);
+        };
+
         createExtensionAPI = function (ecIns: ECharts): ExtensionAPI {
             return new (class extends ExtensionAPI {
                 getCoordinateSystems(): CoordinateSystemMaster[] {
@@ -1820,6 +1848,7 @@ let performPostUpdateFuncs: (ecModel: GlobalModel, api: ExtensionAPI) => void;
 let updateHoverLayerStatus: (ecIns: ECharts, ecModel: GlobalModel) => void;
 let updateBlend: (seriesModel: SeriesModel, chartView: ChartView) => void;
 let updateZ: (model: ComponentModel, view: ComponentView | ChartView) => void;
+let updateHoverEmphasisHandler: (view: ComponentView | ChartView) => void;
 let createExtensionAPI: (ecIns: ECharts) => ExtensionAPI;
 let enableConnect: (chart: ECharts) => void;
 
diff --git a/src/util/graphic.ts b/src/util/graphic.ts
index 94474b6..243ad13 100644
--- a/src/util/graphic.ts
+++ b/src/util/graphic.ts
@@ -358,36 +358,43 @@ function liftColor(color: string): string {
     return liftedColor;
 }
 
-function singleEnterEmphasis(el: Displayable) {
+function singleEnterEmphasis(el: Element) {
+
+    (el as ExtendedElement).__highlighted = true;
+
+    // el may be an array.
     if (!el.states.emphasis) {
         return;
     }
-
-    const emphasisStyle = el.states.emphasis.style;
-    const currentFill = el.style && el.style.fill;
-    const currentStroke = el.style && el.style.stroke;
+    const disp = el as Displayable;
+    const emphasisStyle = disp.states.emphasis.style;
+    const currentFill = disp.style && disp.style.fill;
+    const currentStroke = disp.style && disp.style.stroke;
 
     el.useState('emphasis');
 
-    if (emphasisStyle && !hasFillOrStroke(emphasisStyle.fill)) {
-        el.style.fill = liftColor(currentFill);
-    }
-    if (emphasisStyle && !hasFillOrStroke(emphasisStyle.stroke)) {
-        el.style.stroke = liftColor(currentStroke);
+    if (disp.style) { // Is not group
+        if (emphasisStyle && !hasFillOrStroke(emphasisStyle.fill)) {
+            disp.style.fill = liftColor(currentFill);
+        }
+        if (emphasisStyle && !hasFillOrStroke(emphasisStyle.stroke)) {
+            disp.style.stroke = liftColor(currentStroke);
+        }
+        disp.z2 += Z2_EMPHASIS_LIFT;
     }
 
-    el.z2 += Z2_EMPHASIS_LIFT;
     const textContent = el.getTextContent();
     if (textContent) {
         textContent.z2 += Z2_EMPHASIS_LIFT;
     }
-
     // TODO hover layer
 }
 
 
-function singleEnterNormal(el: Displayable) {
+function singleEnterNormal(el: Element) {
     el.clearStates();
+
+    (el as ExtendedElement).__highlighted = false;
 }
 
 function traverseUpdate<T>(
@@ -433,32 +440,32 @@ export function enableElementHoverEmphasis(el: Displayable, hoverStl?: ZRStylePr
     }
 }
 
-function onElementMouseOver(this: ExtendedDisplayable, e: ElementEvent) {
-    !shouldSilent(this, e)
+export function enterEmphasisWhenMouseOver(el: Element, e: ElementEvent) {
+    !shouldSilent(el, e)
         // "emphasis" event highlight has higher priority than mouse highlight.
-        && !this.__highByOuter
-        && traverseUpdate(this, singleEnterEmphasis);
+        && !(el as ExtendedElement).__highByOuter
+        && traverseUpdate((el as ExtendedElement), singleEnterEmphasis);
 }
 
-function onElementMouseOut(this: ExtendedDisplayable, e: ElementEvent) {
-    !shouldSilent(this, e)
+export function leaveEmphasisWhenMouseOut(el: Element, e: ElementEvent) {
+    !shouldSilent(el, e)
         // "emphasis" event highlight has higher priority than mouse highlight.
-        && !this.__highByOuter
-        && traverseUpdate(this, singleEnterNormal);
+        && !(el as ExtendedElement).__highByOuter
+        && traverseUpdate((el as ExtendedElement), singleEnterNormal);
 }
 
-function onElementEmphasisEvent(this: ExtendedDisplayable, highlightDigit: number) {
-    this.__highByOuter |= 1 << (highlightDigit || 0);
-    traverseUpdate(this, singleEnterEmphasis);
+export function enterEmphasis(el: Element, highlightDigit?: number) {
+    (el as ExtendedElement).__highByOuter |= 1 << (highlightDigit || 0);
+    traverseUpdate((el as ExtendedElement), singleEnterEmphasis);
 }
 
-function onElementNormalEvent(this: ExtendedDisplayable, highlightDigit: number) {
-    !(this.__highByOuter &= ~(1 << (highlightDigit || 0)))
-        && traverseUpdate(this, singleEnterNormal);
+export function leaveEmphasis(el: Element, highlightDigit?: number) {
+    !((el as ExtendedElement).__highByOuter &= ~(1 << (highlightDigit || 0)))
+        && traverseUpdate((el as ExtendedElement), singleEnterNormal);
 }
 
-function shouldSilent(el: ExtendedDisplayable, e: ElementEvent) {
-    return el.__highDownSilentOnTouch && e.zrByTouch;
+function shouldSilent(el: Element, e: ElementEvent) {
+    return (el as ExtendedElement).__highDownSilentOnTouch && e.zrByTouch;
 }
 
 /**
@@ -471,10 +478,10 @@ function shouldSilent(el: ExtendedDisplayable, e: ElementEvent) {
  * (1)
  * Call the method for a "root" element once. Do not call it for each descendants.
  * If the descendants elemenets of a group has itself hover style different from the
- * root group, we can simply mount the style on `el.hoverStyle` for them, but should
+ * root group, we can simply mount the style on `el.states.emphasis` for them, but should
  * not call this method for them.
  *
- * (2) These input parameters can be set directly on `el`:
+ * (2) The given hover style will replace the style in emphasis state already exists.
  */
 export function enableHoverEmphasis(el: Element, hoverStyle?: ZRStyleProps) {
     setAsHighDownDispatcher(el, true);
@@ -530,12 +537,9 @@ export function setAsHighDownDispatcher(el: Element, asDispatcher: boolean) {
     // Simple optimize, since this method might be
     // called for each elements of a group in some cases.
     if (!disable || extendedEl.__highDownDispatcher) {
-        const method: 'on' | 'off' = disable ? 'off' : 'on';
 
-        // Duplicated function will be auto-ignored, see Eventful.js.
-        el[method]('mouseover', onElementMouseOver)[method]('mouseout', onElementMouseOut);
         // Emphasis, normal can be triggered manually by API or other components like hover link.
-        el[method]('emphasis', onElementEmphasisEvent)[method]('normal', onElementNormalEvent);
+        // el[method]('emphasis', onElementEmphasisEvent)[method]('normal', onElementNormalEvent);
         // Also keep previous record.
         extendedEl.__highByOuter = extendedEl.__highByOuter || 0;
 
@@ -624,19 +628,17 @@ export function setLabelStyle<LDI>(
             baseText = isFunction(opt.defaultText) ? opt.defaultText(labelDataIndex, opt) : opt.defaultText;
         }
     }
-    const normalStyleText = showNormal ? baseText : null;
-    const emphasisStyleText = showEmphasis
-        ? retrieve2(
-            labelFetcher
-                ? labelFetcher.getFormattedLabel(labelDataIndex, 'emphasis', null, labelDimIndex)
-                : null,
-            baseText
-        )
-        : null;
+    const normalStyleText = baseText;
+    const emphasisStyleText = retrieve2(
+        labelFetcher
+            ? labelFetcher.getFormattedLabel(labelDataIndex, 'emphasis', null, labelDimIndex)
+            : null,
+        baseText
+    );
 
     let richText = isSetOnRichText ? targetEl as RichText : null;
     // Optimize: If style.text is null, text will not be drawn.
-    if (normalStyleText != null || emphasisStyleText != null) {
+    if (showNormal || showEmphasis) {
         if (!isSetOnRichText) {
             // Reuse the previous
             richText = targetEl.getTextContent();
@@ -644,11 +646,11 @@ export function setLabelStyle<LDI>(
                 richText = new RichText();
                 targetEl.setTextContent(richText);
             }
-            richText.ignore = !normalStyleText;
         }
+        richText.ignore = !showNormal;
 
         const emphasisState = richText.ensureState('emphasis');
-        emphasisState.ignore = !emphasisStyleText;
+        emphasisState.ignore = !showEmphasis;
 
         // Always set `textStyle` even if `normalStyle.text` is null, because default
         // values have to be set on `normalStyle`.
diff --git a/src/view/Chart.ts b/src/view/Chart.ts
index 11a1c1c..4813eda 100644
--- a/src/view/Chart.ts
+++ b/src/view/Chart.ts
@@ -35,6 +35,7 @@ import {
 } from '../util/types';
 import { SeriesTaskContext, SeriesTask } from '../stream/Scheduler';
 import List from '../data/List';
+import { graphic } from '../export';
 
 const inner = modelUtil.makeInner<{
     updateMethod: keyof ChartView
@@ -192,7 +193,9 @@ class ChartView {
  */
 function elSetState(el: Element, state: DisplayState, highlightDigit: number) {
     if (el) {
-        el.trigger(state, highlightDigit);
+        state === 'emphasis' ? graphicUtil.enterEmphasis(el, highlightDigit)
+            : graphicUtil.leaveEmphasis(el, highlightDigit);
+
         if (el.isGroup
             // Simple optimize.
             && !graphicUtil.isHighDownDispatcher(el)


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org