You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by su...@apache.org on 2021/03/31 22:36:47 UTC
[echarts] 01/02: feature: [geo] (1) Support component focus blur.
The option `emphasis.focus` can be specified to enable this feature.
`emphasis.focus` only supports the value `'self'`. The option
`emphasis.focusScope` is not supported in component. That is,
the focus scope can be only a single component itself. All of the elements
in this component will be blurred. Added `Component['focusBlurEnabled']` to
enable component blur. (2) Support component hover link when highlight with
a given name. There proba [...]
This is an automated email from the ASF dual-hosted git repository.
sushuang pushed a commit to branch fix/geo-svg
in repository https://gitbox.apache.org/repos/asf/echarts.git
commit b0d4a358f317c0d99ee3e45fce52e1b03b6d18e4
Author: 100pah <su...@gmail.com>
AuthorDate: Mon Mar 29 19:40:35 2021 +0800
feature: [geo]
(1) Support component focus blur.
The option `emphasis.focus` can be specified to enable this feature. `emphasis.focus` only supports the value `'self'`.
The option `emphasis.focusScope` is not supported in component. That is, the focus scope can be only a single component itself. All of the elements in this component will be blurred.
Added `Component['focusBlurEnabled']` to enable component blur.
(2) Support component hover link when highlight with a given name.
There probably be multiple elements share one region name while those region elements has no common ancestor. hover link enables them to be highlighted together.
Implementation: if a component implements `Component['findHighDownDispatchers']`, dispatcher elements by a given name will be found and this feature is enabled.
(3) Support component highlight/downplay be triggered by `dispatchAction`.
Implementation: if a component implements `Component['findHighDownDispatchers']`, dispatcher elements by a given name will be found and this feature is enabled.
(4) Some refactor.
---
src/chart/graph/GraphView.ts | 4 +-
src/chart/helper/SymbolDraw.ts | 9 +-
src/chart/sunburst/SunburstPiece.ts | 10 +-
src/chart/treemap/TreemapView.ts | 11 +-
src/component/geo/GeoView.ts | 7 +
src/component/helper/MapDraw.ts | 213 +++++++++++++++++++------------
src/component/tooltip/TooltipView.ts | 7 +-
src/coord/geo/GeoSVGResource.ts | 38 +++---
src/coord/geo/geoTypes.ts | 4 +-
src/core/echarts.ts | 63 +++++----
src/util/graphic.ts | 7 +-
src/util/innerStore.ts | 18 ++-
src/util/states.ts | 194 ++++++++++++++++++++++++----
src/util/types.ts | 2 +-
src/view/Component.ts | 18 ++-
test/geo-svg-demo.html | 240 +++++++++++++++++++++++++++++++++++
16 files changed, 665 insertions(+), 180 deletions(-)
diff --git a/src/chart/graph/GraphView.ts b/src/chart/graph/GraphView.ts
index ee068a8..1c8d10f 100644
--- a/src/chart/graph/GraphView.ts
+++ b/src/chart/graph/GraphView.ts
@@ -18,7 +18,7 @@
*/
import * as zrUtil from 'zrender/src/core/util';
-import SymbolDraw from '../helper/SymbolDraw';
+import SymbolDraw, { ListForSymbolDraw } from '../helper/SymbolDraw';
import LineDraw from '../helper/LineDraw';
import RoamController, { RoamControllerHost } from '../../component/helper/RoamController';
import * as roamHelper from '../../component/helper/roamHelper';
@@ -105,7 +105,7 @@ class GraphView extends ChartView {
adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));
const data = seriesModel.getData();
- symbolDraw.updateData(data);
+ symbolDraw.updateData(data as ListForSymbolDraw);
const edgeData = seriesModel.getEdgeData();
// TODO: TYPE
diff --git a/src/chart/helper/SymbolDraw.ts b/src/chart/helper/SymbolDraw.ts
index aace5bd..66edfcc 100644
--- a/src/chart/helper/SymbolDraw.ts
+++ b/src/chart/helper/SymbolDraw.ts
@@ -32,7 +32,8 @@ import {
ZRStyleProps,
StatesOptionMixin,
BlurScope,
- DisplayState
+ DisplayState,
+ DefaultEmphasisFocus
} from '../../util/types';
import { CoordinateSystemClipArea } from '../../coord/CoordinateSystem';
import Model from '../../model/Model';
@@ -94,7 +95,7 @@ interface SymbolDrawStateOption {
export interface SymbolDrawItemModelOption extends SymbolOptionMixin<object>,
StatesOptionMixin<SymbolDrawStateOption, {
emphasis?: {
- focus?: string
+ focus?: DefaultEmphasisFocus
scale?: boolean
}
}>,
@@ -111,7 +112,7 @@ export interface SymbolDrawSeriesScope {
blurItemStyle?: ZRStyleProps
selectItemStyle?: ZRStyleProps
- focus?: string
+ focus?: DefaultEmphasisFocus
blurScope?: BlurScope
symbolRotate?: ScatterSeriesOption['symbolRotate']
@@ -148,7 +149,7 @@ function makeSeriesScope(data: List): SymbolDrawSeriesScope {
};
}
-type ListForSymbolDraw = List<Model<SymbolDrawItemModelOption & AnimationOptionMixin>>;
+export type ListForSymbolDraw = List<Model<SymbolDrawItemModelOption & AnimationOptionMixin>>;
class SymbolDraw {
group = new graphic.Group();
diff --git a/src/chart/sunburst/SunburstPiece.ts b/src/chart/sunburst/SunburstPiece.ts
index f5a53ca..7f0dbe1 100644
--- a/src/chart/sunburst/SunburstPiece.ts
+++ b/src/chart/sunburst/SunburstPiece.ts
@@ -146,12 +146,12 @@ class SunburstPiece extends graphic.Sector {
const focus = emphasisModel.get('focus');
- const focusDataIndices: number[] = focus === 'ancestor'
- ? node.getAncestorsIndices()
- : focus === 'descendant' ? node.getDescendantIndices() : null;
+ const focusOrIndices =
+ focus === 'ancestor' ? node.getAncestorsIndices()
+ : focus === 'descendant' ? node.getDescendantIndices()
+ : focus;
-
- enableHoverEmphasis(this, focusDataIndices || focus, emphasisModel.get('blurScope'));
+ enableHoverEmphasis(this, focusOrIndices, emphasisModel.get('blurScope'));
}
_updateLabel(
diff --git a/src/chart/treemap/TreemapView.ts b/src/chart/treemap/TreemapView.ts
index d784c81..d53aceb 100644
--- a/src/chart/treemap/TreemapView.ts
+++ b/src/chart/treemap/TreemapView.ts
@@ -803,9 +803,10 @@ function renderNode(
const focus = nodeModel.get(['emphasis', 'focus']);
const blurScope = nodeModel.get(['emphasis', 'blurScope']);
- const focusDataIndices: number[] = focus === 'ancestor'
- ? thisNode.getAncestorsIndices()
- : focus === 'descendant' ? thisNode.getDescendantIndices() : null;
+ const focusOrIndices =
+ focus === 'ancestor' ? thisNode.getAncestorsIndices()
+ : focus === 'descendant' ? thisNode.getDescendantIndices()
+ : focus;
// No children, render content.
if (isParent) {
@@ -820,7 +821,7 @@ function renderNode(
// Only for enabling highlight/downplay.
data.setItemGraphicEl(thisNode.dataIndex, bg);
- enableHoverFocus(bg, focusDataIndices || focus, blurScope);
+ enableHoverFocus(bg, focusOrIndices, blurScope);
}
}
else {
@@ -834,7 +835,7 @@ function renderNode(
// Only for enabling highlight/downplay.
data.setItemGraphicEl(thisNode.dataIndex, group);
- enableHoverFocus(group, focusDataIndices || focus, blurScope);
+ enableHoverFocus(group, focusOrIndices, blurScope);
}
return group;
diff --git a/src/component/geo/GeoView.ts b/src/component/geo/GeoView.ts
index 961b541..0db6d36 100644
--- a/src/component/geo/GeoView.ts
+++ b/src/component/geo/GeoView.ts
@@ -26,6 +26,7 @@ import GeoModel from '../../coord/geo/GeoModel';
import { Payload, ZRElementEvent, ECEventData } from '../../util/types';
import { getECData } from '../../util/innerStore';
import { findEventDispatcher } from '../../util/event';
+import Element from 'zrender/src/Element';
class GeoView extends ComponentView {
@@ -38,6 +39,8 @@ class GeoView extends ComponentView {
private _model: GeoModel;
+ focusBlurEnabled = true;
+
init(ecModel: GlobalModel, api: ExtensionAPI) {
const mapDraw = new MapDraw(api);
this._mapDraw = mapDraw;
@@ -94,6 +97,10 @@ class GeoView extends ComponentView {
});
}
+ findHighDownDispatchers(name: string): Element[] {
+ return this._mapDraw && this._mapDraw.findHighDownDispatchers(name, this._model);
+ }
+
dispose(): void {
this._mapDraw && this._mapDraw.remove();
}
diff --git a/src/component/helper/MapDraw.ts b/src/component/helper/MapDraw.ts
index 738edb5..c589119 100644
--- a/src/component/helper/MapDraw.ts
+++ b/src/component/helper/MapDraw.ts
@@ -22,14 +22,19 @@ import RoamController from './RoamController';
import * as roamHelper from '../../component/helper/roamHelper';
import {onIrrelevantElement} from '../../component/helper/cursorHelper';
import * as graphic from '../../util/graphic';
-import { enableHoverEmphasis, DISPLAY_STATES } from '../../util/states';
+import {
+ enableHoverEmphasis,
+ DISPLAY_STATES,
+ enableComponentHighDownFeatures,
+ setDefaultStateProxy
+} from '../../util/states';
import geoSourceManager from '../../coord/geo/geoSourceManager';
import {getUID} from '../../util/component';
import ExtensionAPI from '../../core/ExtensionAPI';
import GeoModel, { GeoCommonOptionMixin, GeoItemStyleOption } from '../../coord/geo/GeoModel';
import MapSeries from '../../chart/map/MapSeries';
import GlobalModel from '../../model/Global';
-import { Payload, ECElement, LineStyleOption } from '../../util/types';
+import { Payload, ECElement, LineStyleOption, InnerFocus } from '../../util/types';
import GeoView from '../geo/GeoView';
import MapView from '../../chart/map/MapView';
import Geo from '../../coord/geo/Geo';
@@ -40,7 +45,7 @@ import { createOrUpdatePatternFromDecal } from '../../util/decal';
import { ViewCoordSysTransformInfoPart } from '../../coord/View';
import { GeoSVGGraphicRecord, GeoSVGResource } from '../../coord/geo/GeoSVGResource';
import Displayable from 'zrender/src/graphic/Displayable';
-import { ElementTextConfig } from 'zrender/src/Element';
+import Element, { ElementTextConfig } from 'zrender/src/Element';
import List from '../../data/List';
import { GeoJSONRegion } from '../../coord/geo/Region';
import { RegionGraphic } from '../../coord/geo/geoTypes';
@@ -102,11 +107,13 @@ class MapDraw {
private _regionsGroup: RegionsGroup;
+ private _regionsGroupByName: zrUtil.HashMap<RegionsGroup>;
+
private _svgMapName: string;
private _svgGroup: graphic.Group;
- private _svgRegionGraphics: GeoSVGGraphicRecord['regionGraphics'];
+ private _svgGraphicRecord: GeoSVGGraphicRecord;
constructor(api: ExtensionAPI) {
@@ -189,7 +196,7 @@ class MapDraw {
}
private _buildGeoJSON(viewBuildCtx: ViewBuildContext): void {
- const nameMap = zrUtil.createHashMap<RegionsGroup>();
+ const nameMap = this._regionsGroupByName = zrUtil.createHashMap<RegionsGroup>();
const regionsGroup = this._regionsGroup;
const transformInfoRaw = viewBuildCtx.transformInfoRaw;
@@ -255,7 +262,7 @@ class MapDraw {
const regionGraphic: RegionGraphic = {
name: region.name,
el: compoundPath,
- styleOptionKey: 'itemStyle',
+ optionStyleEnabled: true,
stateTrigger: regionGroup,
eventTrigger: regionGroup,
useLabel: true
@@ -281,19 +288,50 @@ class MapDraw {
this._useSVG(mapName);
}
- zrUtil.each(this._svgRegionGraphics, function (regionGraphic) {
+ let focusSelf = false;
+ zrUtil.each(this._svgGraphicRecord.regionGraphics, function (regionGraphic) {
// Note that we also allow different elements have the same name.
// For example, a glyph of a city and the label of the city have
// the same name and their tooltip info can be defined in a single
// region option.
- this._resetSingleRegionGraphic(
+ const focus = this._resetSingleRegionGraphic(
viewBuildCtx, regionGraphic, [0, 0], 'inside',
// We do not know how the SVG like so we'd better not to change z2.
// Otherwise it might bring some unexpected result. For example,
// an area hovered that make some inner city can not be clicked.
true
);
+ if (focus === 'self') {
+ focusSelf = true;
+ }
}, this);
+
+ // It's a little complicated to support blurring the entire geoSVG in series-map.
+ // So do not suport it until some requirements come.
+ // At present, in series-map, only regions can be blurred.
+ if (focusSelf && viewBuildCtx.isGeo) {
+ const blurStyle = (viewBuildCtx.mapOrGeoModel as GeoModel).getModel(['blur', 'itemStyle']).getItemStyle();
+ // Only suport `opacity` here. Because not sure that other props are suitable for
+ // all of the elements generated by SVG (especially for Text/TSpan/Image/... ).
+ const opacity = blurStyle.opacity;
+ this._svgGraphicRecord.root.traverse(el => {
+ if (!el.isGroup) {
+ // PENDING: clear those settings to SVG elements when `_freeSVG`.
+ // (Currently it happen not to be needed.)
+ setDefaultStateProxy(el as Displayable);
+ const style = (el as Displayable).ensureState('blur').style || {};
+ // Do not overwrite the region style that already set from region option.
+ if (style.opacity == null && opacity != null) {
+ style.opacity = opacity;
+ }
+ // If opacity not set, but `ensureState('blur').style` set, there will
+ // be default opacity.
+
+ // Enable `stateTransition` (animation).
+ (el as Displayable).ensureState('emphasis');
+ }
+ });
+ }
}
private _resetSingleRegionGraphic(
@@ -302,48 +340,21 @@ class MapDraw {
labelXY: number[],
labelPosition: ElementTextConfig['position'],
noZ2EmphasisLift: boolean
- ): void {
+ ): InnerFocus {
const regionName = regionGraphic.name;
const mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
const data = viewBuildCtx.data;
- const isVisualEncodedByVisualMap = viewBuildCtx.isVisualEncodedByVisualMap;
const isGeo = viewBuildCtx.isGeo;
const dataIdx = data ? data.indexOfName(regionName) : null;
const regionModel = mapOrGeoModel.getRegionModel(regionName);
- const styles = makeStyleForRegion(regionGraphic.styleOptionKey, regionModel);
-
- // Use the itemStyle in data if has data
- if (styles && styles.styleOptionKey === 'itemStyle' && data) {
- // Only visual color of each item will be used. It can be encoded by visualMap
- // But visual color of series is used in symbol drawing
-
- // Visual color for each series is for the symbol draw
- const style = data.getItemVisual(dataIdx, 'style');
- const decal = data.getItemVisual(dataIdx, 'decal');
- if (isVisualEncodedByVisualMap && style.fill) {
- styles.normal.fill = style.fill;
- }
- if (decal) {
- styles.normal.decal = createOrUpdatePatternFromDecal(decal, viewBuildCtx.api);
- }
- }
- // PENDING: SVG text, tspan and image can be named but not supporeted
- // to be styled by region option yet.
- if (styles && regionGraphic.el instanceof graphic.Path) {
- regionGraphic.el.setStyle(styles.normal);
- regionGraphic.el.style.strokeNoScale = true;
- regionGraphic.el.ensureState('emphasis').style = styles.emphasis;
- regionGraphic.el.ensureState('select').style = styles.select;
- regionGraphic.el.ensureState('blur').style = styles.blur;
- }
+ applyOptionStyleForRegion(viewBuildCtx, regionGraphic, dataIdx, regionModel);
if (regionGraphic.el instanceof Displayable) {
regionGraphic.el.culling = true;
}
-
if (noZ2EmphasisLift) {
(regionGraphic.el as ECElement).z2EmphasisLift = 0;
}
@@ -455,25 +466,53 @@ class MapDraw {
});
}
- if (regionGraphic.stateTrigger) {
+ let focus;
+ const stateTrigger = regionGraphic.stateTrigger;
+ if (stateTrigger) {
// @ts-ignore FIXME:TS fix the "compatible with each other"?
- regionGraphic.stateTrigger.highDownSilentOnTouch = !!mapOrGeoModel.get('selectedMode');
+ stateTrigger.highDownSilentOnTouch = !!mapOrGeoModel.get('selectedMode');
// @ts-ignore FIXME:TS fix the "compatible with each other"?
const emphasisModel = regionModel.getModel('emphasis');
+ focus = emphasisModel.get('focus');
enableHoverEmphasis(
- regionGraphic.stateTrigger, emphasisModel.get('focus'), emphasisModel.get('blurScope')
+ stateTrigger, focus, emphasisModel.get('blurScope')
);
+ if (isGeo) {
+ enableComponentHighDownFeatures(stateTrigger, mapOrGeoModel as GeoModel, regionName);
+ }
}
+
+ return focus;
}
remove(): void {
this._regionsGroup.removeAll();
+ this._regionsGroupByName = null;
this._svgGroup.removeAll();
- this._controller.dispose();
this._freeSVG();
+ this._controller.dispose();
this._controllerHost = null;
}
+ findHighDownDispatchers(name: string, geoModel: GeoModel): Element[] {
+ if (name == null) {
+ return [];
+ }
+
+ const geo = geoModel.coordinateSystem;
+
+ if (geo.resourceType === 'geoJSON') {
+ const regionsGroupByName = this._regionsGroupByName;
+ if (regionsGroupByName) {
+ const regionGroup = regionsGroupByName.get(name);
+ return regionGroup ? [regionGroup] : [];
+ }
+ }
+ else if (geo.resourceType === 'geoSVG') {
+ return this._svgGraphicRecord.regionElementMap.get(name) || [];
+ }
+ }
+
private _svgResourceChanged(mapName: string): boolean {
return this._svgMapName !== mapName;
}
@@ -483,7 +522,7 @@ class MapDraw {
if (resource && resource.type === 'geoSVG') {
const svgGraphic = (resource as GeoSVGResource).useGraphic(this.uid);
this._svgGroup.add(svgGraphic.root);
- this._svgRegionGraphics = svgGraphic.regionGraphics;
+ this._svgGraphicRecord = svgGraphic;
this._svgMapName = mapName;
}
}
@@ -493,11 +532,12 @@ class MapDraw {
if (mapName == null) {
return;
}
+
const resource = geoSourceManager.getGeoResource(mapName);
if (resource && resource.type === 'geoSVG') {
(resource as GeoSVGResource).freeGraphic(this.uid);
}
- this._svgRegionGraphics = null;
+ this._svgGraphicRecord = null;
this._svgGroup.removeAll();
this._svgMapName = null;
}
@@ -599,8 +639,10 @@ function labelTextAfterUpdate(this: graphic.Text) {
m[3] /= scaleY;
}
-function makeStyleForRegion(
- styleOptionKey: RegionGraphic['styleOptionKey'],
+function applyOptionStyleForRegion(
+ viewBuildCtx: ViewBuildContext,
+ regionGraphic: RegionGraphic,
+ dataIndex: number,
regionModel: Model<
GeoStyleableOption & {
emphasis?: GeoStyleableOption;
@@ -608,48 +650,59 @@ function makeStyleForRegion(
blur?: GeoStyleableOption;
}
>
-): {
- styleOptionKey: 'itemStyle';
- normal: ItemStyleProps;
- emphasis: ItemStyleProps;
- select: ItemStyleProps;
- blur: ItemStyleProps;
-} | {
- styleOptionKey: 'lineStyle';
- normal: LineStyleProps;
- emphasis: LineStyleProps;
- select: LineStyleProps;
- blur: LineStyleProps;
-} {
- if (!styleOptionKey) {
+): void {
+
+ if (
+ !regionGraphic.optionStyleEnabled
+ || !(regionGraphic.el instanceof Displayable)
+ ) {
return;
}
- const normalStyleModel = regionModel.getModel(styleOptionKey);
- const emphasisStyleModel = regionModel.getModel(['emphasis', styleOptionKey]);
- const blurStyleModel = regionModel.getModel(['blur', styleOptionKey]);
- const selectStyleModel = regionModel.getModel(['select', styleOptionKey]);
+ // All of the path are using `itemStyle`, becuase
+ // (1) Some SVG also use fill on polyline (The different between
+ // polyline and polygon is "open" or "close" but not fill or not).
+ // (2) For the common props like opacity, if some use itemStyle
+ // and some use `lineStyle`, it might confuse users.
+ // (3) Most SVG use <path>, where can not detect wether draw a "line"
+ // or a filled shape, so use `itemStyle` for <path>.
+
+ const normalStyleModel = regionModel.getModel('itemStyle');
+ const emphasisStyleModel = regionModel.getModel(['emphasis', 'itemStyle']);
+ const blurStyleModel = regionModel.getModel(['blur', 'itemStyle']);
+ const selectStyleModel = regionModel.getModel(['select', 'itemStyle']);
// NOTE: DONT use 'style' in visual when drawing map.
// This component is used for drawing underlying map for both geo component and map series.
- if (styleOptionKey === 'itemStyle') {
- return {
- styleOptionKey,
- normal: getFixedItemStyle(normalStyleModel),
- emphasis: getFixedItemStyle(emphasisStyleModel),
- select: getFixedItemStyle(selectStyleModel),
- blur: getFixedItemStyle(blurStyleModel)
- };
- }
- else if (styleOptionKey === 'lineStyle') {
- return {
- styleOptionKey,
- normal: normalStyleModel.getLineStyle(),
- emphasis: emphasisStyleModel.getLineStyle(),
- select: selectStyleModel.getLineStyle(),
- blur: blurStyleModel.getLineStyle()
- };
+ const normalStyle = getFixedItemStyle(normalStyleModel);
+ const emphasisStyle = getFixedItemStyle(emphasisStyleModel);
+ const selectStyle = getFixedItemStyle(selectStyleModel);
+ const blurStyle = getFixedItemStyle(blurStyleModel);
+
+ // Update the itemStyle if has data visual
+ const data = viewBuildCtx.data;
+ if (data) {
+ // Only visual color of each item will be used. It can be encoded by visualMap
+ // But visual color of series is used in symbol drawing
+
+ // Visual color for each series is for the symbol draw
+ const style = data.getItemVisual(dataIndex, 'style');
+ const decal = data.getItemVisual(dataIndex, 'decal');
+ if (viewBuildCtx.isVisualEncodedByVisualMap && style.fill) {
+ normalStyle.fill = style.fill;
+ }
+ if (decal) {
+ normalStyle.decal = createOrUpdatePatternFromDecal(decal, viewBuildCtx.api);
+ }
}
+
+ // SVG text, tspan and image can be named but not supporeted
+ // to be styled by region option yet.
+ regionGraphic.el.setStyle(normalStyle);
+ regionGraphic.el.style.strokeNoScale = true;
+ regionGraphic.el.ensureState('emphasis').style = emphasisStyle;
+ regionGraphic.el.ensureState('select').style = selectStyle;
+ regionGraphic.el.ensureState('blur').style = blurStyle;
}
export default MapDraw;
diff --git a/src/component/tooltip/TooltipView.ts b/src/component/tooltip/TooltipView.ts
index c76b489..93949fc 100644
--- a/src/component/tooltip/TooltipView.ts
+++ b/src/component/tooltip/TooltipView.ts
@@ -319,8 +319,6 @@ class TooltipView extends ComponentView {
el.y = payload.y;
el.update();
getECData(el).tooltipConfig = {
- componentMainType: null,
- componentIndex: null,
name: null,
option: payload.tooltip
};
@@ -707,7 +705,8 @@ class TooltipView extends ComponentView {
el: ECElement,
dispatchAction: ExtensionAPI['dispatchAction']
) {
- const tooltipConfig = getECData(el).tooltipConfig;
+ const ecData = getECData(el);
+ const tooltipConfig = ecData.tooltipConfig;
let tooltipOpt = tooltipConfig.option;
if (zrUtil.isString(tooltipOpt)) {
const content = tooltipOpt;
@@ -719,7 +718,7 @@ class TooltipView extends ComponentView {
}
const tooltipModelCascade = [tooltipOpt] as TooltipModelOptionCascade[];
- const cmpt = this._ecModel.getComponent(tooltipConfig.componentMainType, tooltipConfig.componentIndex);
+ const cmpt = this._ecModel.getComponent(ecData.componentMainType, ecData.componentIndex);
if (cmpt) {
tooltipModelCascade.push(cmpt as Model<TooltipableOption>);
}
diff --git a/src/coord/geo/GeoSVGResource.ts b/src/coord/geo/GeoSVGResource.ts
index 8162879..79455c3 100644
--- a/src/coord/geo/GeoSVGResource.ts
+++ b/src/coord/geo/GeoSVGResource.ts
@@ -20,33 +20,30 @@
import { parseSVG, makeViewBoxTransform, SVGNodeTagLower } from 'zrender/src/tool/parseSVG';
import Group from 'zrender/src/graphic/Group';
import Rect from 'zrender/src/graphic/shape/Rect';
-import {assert, createHashMap, HashMap, hasOwn} from 'zrender/src/core/util';
+import {assert, createHashMap, HashMap} from 'zrender/src/core/util';
import BoundingRect from 'zrender/src/core/BoundingRect';
import { GeoResource, GeoSVGGraphicRoot, GeoSVGSourceInput, RegionGraphic } from './geoTypes';
import { parseXML } from 'zrender/src/tool/parseXML';
import { GeoSVGRegion } from './Region';
+import Element from 'zrender/src/Element';
+type RegionName = string;
export interface GeoSVGGraphicRecord {
root: Group;
boundingRect: BoundingRect;
regionGraphics: RegionGraphic[];
+ // A name may correspond to multiple graphics.
+ regionElementMap: HashMap<Element[], RegionName>;
}
const REGION_AVAILABLE_SVG_TAG_MAP = createHashMap<number, SVGNodeTagLower>([
'rect', 'circle', 'line', 'ellipse', 'polygon', 'polyline', 'text', 'tspan', 'path'
]);
-const STYLE_OPTION_KEY = createHashMap<'itemStyle' | 'lineStyle', SVGNodeTagLower>({
- 'rect': 'itemStyle',
- 'circle': 'itemStyle',
- 'line': 'lineStyle',
- 'ellipse': 'itemStyle',
- 'polygon': 'itemStyle',
- 'polyline': 'lineStyle',
- // 'image': '?', // TODO
- // 'text': '?', // TODO
- // 'tspan': '?', // TODO
- 'path': 'itemStyle'
-});
+
+const OPTION_STYLE_ENABLED_TAG_MAP = createHashMap<number, SVGNodeTagLower>([
+ 'rect', 'circle', 'line', 'ellipse', 'polygon', 'polyline', 'path'
+]);
+
const LABEL_HOST_MAP = createHashMap<number, SVGNodeTagLower>([
'rect', 'circle', 'line', 'ellipse', 'polygon', 'polyline', 'path'
]);
@@ -231,25 +228,30 @@ function buildGraphic(
(root as GeoSVGGraphicRoot).isGeoSVGGraphicRoot = true;
const regionGraphics = [] as GeoSVGGraphicRecord['regionGraphics'];
+ const regionElementMap = createHashMap<Element[], RegionName>();
const named = result.named;
for (let i = 0; i < named.length; i++) {
const namedItem = named[i];
const svgNodeTagLower = namedItem.svgNodeTagLower;
if (REGION_AVAILABLE_SVG_TAG_MAP.get(svgNodeTagLower) != null) {
- const styleOptionKey = STYLE_OPTION_KEY.get(svgNodeTagLower);
+ const optionStyleEnabled = OPTION_STYLE_ENABLED_TAG_MAP.get(svgNodeTagLower);
const el = namedItem.el;
+ const name = namedItem.name;
regionGraphics.push({
- name: namedItem.name,
+ name: name,
el: el,
- styleOptionKey: styleOptionKey,
- stateTrigger: styleOptionKey != null ? el : null,
+ optionStyleEnabled: optionStyleEnabled != null,
+ stateTrigger: optionStyleEnabled != null ? el : null,
// text/tspan/image do not suport style but support event.
eventTrigger: el,
useLabel: LABEL_HOST_MAP.get(svgNodeTagLower) != null
});
+ const els = regionElementMap.get(name) || regionElementMap.set(name, []);
+ els.push(el);
+
// Only named element has silent: false, other elements should
// act as background and has no user interaction.
el.silent = false;
@@ -262,7 +264,7 @@ function buildGraphic(
}
}
- return { root, boundingRect, regionGraphics };
+ return { root, boundingRect, regionGraphics, regionElementMap: regionElementMap };
}
diff --git a/src/coord/geo/geoTypes.ts b/src/coord/geo/geoTypes.ts
index 773cf1c..8674218 100644
--- a/src/coord/geo/geoTypes.ts
+++ b/src/coord/geo/geoTypes.ts
@@ -155,6 +155,6 @@ export type RegionGraphic = {
eventTrigger: Element;
// Whether to set label on `el.textContent`.
useLabel: boolean;
- // Use this key to obtain style config in echarts option.
- styleOptionKey: 'itemStyle' | 'lineStyle';
+ // Whether to be enabled to set style via in echarts option.
+ optionStyleEnabled: boolean;
};
diff --git a/src/core/echarts.ts b/src/core/echarts.ts
index 799a564..2f652a3 100644
--- a/src/core/echarts.ts
+++ b/src/core/echarts.ts
@@ -41,8 +41,7 @@ import {
isHighDownDispatcher,
HOVER_STATE_EMPHASIS,
HOVER_STATE_BLUR,
- blurSeries,
- blurSeriesFromPayload,
+ blurSeriesFromHighlightPayload,
toggleSelectionFromPayload,
updateSeriesElementSelection,
getAllSelectedIndices,
@@ -60,7 +59,11 @@ import {
enterSelect,
leaveSelect,
enterBlur,
- allLeaveBlur
+ allLeaveBlur,
+ findComponentHighDownDispatchers,
+ blurComponent,
+ handleGlobalMouseOverForHighDown,
+ handleGlboalMouseOutForHighDown
} from '../util/states';
import * as modelUtil from '../util/model';
import {throttle} from '../util/throttle';
@@ -1480,9 +1483,26 @@ class ECharts extends Eventful<ECEventDefinition> {
// If dispatchAction before setOption, do nothing.
ecModel && ecModel.eachComponent(condition, function (model) {
if (!excludeSeriesIdMap || excludeSeriesIdMap.get(model.id) == null) {
- if (isHighDownPayload(payload) && !payload.notBlur) {
- if (model instanceof SeriesModel) {
- blurSeriesFromPayload(model, payload, ecIns._api);
+ if (isHighDownPayload(payload)) {
+ if (payload.type === HIGHLIGHT_ACTION_TYPE) {
+ if (model instanceof SeriesModel) {
+ !payload.notBlur && blurSeriesFromHighlightPayload(model, payload, ecIns._api);
+ }
+ else {
+ const { focusSelf, dispatchers } = findComponentHighDownDispatchers(
+ model.mainType, model.componentIndex, payload.name, ecIns._api
+ );
+ if (focusSelf && !payload.notBlur) {
+ blurComponent(model.mainType, model.componentIndex, ecIns._api);
+ }
+ // PENDING:
+ // Whether to put this "enter emphasis" code in `ComponentView`,
+ // which will be the same as `ChartView` but might be not necessary
+ // and will be far from this logic.
+ if (dispatchers) {
+ each(dispatchers, dispatcher => enterEmphasis(dispatcher));
+ }
+ }
}
}
else if (isSelectChangePayload(payload)) {
@@ -1780,7 +1800,7 @@ class ECharts extends Eventful<ECEventDefinition> {
let eventObj: ECActionEvent;
const isSelectChange = isSelectChangePayload(payload);
- const isStatusChange = isHighDownPayload(payload) || isSelectChange;
+ const isHighDown = isHighDownPayload(payload);
each(payloads, (batchItem) => {
// Action can specify the event by return it.
@@ -1792,11 +1812,16 @@ class ECharts extends Eventful<ECEventDefinition> {
eventObjBatch.push(eventObj);
// light update does not perform data process, layout and visual.
- if (isStatusChange) {
- // method, payload, mainType, subType
+ if (isHighDown) {
+ const { queryOptionMap, mainTypeSpecified } = modelUtil.preParseFinder(payload as ModelFinder);
+ const componentMainType = mainTypeSpecified ? queryOptionMap.keys()[0] : 'series';
+ updateDirectly(this, updateMethod, batchItem as Payload, componentMainType);
+ markStatusToUpdate(this);
+ }
+ else if (isSelectChange) {
+ // At present `dispatchAction({ type: 'select', ... })` is not supported on components.
+ // geo still use 'geoselect'.
updateDirectly(this, updateMethod, batchItem as Payload, 'series');
-
- // Mark status to update
markStatusToUpdate(this);
}
else if (cptType) {
@@ -1804,7 +1829,7 @@ class ECharts extends Eventful<ECEventDefinition> {
}
});
- if (updateMethod !== 'none' && !isStatusChange && !cptType) {
+ if (updateMethod !== 'none' && !isHighDown && !isSelectChange && !cptType) {
// Still dirty
if (this[OPTION_UPDATED_KEY]) {
prepare(this);
@@ -1900,24 +1925,14 @@ class ECharts extends Eventful<ECEventDefinition> {
const el = e.target;
const dispatcher = findEventDispatcher(el, isHighDownDispatcher);
if (dispatcher) {
- const ecData = getECData(dispatcher);
- // Try blur all in the related series. Then emphasis the hoverred.
- // TODO. progressive mode.
- blurSeries(
- ecData.seriesIndex, ecData.focus, ecData.blurScope, ecIns._api
- );
- enterEmphasisWhenMouseOver(dispatcher, e);
-
+ handleGlobalMouseOverForHighDown(dispatcher, e, ecIns._api);
markStatusToUpdate(ecIns);
}
}).on('mouseout', function (e) {
const el = e.target;
const dispatcher = findEventDispatcher(el, isHighDownDispatcher);
if (dispatcher) {
- allLeaveBlur(ecIns._api);
-
- leaveEmphasisWhenMouseOut(dispatcher, e);
-
+ handleGlboalMouseOutForHighDown(dispatcher, e, ecIns._api);
markStatusToUpdate(ecIns);
}
}).on('click', function (e) {
diff --git a/src/util/graphic.ts b/src/util/graphic.ts
index 4428ff9..5823c05 100644
--- a/src/util/graphic.ts
+++ b/src/util/graphic.ts
@@ -846,9 +846,10 @@ export function setTooltipConfig(opt: {
});
}
- getECData(opt.el).tooltipConfig = {
- componentMainType: mainType,
- componentIndex: componentIndex,
+ const ecData = getECData(opt.el);
+ ecData.componentMainType = mainType;
+ ecData.componentIndex = componentIndex;
+ ecData.tooltipConfig = {
name: itemName,
option: defaults({
content: itemName,
diff --git a/src/util/innerStore.ts b/src/util/innerStore.ts
index 65f5aad..9fa4355 100644
--- a/src/util/innerStore.ts
+++ b/src/util/innerStore.ts
@@ -34,14 +34,18 @@ export interface ECData {
dataType?: SeriesDataType;
focus?: InnerFocus;
blurScope?: BlurScope;
+
+ // Required by `tooltipConfig` and `focus`.
+ componentMainType?: ComponentMainType;
+ componentIndex?: number;
+ componentHighDownName?: string;
+
+ // To make a tooltipConfig, seach `setTooltipConfig`.
+ // Used to find component tooltip option, which is used as
+ // the parent of tooltipConfig.option for cascading.
+ // If not provided, do not use component as its parent.
+ // (Set manatary to make developers not to forget them).
tooltipConfig?: {
- // To make a tooltipConfig, seach `setTooltipConfig`.
- // Used to find component tooltip option, which is used as
- // the parent of tooltipConfig.option for cascading.
- // If not provided, do not use component as its parent.
- // (Set manatary to make developers not to forget them).
- componentMainType: ComponentMainType;
- componentIndex: number;
// Target item name to locate tooltip.
name: string;
option: ComponentItemTooltipOption<unknown>;
diff --git a/src/util/states.ts b/src/util/states.ts
index b3de1c1..896bc70 100644
--- a/src/util/states.ts
+++ b/src/util/states.ts
@@ -35,9 +35,10 @@ import {
Payload,
ZRColor,
HighlightPayload,
- DownplayPayload
+ DownplayPayload,
+ ComponentMainType
} from './types';
-import { extend, indexOf, isArrayLike, isObject, keys, isArray, each } from 'zrender/src/core/util';
+import { extend, indexOf, isArrayLike, isObject, keys, isArray, each, assert } from 'zrender/src/core/util';
import { getECData } from './innerStore';
import * as colorTool from 'zrender/src/tool/color';
import List from '../data/List';
@@ -47,6 +48,8 @@ import { queryDataIndex, makeInner } from './model';
import Path, { PathStyleProps } from 'zrender/src/graphic/Path';
import GlobalModel from '../model/Global';
import ExtensionAPI from '../core/ExtensionAPI';
+import ComponentModel from '../model/Component';
+
// Reserve 0 as default.
let _highlightNextDigit = 1;
@@ -223,7 +226,7 @@ function createEmphasisDefaultState(
stateName: 'emphasis',
targetStates: string[],
state: Displayable['states'][number]
-) {
+): DisplayableState {
const hasSelect = targetStates && indexOf(targetStates, 'select') >= 0;
let cloned = false;
if (el instanceof Path) {
@@ -270,7 +273,7 @@ function createSelectDefaultState(
el: Displayable,
stateName: 'select',
state: Displayable['states'][number]
-) {
+): DisplayableState {
// const hasSelect = indexOf(el.currentStates, stateName) >= 0;
if (state) {
// TODO Share with textContent?
@@ -287,7 +290,7 @@ function createBlurDefaultState(
el: Displayable,
stateName: 'blur',
state: Displayable['states'][number]
-) {
+): DisplayableState {
const hasBlur = indexOf(el.currentStates, stateName) >= 0;
const currentOpacity = el.style.opacity;
@@ -482,16 +485,35 @@ export function blurSeries(
});
}
-export function blurSeriesFromPayload(
- seriesModel: SeriesModel,
- payload: Payload,
+export function blurComponent(
+ componentMainType: ComponentMainType,
+ componentIndex: number,
api: ExtensionAPI
) {
- if (!isHighDownPayload(payload)) {
+ if (componentMainType == null || componentIndex == null) {
+ return;
+ }
+
+ const componentModel = api.getModel().getComponent(componentMainType, componentIndex);
+ if (!componentModel) {
return;
}
- const isHighlight = payload.type === HIGHLIGHT_ACTION_TYPE;
+ const view = api.getViewOfComponentModel(componentModel);
+ if (!view || !view.focusBlurEnabled) {
+ return;
+ }
+
+ view.group.traverse(function (child) {
+ singleEnterBlur(child);
+ });
+}
+
+export function blurSeriesFromHighlightPayload(
+ seriesModel: SeriesModel,
+ payload: HighlightPayload,
+ api: ExtensionAPI
+) {
const seriesIndex = seriesModel.seriesIndex;
const data = seriesModel.getData(payload.dataType);
let dataIndex = queryDataIndex(data, payload);
@@ -507,25 +529,133 @@ export function blurSeriesFromPayload(
}
}
- if (isHighlight) {
- if (el) {
- const ecData = getECData(el);
- blurSeries(
- seriesIndex, ecData.focus, ecData.blurScope, api
- );
+ if (el) {
+ const ecData = getECData(el);
+ blurSeries(
+ seriesIndex, ecData.focus, ecData.blurScope, api
+ );
+ }
+ else {
+ // If there is no element put on the data. Try getting it from raw option
+ // TODO Should put it on seriesModel?
+ const focus = seriesModel.get(['emphasis', 'focus']);
+ const blurScope = seriesModel.get(['emphasis', 'blurScope']);
+ if (focus != null) {
+ blurSeries(seriesIndex, focus, blurScope, api);
}
- else {
- // If there is no element put on the data. Try getting it from raw option
- // TODO Should put it on seriesModel?
- const focus = seriesModel.get(['emphasis', 'focus']);
- const blurScope = seriesModel.get(['emphasis', 'blurScope']);
- if (focus != null) {
- blurSeries(seriesIndex, focus, blurScope, api);
- }
+ }
+}
+
+export function findComponentHighDownDispatchers(
+ componentMainType: ComponentMainType,
+ componentIndex: number,
+ name: string,
+ api: ExtensionAPI
+): {
+ focusSelf: boolean;
+ // If return null/undefined, do not support this feature.
+ dispatchers: Element[];
+} {
+ const ret = {
+ focusSelf: false,
+ dispatchers: null as Element[]
+ };
+ if (componentMainType == null
+ || componentMainType === 'series'
+ || componentIndex == null
+ || name == null
+ ) {
+ return ret;
+ }
+
+ const componentModel = api.getModel().getComponent(componentMainType, componentIndex);
+ if (!componentModel) {
+ return ret;
+ }
+
+ const view = api.getViewOfComponentModel(componentModel);
+ if (!view || !view.findHighDownDispatchers) {
+ return ret;
+ }
+
+ const dispatchers = view.findHighDownDispatchers(name);
+
+ // At presnet, the component (like Geo) only blur inside itself.
+ // So we do not use `blurScope` in component.
+ let focusSelf: boolean;
+ for (let i = 0; i < dispatchers.length; i++) {
+ if (__DEV__) {
+ assert(isHighDownDispatcher(dispatchers[i]));
+ }
+ if (getECData(dispatchers[i]).focus === 'self') {
+ focusSelf = true;
+ break;
}
}
+
+ return { focusSelf, dispatchers };
+}
+
+export function handleGlobalMouseOverForHighDown(
+ dispatcher: Element,
+ e: ElementEvent,
+ api: ExtensionAPI
+): void {
+ if (__DEV__) {
+ assert(isHighDownDispatcher(dispatcher));
+ }
+
+ const ecData = getECData(dispatcher);
+
+ const { dispatchers, focusSelf } = findComponentHighDownDispatchers(
+ ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api
+ );
+ // If `findHighDownDispatchers` is supported on the component,
+ // highlight/downplay elements with the same name.
+ if (dispatchers) {
+ if (focusSelf) {
+ blurComponent(ecData.componentMainType, ecData.componentIndex, api);
+ }
+ each(dispatchers, dispatcher => enterEmphasisWhenMouseOver(dispatcher, e));
+ }
+ else {
+ // Try blur all in the related series. Then emphasis the hoverred.
+ // TODO. progressive mode.
+ blurSeries(ecData.seriesIndex, ecData.focus, ecData.blurScope, api);
+ if (ecData.focus === 'self') {
+ blurComponent(ecData.componentMainType, ecData.componentIndex, api);
+ }
+ // Other than series, component that not support `findHighDownDispatcher` will
+ // also use it. But in this case, highlight/downplay are only supported in
+ // mouse hover but not in dispatchAction.
+ enterEmphasisWhenMouseOver(dispatcher, e);
+ }
}
+export function handleGlboalMouseOutForHighDown(
+ dispatcher: Element,
+ e: ElementEvent,
+ api: ExtensionAPI
+): void {
+ if (__DEV__) {
+ assert(isHighDownDispatcher(dispatcher));
+ }
+
+ allLeaveBlur(api);
+
+ const ecData = getECData(dispatcher);
+ const { dispatchers } = findComponentHighDownDispatchers(
+ ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api
+ );
+ if (dispatchers) {
+ each(dispatchers, dispatcher => leaveEmphasisWhenMouseOut(dispatcher, e));
+ }
+ else {
+ leaveEmphasisWhenMouseOut(dispatcher, e);
+ }
+}
+
+
export function toggleSelectionFromPayload(
seriesModel: SeriesModel,
payload: Payload,
@@ -680,6 +810,22 @@ export function isHighDownDispatcher(el: Element): boolean {
}
/**
+ * Enable component highlight/downplay features:
+ * + hover link (within the same name)
+ * + focus blur in component
+ */
+export function enableComponentHighDownFeatures(
+ el: Element,
+ componentModel: ComponentModel,
+ componentHighDownName: string
+): void {
+ const ecData = getECData(el);
+ ecData.componentMainType = componentModel.mainType;
+ ecData.componentIndex = componentModel.componentIndex;
+ ecData.componentHighDownName = componentHighDownName;
+}
+
+/**
* Support hightlight/downplay record on each elements.
* For the case: hover highlight/downplay (legend, visualMap, ...) and
* user triggerred hightlight/downplay should not conflict.
diff --git a/src/util/types.ts b/src/util/types.ts
index e519ec9..4d0aae2 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -1484,7 +1484,7 @@ export type BlurScope = 'coordinateSystem' | 'series' | 'global';
* can be array of data indices.
* Or may be an dictionary if have different types of data like in graph.
*/
-export type InnerFocus = string | ArrayLike<number> | Dictionary<ArrayLike<number>>;
+export type InnerFocus = DefaultEmphasisFocus | ArrayLike<number> | Dictionary<ArrayLike<number>>;
export interface DefaultExtraStateOpts {
emphasis: any
diff --git a/src/view/Component.ts b/src/view/Component.ts
index 8521e84..cfefd04 100644
--- a/src/view/Component.ts
+++ b/src/view/Component.ts
@@ -32,7 +32,7 @@ interface ComponentView {
* Implement it if needed.
*/
updateTransform?(
- seriesModel: ComponentModel, ecModel: GlobalModel, api: ExtensionAPI, payload: Payload
+ model: ComponentModel, ecModel: GlobalModel, api: ExtensionAPI, payload: Payload
): void | {update: true};
/**
@@ -42,6 +42,22 @@ interface ComponentView {
filterForExposedEvent(
eventType: string, query: EventQueryItem, targetEl: Element, packedEvent: ECActionEvent | ECElementEvent
): boolean;
+
+ /**
+ * Find dispatchers for highlight/downplay by name.
+ * If this methods provided, hover link (within the same name) is enabled in component.
+ * That is, in component, a name can correspond to multiple dispatchers.
+ * Those dispatchers can have no common ancestor.
+ * The highlight/downplay state change will be applied on the
+ * dispatchers and their descendents.
+ *
+ * @return Must return an array but not null/undefined.
+ */
+ findHighDownDispatchers?(
+ name: string
+ ): Element[];
+
+ focusBlurEnabled?: boolean;
}
class ComponentView {
diff --git a/test/geo-svg-demo.html b/test/geo-svg-demo.html
new file mode 100644
index 0000000..ed5afe8
--- /dev/null
+++ b/test/geo-svg-demo.html
@@ -0,0 +1,240 @@
+<!DOCTYPE html>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <script src="lib/esl.js"></script>
+ <script src="lib/config.js"></script>
+ <script src="lib/jquery.min.js"></script>
+ <script src="lib/facePrint.js"></script>
+ <script src="lib/testHelper.js"></script>
+ <!-- <script src="ut/lib/canteen.js"></script> -->
+ <link rel="stylesheet" href="lib/reset.css" />
+ </head>
+ <body>
+ <style>
+ </style>
+
+
+
+ <div id="main_geo_svg_organ"></div>
+ <!-- <div id="main_geo_svg_organ1"></div> -->
+
+
+
+
+
+ <script>
+ function listenAndPrintEvent(chart) {
+ if (!chart) {
+ return;
+ }
+ const out = {
+ };
+ chart.on('geoselectchanged', function (params) {
+ out.geoselectechanged = {
+ allSelected: params.allSelected
+ };
+ console.log('geoselectechanged', params);
+ chart.__testHelper.updateInfo(out, 'event');
+ });
+ chart.on('selectchanged', function (params) {
+ out.selectechanged = {
+ selected: params.selected
+ };
+ console.log('selectechanged', params);
+ chart.__testHelper.updateInfo(out, 'event');
+ });
+ chart.on('click', function (params) {
+ out.click = {
+ componentIndex: params.componentIndex,
+ componentType: params.componentType,
+ geoIndex: params.geoIndex,
+ name: params.name
+ };
+ console.log('click', params);
+ chart.__testHelper.updateInfo(out, 'event');
+ });
+ }
+ </script>
+
+
+
+
+
+
+ <script>
+ require(['echarts'/*, 'map/js/china' */], function (echarts) {
+ var option;
+ $.ajax({
+ url: '../../vis-data/map/svg/organ/Veins_Medical_Diagram_clip_art.svg',
+ dataType: 'text'
+ }).done(function (svg) {
+
+ echarts.registerMap('seatmap', {
+ svg: svg
+ });
+
+ option = {
+ tooltip: {
+ },
+ geo: {
+ map: 'seatmap',
+ roam: true,
+ selectedMode: 'multiple',
+ // height: 100,
+ // zoom: 1.5
+ emphasis: {
+ focus: 'self',
+ itemStyle: {
+ // color: null
+ },
+ label: {
+ show: false,
+ textBorderColor: '#fff',
+ textBorderWidth: 2
+ }
+ },
+ blur: {
+ // itemStyle: {
+ // opacity: 0.3
+ // }
+ },
+ select: {
+ itemStyle: {
+ color: '#b50205'
+ },
+ label: {
+ show: false,
+ textBorderColor: '#fff',
+ textBorderWidth: 2
+ }
+ }
+ }
+ };
+
+ var chart = testHelper.create(echarts, 'main_geo_svg_organ', {
+ title: [
+ 'pure geo component with svg resource',
+ 'click seat: check **allSelected** correct.'
+ ],
+ option: option,
+ info: {},
+ infoKey: 'event',
+ height: 500
+ // buttons: [{text: 'btn-txt', onclick: function () {}}],
+ // recordCanvas: true,
+ });
+
+ listenAndPrintEvent(chart);
+
+ if (chart) {
+ chart.on('highlight', function () {
+ console.log('agsd');
+ });
+ }
+
+ });
+
+ });
+ </script>
+
+
+
+
+<!--
+
+
+ <script>
+ require(['echarts'/*, 'map/js/china' */], function (echarts) {
+ var option;
+ $.ajax({
+ url: '../../vis-data/map/svg/organ/Veins_Medical_Diagram_clip_art.svg',
+ dataType: 'text'
+ }).done(function (svg) {
+
+ echarts.registerMap('seatmap', {
+ svg: svg
+ });
+
+ option = {
+ tooltip: {
+ },
+ series: {
+ type: 'map',
+ map: 'seatmap',
+ roam: true,
+ selectedMode: 'multiple',
+ // height: 100,
+ // zoom: 1.5
+ emphasis: {
+ focus: 'self',
+ label: {
+ textBorderColor: '#fff',
+ textBorderWidth: 2
+ }
+ },
+ select: {
+ itemStyle: {
+ color: '#b50205'
+ },
+ label: {
+ show: false,
+ textBorderColor: '#fff',
+ textBorderWidth: 2
+ }
+ }
+ }
+ };
+
+ var chart = testHelper.create(echarts, 'main_geo_svg_organ1', {
+ title: [
+ 'pure geo component with svg resource',
+ 'click seat: check **allSelected** correct.'
+ ],
+ option: option,
+ info: {},
+ infoKey: 'event',
+ height: 500
+ // buttons: [{text: 'btn-txt', onclick: function () {}}],
+ // recordCanvas: true,
+ });
+
+ listenAndPrintEvent(chart);
+
+ if (chart) {
+ chart.on('highlight', function () {
+ console.log('agsd');
+ });
+ }
+
+ });
+
+ });
+ </script> -->
+
+
+
+ </body>
+</html>
+
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org