topo-engine 0.1.9 → 0.1.10
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/README.md +3 -1
- package/dist/index.d.ts +18 -1
- package/dist/style.css +11 -11
- package/dist/topo-engine.cjs +335 -57
- package/dist/topo-engine.cjs.map +1 -1
- package/dist/topo-engine.js +335 -57
- package/dist/topo-engine.js.map +1 -1
- package/dist/topo-engine.umd.cjs +335 -57
- package/dist/topo-engine.umd.cjs.map +1 -1
- package/docs/API.md +46 -11
- package/package.json +1 -1
package/dist/topo-engine.js
CHANGED
|
@@ -6658,11 +6658,11 @@ var parseGradient$1 = /* @__PURE__ */ function() {
|
|
|
6658
6658
|
}
|
|
6659
6659
|
}
|
|
6660
6660
|
function matchPositioning() {
|
|
6661
|
-
var
|
|
6662
|
-
if (
|
|
6661
|
+
var location2 = matchCoordinates();
|
|
6662
|
+
if (location2.x || location2.y) {
|
|
6663
6663
|
return {
|
|
6664
6664
|
type: "position",
|
|
6665
|
-
value:
|
|
6665
|
+
value: location2
|
|
6666
6666
|
};
|
|
6667
6667
|
}
|
|
6668
6668
|
}
|
|
@@ -26311,8 +26311,10 @@ class TopoApi {
|
|
|
26311
26311
|
}
|
|
26312
26312
|
// ------------------------------------------------------------
|
|
26313
26313
|
// 光晕 / 脉动 动画 —— 节点 & 箱内电表户
|
|
26314
|
-
// setNodeGlow(ref, { color, spread/radius, duration, opacity })
|
|
26314
|
+
// setNodeGlow(ref, { color, spread/radius, duration, opacity, width, intensity, blink })
|
|
26315
26315
|
// ref = 节点 id/psrId → 图元光环;assetNo → 该户表位光环
|
|
26316
|
+
// 强度栈:blur 柔光底衬 + 实心光块 + 外扩散环×2 + 霓虹主环(shadowBlur) + 亮芯环
|
|
26317
|
+
// intensity = 强度倍率(默认 1);blink = true/0~1 → 图元「整体闪烁」
|
|
26316
26318
|
// setNodePulse(ref, opts) → 节点透明度呼吸;assetNo → 该户电表格淡入淡出
|
|
26317
26319
|
// ------------------------------------------------------------
|
|
26318
26320
|
/** 是否有需要逐帧推进的动画(节点光晕 / 户光晕 / 户脉动) */
|
|
@@ -26410,6 +26412,9 @@ class TopoApi {
|
|
|
26410
26412
|
_glowSpread: void 0,
|
|
26411
26413
|
_glowOpacity: void 0,
|
|
26412
26414
|
_glowDuration: void 0,
|
|
26415
|
+
_glowWidth: void 0,
|
|
26416
|
+
_glowLevel: void 0,
|
|
26417
|
+
_glowBlink: void 0,
|
|
26413
26418
|
_glowT: void 0
|
|
26414
26419
|
}
|
|
26415
26420
|
}]);
|
|
@@ -26417,9 +26422,32 @@ class TopoApi {
|
|
|
26417
26422
|
}
|
|
26418
26423
|
}
|
|
26419
26424
|
/**
|
|
26420
|
-
*
|
|
26425
|
+
* 归一化「整体闪烁」参数:false / 未给 → 0(只画光环);true → 0.85;数字 → clamp(0,1)。
|
|
26426
|
+
* 数值含义 = 图元最暗时被压掉的透明度幅度(1 → 图元完全隐去,0.5 → 最暗降到 50%)。
|
|
26427
|
+
*/
|
|
26428
|
+
_normBlink(v) {
|
|
26429
|
+
if (v === true) return 0.85;
|
|
26430
|
+
if (v === false || v == null) return 0;
|
|
26431
|
+
const n = Number(v);
|
|
26432
|
+
return Number.isFinite(n) ? Math.max(0, Math.min(1, n)) : 0;
|
|
26433
|
+
}
|
|
26434
|
+
/** 归一化强度倍率(intensity/level/strength):默认 1,范围 0.2~3 */
|
|
26435
|
+
_normLevel(v) {
|
|
26436
|
+
const n = Number(v);
|
|
26437
|
+
return Number.isFinite(n) && n > 0 ? Math.max(0.2, Math.min(3, n)) : 1;
|
|
26438
|
+
}
|
|
26439
|
+
/**
|
|
26440
|
+
* 节点 / 箱内电表户光晕(发光环 + 霓虹辉光)动画。
|
|
26421
26441
|
* @param {string} ref 节点 id / psrId(图元光环)或资产编号 assetNo(该户表位光环)
|
|
26422
|
-
* @param {object} [opts] - { color, spread/radius, duration, opacity }
|
|
26442
|
+
* @param {object} [opts] - { color, spread/radius, duration, opacity, width, intensity/level/strength, blink/flash }
|
|
26443
|
+
* 渲染栈:blur 柔光底衬 + 贴合图元的实心光块(面光)→ 图元 → 外扩散环 ×2 →
|
|
26444
|
+
* 霓虹主环(粗线 + canvas shadowBlur 辉光)→ 偏白亮芯环(刺眼高光)。
|
|
26445
|
+
* intensity:强度倍率,默认 1(线宽/辉光/底光同时放大);想“更夸张”给 1.5~2.5,想收敛给 0.5~0.7。
|
|
26446
|
+
* spread:光环外扩半径,默认按图元大小自适应(短边 ×0.7,16~46px)。
|
|
26447
|
+
* blink:图元「整体闪烁」开关/强度(默认 false 只画光环;true = 0.85;数字 0~1)。
|
|
26448
|
+
* 开启后图元本体透明度随相位「亮 ↔ 暗」交替(与光环相位互补,始终有强视觉元素),
|
|
26449
|
+
* 图元变暗的瞬间底衬光块最亮 —— 整块明暗交替比细线醒目得多。
|
|
26450
|
+
* width:主环初始线宽 (px),默认 5.6(节点)/ 3.6(户表位),随相位收细。
|
|
26423
26451
|
* @returns {boolean} 是否命中并启动
|
|
26424
26452
|
*/
|
|
26425
26453
|
setNodeGlow(ref2, opts = {}) {
|
|
@@ -26429,11 +26457,17 @@ class TopoApi {
|
|
|
26429
26457
|
console.warn(`[TopoApi] setNodeGlow: 无法解析目标 ${ref2}(节点用 id/psrId,电表户用 assetNo)`);
|
|
26430
26458
|
return false;
|
|
26431
26459
|
}
|
|
26460
|
+
const width = parseFloat(opts.width);
|
|
26461
|
+
const spread = opts.spread != null ? opts.spread : opts.radius;
|
|
26432
26462
|
const cfg = {
|
|
26433
26463
|
color: opts.color || "#00C8FF",
|
|
26434
|
-
spread:
|
|
26435
|
-
|
|
26464
|
+
spread: Number.isFinite(parseFloat(spread)) ? parseFloat(spread) : null,
|
|
26465
|
+
// null → 按图元大小自适应
|
|
26466
|
+
opacity: opts.opacity != null ? opts.opacity : 0.95,
|
|
26436
26467
|
duration: opts.duration || 1600,
|
|
26468
|
+
width: Number.isFinite(width) && width > 0 ? width : null,
|
|
26469
|
+
level: this._normLevel(opts.intensity != null ? opts.intensity : opts.level != null ? opts.level : opts.strength),
|
|
26470
|
+
blink: this._normBlink(opts.blink != null ? opts.blink : opts.flash),
|
|
26437
26471
|
_start: performance.now(),
|
|
26438
26472
|
t: 0
|
|
26439
26473
|
};
|
|
@@ -26443,9 +26477,12 @@ class TopoApi {
|
|
|
26443
26477
|
id: t.id,
|
|
26444
26478
|
style: {
|
|
26445
26479
|
_glowColor: cfg.color,
|
|
26446
|
-
_glowSpread: cfg.spread,
|
|
26480
|
+
_glowSpread: cfg.spread == null ? void 0 : cfg.spread,
|
|
26447
26481
|
_glowOpacity: cfg.opacity,
|
|
26448
26482
|
_glowDuration: cfg.duration,
|
|
26483
|
+
_glowWidth: cfg.width == null ? void 0 : cfg.width,
|
|
26484
|
+
_glowLevel: cfg.level,
|
|
26485
|
+
_glowBlink: cfg.blink || void 0,
|
|
26449
26486
|
_glowT: 0
|
|
26450
26487
|
}
|
|
26451
26488
|
}]);
|
|
@@ -26497,6 +26534,9 @@ class TopoApi {
|
|
|
26497
26534
|
_glowSpread: void 0,
|
|
26498
26535
|
_glowOpacity: void 0,
|
|
26499
26536
|
_glowDuration: void 0,
|
|
26537
|
+
_glowWidth: void 0,
|
|
26538
|
+
_glowLevel: void 0,
|
|
26539
|
+
_glowBlink: void 0,
|
|
26500
26540
|
_glowT: void 0
|
|
26501
26541
|
}
|
|
26502
26542
|
});
|
|
@@ -28699,6 +28739,8 @@ const THEMES = {
|
|
|
28699
28739
|
cyan: "#00C8FF",
|
|
28700
28740
|
gold: "#FFD700",
|
|
28701
28741
|
gray: "#8B8B8B",
|
|
28742
|
+
// 开关/熔丝(Kxx)标签文字:画在红色箱体(red)里的文字色,随主题切换
|
|
28743
|
+
switchText: "#FFFFFF",
|
|
28702
28744
|
// 计量箱(JX):深色主题黑底白字;浅色主题白底深框深字(随画布配套)
|
|
28703
28745
|
meterFill: "#000000",
|
|
28704
28746
|
meterText: "#FFFFFF",
|
|
@@ -28727,6 +28769,9 @@ const THEMES = {
|
|
|
28727
28769
|
cyan: "#0087B8",
|
|
28728
28770
|
gold: "#B8860B",
|
|
28729
28771
|
gray: "#9C9C9C",
|
|
28772
|
+
// 开关标签:浅色主题下箱体仍是深红 red(#C62828),此处保持浅色字
|
|
28773
|
+
// (白字对比度 ≈5.6:1;若改成深字,请连 red 一起调浅,否则只剩 ≈2.3:1 会发糊)
|
|
28774
|
+
switchText: "#FFFFFF",
|
|
28730
28775
|
meterFill: "#FFFFFF",
|
|
28731
28776
|
// 浅色主题:白底 + 深框深字(随白画布配套)
|
|
28732
28777
|
meterText: "#3A3A3A",
|
|
@@ -28930,6 +28975,19 @@ function withAlpha(color2, a2) {
|
|
|
28930
28975
|
}
|
|
28931
28976
|
const LW = 1.8;
|
|
28932
28977
|
const LW_HI = 2.2;
|
|
28978
|
+
function mixWhite(color2, k) {
|
|
28979
|
+
if (typeof color2 !== "string") return color2;
|
|
28980
|
+
const m = color2.match(/^#([0-9a-f]{6}|[0-9a-f]{3})$/i);
|
|
28981
|
+
if (!m) return color2;
|
|
28982
|
+
let hex2 = m[1];
|
|
28983
|
+
if (hex2.length === 3) hex2 = hex2.split("").map((h) => h + h).join("");
|
|
28984
|
+
const n = parseInt(hex2, 16);
|
|
28985
|
+
const mix = (v) => Math.round(v + (255 - v) * Math.max(0, Math.min(1, k)));
|
|
28986
|
+
const r = mix(n >> 16 & 255), g = mix(n >> 8 & 255), b = mix(n & 255);
|
|
28987
|
+
return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0")}`;
|
|
28988
|
+
}
|
|
28989
|
+
const clampNum = (v, lo, hi) => v < lo ? lo : v > hi ? hi : v;
|
|
28990
|
+
const NO_HIT = { pointerEvents: "none" };
|
|
28933
28991
|
function drawHighlight(attributes, group) {
|
|
28934
28992
|
if (!attributes.highlight) return;
|
|
28935
28993
|
const [w, h] = attributes.size;
|
|
@@ -29023,7 +29081,7 @@ function _wrapLinesFixed(str2, chars2) {
|
|
|
29023
29081
|
if (line) lines.push(line);
|
|
29024
29082
|
return lines;
|
|
29025
29083
|
}
|
|
29026
|
-
function _drawWrappedTextFixed(group, str2, x, y, fontSize2, fill, chars2, lineGap = 1.3, weight = 400, align = "center") {
|
|
29084
|
+
function _drawWrappedTextFixed(group, str2, x, y, fontSize2, fill, chars2, lineGap = 1.3, weight = 400, align = "center", extra = null) {
|
|
29027
29085
|
if (!str2) return;
|
|
29028
29086
|
const lines = _wrapLinesFixed(str2, chars2);
|
|
29029
29087
|
if (!lines.length) return;
|
|
@@ -29032,6 +29090,7 @@ function _drawWrappedTextFixed(group, str2, x, y, fontSize2, fill, chars2, lineG
|
|
|
29032
29090
|
group.appendChild(
|
|
29033
29091
|
new Text({
|
|
29034
29092
|
style: {
|
|
29093
|
+
...extra || {},
|
|
29035
29094
|
text: lines[i],
|
|
29036
29095
|
x,
|
|
29037
29096
|
y: y + lineHeight2 * i,
|
|
@@ -29105,7 +29164,7 @@ function drawBreaker(attributes, group) {
|
|
|
29105
29164
|
}
|
|
29106
29165
|
group.appendChild(new Rect({ style: { x: bx, y: by, width: bw, height: bh, radius: r, fill: P.red, stroke: withAlpha(C2.white, 0.22), lineWidth: 1 } }));
|
|
29107
29166
|
if (attributes.labelText) {
|
|
29108
|
-
_drawWrappedText(group, attributes.labelText, 0, 0.6, 11.5,
|
|
29167
|
+
_drawWrappedText(group, attributes.labelText, 0, 0.6, 11.5, C2.switchText, bw - 8, 1.15, 700);
|
|
29109
29168
|
}
|
|
29110
29169
|
}
|
|
29111
29170
|
function drawCableTerminal(attributes, group) {
|
|
@@ -29152,20 +29211,33 @@ function cellFxAt(attributes, i) {
|
|
|
29152
29211
|
return fx && typeof fx === "object" ? fx[i] || null : null;
|
|
29153
29212
|
}
|
|
29154
29213
|
function drawCellGlowRings(group, cx, cy, baseR, g, t) {
|
|
29155
|
-
|
|
29156
|
-
|
|
29157
|
-
|
|
29158
|
-
|
|
29159
|
-
|
|
29160
|
-
|
|
29161
|
-
|
|
29162
|
-
|
|
29163
|
-
|
|
29164
|
-
|
|
29214
|
+
glowStack(group, cx, cy, baseR, {
|
|
29215
|
+
color: g.color,
|
|
29216
|
+
t: t == null ? g.t : t,
|
|
29217
|
+
spread: g.spread,
|
|
29218
|
+
opacity: g.opacity,
|
|
29219
|
+
width: g.width,
|
|
29220
|
+
level: g.level
|
|
29221
|
+
});
|
|
29222
|
+
}
|
|
29223
|
+
function cellBlinkOpacity(g) {
|
|
29224
|
+
if (!g || !g.blink) return 1;
|
|
29225
|
+
return 1 - g.blink * glowBlinkK(g.t == null ? 0 : g.t);
|
|
29226
|
+
}
|
|
29227
|
+
function drawCellGlowBackdrop(group, cx, cy, meterW, meterH, g) {
|
|
29228
|
+
if (!g) return;
|
|
29229
|
+
glowBackdrop(group, cx, cy, meterW, meterH, {
|
|
29230
|
+
color: g.color,
|
|
29231
|
+
t: g.t,
|
|
29232
|
+
spread: g.spread != null ? g.spread : 14,
|
|
29233
|
+
level: g.level,
|
|
29234
|
+
blink: g.blink
|
|
29235
|
+
});
|
|
29165
29236
|
}
|
|
29166
29237
|
function drawCellHighlight(group, cx, cy, baseR, hl) {
|
|
29167
29238
|
group.appendChild(new Circle({
|
|
29168
29239
|
style: {
|
|
29240
|
+
...NO_HIT,
|
|
29169
29241
|
cx,
|
|
29170
29242
|
cy,
|
|
29171
29243
|
r: baseR + 3,
|
|
@@ -29181,7 +29253,7 @@ function drawCellNote(group, cx, cy, baseR, note) {
|
|
|
29181
29253
|
const color2 = note.color || C2.gold;
|
|
29182
29254
|
const top = !note.position || note.position === "top";
|
|
29183
29255
|
const y = top ? cy - baseR - 5 - size / 2 : cy + baseR + 6 + size / 2;
|
|
29184
|
-
_drawWrappedTextFixed(group, note.text, cx, y, size, color2, 6, 1.15, 600, "center");
|
|
29256
|
+
_drawWrappedTextFixed(group, note.text, cx, y, size, color2, 6, 1.15, 600, "center", NO_HIT);
|
|
29185
29257
|
}
|
|
29186
29258
|
function drawMeterBox(attributes, group) {
|
|
29187
29259
|
const [w, h] = attributes.size;
|
|
@@ -29203,6 +29275,8 @@ function drawMeterBox(attributes, group) {
|
|
|
29203
29275
|
const meterH = 26;
|
|
29204
29276
|
const cx = 0;
|
|
29205
29277
|
const cy = -1;
|
|
29278
|
+
const baseR = Math.max(12, meterH / 2 + 2);
|
|
29279
|
+
if (fx && fx.glow) drawCellGlowBackdrop(cellGroup, cx, cy, meterW, meterH, fx.glow);
|
|
29206
29280
|
if (sel || hover) {
|
|
29207
29281
|
const ring = new Rect({
|
|
29208
29282
|
style: {
|
|
@@ -29219,9 +29293,10 @@ function drawMeterBox(attributes, group) {
|
|
|
29219
29293
|
markCell(ring);
|
|
29220
29294
|
cellGroup.appendChild(ring);
|
|
29221
29295
|
}
|
|
29296
|
+
const faceStart = cellGroup.children.length;
|
|
29222
29297
|
drawMeterFace(cellGroup, cx, cy, meterW, meterH, lineColor, markCell, 0);
|
|
29298
|
+
const faceEnd = cellGroup.children.length;
|
|
29223
29299
|
if (fx) {
|
|
29224
|
-
const baseR = Math.max(12, meterH / 2 + 2);
|
|
29225
29300
|
if (fx.hl) drawCellHighlight(cellGroup, cx, cy, baseR, fx.hl);
|
|
29226
29301
|
if (fx.note && fx.note.text) drawCellNote(cellGroup, cx, cy, baseR, fx.note);
|
|
29227
29302
|
if (fx.glow) drawCellGlowRings(cellGroup, cx, cy, baseR, fx.glow, fx.glow.t || 0);
|
|
@@ -29233,6 +29308,13 @@ function drawMeterBox(attributes, group) {
|
|
|
29233
29308
|
if (fx && fx.pulse && fx.pulse.opacity != null && fx.pulse.opacity < 1) {
|
|
29234
29309
|
cellGroup.style.opacity = fx.pulse.opacity;
|
|
29235
29310
|
}
|
|
29311
|
+
const blinkOp0 = fx && fx.glow ? cellBlinkOpacity(fx.glow) : 1;
|
|
29312
|
+
if (blinkOp0 < 1) {
|
|
29313
|
+
for (let k = faceStart; k < faceEnd && k < cellGroup.children.length; k++) {
|
|
29314
|
+
const s2 = cellGroup.children[k].style;
|
|
29315
|
+
s2.opacity = (s2.opacity == null ? 1 : s2.opacity) * blinkOp0;
|
|
29316
|
+
}
|
|
29317
|
+
}
|
|
29236
29318
|
group.appendChild(cellGroup);
|
|
29237
29319
|
} else if (attributes._meterBoxMode === "grid" && attributes._customers) {
|
|
29238
29320
|
const frameColor = boxColor || C2.meterText;
|
|
@@ -29258,6 +29340,7 @@ function drawMeterBox(attributes, group) {
|
|
|
29258
29340
|
shape.__custBox = nodeId;
|
|
29259
29341
|
shape.__custIndex = i;
|
|
29260
29342
|
};
|
|
29343
|
+
const hitLayer = new Group({});
|
|
29261
29344
|
for (let i = 0; i < customers.length; i++) {
|
|
29262
29345
|
const row2 = Math.floor(i / cols);
|
|
29263
29346
|
const col = i % cols;
|
|
@@ -29269,6 +29352,7 @@ function drawMeterBox(attributes, group) {
|
|
|
29269
29352
|
const lineColor = sel ? C2.gold : hover ? C2.cyan : baseColor;
|
|
29270
29353
|
const fx = cellFxAt(attributes, i);
|
|
29271
29354
|
const cellGroup = new Group({});
|
|
29355
|
+
if (fx && fx.glow) drawCellGlowBackdrop(cellGroup, cx, cy, meterW, meterH, fx.glow);
|
|
29272
29356
|
if (sel || hover) {
|
|
29273
29357
|
cellGroup.appendChild(new Circle({
|
|
29274
29358
|
style: {
|
|
@@ -29282,7 +29366,9 @@ function drawMeterBox(attributes, group) {
|
|
|
29282
29366
|
}
|
|
29283
29367
|
}));
|
|
29284
29368
|
}
|
|
29369
|
+
const faceStart = cellGroup.children.length;
|
|
29285
29370
|
drawMeterFace(cellGroup, cx, cy, meterW, meterH, lineColor, markCell, i);
|
|
29371
|
+
const faceEnd = cellGroup.children.length;
|
|
29286
29372
|
if (fx) {
|
|
29287
29373
|
if (fx.hl) drawCellHighlight(cellGroup, cx, cy, hitR, fx.hl);
|
|
29288
29374
|
if (fx.note && fx.note.text) drawCellNote(cellGroup, cx, cy, hitR, fx.note);
|
|
@@ -29294,9 +29380,19 @@ function drawMeterBox(attributes, group) {
|
|
|
29294
29380
|
_drawWrappedTextFixed(cellGroup, name, cx, cy + meterH / 2 + 6.5, 6.5, lineColor, 4, 1.15, 500);
|
|
29295
29381
|
}
|
|
29296
29382
|
}
|
|
29297
|
-
const
|
|
29298
|
-
|
|
29299
|
-
|
|
29383
|
+
const hitCell = new Rect({
|
|
29384
|
+
style: {
|
|
29385
|
+
x: cx - cellW / 2 - METER_GAP / 2,
|
|
29386
|
+
y: cy - cellW / 2 - METER_GAP / 2,
|
|
29387
|
+
width: cellW + METER_GAP,
|
|
29388
|
+
height: cellH + METER_GAP,
|
|
29389
|
+
fill: "rgba(255,255,255,0.01)",
|
|
29390
|
+
stroke: "none",
|
|
29391
|
+
cursor: "pointer"
|
|
29392
|
+
}
|
|
29393
|
+
});
|
|
29394
|
+
markCell(hitCell, i);
|
|
29395
|
+
hitLayer.appendChild(hitCell);
|
|
29300
29396
|
if (showName) {
|
|
29301
29397
|
const name = customers[i].realConsName || customers[i].consName || "";
|
|
29302
29398
|
if (name) {
|
|
@@ -29311,14 +29407,22 @@ function drawMeterBox(attributes, group) {
|
|
|
29311
29407
|
}
|
|
29312
29408
|
});
|
|
29313
29409
|
markCell(hitName, i);
|
|
29314
|
-
|
|
29410
|
+
hitLayer.appendChild(hitName);
|
|
29315
29411
|
}
|
|
29316
29412
|
}
|
|
29317
29413
|
if (fx && fx.pulse && fx.pulse.opacity != null && fx.pulse.opacity < 1) {
|
|
29318
29414
|
cellGroup.style.opacity = fx.pulse.opacity;
|
|
29319
29415
|
}
|
|
29416
|
+
const blinkOp = fx && fx.glow ? cellBlinkOpacity(fx.glow) : 1;
|
|
29417
|
+
if (blinkOp < 1) {
|
|
29418
|
+
for (let k = faceStart; k < faceEnd && k < cellGroup.children.length; k++) {
|
|
29419
|
+
const s2 = cellGroup.children[k].style;
|
|
29420
|
+
s2.opacity = (s2.opacity == null ? 1 : s2.opacity) * blinkOp;
|
|
29421
|
+
}
|
|
29422
|
+
}
|
|
29320
29423
|
group.appendChild(cellGroup);
|
|
29321
29424
|
}
|
|
29425
|
+
group.appendChild(hitLayer);
|
|
29322
29426
|
} else {
|
|
29323
29427
|
const s2 = Math.min(w, h) || 21;
|
|
29324
29428
|
const ink = boxColor || C2.meterText;
|
|
@@ -29406,35 +29510,134 @@ const DRAWERS = {
|
|
|
29406
29510
|
other: drawUnknown
|
|
29407
29511
|
};
|
|
29408
29512
|
const _pulseState = /* @__PURE__ */ new Map();
|
|
29409
|
-
function
|
|
29410
|
-
|
|
29411
|
-
|
|
29412
|
-
|
|
29413
|
-
|
|
29414
|
-
|
|
29415
|
-
|
|
29416
|
-
|
|
29417
|
-
|
|
29418
|
-
|
|
29513
|
+
function pushGlowRing(group, cx, cy, r, lineWidth, strokeOpacity, color2, blur) {
|
|
29514
|
+
if (strokeOpacity <= 0.015 || lineWidth <= 0) return;
|
|
29515
|
+
const style = {
|
|
29516
|
+
...NO_HIT,
|
|
29517
|
+
cx,
|
|
29518
|
+
cy,
|
|
29519
|
+
r,
|
|
29520
|
+
stroke: color2,
|
|
29521
|
+
lineWidth,
|
|
29522
|
+
strokeOpacity,
|
|
29523
|
+
fill: "none",
|
|
29524
|
+
lineCap: "round"
|
|
29525
|
+
};
|
|
29526
|
+
if (blur > 0.5) {
|
|
29527
|
+
style.shadowColor = color2;
|
|
29528
|
+
style.shadowBlur = blur;
|
|
29529
|
+
}
|
|
29530
|
+
group.appendChild(new Circle({ style }));
|
|
29531
|
+
}
|
|
29532
|
+
function glowStack(group, cx, cy, baseR, g) {
|
|
29533
|
+
const color2 = g.color || "#00C8FF";
|
|
29534
|
+
const level = g.level > 0 ? g.level : 1;
|
|
29535
|
+
const tt = clampNum(g.t == null ? 0 : g.t, 0, 1);
|
|
29536
|
+
const spread = g.spread != null ? g.spread : 14;
|
|
29537
|
+
const maxOp = g.opacity == null ? 0.95 : g.opacity;
|
|
29538
|
+
const alpha = Math.min(1, maxOp * Math.pow(1 - tt, 1.1) * Math.min(1.5, level));
|
|
29419
29539
|
if (alpha <= 0.02) return;
|
|
29420
|
-
const r = baseR + spread *
|
|
29421
|
-
const lw = Math.max(1.
|
|
29422
|
-
group.
|
|
29423
|
-
|
|
29540
|
+
const r = baseR + spread * (1 - (1 - tt) * (1 - tt));
|
|
29541
|
+
const lw = Math.max(1.3, (g.width || 3.6) * level * (0.34 + 0.66 * (1 - tt)));
|
|
29542
|
+
pushGlowRing(group, cx, cy, r + spread * 1.1, lw * 0.4, alpha * 0.26, color2, 0);
|
|
29543
|
+
pushGlowRing(group, cx, cy, r + spread * 0.55, lw * 0.62, alpha * 0.5, color2, lw * 2.5);
|
|
29544
|
+
pushGlowRing(group, cx, cy, r, lw, alpha, color2, lw * 6);
|
|
29545
|
+
pushGlowRing(group, cx, cy, r, Math.max(1.1, lw * 0.34), Math.min(1, alpha * 1.05), mixWhite(color2, 0.62), lw * 2);
|
|
29546
|
+
}
|
|
29547
|
+
function glowBackdrop(group, x, y, w, h, g) {
|
|
29548
|
+
const color2 = g.color || "#00C8FF";
|
|
29549
|
+
const level = g.level > 0 ? g.level : 1;
|
|
29550
|
+
const tt = clampNum(g.t == null ? 0 : g.t, 0, 1);
|
|
29551
|
+
const spread = g.spread != null ? g.spread : Math.max(14, Math.min(w, h) * 0.7);
|
|
29552
|
+
const blink = g.blink || 0;
|
|
29553
|
+
const fade = Math.pow(1 - tt, 1.1);
|
|
29554
|
+
const bk = glowBlinkK(tt);
|
|
29555
|
+
const base = Math.min(0.6, level * (0.26 * fade + 0.5 * blink * bk));
|
|
29556
|
+
const aura = Math.min(0.45, level * (0.2 * fade + 0.42 * blink * bk));
|
|
29557
|
+
if (base <= 0.02 && aura <= 0.02) return;
|
|
29558
|
+
const rad2 = Math.max(3, Math.min(w, h) * 0.16);
|
|
29559
|
+
const blurPx = clampNum(Math.min(w, h) * 0.28, 4, 18) * level;
|
|
29560
|
+
group.appendChild(new Rect({
|
|
29561
|
+
style: {
|
|
29562
|
+
...NO_HIT,
|
|
29563
|
+
x: x - w / 2 - spread * 0.85,
|
|
29564
|
+
y: y - h / 2 - spread * 0.85,
|
|
29565
|
+
width: w + spread * 1.7,
|
|
29566
|
+
height: h + spread * 1.7,
|
|
29567
|
+
radius: rad2 + 4,
|
|
29568
|
+
fill: color2,
|
|
29569
|
+
fillOpacity: aura,
|
|
29570
|
+
stroke: "none",
|
|
29571
|
+
filter: `blur(${blurPx.toFixed(1)}px)`
|
|
29572
|
+
}
|
|
29424
29573
|
}));
|
|
29425
|
-
group.appendChild(new
|
|
29574
|
+
group.appendChild(new Rect({
|
|
29426
29575
|
style: {
|
|
29427
|
-
|
|
29428
|
-
|
|
29429
|
-
|
|
29430
|
-
|
|
29431
|
-
|
|
29432
|
-
|
|
29433
|
-
fill:
|
|
29434
|
-
|
|
29576
|
+
...NO_HIT,
|
|
29577
|
+
x: x - w / 2 - 2.5,
|
|
29578
|
+
y: y - h / 2 - 2.5,
|
|
29579
|
+
width: w + 5,
|
|
29580
|
+
height: h + 5,
|
|
29581
|
+
radius: rad2,
|
|
29582
|
+
fill: color2,
|
|
29583
|
+
fillOpacity: base,
|
|
29584
|
+
stroke: "none"
|
|
29435
29585
|
}
|
|
29436
29586
|
}));
|
|
29437
29587
|
}
|
|
29588
|
+
function glowBlinkK(t) {
|
|
29589
|
+
return 0.5 - 0.5 * Math.cos((t || 0) * Math.PI * 2);
|
|
29590
|
+
}
|
|
29591
|
+
function glowParams(attributes) {
|
|
29592
|
+
const color2 = attributes._glowColor;
|
|
29593
|
+
if (!color2) return null;
|
|
29594
|
+
const [w, h] = attributes.size || [40, 40];
|
|
29595
|
+
const t = clampNum(attributes._glowT == null ? 0 : attributes._glowT, 0, 1);
|
|
29596
|
+
const level = attributes._glowLevel > 0 ? attributes._glowLevel : 1;
|
|
29597
|
+
const spread = attributes._glowSpread != null ? attributes._glowSpread : clampNum(Math.min(w, h) * 0.7, 16, 46);
|
|
29598
|
+
return {
|
|
29599
|
+
color: color2,
|
|
29600
|
+
t,
|
|
29601
|
+
w,
|
|
29602
|
+
h,
|
|
29603
|
+
level,
|
|
29604
|
+
baseR: Math.max(w, h) / 2 + 3,
|
|
29605
|
+
spread,
|
|
29606
|
+
maxOp: attributes._glowOpacity == null ? 0.95 : attributes._glowOpacity,
|
|
29607
|
+
lw0: attributes._glowWidth || 5.6,
|
|
29608
|
+
// 主环初始线宽(可调,默认 5.6)
|
|
29609
|
+
blink: attributes._glowBlink || 0
|
|
29610
|
+
// 整体闪烁强度(0=关;setNodeGlow blink 参数)
|
|
29611
|
+
};
|
|
29612
|
+
}
|
|
29613
|
+
function drawGlowBackdrop(attributes, group) {
|
|
29614
|
+
const p = glowParams(attributes);
|
|
29615
|
+
if (!p) return;
|
|
29616
|
+
glowBackdrop(group, 0, 0, p.w, p.h, {
|
|
29617
|
+
color: p.color,
|
|
29618
|
+
t: p.t,
|
|
29619
|
+
spread: p.spread,
|
|
29620
|
+
level: p.level,
|
|
29621
|
+
blink: p.blink
|
|
29622
|
+
});
|
|
29623
|
+
}
|
|
29624
|
+
function nodeBlinkOpacity(attributes) {
|
|
29625
|
+
const blink = attributes._glowBlink;
|
|
29626
|
+
if (!blink) return 1;
|
|
29627
|
+
return 1 - blink * glowBlinkK(attributes._glowT == null ? 0 : attributes._glowT);
|
|
29628
|
+
}
|
|
29629
|
+
function drawGlow(attributes, group) {
|
|
29630
|
+
const p = glowParams(attributes);
|
|
29631
|
+
if (!p) return;
|
|
29632
|
+
glowStack(group, 0, 0, p.baseR, {
|
|
29633
|
+
color: p.color,
|
|
29634
|
+
t: p.t,
|
|
29635
|
+
spread: p.spread,
|
|
29636
|
+
opacity: p.maxOp,
|
|
29637
|
+
width: p.lw0,
|
|
29638
|
+
level: p.level
|
|
29639
|
+
});
|
|
29640
|
+
}
|
|
29438
29641
|
class SvgSymbolNode extends BaseNode {
|
|
29439
29642
|
drawKeyShape(attributes, container) {
|
|
29440
29643
|
const [w, h] = attributes.size;
|
|
@@ -29464,7 +29667,10 @@ class SvgSymbolNode extends BaseNode {
|
|
|
29464
29667
|
const target = rot ? new Group({ style: { transform: `rotate(${rot}deg)` } }) : key;
|
|
29465
29668
|
if (rot) key.appendChild(target);
|
|
29466
29669
|
const draw = DRAWERS[attributes.cat] || drawUnknown;
|
|
29670
|
+
drawGlowBackdrop(attributes, target);
|
|
29671
|
+
const symStart = (target.children || []).length;
|
|
29467
29672
|
draw(attributes, target);
|
|
29673
|
+
const symEnd = (target.children || []).length;
|
|
29468
29674
|
drawGlow(attributes, target);
|
|
29469
29675
|
drawHighlight(attributes, target);
|
|
29470
29676
|
drawAnnotation(attributes, target);
|
|
@@ -29482,6 +29688,15 @@ class SvgSymbolNode extends BaseNode {
|
|
|
29482
29688
|
for (const child of items) child.style.opacity = op;
|
|
29483
29689
|
}
|
|
29484
29690
|
}
|
|
29691
|
+
const blinkOp = nodeBlinkOpacity(attributes);
|
|
29692
|
+
if (blinkOp < 1) {
|
|
29693
|
+
const kids = target.children || [];
|
|
29694
|
+
for (let i = symStart; i < symEnd && i < kids.length; i++) {
|
|
29695
|
+
const s2 = kids[i].style;
|
|
29696
|
+
const base = s2.opacity == null ? 1 : s2.opacity;
|
|
29697
|
+
s2.opacity = base * blinkOp;
|
|
29698
|
+
}
|
|
29699
|
+
}
|
|
29485
29700
|
return key;
|
|
29486
29701
|
}
|
|
29487
29702
|
}
|
|
@@ -29579,6 +29794,56 @@ const _sfc_main$2 = {
|
|
|
29579
29794
|
function cellFromShape(shape) {
|
|
29580
29795
|
return shape && shape.__custBox != null && shape.__custIndex != null ? { nodeId: shape.__custBox, index: shape.__custIndex } : null;
|
|
29581
29796
|
}
|
|
29797
|
+
function cellIndexAtPoint(nodeId, evt) {
|
|
29798
|
+
const st = styleOf(nodeId);
|
|
29799
|
+
if (!st || st._meterBoxMode !== "grid" || !Array.isArray(st._customers) || !st._customers.length) return null;
|
|
29800
|
+
const c = evt && (evt.canvas || evt.viewport) || {};
|
|
29801
|
+
if (c.x == null || c.y == null || st.x == null || st.y == null) return null;
|
|
29802
|
+
let lx = c.x - st.x;
|
|
29803
|
+
let ly = c.y - st.y;
|
|
29804
|
+
const rot = (st.rotate || 0) * Math.PI / 180;
|
|
29805
|
+
if (rot) {
|
|
29806
|
+
const cos = Math.cos(-rot);
|
|
29807
|
+
const sin = Math.sin(-rot);
|
|
29808
|
+
const nx = lx * cos - ly * sin;
|
|
29809
|
+
const ny = lx * sin + ly * cos;
|
|
29810
|
+
lx = nx;
|
|
29811
|
+
ly = ny;
|
|
29812
|
+
}
|
|
29813
|
+
const cols = st._meterBoxCols || Math.min(st._customers.length, MAX_COLS);
|
|
29814
|
+
const cellW = METER_CELL_W;
|
|
29815
|
+
const cellH = st._meterBoxShowName ? METER_CELL_H : METER_CELL_W;
|
|
29816
|
+
const rows = st._meterBoxRows || Math.ceil(st._customers.length / cols);
|
|
29817
|
+
const gridW = cols * cellW + (cols - 1) * METER_GAP;
|
|
29818
|
+
const gridH = rows * cellH + (rows - 1) * METER_GAP;
|
|
29819
|
+
const col = Math.floor((lx + gridW / 2) / (cellW + METER_GAP));
|
|
29820
|
+
const row2 = Math.floor((ly + gridH / 2) / (cellH + METER_GAP));
|
|
29821
|
+
if (col < 0 || col >= cols || row2 < 0 || row2 >= rows) return null;
|
|
29822
|
+
const i = row2 * cols + col;
|
|
29823
|
+
return i < st._customers.length ? i : null;
|
|
29824
|
+
}
|
|
29825
|
+
const DEBUG_CELL = typeof location !== "undefined" && /[?&]debugCell\b/.test(location.search);
|
|
29826
|
+
function dbgCell(tag, detail) {
|
|
29827
|
+
if (DEBUG_CELL) console.log("[cell-debug]", tag, detail);
|
|
29828
|
+
}
|
|
29829
|
+
function nodeIdOfShape(shape) {
|
|
29830
|
+
if (!shape || !nodeByIdMap) return null;
|
|
29831
|
+
let el = shape;
|
|
29832
|
+
for (let hops = 0; el && hops < 16; hops++) {
|
|
29833
|
+
if (el.id && nodeByIdMap.has(el.id)) return el.id;
|
|
29834
|
+
el = el.parentElement;
|
|
29835
|
+
}
|
|
29836
|
+
return null;
|
|
29837
|
+
}
|
|
29838
|
+
function resolveCell(evt, shape, nodeIdHint, allowBboxFallback = true) {
|
|
29839
|
+
const direct = cellFromShape(shape);
|
|
29840
|
+
if (direct) return direct;
|
|
29841
|
+
let nid = nodeIdHint || nodeIdOfShape(shape);
|
|
29842
|
+
if (!nid && allowBboxFallback) nid = hitTestNodeAtCanvas(evt);
|
|
29843
|
+
if (!nid) return null;
|
|
29844
|
+
const idx = cellIndexAtPoint(nid, evt);
|
|
29845
|
+
return idx == null ? null : { nodeId: nid, index: idx };
|
|
29846
|
+
}
|
|
29582
29847
|
function neighborsOf(id2) {
|
|
29583
29848
|
const upstream = [];
|
|
29584
29849
|
const downstream = [];
|
|
@@ -29816,14 +30081,21 @@ const _sfc_main$2 = {
|
|
|
29816
30081
|
graph.on("node:click", (evt) => {
|
|
29817
30082
|
const id2 = evt.target.id;
|
|
29818
30083
|
if (!id2) return;
|
|
29819
|
-
const cell =
|
|
29820
|
-
|
|
30084
|
+
const cell = resolveCell(evt, evt.originalTarget, id2);
|
|
30085
|
+
dbgCell("node:click", {
|
|
30086
|
+
id: id2,
|
|
30087
|
+
shape: evt.originalTarget && evt.originalTarget.nodeName,
|
|
30088
|
+
mark: cellFromShape(evt.originalTarget),
|
|
30089
|
+
cell,
|
|
30090
|
+
canvas: evt.canvas
|
|
30091
|
+
});
|
|
30092
|
+
if (cell && customersOf(id2) && cell.nodeId === id2) {
|
|
29821
30093
|
selectCustomerWithInfo(id2, cell.index);
|
|
29822
30094
|
return;
|
|
29823
30095
|
}
|
|
29824
30096
|
routeNodeTap(id2);
|
|
29825
30097
|
});
|
|
29826
|
-
function
|
|
30098
|
+
function hitTestNodeAtCanvas2(evt) {
|
|
29827
30099
|
const c = evt && (evt.canvas || evt.viewport) || {};
|
|
29828
30100
|
const cx = c.x, cy = c.y;
|
|
29829
30101
|
if (cx == null || cy == null) return null;
|
|
@@ -29873,8 +30145,14 @@ const _sfc_main$2 = {
|
|
|
29873
30145
|
api._emit("edge:click", { edgeId: id2, source: src, target: tgt });
|
|
29874
30146
|
});
|
|
29875
30147
|
graph.on("canvas:click", (evt) => {
|
|
29876
|
-
const hitId =
|
|
30148
|
+
const hitId = hitTestNodeAtCanvas2(evt);
|
|
29877
30149
|
if (hitId) {
|
|
30150
|
+
const cell = resolveCell(evt, null, hitId);
|
|
30151
|
+
dbgCell("canvas:click", { hitId, cell, canvas: evt.canvas });
|
|
30152
|
+
if (cell && cell.nodeId === hitId && customersOf(hitId)) {
|
|
30153
|
+
selectCustomerWithInfo(hitId, cell.index);
|
|
30154
|
+
return;
|
|
30155
|
+
}
|
|
29878
30156
|
routeNodeTap(hitId);
|
|
29879
30157
|
return;
|
|
29880
30158
|
}
|
|
@@ -29896,7 +30174,7 @@ const _sfc_main$2 = {
|
|
|
29896
30174
|
const gCanvas = graph.getCanvas && graph.getCanvas();
|
|
29897
30175
|
const doc = gCanvas && gCanvas.document;
|
|
29898
30176
|
if (doc) {
|
|
29899
|
-
doc.addEventListener("pointermove", (e2) => setCellHover(
|
|
30177
|
+
doc.addEventListener("pointermove", (e2) => setCellHover(resolveCell(e2, e2 && e2.target, null, false)));
|
|
29900
30178
|
}
|
|
29901
30179
|
hoverLeaveHandler = () => setCellHover(null);
|
|
29902
30180
|
container.value.addEventListener("pointerleave", hoverLeaveHandler);
|
|
@@ -30036,7 +30314,7 @@ const _sfc_main$2 = {
|
|
|
30036
30314
|
};
|
|
30037
30315
|
}
|
|
30038
30316
|
};
|
|
30039
|
-
const TopoGraph = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-
|
|
30317
|
+
const TopoGraph = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-a4a4c398"]]);
|
|
30040
30318
|
const _hoisted_1$1 = ["data-theme"];
|
|
30041
30319
|
const _hoisted_2$1 = { class: "panel-head" };
|
|
30042
30320
|
const _hoisted_3$1 = {
|
|
@@ -30409,7 +30687,7 @@ const _sfc_main = {
|
|
|
30409
30687
|
}
|
|
30410
30688
|
};
|
|
30411
30689
|
const DistanceTop10 = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-438b6017"]]);
|
|
30412
|
-
const VERSION = "0.1.
|
|
30690
|
+
const VERSION = "0.1.10";
|
|
30413
30691
|
const DESCRIPTION = "配电台区单线图拓扑成图引擎";
|
|
30414
30692
|
export {
|
|
30415
30693
|
DESCRIPTION,
|