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