wt-huatu 1.3.4

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.
Files changed (110) hide show
  1. package/Readme.md +223 -0
  2. package/component/HuatuComponentCache.js +89 -0
  3. package/component/HuatuComponentDef.js +249 -0
  4. package/component/HuatuComponentPlacement.js +172 -0
  5. package/component/HuatuComponentPort.js +58 -0
  6. package/component/IHuatuComponent.js +2 -0
  7. package/for-node/node-cli-funcs.js +36 -0
  8. package/geometry/AngDeg.js +68 -0
  9. package/geometry/Angle.js +77 -0
  10. package/geometry/Bezier.js +623 -0
  11. package/geometry/Circle.js +143 -0
  12. package/geometry/Ellipse.js +546 -0
  13. package/geometry/EllipticalArc.js +337 -0
  14. package/geometry/IGeometry.js +1 -0
  15. package/geometry/Intersection.js +601 -0
  16. package/geometry/Line.js +136 -0
  17. package/geometry/LineSeg.js +179 -0
  18. package/geometry/Point.js +88 -0
  19. package/geometry/PolyLine.js +97 -0
  20. package/geometry/Polygon.js +122 -0
  21. package/geometry/Rect.js +149 -0
  22. package/geometry/Ring.js +91 -0
  23. package/geometry/SegmentModel.js +206 -0
  24. package/geometry/Triangle.js +168 -0
  25. package/geometry/Vector.js +92 -0
  26. package/huatu/Huatu.js +4279 -0
  27. package/huatu/HuatuAngleMark.js +400 -0
  28. package/huatu/HuatuBlock.js +26 -0
  29. package/huatu/HuatuClipPath.js +29 -0
  30. package/huatu/HuatuCompDrawing.js +77 -0
  31. package/huatu/HuatuDimMark.js +579 -0
  32. package/huatu/HuatuDrawing.js +185 -0
  33. package/huatu/HuatuDrawingGroup.js +52 -0
  34. package/huatu/HuatuJob.js +347 -0
  35. package/huatu/HuatuLabel.js +311 -0
  36. package/huatu/HuatuLabelStyle.js +190 -0
  37. package/huatu/HuatuLayer.js +10 -0
  38. package/huatu/HuatuMarker.js +209 -0
  39. package/huatu/HuatuParser.js +435 -0
  40. package/huatu/HuatuPath.js +131 -0
  41. package/huatu/HuatuPathSeries.js +51 -0
  42. package/huatu/HuatuPattern.js +54 -0
  43. package/huatu/HuatuPoint.js +20 -0
  44. package/huatu/HuatuPointSeries.js +67 -0
  45. package/huatu/HuatuStyle.js +394 -0
  46. package/huatu/HuatuSymbol.js +81 -0
  47. package/huatu/HuatuSymbolArray.js +235 -0
  48. package/huatu/HuatuTransform.js +113 -0
  49. package/huatu/HuatuVar.js +17 -0
  50. package/huatu/HuatuYml.js +271 -0
  51. package/huatu/IHuatu.js +2 -0
  52. package/huatu/IHuatuYml.js +1 -0
  53. package/huatu/IndentParsingStack.js +82 -0
  54. package/index.d.ts +1747 -0
  55. package/index.js +247 -0
  56. package/math/Complex.js +72 -0
  57. package/math/Matrix.js +31 -0
  58. package/math/NumberRange.js +38 -0
  59. package/math/VarFuncs.js +24 -0
  60. package/math/WtMath.js +217 -0
  61. package/package.json +34 -0
  62. package/path/PathBezier2.js +75 -0
  63. package/path/PathBezier3.js +89 -0
  64. package/path/PathCircle.js +82 -0
  65. package/path/PathConfig.js +81 -0
  66. package/path/PathContinuousSegmentedPath.js +390 -0
  67. package/path/PathEllipse.js +99 -0
  68. package/path/PathEllipticalArc.js +111 -0
  69. package/path/PathGeneric.js +59 -0
  70. package/path/PathLine.js +75 -0
  71. package/path/PathLines.js +46 -0
  72. package/path/PathPolygon.js +142 -0
  73. package/path/PathPolyline.js +266 -0
  74. package/path/PathRect.js +125 -0
  75. package/path/PathRing.js +51 -0
  76. package/path/PathSegmentedPath.js +199 -0
  77. package/path/PathTriangle.js +90 -0
  78. package/presets/marker.js +37 -0
  79. package/presets/pattern.js +85 -0
  80. package/shape/SvgShapeArrowHead.js +92 -0
  81. package/shape/SvgShapeCircle.js +26 -0
  82. package/shape/SvgShapeCross.js +43 -0
  83. package/shape/SvgShapeEllipse.js +28 -0
  84. package/shape/SvgShapeGeneric.js +50 -0
  85. package/shape/SvgShapeHeart.js +40 -0
  86. package/shape/SvgShapeIsoscelesTriangle.js +52 -0
  87. package/shape/SvgShapePolygon.js +39 -0
  88. package/shape/SvgShapeRect.js +26 -0
  89. package/shape/SvgShapeRhombus.js +27 -0
  90. package/shape/SvgShapeStar.js +103 -0
  91. package/svg/ISvg.js +1 -0
  92. package/svg/SvgBBox.js +149 -0
  93. package/svg/SvgConstants.js +14 -0
  94. package/svg/SvgGradient.js +97 -0
  95. package/svg/SvgMarker.js +221 -0
  96. package/svg/SvgPattern.js +228 -0
  97. package/svg/SvgPoint.js +33 -0
  98. package/svg/SvgPointSet.js +41 -0
  99. package/templates/lines.js +35 -0
  100. package/tools/gen-id.js +2 -0
  101. package/tools/html.js +2 -0
  102. package/tools/katex.js +75 -0
  103. package/tools/rand-str.js +122 -0
  104. package/tools/regex.js +15 -0
  105. package/tools/utils.js +438 -0
  106. package/tools/webColor.js +700 -0
  107. package/wire/HuatuNet.js +22 -0
  108. package/wire/HuatuWire.js +415 -0
  109. package/wire/HuatuWireDrawing.js +17 -0
  110. package/wire/IHuatuWire.js +1 -0
