zrender-nightly 5.4.4-dev.20231115 → 5.4.4-dev.20231116

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/Element.d.ts CHANGED
@@ -166,6 +166,7 @@ declare class Element<Props extends ElementProps = ElementProps> {
166
166
  clearStates(noAnimation?: boolean): void;
167
167
  useState(stateName: string, keepCurrentStates?: boolean, noAnimation?: boolean, forceUseHoverLayer?: boolean): ElementState;
168
168
  useStates(states: string[], noAnimation?: boolean, forceUseHoverLayer?: boolean): void;
169
+ isSilent(): boolean;
169
170
  private _updateAnimationTargets;
170
171
  removeState(state: string): void;
171
172
  replaceState(oldState: string, newState: string, forceAdd: boolean): void;
package/lib/Element.js CHANGED
@@ -400,6 +400,18 @@ var Element = (function () {
400
400
  }
401
401
  }
402
402
  };
403
+ Element.prototype.isSilent = function () {
404
+ var isSilent = this.silent;
405
+ var ancestor = this.parent;
406
+ while (!isSilent && ancestor) {
407
+ if (ancestor.silent) {
408
+ isSilent = true;
409
+ break;
410
+ }
411
+ ancestor = ancestor.parent;
412
+ }
413
+ return isSilent;
414
+ };
403
415
  Element.prototype._updateAnimationTargets = function () {
404
416
  for (var i = 0; i < this.animators.length; i++) {
405
417
  var animator = this.animators[i];
@@ -39,9 +39,11 @@ declare class SVGPainter implements PainterBase {
39
39
  willUpdate?: boolean;
40
40
  compress?: boolean;
41
41
  useViewBox?: boolean;
42
+ emphasis?: boolean;
42
43
  }): SVGVNode;
43
44
  renderToString(opts?: {
44
45
  cssAnimation?: boolean;
46
+ cssEmphasis?: boolean;
45
47
  useViewBox?: boolean;
46
48
  }): string;
47
49
  setBackgroundColor(backgroundColor: SVGPainterBackgroundColor): void;
@@ -65,6 +65,7 @@ var SVGPainter = (function () {
65
65
  scope.animation = opts.animation;
66
66
  scope.willUpdate = opts.willUpdate;
67
67
  scope.compress = opts.compress;
68
+ scope.emphasis = opts.emphasis;
68
69
  var children = [];
69
70
  var bgVNode = this._bgVNode = createBackgroundVNode(width, height, this._backgroundColor, scope);
70
71
  bgVNode && children.push(bgVNode);
@@ -89,6 +90,7 @@ var SVGPainter = (function () {
89
90
  opts = opts || {};
90
91
  return vNodeToString(this.renderToVNode({
91
92
  animation: retrieve2(opts.cssAnimation, true),
93
+ emphasis: retrieve2(opts.cssEmphasis, true),
92
94
  willUpdate: false,
93
95
  compress: true,
94
96
  useViewBox: retrieve2(opts.useViewBox, true)
package/lib/svg/core.d.ts CHANGED
@@ -4,6 +4,7 @@ export declare const SVGNS = "http://www.w3.org/2000/svg";
4
4
  export declare const XLINKNS = "http://www.w3.org/1999/xlink";
5
5
  export declare const XMLNS = "http://www.w3.org/2000/xmlns/";
6
6
  export declare const XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace";
7
+ export declare const META_DATA_PREFIX = "ecmeta_";
7
8
  export declare function createElement(name: string): SVGElement;
8
9
  export declare type SVGVNodeAttrs = Record<string, string | number | undefined | boolean>;
9
10
  export interface SVGVNode {
@@ -30,13 +31,14 @@ export interface BrushScope {
30
31
  defs: Record<string, SVGVNode>;
31
32
  cssNodes: Record<string, CSSSelectorVNode>;
32
33
  cssAnims: Record<string, Record<string, Record<string, string>>>;
33
- cssClassIdx: number;
34
+ cssStyleCache: Record<string, string>;
34
35
  cssAnimIdx: number;
35
36
  shadowIdx: number;
36
37
  gradientIdx: number;
37
38
  patternIdx: number;
38
39
  clipPathIdx: number;
39
40
  animation?: boolean;
41
+ emphasis?: boolean;
40
42
  willUpdate?: boolean;
41
43
  compress?: boolean;
42
44
  }
package/lib/svg/core.js CHANGED
@@ -4,6 +4,7 @@ export var SVGNS = 'http://www.w3.org/2000/svg';
4
4
  export var XLINKNS = 'http://www.w3.org/1999/xlink';
5
5
  export var XMLNS = 'http://www.w3.org/2000/xmlns/';
6
6
  export var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
7
+ export var META_DATA_PREFIX = 'ecmeta_';
7
8
  export function createElement(name) {
8
9
  return document.createElementNS(SVGNS, name);
9
10
  }
@@ -85,7 +86,7 @@ export function createBrushScope(zrId) {
85
86
  defs: {},
86
87
  cssNodes: {},
87
88
  cssAnims: {},
88
- cssClassIdx: 0,
89
+ cssStyleCache: {},
89
90
  cssAnimIdx: 0,
90
91
  shadowIdx: 0,
91
92
  gradientIdx: 0,
@@ -6,6 +6,7 @@ import { getPathPrecision, getSRTTransformString } from './helper.js';
6
6
  import { each, extend, filter, isNumber, isString, keys } from '../core/util.js';
7
7
  import CompoundPath from '../graphic/CompoundPath.js';
8
8
  import { createCubicEasingFunc } from '../animation/cubicEasing.js';
9
+ import { getClassId } from './cssClassId.js';
9
10
  export var EASING_MAP = {
10
11
  cubicIn: '0.32,0,0.67,0',
11
12
  cubicOut: '0.33,1,0.68,1',
@@ -266,7 +267,7 @@ export function createCSSAnimation(el, attrs, scope, onlyShape) {
266
267
  }
267
268
  }
268
269
  if (cssAnimations.length) {
269
- var className = scope.zrId + '-cls-' + scope.cssClassIdx++;
270
+ var className = scope.zrId + '-cls-' + getClassId();
270
271
  scope.cssNodes['.' + className] = {
271
272
  animation: cssAnimations.join(',')
272
273
  };
@@ -0,0 +1 @@
1
+ export declare function getClassId(): number;
@@ -0,0 +1,4 @@
1
+ var cssClassIdx = 0;
2
+ export function getClassId() {
3
+ return cssClassIdx++;
4
+ }
@@ -0,0 +1,3 @@
1
+ import Displayable from '../graphic/Displayable';
2
+ import { BrushScope, SVGVNodeAttrs } from './core';
3
+ export declare function createCSSEmphasis(el: Displayable, attrs: SVGVNodeAttrs, scope: BrushScope): void;
@@ -0,0 +1,60 @@
1
+ import { liftColor } from '../tool/color.js';
2
+ import { getClassId } from './cssClassId.js';
3
+ export function createCSSEmphasis(el, attrs, scope) {
4
+ if (!el.ignore) {
5
+ if (el.isSilent()) {
6
+ var style = {
7
+ 'pointer-events': 'none'
8
+ };
9
+ setClassAttribute(style, attrs, scope, true);
10
+ }
11
+ else {
12
+ var emphasisStyle = el.states.emphasis && el.states.emphasis.style
13
+ ? el.states.emphasis.style
14
+ : {};
15
+ var fill = emphasisStyle.fill;
16
+ if (!fill) {
17
+ var normalFill = el.style && el.style.fill;
18
+ var selectFill = el.states.select
19
+ && el.states.select.style
20
+ && el.states.select.style.fill;
21
+ var fromFill = el.currentStates.indexOf('select') >= 0
22
+ ? (selectFill || normalFill)
23
+ : normalFill;
24
+ if (fromFill) {
25
+ fill = liftColor(fromFill);
26
+ }
27
+ }
28
+ var lineWidth = emphasisStyle.lineWidth;
29
+ if (lineWidth) {
30
+ var scaleX = (!emphasisStyle.strokeNoScale && el.transform)
31
+ ? el.transform[0]
32
+ : 1;
33
+ lineWidth = lineWidth / scaleX;
34
+ }
35
+ var style = {
36
+ cursor: 'pointer'
37
+ };
38
+ if (fill) {
39
+ style.fill = fill;
40
+ }
41
+ if (emphasisStyle.stroke) {
42
+ style.stroke = emphasisStyle.stroke;
43
+ }
44
+ if (lineWidth) {
45
+ style['stroke-width'] = lineWidth;
46
+ }
47
+ setClassAttribute(style, attrs, scope, true);
48
+ }
49
+ }
50
+ }
51
+ function setClassAttribute(style, attrs, scope, withHover) {
52
+ var styleKey = JSON.stringify(style);
53
+ var className = scope.cssStyleCache[styleKey];
54
+ if (!className) {
55
+ className = scope.zrId + '-cls-' + getClassId();
56
+ scope.cssStyleCache[styleKey] = className;
57
+ scope.cssNodes['.' + className + (withHover ? ':hover' : '')] = style;
58
+ }
59
+ attrs["class"] = attrs["class"] ? (attrs["class"] + ' ' + className) : className;
60
+ }
@@ -5,12 +5,14 @@ import { getLineHeight } from '../contain/text.js';
5
5
  import TSpan from '../graphic/TSpan.js';
6
6
  import SVGPathRebuilder from './SVGPathRebuilder.js';
7
7
  import mapStyleToAttrs from './mapStyleToAttrs.js';
8
- import { createVNode, vNodeToString } from './core.js';
8
+ import { createVNode, vNodeToString, META_DATA_PREFIX } from './core.js';
9
9
  import { assert, clone, isFunction, isString, logError, map, retrieve2 } from '../core/util.js';
10
10
  import { createOrUpdateImage } from '../graphic/helper/image.js';
11
11
  import { createCSSAnimation } from './cssAnimation.js';
12
12
  import { hasSeparateFont, parseFontSize } from '../graphic/Text.js';
13
13
  import { DEFAULT_FONT, DEFAULT_FONT_FAMILY } from '../core/platform.js';
14
+ import { createCSSEmphasis } from './cssEmphasis.js';
15
+ import { getElementSSRData } from '../zrender.js';
14
16
  var round = Math.round;
15
17
  function isImageLike(val) {
16
18
  return val && isString(val.src);
@@ -27,12 +29,27 @@ function setStyleAttrs(attrs, style, el, scope) {
27
29
  else if (isFillStroke && isPattern(val)) {
28
30
  setPattern(el, attrs, key, scope);
29
31
  }
32
+ else if (isFillStroke && val === 'none') {
33
+ attrs[key] = 'transparent';
34
+ }
30
35
  else {
31
36
  attrs[key] = val;
32
37
  }
33
38
  }, style, el, false);
34
39
  setShadow(el, attrs, scope);
35
40
  }
41
+ function setMetaData(attrs, el) {
42
+ var metaData = getElementSSRData(el);
43
+ if (metaData) {
44
+ metaData.each(function (val, key) {
45
+ attrs[(META_DATA_PREFIX + key).toLowerCase()]
46
+ = val + '';
47
+ });
48
+ if (el.isSilent()) {
49
+ attrs[META_DATA_PREFIX + 'silent'] = 'true';
50
+ }
51
+ }
52
+ }
36
53
  function noRotateScale(m) {
37
54
  return isAroundZero(m[0] - 1)
38
55
  && isAroundZero(m[1])
@@ -137,7 +154,9 @@ export function brushSVGPath(el, scope) {
137
154
  }
138
155
  setTransform(attrs, el.transform);
139
156
  setStyleAttrs(attrs, style, el, scope);
157
+ setMetaData(attrs, el);
140
158
  scope.animation && createCSSAnimation(el, attrs, scope);
159
+ scope.emphasis && createCSSEmphasis(el, attrs, scope);
141
160
  return createVNode(svgElType, el.id + '', attrs);
142
161
  }
143
162
  export function brushSVGImage(el, scope) {
@@ -171,6 +190,7 @@ export function brushSVGImage(el, scope) {
171
190
  }
172
191
  setTransform(attrs, el.transform);
173
192
  setStyleAttrs(attrs, style, el, scope);
193
+ setMetaData(attrs, el);
174
194
  scope.animation && createCSSAnimation(el, attrs, scope);
175
195
  return createVNode('image', el.id + '', attrs);
176
196
  }
@@ -223,6 +243,7 @@ export function brushSVGTSpan(el, scope) {
223
243
  }
224
244
  setTransform(attrs, el.transform);
225
245
  setStyleAttrs(attrs, style, el, scope);
246
+ setMetaData(attrs, el);
226
247
  scope.animation && createCSSAnimation(el, attrs, scope);
227
248
  return createVNode('text', el.id + '', attrs, undefined, text);
228
249
  }
@@ -1,3 +1,4 @@
1
+ import { GradientObject } from '../graphic/Gradient';
1
2
  export declare function parse(colorStr: string, rgbaArr?: number[]): number[];
2
3
  export declare function lift(color: string, level: number): string;
3
4
  export declare function toHex(color: string): string;
@@ -17,4 +18,6 @@ export declare function modifyAlpha(color: string, alpha?: number): string;
17
18
  export declare function stringify(arrColor: number[], type: string): string;
18
19
  export declare function lum(color: string, backgroundLum: number): number;
19
20
  export declare function random(): string;
21
+ export declare function liftColor(color: GradientObject): GradientObject;
22
+ export declare function liftColor(color: string): string;
20
23
  export {};
package/lib/tool/color.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import LRU from '../core/LRU.js';
2
+ import { extend, isGradientObject, isString, map } from '../core/util.js';
2
3
  var kCSSColorTable = {
3
4
  'transparent': [0, 0, 0, 0], 'aliceblue': [240, 248, 255, 1],
4
5
  'antiquewhite': [250, 235, 215, 1], 'aqua': [0, 255, 255, 1],
@@ -406,3 +407,23 @@ export function random() {
406
407
  Math.round(Math.random() * 255)
407
408
  ], 'rgb');
408
409
  }
410
+ var liftedColorCache = new LRU(100);
411
+ export function liftColor(color) {
412
+ if (isString(color)) {
413
+ var liftedColor = liftedColorCache.get(color);
414
+ if (!liftedColor) {
415
+ liftedColor = lift(color, -0.1);
416
+ liftedColorCache.put(color, liftedColor);
417
+ }
418
+ return liftedColor;
419
+ }
420
+ else if (isGradientObject(color)) {
421
+ var ret = extend({}, color);
422
+ ret.colorStops = map(color.colorStops, function (stop) { return ({
423
+ offset: stop.offset,
424
+ color: lift(stop.color, -0.1)
425
+ }); });
426
+ return ret;
427
+ }
428
+ return color;
429
+ }
package/lib/zrender.d.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  * LICENSE
8
8
  * https://github.com/ecomfe/zrender/blob/master/LICENSE.txt
9
9
  */
10
+ import * as zrUtil from './core/util';
10
11
  import Handler from './Handler';
11
12
  import Storage from './Storage';
12
13
  import { PainterBase } from './PainterBase';
@@ -84,7 +85,11 @@ export declare function dispose(zr: ZRender): void;
84
85
  export declare function disposeAll(): void;
85
86
  export declare function getInstance(id: number): ZRender;
86
87
  export declare function registerPainter(name: string, Ctor: PainterBaseCtor): void;
87
- export declare const version = "5.4.4-dev.20231115";
88
+ export declare type ElementSSRData = zrUtil.HashMap<unknown>;
89
+ export declare type ElementSSRDataGetter<T> = (el: Element) => zrUtil.HashMap<T>;
90
+ export declare function getElementSSRData(el: Element): ElementSSRData;
91
+ export declare function registerSSRDataGetter<T>(getter: ElementSSRDataGetter<T>): void;
92
+ export declare const version = "5.4.4-dev.20231116";
88
93
  export interface ZRenderType extends ZRender {
89
94
  }
90
95
  export {};
package/lib/zrender.js CHANGED
@@ -261,5 +261,16 @@ export function getInstance(id) {
261
261
  export function registerPainter(name, Ctor) {
262
262
  painterCtors[name] = Ctor;
263
263
  }
264
- export var version = '5.4.4-dev.20231115';
264
+ var ssrDataGetter = function (el) {
265
+ return null;
266
+ };
267
+ export function getElementSSRData(el) {
268
+ if (typeof ssrDataGetter === 'function') {
269
+ return ssrDataGetter(el);
270
+ }
271
+ }
272
+ export function registerSSRDataGetter(getter) {
273
+ ssrDataGetter = getter;
274
+ }
275
+ export var version = '5.4.4-dev.20231116';
265
276
  ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zrender-nightly",
3
- "version": "5.4.4-dev.20231115",
3
+ "version": "5.4.4-dev.20231116",
4
4
  "description": "A lightweight graphic library providing 2d draw for Apache ECharts",
5
5
  "keywords": [
6
6
  "canvas",
package/src/Element.ts CHANGED
@@ -1017,6 +1017,22 @@ class Element<Props extends ElementProps = ElementProps> {
1017
1017
  }
1018
1018
  }
1019
1019
 
1020
+ /**
1021
+ * Return if el.silent or any ancestor element has silent true.
1022
+ */
1023
+ isSilent() {
1024
+ let isSilent = this.silent;
1025
+ let ancestor = this.parent;
1026
+ while (!isSilent && ancestor) {
1027
+ if (ancestor.silent) {
1028
+ isSilent = true;
1029
+ break;
1030
+ }
1031
+ ancestor = ancestor.parent;
1032
+ }
1033
+ return isSilent;
1034
+ }
1035
+
1020
1036
  /**
1021
1037
  * Update animation targets when reference is changed.
1022
1038
  */
@@ -124,10 +124,11 @@ class SVGPainter implements PainterBase {
124
124
  }
125
125
 
126
126
  renderToVNode(opts?: {
127
- animation?: boolean
128
- willUpdate?: boolean
127
+ animation?: boolean,
128
+ willUpdate?: boolean,
129
129
  compress?: boolean,
130
- useViewBox?: boolean
130
+ useViewBox?: boolean,
131
+ emphasis?: boolean
131
132
  }) {
132
133
 
133
134
  opts = opts || {};
@@ -140,6 +141,7 @@ class SVGPainter implements PainterBase {
140
141
  scope.animation = opts.animation;
141
142
  scope.willUpdate = opts.willUpdate;
142
143
  scope.compress = opts.compress;
144
+ scope.emphasis = opts.emphasis;
143
145
 
144
146
  const children: SVGVNode[] = [];
145
147
 
@@ -173,7 +175,12 @@ class SVGPainter implements PainterBase {
173
175
  * If add css animation.
174
176
  * @default true
175
177
  */
176
- cssAnimation?: boolean
178
+ cssAnimation?: boolean,
179
+ /**
180
+ * If add css emphasis.
181
+ * @default true
182
+ */
183
+ cssEmphasis?: boolean,
177
184
  /**
178
185
  * If use viewBox
179
186
  * @default true
@@ -183,6 +190,7 @@ class SVGPainter implements PainterBase {
183
190
  opts = opts || {};
184
191
  return vNodeToString(this.renderToVNode({
185
192
  animation: retrieve2(opts.cssAnimation, true),
193
+ emphasis: retrieve2(opts.cssEmphasis, true),
186
194
  willUpdate: false,
187
195
  compress: true,
188
196
  useViewBox: retrieve2(opts.useViewBox, true)
package/src/svg/core.ts CHANGED
@@ -8,6 +8,7 @@ export const SVGNS = 'http://www.w3.org/2000/svg';
8
8
  export const XLINKNS = 'http://www.w3.org/1999/xlink';
9
9
  export const XMLNS = 'http://www.w3.org/2000/xmlns/';
10
10
  export const XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
11
+ export const META_DATA_PREFIX = 'ecmeta_';
11
12
 
12
13
  export function createElement(name: string) {
13
14
  return document.createElementNS(SVGNS, name);
@@ -128,8 +129,11 @@ export interface BrushScope {
128
129
 
129
130
  cssNodes: Record<string, CSSSelectorVNode>
130
131
  cssAnims: Record<string, Record<string, Record<string, string>>>
132
+ /**
133
+ * Cache for css style string, mapping from style string to class name.
134
+ */
135
+ cssStyleCache: Record<string, string>
131
136
 
132
- cssClassIdx: number
133
137
  cssAnimIdx: number
134
138
 
135
139
  shadowIdx: number
@@ -141,6 +145,10 @@ export interface BrushScope {
141
145
  * If create animates nodes.
142
146
  */
143
147
  animation?: boolean,
148
+ /**
149
+ * If create emphasis styles.
150
+ */
151
+ emphasis?: boolean,
144
152
 
145
153
  /**
146
154
  * If will update. Some optimization for string generation can't be applied.
@@ -164,8 +172,8 @@ export function createBrushScope(zrId: string): BrushScope {
164
172
 
165
173
  cssNodes: {},
166
174
  cssAnims: {},
175
+ cssStyleCache: {},
167
176
 
168
- cssClassIdx: 0,
169
177
  cssAnimIdx: 0,
170
178
 
171
179
  shadowIdx: 0,
@@ -10,6 +10,7 @@ import Animator from '../animation/Animator';
10
10
  import CompoundPath from '../graphic/CompoundPath';
11
11
  import { AnimationEasing } from '../animation/easing';
12
12
  import { createCubicEasingFunc } from '../animation/cubicEasing';
13
+ import { getClassId } from './cssClassId';
13
14
 
14
15
  export const EASING_MAP: Record<string, string> = {
15
16
  // From https://easings.net/
@@ -355,7 +356,7 @@ export function createCSSAnimation(
355
356
  }
356
357
 
357
358
  if (cssAnimations.length) {
358
- const className = scope.zrId + '-cls-' + scope.cssClassIdx++;
359
+ const className = scope.zrId + '-cls-' + getClassId();
359
360
  scope.cssNodes['.' + className] = {
360
361
  animation: cssAnimations.join(',')
361
362
  };
@@ -0,0 +1,5 @@
1
+ let cssClassIdx = 0;
2
+
3
+ export function getClassId() {
4
+ return cssClassIdx++;
5
+ }
@@ -0,0 +1,73 @@
1
+ import Displayable from '../graphic/Displayable';
2
+ import { liftColor } from '../tool/color';
3
+ import { BrushScope, SVGVNodeAttrs } from './core';
4
+ import { getClassId } from './cssClassId';
5
+
6
+ export function createCSSEmphasis(
7
+ el: Displayable,
8
+ attrs: SVGVNodeAttrs,
9
+ scope: BrushScope
10
+ ) {
11
+ if (!el.ignore) {
12
+ if (el.isSilent()) {
13
+ // If el is silent, it can not be hovered nor selected.
14
+ // So set pointer-events to pass through.
15
+ const style = {
16
+ 'pointer-events': 'none'
17
+ };
18
+ setClassAttribute(style, attrs, scope, true);
19
+ }
20
+ else {
21
+ const emphasisStyle = el.states.emphasis && el.states.emphasis.style
22
+ ? el.states.emphasis.style
23
+ : {};
24
+ let fill = emphasisStyle.fill;
25
+ if (!fill) {
26
+ // No empahsis fill, lift color
27
+ const normalFill = el.style && el.style.fill;
28
+ const selectFill = el.states.select
29
+ && el.states.select.style
30
+ && el.states.select.style.fill;
31
+ const fromFill = el.currentStates.indexOf('select') >= 0
32
+ ? (selectFill || normalFill)
33
+ : normalFill;
34
+ if (fromFill) {
35
+ fill = liftColor(fromFill);
36
+ }
37
+ }
38
+ let lineWidth = emphasisStyle.lineWidth;
39
+ if (lineWidth) {
40
+ // Symbols use transform to set size, so lineWidth
41
+ // should be divided by scaleX
42
+ const scaleX = (!emphasisStyle.strokeNoScale && el.transform)
43
+ ? el.transform[0]
44
+ : 1;
45
+ lineWidth = lineWidth / scaleX;
46
+ }
47
+ const style = {
48
+ cursor: 'pointer', // TODO: Should this be customized?
49
+ } as any;
50
+ if (fill) {
51
+ style.fill = fill;
52
+ }
53
+ if (emphasisStyle.stroke) {
54
+ style.stroke = emphasisStyle.stroke;
55
+ }
56
+ if (lineWidth) {
57
+ style['stroke-width'] = lineWidth;
58
+ }
59
+ setClassAttribute(style, attrs, scope, true);
60
+ }
61
+ }
62
+ }
63
+
64
+ function setClassAttribute(style: object, attrs: SVGVNodeAttrs, scope: BrushScope, withHover: boolean) {
65
+ const styleKey = JSON.stringify(style);
66
+ let className = scope.cssStyleCache[styleKey];
67
+ if (!className) {
68
+ className = scope.zrId + '-cls-' + getClassId();
69
+ scope.cssStyleCache[styleKey] = className;
70
+ scope.cssNodes['.' + className + (withHover ? ':hover' : '')] = style as any;
71
+ }
72
+ attrs.class = attrs.class ? (attrs.class + ' ' + className) : className;
73
+ }
@@ -26,7 +26,7 @@ import { getLineHeight } from '../contain/text';
26
26
  import TSpan, { TSpanStyleProps } from '../graphic/TSpan';
27
27
  import SVGPathRebuilder from './SVGPathRebuilder';
28
28
  import mapStyleToAttrs from './mapStyleToAttrs';
29
- import { SVGVNodeAttrs, createVNode, SVGVNode, vNodeToString, BrushScope } from './core';
29
+ import { SVGVNodeAttrs, createVNode, SVGVNode, vNodeToString, BrushScope, META_DATA_PREFIX } from './core';
30
30
  import { MatrixArray } from '../core/matrix';
31
31
  import Displayable from '../graphic/Displayable';
32
32
  import { assert, clone, isFunction, isString, logError, map, retrieve2 } from '../core/util';
@@ -39,6 +39,8 @@ import { ImageLike } from '../core/types';
39
39
  import { createCSSAnimation } from './cssAnimation';
40
40
  import { hasSeparateFont, parseFontSize } from '../graphic/Text';
41
41
  import { DEFAULT_FONT, DEFAULT_FONT_FAMILY } from '../core/platform';
42
+ import { createCSSEmphasis } from './cssEmphasis';
43
+ import { getElementSSRData } from '../zrender';
42
44
 
43
45
  const round = Math.round;
44
46
 
@@ -61,6 +63,10 @@ function setStyleAttrs(attrs: SVGVNodeAttrs, style: AllStyleOption, el: Path | T
61
63
  else if (isFillStroke && isPattern(val)) {
62
64
  setPattern(el, attrs, key, scope);
63
65
  }
66
+ else if (isFillStroke && val === 'none') {
67
+ // When is none, it cannot be interacted when ssr
68
+ attrs[key] = 'transparent';
69
+ }
64
70
  else {
65
71
  attrs[key] = val;
66
72
  }
@@ -69,6 +75,19 @@ function setStyleAttrs(attrs: SVGVNodeAttrs, style: AllStyleOption, el: Path | T
69
75
  setShadow(el, attrs, scope);
70
76
  }
71
77
 
78
+ function setMetaData(attrs: SVGVNodeAttrs, el: Path | TSpan | ZRImage) {
79
+ const metaData = getElementSSRData(el);
80
+ if (metaData) {
81
+ metaData.each((val, key) => {
82
+ attrs[(META_DATA_PREFIX + key).toLowerCase()]
83
+ = val + '';
84
+ });
85
+ if (el.isSilent()) {
86
+ attrs[META_DATA_PREFIX + 'silent'] = 'true';
87
+ }
88
+ }
89
+ }
90
+
72
91
  function noRotateScale(m: MatrixArray) {
73
92
  return isAroundZero(m[0] - 1)
74
93
  && isAroundZero(m[1])
@@ -204,8 +223,10 @@ export function brushSVGPath(el: Path, scope: BrushScope) {
204
223
 
205
224
  setTransform(attrs, el.transform);
206
225
  setStyleAttrs(attrs, style, el, scope);
226
+ setMetaData(attrs, el);
207
227
 
208
228
  scope.animation && createCSSAnimation(el, attrs, scope);
229
+ scope.emphasis && createCSSEmphasis(el, attrs, scope);
209
230
 
210
231
  return createVNode(svgElType, el.id + '', attrs);
211
232
  }
@@ -248,6 +269,7 @@ export function brushSVGImage(el: ZRImage, scope: BrushScope) {
248
269
 
249
270
  setTransform(attrs, el.transform);
250
271
  setStyleAttrs(attrs, style, el, scope);
272
+ setMetaData(attrs, el);
251
273
 
252
274
  scope.animation && createCSSAnimation(el, attrs, scope);
253
275
 
@@ -319,6 +341,7 @@ export function brushSVGTSpan(el: TSpan, scope: BrushScope) {
319
341
  }
320
342
  setTransform(attrs, el.transform);
321
343
  setStyleAttrs(attrs, style, el, scope);
344
+ setMetaData(attrs, el);
322
345
 
323
346
  scope.animation && createCSSAnimation(el, attrs, scope);
324
347