Skip to content

Commit fb4c265

Browse files
committed
feat(ssr): provide registerSSRDataGetter
1 parent d7005b8 commit fb4c265

File tree

4 files changed

+103
-52
lines changed

4 files changed

+103
-52
lines changed

src/Element.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,6 @@ class Element<Props extends ElementProps = ElementProps> {
368368
*/
369369
__inHover: boolean
370370

371-
/**
372-
* Any information to be binded on the element when rendering.
373-
*/
374-
__metaData: Record<string, string | number | boolean>
375-
376371
/**
377372
* path to clip the elements and its children, if it is a group.
378373
* @see http://www.w3.org/TR/2dcontext/#clipping-region
@@ -1022,6 +1017,22 @@ class Element<Props extends ElementProps = ElementProps> {
10221017
}
10231018
}
10241019

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+
10251036
/**
10261037
* Update animation targets when reference is changed.
10271038
*/

src/svg/cssEmphasis.ts

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,52 +8,66 @@ export function createCSSEmphasis(
88
attrs: SVGVNodeAttrs,
99
scope: BrushScope
1010
) {
11-
if (!el.ignore && el.__metaData) {
12-
const emphasisStyle = el.states.emphasis && el.states.emphasis.style
13-
? el.states.emphasis.style
14-
: {};
15-
let fill = emphasisStyle.fill;
16-
if (!fill) {
17-
// No empahsis fill, lift color
18-
const normalFill = el.style && el.style.fill;
19-
const selectFill = el.states.select
20-
&& el.states.select.style
21-
&& el.states.select.style.fill;
22-
const fromFill = el.currentStates.indexOf('select') >= 0
23-
? (selectFill || normalFill)
24-
: normalFill;
25-
if (fromFill) {
26-
fill = liftColor(fromFill);
27-
}
28-
}
29-
let lineWidth = emphasisStyle.lineWidth;
30-
if (lineWidth) {
31-
// Symbols use transform to set size, so lineWidth
32-
// should be divided by scaleX
33-
const scaleX = (!emphasisStyle.strokeNoScale && el.transform)
34-
? el.transform[0]
35-
: 1;
36-
lineWidth = lineWidth / scaleX;
37-
}
38-
const style = {
39-
cursor: 'pointer', // TODO: Should this be customized?
40-
} as any;
41-
if (fill) {
42-
style.fill = fill;
43-
}
44-
if (emphasisStyle.stroke) {
45-
style.stroke = emphasisStyle.stroke;
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);
4619
}
47-
if (lineWidth) {
48-
style['stroke-width'] = lineWidth;
49-
}
50-
const styleKey = JSON.stringify(style);
51-
let className = scope.cssStyleCache[styleKey];
52-
if (!className) {
53-
className = scope.zrId + '-cls-' + getClassId();
54-
scope.cssStyleCache[styleKey] = className;
55-
scope.cssNodes['.' + className + ':hover'] = style;
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);
5660
}
57-
attrs.class = attrs.class ? (attrs.class + ' ' + className) : className;
5861
}
5962
}
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+
}

src/svg/graphic.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import { createCSSAnimation } from './cssAnimation';
4040
import { hasSeparateFont, parseFontSize } from '../graphic/Text';
4141
import { DEFAULT_FONT, DEFAULT_FONT_FAMILY } from '../core/platform';
4242
import { createCSSEmphasis } from './cssEmphasis';
43+
import { getElementSSRData } from '../zrender';
4344

4445
const round = Math.round;
4546

@@ -62,6 +63,10 @@ function setStyleAttrs(attrs: SVGVNodeAttrs, style: AllStyleOption, el: Path | T
6263
else if (isFillStroke && isPattern(val)) {
6364
setPattern(el, attrs, key, scope);
6465
}
66+
else if (isFillStroke && val === 'none') {
67+
// When is none, it cannot be interacted when ssr
68+
attrs[key] = 'transparent';
69+
}
6570
else {
6671
attrs[key] = val;
6772
}
@@ -71,11 +76,15 @@ function setStyleAttrs(attrs: SVGVNodeAttrs, style: AllStyleOption, el: Path | T
7176
}
7277

7378
function setMetaData(attrs: SVGVNodeAttrs, el: Path | TSpan | ZRImage) {
74-
if (el.__metaData) {
75-
each(el.__metaData, function (val, key) {
79+
const metaData = getElementSSRData(el);
80+
if (metaData) {
81+
metaData.each((val, key) => {
7682
attrs[(META_DATA_PREFIX + key).toLowerCase()]
7783
= val + '';
7884
});
85+
if (el.isSilent()) {
86+
attrs[META_DATA_PREFIX + 'silent'] = 'true';
87+
}
7988
}
8089
}
8190

src/zrender.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,23 @@ export function registerPainter(name: string, Ctor: PainterBaseCtor) {
482482
painterCtors[name] = Ctor;
483483
}
484484

485+
export type ElementSSRData = zrUtil.HashMap<unknown>;
486+
export type ElementSSRDataGetter<T> = (el: Element) => zrUtil.HashMap<T>;
487+
488+
let ssrDataGetter = function (el: Element): ElementSSRData {
489+
return null;
490+
}
491+
492+
export function getElementSSRData(el: Element): ElementSSRData {
493+
if (typeof ssrDataGetter === 'function') {
494+
return ssrDataGetter(el);
495+
}
496+
}
497+
498+
export function registerSSRDataGetter<T>(getter: ElementSSRDataGetter<T>) {
499+
ssrDataGetter = getter;
500+
}
501+
485502
/**
486503
* @type {string}
487504
*/

0 commit comments

Comments
 (0)