@@ -0,0 +1,394 @@
1
+ import { SvgCsts } from "../svg/SvgConstants.js";
2
+ import { WtMath } from "../math/WtMath.js";
3
+ import { isValidColor } from "../tools/webColor.js";
4
+ import { genHex } from "../tools/gen-id.js";
5
+ export class HuatuStyle {
6
+ refStyles = [];
7
+ name;
8
+ fillColor;
9
+ fillOpacity;
10
+ fillPattern;
11
+ fillRule;
12
+ fillGradient;
13
+ strokeColor;
14
+ strokeWidth;
15
+ strokeOpacity;
16
+ strokeLineCap;
17
+ strokeLineJoin;
18
+ strokeMiterLimit;
19
+ strokeDashArray;
20
+ strokeDashOffset;
21
+ markerStart;
22
+ markerMid;
23
+ markerEnd;
24
+ clipPath;
25
+ refCount = 0;
26
+ magicId;
27
+ constructor(name) {
28
+ this.name = name;
29
+ this.magicId = genHex(8);
30
+ }
31
+ copyRefAttrs() {
32
+ if (this.refStyles.length < 1)
33
+ return;
34
+ // Assign
35
+ ["fillColor", "fillOpacity", "fillPattern", "fillRule", "fillGradient",
36
+ "strokeColor", "strokeWidth", "strokeOpacity", "strokeLineCap",
37
+ "strokeLineJoin", "strokeMiterLimit", "strokeDashArray", "strokeDashOffset",
38
+ "markerStart", "markerMid", "markerEnd",
39
+ "clipPath"
40
+ ].forEach(k => {
41
+ const kAttr = k;
42
+ if (!this[kAttr]) {
43
+ let i = this.refStyles.length - 1;
44
+ while (i >= 0) {
45
+ const ref = this.refStyles[i--];
46
+ if (ref[kAttr]) {
47
+ this[kAttr] = ref[kAttr];
48
+ break;
49
+ }
50
+ }
51
+ }
52
+ });
53
+ }
54
+ buildAttrArray() {
55
+ const attrs = [];
56
+ // Fill
57
+ if (this.fillPattern) {
58
+ attrs.push([`fill`, `url(#${this.fillPattern.buildId()})`]);
59
+ }
60
+ else if (this.fillGradient) { // TODO: for gradient, there might be some similar actions to build IDs
61
+ attrs.push([`fill`, `url(#${this.fillGradient})`]);
62
+ }
63
+ else if (this.fillColor) {
64
+ attrs.push([`fill`, `${this.fillColor}`]);
65
+ }
66
+ if (this.fillOpacity !== undefined && WtMath.isIn0and1(this.fillOpacity)) {
67
+ attrs.push([`fill-opacity`, `${this.fillOpacity.toFixed(2)}`]);
68
+ }
69
+ if (this.fillRule) {
70
+ attrs.push([`fill-rule`, this.fillRule]);
71
+ }
72
+ // Stroke
73
+ if (this.strokeColor) {
74
+ attrs.push([`stroke`, `${this.strokeColor}`]);
75
+ }
76
+ if (this.strokeWidth) {
77
+ attrs.push([`stroke-width`, `${this.strokeWidth.toFixed(6)}`]);
78
+ }
79
+ if (this.strokeOpacity) {
80
+ attrs.push([`stroke-opacity`, `${this.strokeOpacity}`]);
81
+ }
82
+ if (this.strokeLineCap && this.strokeLineCap !== "butt") {
83
+ attrs.push([`stroke-linecap`, `${this.strokeLineCap}`]);
84
+ }
85
+ if (this.strokeLineJoin && this.strokeLineJoin !== "miter") {
86
+ attrs.push([`stroke-linejoin`, `${this.strokeLineJoin}`]);
87
+ }
88
+ if (this.strokeDashArray && Array.isArray(this.strokeDashArray)) {
89
+ attrs.push([
90
+ `stroke-dasharray`,
91
+ this.strokeDashArray.map(d => `${d}`).join(" ")
92
+ ]);
93
+ }
94
+ if (this.strokeDashOffset) {
95
+ attrs.push([`stroke-dashoffset`, `${this.strokeDashOffset}`]);
96
+ }
97
+ if (this.markerStart) {
98
+ attrs.push([`marker-start`, `url(#${this.markerStart.buildId()})`]);
99
+ }
100
+ if (this.markerMid) {
101
+ attrs.push([`marker-mid`, `url(#${this.markerMid.buildId()})`]);
102
+ }
103
+ if (this.markerEnd) {
104
+ attrs.push([`marker-end`, `url(#${this.markerEnd.buildId()})`]);
105
+ }
106
+ if (this.clipPath) {
107
+ attrs.push([`clip-path`, `url(#${this.clipPath.buildId()})`]);
108
+ }
109
+ return attrs;
110
+ }
111
+ buildCss() {
112
+ if (!this.name)
113
+ return "";
114
+ const attrs = this.buildAttrArray();
115
+ if (attrs.length < 1)
116
+ return "";
117
+ return `.${HuatuStyle.buildStyleClassName(this)} {\n${attrs.map(a => `${a[0]}: ${a[1]};`).join("\n")}\n}`;
118
+ }
119
+ buildSvgAttr(direct) {
120
+ const mergeStyles = (styles, newStyles) => {
121
+ newStyles.forEach(ns => {
122
+ let idx = styles.findIndex(s => s[0] === ns[0]);
123
+ if (idx >= 0)
124
+ styles[idx][1] = ns[1];
125
+ else
126
+ styles.push([ns[0], ns[1]]);
127
+ });
128
+ };
129
+ const attrArray = []; // = this.buildAttrArray();
130
+ if (globalThis.wtHuatuConfig?.noRefStyle) {
131
+ this.refStyles.forEach(s => mergeStyles(attrArray, s.buildAttrArray()));
132
+ mergeStyles(attrArray, this.buildAttrArray());
133
+ return attrArray.map(a => `${a[0]}="${a[1]}"`).join(" ");
134
+ }
135
+ const classes = this.refStyles.map(s => HuatuStyle.buildStyleClassName(s)).filter(x => !!x);
136
+ if (!direct && this.name) {
137
+ classes.push(HuatuStyle.buildStyleClassName(this));
138
+ return `class="${classes.join(' ')}"`;
139
+ }
140
+ if (classes.length > 0) {
141
+ attrArray.push(["class", `${classes.join(' ')}`]);
142
+ }
143
+ attrArray.push(...this.buildAttrArray());
144
+ return attrArray.map(a => `${a[0]}="${a[1]}"`).join(" ");
145
+ }
146
+ toPathConfigs() {
147
+ return HuatuStyle.convertStyleToPathConfigs(this);
148
+ }
149
+ static buildStyleClassName(style) {
150
+ if (!style.name)
151
+ return "";
152
+ return `sty-${style.magicId}`;
153
+ }
154
+ static judgeStrokeWidth(style) {
155
+ if (!style)
156
+ return 0;
157
+ let i = 0;
158
+ let strokeWidth;
159
+ let strokeColor;
160
+ while (i < style.refStyles.length) {
161
+ let sty = style.refStyles[i++];
162
+ if (sty.strokeWidth && strokeWidth === undefined)
163
+ strokeWidth = sty.strokeWidth;
164
+ if (sty.strokeColor && !strokeColor)
165
+ strokeColor = sty.strokeColor;
166
+ if (strokeWidth && strokeColor)
167
+ break;
168
+ }
169
+ strokeColor = style.strokeColor ? style.strokeColor : strokeColor;
170
+ return style.strokeWidth ? style.strokeWidth
171
+ : strokeWidth ? strokeWidth
172
+ : strokeColor && strokeColor.toLowerCase() !== "none" ? 1
173
+ : 0;
174
+ }
175
+ static buildForSvg(style, direct) {
176
+ if (!style)
177
+ return ``;
178
+ return style.buildSvgAttr(direct);
179
+ }
180
+ static convertStyleToPathConfigs(style) {
181
+ const configs = {};
182
+ if (style.fillPattern) {
183
+ configs.fill = { color: `url(#${style.fillPattern.buildId()})` };
184
+ }
185
+ else if (style.fillGradient) {
186
+ configs.fill = { color: `url(#${style.fillGradient})` };
187
+ }
188
+ else if (style.fillColor) {
189
+ configs.fill = { color: `${style.fillColor}` };
190
+ }
191
+ if (style.fillOpacity !== undefined && WtMath.isIn0and1(style.fillOpacity)) {
192
+ if (configs.fill)
193
+ configs.fill.opacity = style.fillOpacity;
194
+ else
195
+ configs.fill = { opacity: style.fillOpacity };
196
+ }
197
+ if (style.fillRule) {
198
+ if (configs.fill)
199
+ configs.fill.rule = style.fillRule;
200
+ else
201
+ configs.fill = { rule: style.fillRule };
202
+ }
203
+ configs.stroke = { color: style.strokeColor };
204
+ if (style.strokeWidth) {
205
+ configs.stroke.width = style.strokeWidth;
206
+ }
207
+ if (style.strokeOpacity) {
208
+ configs.stroke.opacity = style.strokeOpacity;
209
+ }
210
+ if (style.strokeLineCap && style.strokeLineCap !== "butt") {
211
+ configs.stroke.lineCap = style.strokeLineCap;
212
+ }
213
+ if (style.strokeLineJoin && style.strokeLineJoin !== "miter") {
214
+ configs.stroke.lineJoin = style.strokeLineJoin;
215
+ }
216
+ if (style.strokeDashArray) {
217
+ configs.stroke.dashArray = style.strokeDashArray;
218
+ }
219
+ if (style.strokeDashOffset) {
220
+ configs.stroke.dashOffset = style.strokeDashOffset;
221
+ }
222
+ if (style.markerStart) {
223
+ if (configs.marker)
224
+ configs.marker.start = style.markerStart.buildId();
225
+ else
226
+ configs.marker = { start: style.markerStart.buildId() };
227
+ }
228
+ if (style.markerMid) {
229
+ if (configs.marker)
230
+ configs.marker.mid = style.markerMid.buildId();
231
+ else
232
+ configs.marker = { mid: style.markerMid.buildId() };
233
+ }
234
+ if (style.markerEnd) {
235
+ if (configs.marker)
236
+ configs.marker.end = style.markerEnd.buildId();
237
+ else
238
+ configs.marker = { end: style.markerEnd.buildId() };
239
+ }
240
+ if (style.clipPath) {
241
+ configs.clip = style.clipPath.buildId();
242
+ }
243
+ return configs;
244
+ }
245
+ static optsFill = {
246
+ keys: [
247
+ ["color"],
248
+ ["opacity"],
249
+ ["pattern"],
250
+ ["gradient"],
251
+ ["rule"],
252
+ ],
253
+ allowAppend: [],
254
+ numbers: ["opacity"],
255
+ ints: [],
256
+ booleans: [],
257
+ qualifiers: {
258
+ "color": isValidColor,
259
+ "rule": SvgCsts.FILL_RULES,
260
+ },
261
+ blindGuess: {
262
+ "color": isValidColor,
263
+ "rule": SvgCsts.FILL_RULES,
264
+ "opacity": (op) => {
265
+ let x = parseFloat(op);
266
+ return Number.isNaN(x) ? undefined : x;
267
+ },
268
+ }
269
+ };
270
+ static optsFillColorAndOpacity = {
271
+ keys: [
272
+ ["color"],
273
+ ["opacity"],
274
+ ],
275
+ allowAppend: [],
276
+ numbers: ["opacity"],
277
+ ints: [],
278
+ booleans: [],
279
+ qualifiers: {
280
+ "color": isValidColor,
281
+ },
282
+ blindGuess: {
283
+ "color": isValidColor,
284
+ "opacity": (op) => {
285
+ let x = parseFloat(op);
286
+ return Number.isNaN(x) ? undefined : x;
287
+ },
288
+ }
289
+ };
290
+ static optsStroke = {
291
+ keys: [
292
+ ["color"],
293
+ ["width"],
294
+ ["opacity"],
295
+ ["lineCap"],
296
+ ["lineJoin"],
297
+ ["miterLimit"],
298
+ ["dashArray", "array", "dash"],
299
+ ["dashOffset", "offset"],
300
+ ],
301
+ allowAppend: ["dashArray", "array", "dash"],
302
+ numbers: ["width", "opacity", "miterLimit", "dashOffset", "offset"],
303
+ ints: [],
304
+ booleans: [],
305
+ qualifiers: {
306
+ "color": isValidColor,
307
+ "dashArray": "number[]",
308
+ "array": "number[]",
309
+ "dash": "number[]",
310
+ "lineCap": SvgCsts.LINE_CAPS,
311
+ "lineJoin": SvgCsts.LINE_JOINS,
312
+ },
313
+ blindGuess: {
314
+ "color": isValidColor,
315
+ "lineCap": SvgCsts.LINE_CAPS,
316
+ "lineJoin": SvgCsts.LINE_JOINS,
317
+ "width": (w) => {
318
+ let x = parseFloat(w);
319
+ return Number.isNaN(x) ? undefined : x;
320
+ },
321
+ }
322
+ };
323
+ static optsMarker = {
324
+ keys: [
325
+ ["start"],
326
+ ["mid", "middle"],
327
+ ["end"],
328
+ ],
329
+ allowAppend: [],
330
+ ints: [],
331
+ numbers: [],
332
+ booleans: [],
333
+ qualifiers: {},
334
+ blindGuess: {},
335
+ };
336
+ static optsStyle = {
337
+ keys: [
338
+ ["styles", "style", "refs", "ref"],
339
+ // Style keys
340
+ ["fill"],
341
+ ["fillOpacity"],
342
+ ["opaque"],
343
+ ["fillRule"],
344
+ ["fillColor"],
345
+ ["stroke"],
346
+ ["lineJoin", "strokeLineJoin"],
347
+ ["lineCap", "strokeLineCap"],
348
+ ["strokeOpacity"],
349
+ ["strokeColor"],
350
+ ["strokeWidth"],
351
+ ["dashArray", "array", "dash", "strokeDashArray"],
352
+ ["dashOffset", "arrayOffset", "offset"],
353
+ ["gradient"],
354
+ ["pattern"],
355
+ ["marker"],
356
+ ["clip"],
357
+ ["markerStart"],
358
+ ["markerMid", "markerMiddle"],
359
+ ["markerEnd"],
360
+ ],
361
+ allowAppend: ["fill", "stroke", "marker", "smooth"],
362
+ booleans: [],
363
+ ints: [],
364
+ numbers: [
365
+ "fillOpacity", "opaque",
366
+ "strokeWidth",
367
+ "strokeOpacity",
368
+ "dashOffset", "arrayOffset", "offset",
369
+ ],
370
+ qualifiers: {
371
+ "dashArray": "number[]",
372
+ "array": "number[]",
373
+ "dash": "number[]",
374
+ "strokeDashArray": "number[]",
375
+ "fillColor": isValidColor,
376
+ "strokeColor": isValidColor,
377
+ "lineCap": SvgCsts.LINE_CAPS,
378
+ "strokeLineCap": SvgCsts.LINE_CAPS,
379
+ "lineJoin": SvgCsts.LINE_JOINS,
380
+ "strokeLineJoin": SvgCsts.LINE_JOINS,
381
+ "fillRule": SvgCsts.FILL_RULES,
382
+ },
383
+ blindGuess: {
384
+ "fillRule": SvgCsts.FILL_RULES,
385
+ "lineCap": SvgCsts.LINE_CAPS,
386
+ "lineJoin": SvgCsts.LINE_JOINS,
387
+ },
388
+ subKeys: {
389
+ "fill": HuatuStyle.optsFill,
390
+ "stroke": HuatuStyle.optsStroke,
391
+ "marker": HuatuStyle.optsMarker,
392
+ }
393
+ };
394
+ }
@@ -0,0 +1,81 @@
1
+ import { HuatuTransform } from "./HuatuTransform.js";
2
+ import { SvgBBox } from "../svg/SvgBBox.js";
3
+ import { HuatuDrawingGroup } from "./HuatuDrawingGroup.js";
4
+ import { HuatuStyle } from "./HuatuStyle.js";
5
+ import { genHex } from "../tools/gen-id.js";
6
+ export class HuatuSymbol extends HuatuDrawingGroup {
7
+ refCount = 0;
8
+ alwaysInDef = true;
9
+ magicId;
10
+ viewBox;
11
+ constructor(name, desc) {
12
+ super(name, desc);
13
+ this.magicId = genHex(8);
14
+ }
15
+ getWidth() {
16
+ return this.viewBox ? this.viewBox.w : this.bbox.w;
17
+ }
18
+ getHeight() {
19
+ return this.viewBox ? this.viewBox.h : this.bbox.h;
20
+ }
21
+ setViewBox(viewBox) {
22
+ this.viewBox = viewBox;
23
+ }
24
+ // For a Symbol, the real size is determined by viewBox, so here we have to override the definition in parent class
25
+ // i.e. Huatu Drawing Group
26
+ getBBox(style) {
27
+ let width, height;
28
+ if (this.viewBox) {
29
+ width = this.viewBox.w;
30
+ height = this.viewBox.h;
31
+ }
32
+ else {
33
+ const bbox = this.bbox.extendByStroke(HuatuStyle.judgeStrokeWidth(style));
34
+ width = bbox.w;
35
+ height = bbox.h;
36
+ }
37
+ // The X and Y is not determined by symbol it self, so return 0 here
38
+ return new SvgBBox(0, 0, width, height);
39
+ }
40
+ buildId() {
41
+ return `sym-${this.magicId}`;
42
+ }
43
+ buildHtmlForDef() {
44
+ return `<symbol id="${this.buildId()}" viewBox="${(this.viewBox ?? this.bbox).buildString()}">\n`
45
+ + (this.desc ? `<desc>${this.desc}</desc>\n` : ``)
46
+ + this.elements.map(e => e.buildHtml("direct")).join("\n") // For def building, always use direct output
47
+ + `</symbol>`;
48
+ }
49
+ buildTransformStr(transform, alignCenter) {
50
+ const attrs = [];
51
+ let width = this.getWidth(), height = this.getHeight();
52
+ if (transform) {
53
+ const scale = HuatuTransform.judgeScale(transform);
54
+ width *= scale;
55
+ height *= scale;
56
+ const rotAttrs = HuatuTransform.buildTransformAttrsForSymbol(transform);
57
+ if (rotAttrs.length > 0)
58
+ attrs.push(...rotAttrs);
59
+ }
60
+ // This Align-To-Center action is to make sure that the symbol will be re-positioned
61
+ // to make sure its geometry center is at the point given. And the parameter input
62
+ // alignCenter will switch it on/off
63
+ if (alignCenter)
64
+ attrs.push(`translate(${-width / 2},${-height / 2})`);
65
+ if (attrs.length < 1)
66
+ return "";
67
+ return `transform="${attrs.join(" ")}"`;
68
+ }
69
+ buildSvgOfLink(style, transform, alignCenter) {
70
+ const scale = HuatuTransform.judgeScale(transform);
71
+ let width = scale * this.getWidth(), height = scale * this.getHeight();
72
+ const attrs = [];
73
+ attrs.push(`xlink:href="#${this.buildId()}"`);
74
+ attrs.push(`href="#${this.buildId()}"`);
75
+ attrs.push(`width="${width}"`);
76
+ attrs.push(`height="${height}"`);
77
+ attrs.push(this.buildTransformStr(transform, alignCenter));
78
+ attrs.push(HuatuStyle.buildForSvg(style));
79
+ return `<use ${attrs.join(" ")} />`;
80
+ }
81
+ }