topo-engine 0.1.2 → 0.1.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.
- package/README.md +402 -366
- package/dist/style.css +366 -248
- package/dist/topo-engine.cjs +228 -91
- package/dist/topo-engine.cjs.map +1 -1
- package/dist/topo-engine.js +228 -91
- package/dist/topo-engine.js.map +1 -1
- package/dist/topo-engine.umd.cjs +228 -91
- package/dist/topo-engine.umd.cjs.map +1 -1
- package/package.json +1 -1
package/dist/topo-engine.cjs
CHANGED
|
@@ -1335,11 +1335,26 @@ function foldModel(model, plans, nodeMap) {
|
|
|
1335
1335
|
const extNodes = model.nodes.filter((n) => !containAll.has(n.id)).map((n) => ({ ...n }));
|
|
1336
1336
|
for (const p of plans) {
|
|
1337
1337
|
const inner = stationInner(p, model, 50, nodeMap);
|
|
1338
|
+
let estH = inner.estH;
|
|
1339
|
+
const title = p.name || "";
|
|
1340
|
+
if (title && inner.estW > 24) {
|
|
1341
|
+
const tFs = 11, tLH = tFs * 1.35;
|
|
1342
|
+
let tW = 0, lines = 1;
|
|
1343
|
+
for (const ch of title) {
|
|
1344
|
+
const cw = /[\u4e00-\u9fff\u3000-\u303f\uff00-\uffef]/.test(ch) ? tFs : tFs * 0.6;
|
|
1345
|
+
if (tW && tW + cw > inner.estW - 12) {
|
|
1346
|
+
lines++;
|
|
1347
|
+
tW = 0;
|
|
1348
|
+
}
|
|
1349
|
+
tW += cw;
|
|
1350
|
+
}
|
|
1351
|
+
estH = Math.max(estH, 13 + lines * tLH + 6);
|
|
1352
|
+
}
|
|
1338
1353
|
extNodes.push({
|
|
1339
1354
|
id: p.sid,
|
|
1340
1355
|
cat: "station",
|
|
1341
1356
|
name: p.name,
|
|
1342
|
-
_size: { w: inner.estW, h:
|
|
1357
|
+
_size: { w: inner.estW, h: estH },
|
|
1343
1358
|
_fanW: inner.fanW
|
|
1344
1359
|
});
|
|
1345
1360
|
}
|
|
@@ -1834,7 +1849,23 @@ function expandStations(model, plans, pos, edgeCP, band, bandClear, vTrunkStatio
|
|
|
1834
1849
|
const fx = xS + (bminX + bmaxX) / 2;
|
|
1835
1850
|
const fy = yS + (bminY + bmaxY) / 2;
|
|
1836
1851
|
const fw = bmaxX - bminX + 2 * HM;
|
|
1837
|
-
|
|
1852
|
+
let fh = bmaxY - bminY + 2 * VM;
|
|
1853
|
+
const title = plan.name || "";
|
|
1854
|
+
if (title && fw > 24) {
|
|
1855
|
+
const tFs = 11;
|
|
1856
|
+
const tLH = tFs * 1.35;
|
|
1857
|
+
let tW = 0, lines = 1;
|
|
1858
|
+
for (const ch of title) {
|
|
1859
|
+
const cw = /[\u4e00-\u9fff\u3000-\u303f\uff00-\uffef]/.test(ch) ? tFs : tFs * 0.6;
|
|
1860
|
+
if (tW && tW + cw > fw - 12) {
|
|
1861
|
+
lines++;
|
|
1862
|
+
tW = 0;
|
|
1863
|
+
}
|
|
1864
|
+
tW += cw;
|
|
1865
|
+
}
|
|
1866
|
+
const titleH = 13 + lines * tLH + 6;
|
|
1867
|
+
fh = Math.max(fh, titleH);
|
|
1868
|
+
}
|
|
1838
1869
|
pos.set(plan.sid, { x: fx, y: fy });
|
|
1839
1870
|
frames.push({ id: plan.sid, x: fx, y: fy, w: fw, h: fh, name: plan.name });
|
|
1840
1871
|
if (plan.busNode) busWidth.set(plan.busNode, bs.w);
|
|
@@ -2424,6 +2455,69 @@ function assertOrthogonal(model, edgeCP) {
|
|
|
2424
2455
|
}
|
|
2425
2456
|
return bad;
|
|
2426
2457
|
}
|
|
2458
|
+
const THEMES = {
|
|
2459
|
+
// —— 深色主题(默认,与历史版本完全一致)——
|
|
2460
|
+
dark: {
|
|
2461
|
+
// 画布背景
|
|
2462
|
+
canvasBg: "#050505",
|
|
2463
|
+
// 导线(边)
|
|
2464
|
+
trunkEdge: "#FFFFFF",
|
|
2465
|
+
// 干线:白
|
|
2466
|
+
branchEdge: "#8B8B8B",
|
|
2467
|
+
// 支线:灰
|
|
2468
|
+
// 图元符号
|
|
2469
|
+
trunkLine: "#07A4F8",
|
|
2470
|
+
// 变压器连接线(蓝)
|
|
2471
|
+
red: "#F00",
|
|
2472
|
+
orange: "#FF6600",
|
|
2473
|
+
white: "#FFF",
|
|
2474
|
+
// 通用浅色元素(描边/文字/标签),light 下为深色
|
|
2475
|
+
cyan: "#00C8FF",
|
|
2476
|
+
gold: "#FFD700",
|
|
2477
|
+
gray: "#8B8B8B",
|
|
2478
|
+
// 计量箱(JX):深色主题黑底白字;浅色主题白底深框深字(随画布配套)
|
|
2479
|
+
meterFill: "#000000",
|
|
2480
|
+
meterText: "#FFFFFF",
|
|
2481
|
+
// 母线填充
|
|
2482
|
+
busFill: "rgba(255,255,255,0.15)",
|
|
2483
|
+
// 导线连接点填充
|
|
2484
|
+
dotFill: "rgba(0,200,255,0.18)",
|
|
2485
|
+
// 站房外框
|
|
2486
|
+
stationFill: "rgba(255,255,255,0.02)",
|
|
2487
|
+
stationText: "rgba(255,255,255,0.85)",
|
|
2488
|
+
// 未知图元
|
|
2489
|
+
unknownFill: "#333333",
|
|
2490
|
+
unknownStroke: "#AAAAAA"
|
|
2491
|
+
},
|
|
2492
|
+
// —— 浅色主题(白色画布 + 配套深色图元)——
|
|
2493
|
+
light: {
|
|
2494
|
+
canvasBg: "#FFFFFF",
|
|
2495
|
+
// 白底上干线用深灰、支线用浅灰
|
|
2496
|
+
trunkEdge: "#3F3F3F",
|
|
2497
|
+
branchEdge: "#9C9C9C",
|
|
2498
|
+
// 蓝/橙/红在白底上加深一档保证对比度
|
|
2499
|
+
trunkLine: "#0B78B5",
|
|
2500
|
+
red: "#C62828",
|
|
2501
|
+
orange: "#E05F00",
|
|
2502
|
+
white: "#333333",
|
|
2503
|
+
cyan: "#0087B8",
|
|
2504
|
+
gold: "#B8860B",
|
|
2505
|
+
gray: "#9C9C9C",
|
|
2506
|
+
meterFill: "#FFFFFF",
|
|
2507
|
+
// 浅色主题:白底 + 深框深字(随白画布配套)
|
|
2508
|
+
meterText: "#3A3A3A",
|
|
2509
|
+
busFill: "rgba(0,0,0,0.07)",
|
|
2510
|
+
dotFill: "rgba(0,135,184,0.14)",
|
|
2511
|
+
stationFill: "rgba(0,0,0,0.03)",
|
|
2512
|
+
stationText: "rgba(50,50,50,0.8)",
|
|
2513
|
+
unknownFill: "#EDEDED",
|
|
2514
|
+
unknownStroke: "#777777"
|
|
2515
|
+
}
|
|
2516
|
+
};
|
|
2517
|
+
let edgeTheme = THEMES.dark;
|
|
2518
|
+
function setEdgeTheme(themeName) {
|
|
2519
|
+
edgeTheme = THEMES[themeName] || THEMES.dark;
|
|
2520
|
+
}
|
|
2427
2521
|
function buildGraphData(model, layout) {
|
|
2428
2522
|
const nodes = model.nodes.map((n) => {
|
|
2429
2523
|
const spec = getSymbolSpec(n.cat);
|
|
@@ -2439,7 +2533,7 @@ function buildGraphData(model, layout) {
|
|
|
2439
2533
|
size: [w, spec.h],
|
|
2440
2534
|
// 自定义字段(进 attributes,供 svg-symbol 节点绘制使用)
|
|
2441
2535
|
cat: n.cat,
|
|
2442
|
-
labelText: n.shortName || "",
|
|
2536
|
+
labelText: n.cat === "bus" || n.cat === "cableTerminal" ? "" : n.shortName || "",
|
|
2443
2537
|
rotate: layout.stationRotate && layout.stationRotate.get(n.id) || 0,
|
|
2444
2538
|
highlight: 0,
|
|
2445
2539
|
cursor: "pointer",
|
|
@@ -2456,9 +2550,9 @@ function buildGraphData(model, layout) {
|
|
|
2456
2550
|
y: f2.y,
|
|
2457
2551
|
size: [f2.w, f2.h],
|
|
2458
2552
|
cat: "station",
|
|
2459
|
-
labelText: f2.name || "",
|
|
2460
2553
|
highlight: 0,
|
|
2461
|
-
zIndex: -1
|
|
2554
|
+
zIndex: -1,
|
|
2555
|
+
_stationTitle: f2.name || ""
|
|
2462
2556
|
}
|
|
2463
2557
|
});
|
|
2464
2558
|
}
|
|
@@ -2498,7 +2592,7 @@ function edgeStyle(datum) {
|
|
|
2498
2592
|
};
|
|
2499
2593
|
}
|
|
2500
2594
|
const base = {
|
|
2501
|
-
stroke: s2 && s2.overrideStroke || d2 && d2.overrideStroke || (isBranch ?
|
|
2595
|
+
stroke: s2 && s2.overrideStroke || d2 && d2.overrideStroke || (isBranch ? edgeTheme.branchEdge : edgeTheme.trunkEdge),
|
|
2502
2596
|
lineWidth: s2 && s2.overrideLineWidth || d2 && d2.overrideLineWidth || (isBranch ? 1.1 : 1.5),
|
|
2503
2597
|
opacity: s2 && s2.overrideOpacity != null ? s2.overrideOpacity : d2 && d2.overrideOpacity != null ? d2.overrideOpacity : isBranch ? 0.85 : 1,
|
|
2504
2598
|
controlPoints: d2 && d2.cp || [],
|
|
@@ -27559,14 +27653,13 @@ var Sector = /* @__PURE__ */ function(_Path) {
|
|
|
27559
27653
|
}]);
|
|
27560
27654
|
}(Path);
|
|
27561
27655
|
Sector.PARSED_STYLE_LIST = new Set([].concat(_toConsumableArray(Path.PARSED_STYLE_LIST), ["x", "y", "sr", "sr0", "radius", "startAngle", "endAngle"]));
|
|
27562
|
-
const C2 = {
|
|
27563
|
-
|
|
27564
|
-
|
|
27565
|
-
|
|
27566
|
-
|
|
27567
|
-
|
|
27568
|
-
|
|
27569
|
-
};
|
|
27656
|
+
const C2 = { ...THEMES.dark };
|
|
27657
|
+
function setNodePalette(themeName) {
|
|
27658
|
+
const t = THEMES[themeName] || THEMES.dark;
|
|
27659
|
+
for (const key of Object.keys(t)) {
|
|
27660
|
+
if (key in C2) C2[key] = t[key];
|
|
27661
|
+
}
|
|
27662
|
+
}
|
|
27570
27663
|
function drawHighlight(attributes, group) {
|
|
27571
27664
|
if (!attributes.highlight) return;
|
|
27572
27665
|
const [w, h] = attributes.size;
|
|
@@ -27587,45 +27680,19 @@ function drawHighlight(attributes, group) {
|
|
|
27587
27680
|
);
|
|
27588
27681
|
}
|
|
27589
27682
|
function drawAnnotation(attributes, group) {
|
|
27590
|
-
const
|
|
27591
|
-
if (!
|
|
27592
|
-
const [, h] = attributes.size;
|
|
27683
|
+
const label = attributes.annotationText;
|
|
27684
|
+
if (!label) return;
|
|
27685
|
+
const [w, h] = attributes.size;
|
|
27593
27686
|
const pos = attributes.annotationPos || "top";
|
|
27594
27687
|
const offset = attributes.annotationOffset || 4;
|
|
27595
27688
|
const y = pos === "top" ? -h / 2 - offset - 6 : h / 2 + offset + 6;
|
|
27596
|
-
group.
|
|
27597
|
-
new Text({
|
|
27598
|
-
style: {
|
|
27599
|
-
text: text2,
|
|
27600
|
-
x: 0,
|
|
27601
|
-
y,
|
|
27602
|
-
fontSize: attributes.annotationSize || 12,
|
|
27603
|
-
fill: attributes.annotationColor || "#FFFFFF",
|
|
27604
|
-
fontFamily: FONT,
|
|
27605
|
-
textAlign: "center",
|
|
27606
|
-
textBaseline: "middle"
|
|
27607
|
-
}
|
|
27608
|
-
})
|
|
27609
|
-
);
|
|
27689
|
+
_drawWrappedText(group, label, 0, y, attributes.annotationSize || 12, attributes.annotationColor || C2.white, w + 10, 1.25);
|
|
27610
27690
|
}
|
|
27611
27691
|
function drawLabelUnder(attributes, group) {
|
|
27612
|
-
const
|
|
27613
|
-
if (!
|
|
27692
|
+
const label = attributes.labelText || "";
|
|
27693
|
+
if (!label) return;
|
|
27614
27694
|
const [w, h] = attributes.size;
|
|
27615
|
-
group.
|
|
27616
|
-
new Text({
|
|
27617
|
-
style: {
|
|
27618
|
-
text: text2,
|
|
27619
|
-
x: 0,
|
|
27620
|
-
y: h / 2 + 8,
|
|
27621
|
-
fontSize: 11,
|
|
27622
|
-
fill: C2.white,
|
|
27623
|
-
fontFamily: FONT,
|
|
27624
|
-
textAlign: "center",
|
|
27625
|
-
textBaseline: "middle"
|
|
27626
|
-
}
|
|
27627
|
-
})
|
|
27628
|
-
);
|
|
27695
|
+
_drawWrappedText(group, label, 0, h / 2 + 8, 11, C2.white, w + 4, 1.3);
|
|
27629
27696
|
}
|
|
27630
27697
|
function text(attributes, group, str2, x, y, size, fill) {
|
|
27631
27698
|
if (!str2) return;
|
|
@@ -27644,6 +27711,52 @@ function text(attributes, group, str2, x, y, size, fill) {
|
|
|
27644
27711
|
})
|
|
27645
27712
|
);
|
|
27646
27713
|
}
|
|
27714
|
+
function _measureWidth(str2, fontSize2) {
|
|
27715
|
+
let w = 0;
|
|
27716
|
+
for (const ch of str2) {
|
|
27717
|
+
w += /[\u4e00-\u9fff\u3000-\u303f\uff00-\uffef]/.test(ch) ? fontSize2 : fontSize2 * 0.6;
|
|
27718
|
+
}
|
|
27719
|
+
return w;
|
|
27720
|
+
}
|
|
27721
|
+
function _wrapLines(str2, fontSize2, maxWidth) {
|
|
27722
|
+
if (!str2) return [];
|
|
27723
|
+
const lines = [];
|
|
27724
|
+
let line = "";
|
|
27725
|
+
for (const ch of str2) {
|
|
27726
|
+
const test = line + ch;
|
|
27727
|
+
if (line && _measureWidth(test, fontSize2) > maxWidth) {
|
|
27728
|
+
lines.push(line);
|
|
27729
|
+
line = ch;
|
|
27730
|
+
} else {
|
|
27731
|
+
line = test;
|
|
27732
|
+
}
|
|
27733
|
+
}
|
|
27734
|
+
if (line) lines.push(line);
|
|
27735
|
+
return lines;
|
|
27736
|
+
}
|
|
27737
|
+
function _drawWrappedText(group, str2, x, y, fontSize2, fill, maxWidth, lineGap = 1.3) {
|
|
27738
|
+
if (!str2) return;
|
|
27739
|
+
const lines = _wrapLines(str2, fontSize2, maxWidth);
|
|
27740
|
+
if (!lines.length) return;
|
|
27741
|
+
const lineHeight2 = fontSize2 * lineGap;
|
|
27742
|
+
const totalH = lines.length * lineHeight2;
|
|
27743
|
+
for (let i = 0; i < lines.length; i++) {
|
|
27744
|
+
group.appendChild(
|
|
27745
|
+
new Text({
|
|
27746
|
+
style: {
|
|
27747
|
+
text: lines[i],
|
|
27748
|
+
x,
|
|
27749
|
+
y: y - totalH / 2 + lineHeight2 * (i + 0.5),
|
|
27750
|
+
fontSize: fontSize2,
|
|
27751
|
+
fill,
|
|
27752
|
+
fontFamily: FONT,
|
|
27753
|
+
textAlign: "center",
|
|
27754
|
+
textBaseline: "middle"
|
|
27755
|
+
}
|
|
27756
|
+
})
|
|
27757
|
+
);
|
|
27758
|
+
}
|
|
27759
|
+
}
|
|
27647
27760
|
function drawTransformer(attributes, group) {
|
|
27648
27761
|
const lw = 1.4;
|
|
27649
27762
|
group.appendChild(new Line({ style: { x1: -24, y1: 0, x2: -15, y2: 0, stroke: C2.trunkLine, lineWidth: lw } }));
|
|
@@ -27665,7 +27778,7 @@ function drawBreaker(attributes, group) {
|
|
|
27665
27778
|
group.appendChild(new Line({ style: { x1: -28, y1: 0, x2: -21, y2: 0, stroke: C2.red, lineWidth: lw } }));
|
|
27666
27779
|
group.appendChild(new Rect({ style: { x: -21, y: -9, width: 42, height: 18, radius: 2, fill: "none", stroke: C2.red, lineWidth: lw } }));
|
|
27667
27780
|
group.appendChild(new Rect({ style: { x: -21, y: -9, width: 42, height: 7, fill: "rgba(255,0,0,0.25)" } }));
|
|
27668
|
-
|
|
27781
|
+
_drawWrappedText(group, attributes.labelText, 0, 0.5, 10, C2.white, 36, 1.2);
|
|
27669
27782
|
group.appendChild(new Line({ style: { x1: 21, y1: 0, x2: 28, y2: 0, stroke: C2.red, lineWidth: lw } }));
|
|
27670
27783
|
}
|
|
27671
27784
|
function drawCableTerminal(attributes, group) {
|
|
@@ -27676,8 +27789,8 @@ function drawStationTerminal(attributes, group) {
|
|
|
27676
27789
|
group.appendChild(new Polygon({ style: { points: [[0, -5], [0, 5], [9, 0]], fill: "none", stroke: C2.red, lineWidth: 1.4 } }));
|
|
27677
27790
|
}
|
|
27678
27791
|
function drawMeterBox(attributes, group) {
|
|
27679
|
-
group.appendChild(new Rect({ style: { x: -9.5, y: -9.5, width: 19, height: 19, fill:
|
|
27680
|
-
text(attributes, group, "JX", 0, 0.5, 7.5, C2.
|
|
27792
|
+
group.appendChild(new Rect({ style: { x: -9.5, y: -9.5, width: 19, height: 19, fill: C2.meterFill, stroke: C2.meterText, lineWidth: 0.9 } }));
|
|
27793
|
+
text(attributes, group, "JX", 0, 0.5, 7.5, C2.meterText);
|
|
27681
27794
|
}
|
|
27682
27795
|
function drawConsumer(attributes, group) {
|
|
27683
27796
|
group.appendChild(new Circle({ style: { cx: 0, cy: 0, r: 12.5, fill: "none", stroke: C2.white, lineWidth: 1.8 } }));
|
|
@@ -27685,10 +27798,10 @@ function drawConsumer(attributes, group) {
|
|
|
27685
27798
|
}
|
|
27686
27799
|
function drawBus(attributes, group) {
|
|
27687
27800
|
const [w] = attributes.size;
|
|
27688
|
-
group.appendChild(new Rect({ style: { x: -w / 2, y: -3, width: w, height: 6, radius: 2, fill:
|
|
27801
|
+
group.appendChild(new Rect({ style: { x: -w / 2, y: -3, width: w, height: 6, radius: 2, fill: C2.busFill, stroke: C2.white, lineWidth: 1.4 } }));
|
|
27689
27802
|
}
|
|
27690
27803
|
function drawLineDot(attributes, group) {
|
|
27691
|
-
group.appendChild(new Circle({ style: { cx: 0, cy: 0, r: 4, fill:
|
|
27804
|
+
group.appendChild(new Circle({ style: { cx: 0, cy: 0, r: 4, fill: C2.dotFill, stroke: C2.cyan, lineWidth: 1.4 } }));
|
|
27692
27805
|
}
|
|
27693
27806
|
function drawJunction(attributes, group) {
|
|
27694
27807
|
const lw = 1.4;
|
|
@@ -27698,7 +27811,7 @@ function drawJunction(attributes, group) {
|
|
|
27698
27811
|
group.appendChild(new Line({ style: { x1: 3.5, y1: -3.5, x2: -3.5, y2: 3.5, stroke: C2.red, lineWidth: lw } }));
|
|
27699
27812
|
}
|
|
27700
27813
|
function drawUnknown(attributes, group) {
|
|
27701
|
-
group.appendChild(new Circle({ style: { cx: 0, cy: 0, r: 8, fill:
|
|
27814
|
+
group.appendChild(new Circle({ style: { cx: 0, cy: 0, r: 8, fill: C2.unknownFill, stroke: C2.unknownStroke, lineWidth: 1.2 } }));
|
|
27702
27815
|
}
|
|
27703
27816
|
function drawStation(attributes, group) {
|
|
27704
27817
|
const [w, h] = attributes.size;
|
|
@@ -27710,28 +27823,15 @@ function drawStation(attributes, group) {
|
|
|
27710
27823
|
width: w,
|
|
27711
27824
|
height: h,
|
|
27712
27825
|
radius: 2,
|
|
27713
|
-
fill:
|
|
27826
|
+
fill: C2.stationFill,
|
|
27714
27827
|
stroke: C2.white,
|
|
27715
27828
|
lineWidth: 1.2,
|
|
27716
27829
|
opacity: 0.9
|
|
27717
27830
|
}
|
|
27718
27831
|
})
|
|
27719
27832
|
);
|
|
27720
|
-
if (attributes.
|
|
27721
|
-
group.
|
|
27722
|
-
new Text({
|
|
27723
|
-
style: {
|
|
27724
|
-
text: attributes.labelText,
|
|
27725
|
-
x: 0,
|
|
27726
|
-
y: -h / 2 + 13,
|
|
27727
|
-
fontSize: 11,
|
|
27728
|
-
fill: "rgba(255,255,255,0.85)",
|
|
27729
|
-
fontFamily: FONT,
|
|
27730
|
-
textAlign: "center",
|
|
27731
|
-
textBaseline: "middle"
|
|
27732
|
-
}
|
|
27733
|
-
})
|
|
27734
|
-
);
|
|
27833
|
+
if (attributes._stationTitle) {
|
|
27834
|
+
_drawWrappedText(group, attributes._stationTitle, 0, -h / 2 + 13, 11, C2.stationText, w - 12, 1.35);
|
|
27735
27835
|
}
|
|
27736
27836
|
}
|
|
27737
27837
|
const DRAWERS = {
|
|
@@ -27748,7 +27848,7 @@ const DRAWERS = {
|
|
|
27748
27848
|
station: drawStation,
|
|
27749
27849
|
other: drawUnknown
|
|
27750
27850
|
};
|
|
27751
|
-
const LABEL_UNDER = /* @__PURE__ */ new Set(["transformer", "fuse"
|
|
27851
|
+
const LABEL_UNDER = /* @__PURE__ */ new Set(["transformer", "fuse"]);
|
|
27752
27852
|
const _pulseState = /* @__PURE__ */ new Map();
|
|
27753
27853
|
class SvgSymbolNode extends g6.BaseNode {
|
|
27754
27854
|
drawKeyShape(attributes, container) {
|
|
@@ -27798,15 +27898,16 @@ const _export_sfc = (sfc, props) => {
|
|
|
27798
27898
|
}
|
|
27799
27899
|
return target;
|
|
27800
27900
|
};
|
|
27801
|
-
const _hoisted_1$2 =
|
|
27901
|
+
const _hoisted_1$2 = ["data-theme"];
|
|
27802
27902
|
const _hoisted_2$2 = { class: "topo-toolbar" };
|
|
27803
27903
|
const _hoisted_3$2 = { class: "topo-title" };
|
|
27804
27904
|
const _hoisted_4$2 = { class: "topo-meta" };
|
|
27805
|
-
const _hoisted_5$2 =
|
|
27905
|
+
const _hoisted_5$2 = ["title"];
|
|
27906
|
+
const _hoisted_6$2 = {
|
|
27806
27907
|
key: 0,
|
|
27807
27908
|
class: "topo-loading"
|
|
27808
27909
|
};
|
|
27809
|
-
const
|
|
27910
|
+
const _hoisted_7$2 = {
|
|
27810
27911
|
key: 1,
|
|
27811
27912
|
class: "topo-error"
|
|
27812
27913
|
};
|
|
@@ -27814,9 +27915,11 @@ const _sfc_main$2 = {
|
|
|
27814
27915
|
__name: "TopoGraph",
|
|
27815
27916
|
props: {
|
|
27816
27917
|
dataUrl: { type: String, default: "" },
|
|
27817
|
-
data: { type: Object, default: null }
|
|
27918
|
+
data: { type: Object, default: null },
|
|
27919
|
+
/** 主题:'dark'(默认,黑底 SCADA 风)| 'light'(白底);支持 v-model:theme 双向绑定 */
|
|
27920
|
+
theme: { type: String, default: "dark" }
|
|
27818
27921
|
},
|
|
27819
|
-
emits: ["node-select", "loaded", "top-distances"],
|
|
27922
|
+
emits: ["node-select", "loaded", "top-distances", "update:theme"],
|
|
27820
27923
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
27821
27924
|
const props = __props;
|
|
27822
27925
|
const emit = __emit;
|
|
@@ -27890,6 +27993,7 @@ const _sfc_main$2 = {
|
|
|
27890
27993
|
console.error("导出 PNG 失败:", e2);
|
|
27891
27994
|
}
|
|
27892
27995
|
}
|
|
27996
|
+
const lastRaw = vue.ref(null);
|
|
27893
27997
|
async function loadAndRender() {
|
|
27894
27998
|
loading.value = true;
|
|
27895
27999
|
error.value = "";
|
|
@@ -27918,7 +28022,16 @@ const _sfc_main$2 = {
|
|
|
27918
28022
|
rawText = text2;
|
|
27919
28023
|
loadAndRender();
|
|
27920
28024
|
}
|
|
28025
|
+
const themeName = () => props.theme === "light" ? "light" : "dark";
|
|
28026
|
+
function applyTheme() {
|
|
28027
|
+
const t = themeName();
|
|
28028
|
+
setNodePalette(t);
|
|
28029
|
+
setEdgeTheme(t);
|
|
28030
|
+
return t;
|
|
28031
|
+
}
|
|
27921
28032
|
function render(raw) {
|
|
28033
|
+
lastRaw.value = raw;
|
|
28034
|
+
const theme = applyTheme();
|
|
27922
28035
|
model = parseTopo(raw);
|
|
27923
28036
|
nodeByIdMap = new Map(model.nodes.map((n) => [n.id, n]));
|
|
27924
28037
|
title.value = String(model.title || "").replace(/\.+$/, "");
|
|
@@ -27945,7 +28058,7 @@ const _sfc_main$2 = {
|
|
|
27945
28058
|
graph = new g6.Graph({
|
|
27946
28059
|
container: container.value,
|
|
27947
28060
|
autoResize: true,
|
|
27948
|
-
background:
|
|
28061
|
+
background: THEMES[theme].canvasBg,
|
|
27949
28062
|
data: data2,
|
|
27950
28063
|
// 节点坐标与边路径均由正交布局引擎显式给定(存储在layoutData中)
|
|
27951
28064
|
node: {
|
|
@@ -28045,6 +28158,12 @@ const _sfc_main$2 = {
|
|
|
28045
28158
|
},
|
|
28046
28159
|
{ deep: true }
|
|
28047
28160
|
);
|
|
28161
|
+
vue.watch(
|
|
28162
|
+
() => props.theme,
|
|
28163
|
+
() => {
|
|
28164
|
+
if (lastRaw.value) render(lastRaw.value);
|
|
28165
|
+
}
|
|
28166
|
+
);
|
|
28048
28167
|
vue.onBeforeUnmount(() => {
|
|
28049
28168
|
if (api) {
|
|
28050
28169
|
api.destroy();
|
|
@@ -28073,7 +28192,10 @@ const _sfc_main$2 = {
|
|
|
28073
28192
|
getTopDistances: () => topDistances.value
|
|
28074
28193
|
});
|
|
28075
28194
|
return (_ctx, _cache) => {
|
|
28076
|
-
return vue.openBlock(), vue.createElementBlock("div",
|
|
28195
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
28196
|
+
class: "topo-wrap",
|
|
28197
|
+
"data-theme": themeName()
|
|
28198
|
+
}, [
|
|
28077
28199
|
vue.createElementVNode("div", {
|
|
28078
28200
|
ref_key: "container",
|
|
28079
28201
|
ref: container,
|
|
@@ -28082,6 +28204,11 @@ const _sfc_main$2 = {
|
|
|
28082
28204
|
vue.createElementVNode("div", _hoisted_2$2, [
|
|
28083
28205
|
vue.createElementVNode("span", _hoisted_3$2, vue.toDisplayString(title.value), 1),
|
|
28084
28206
|
vue.createElementVNode("span", _hoisted_4$2, " 节点 " + vue.toDisplayString(stats.value.total) + " · 边 " + vue.toDisplayString(edgeCount.value) + " · 深度 " + vue.toDisplayString(stats.value.depth) + " · 叶子 " + vue.toDisplayString(stats.value.leaves), 1),
|
|
28207
|
+
vue.createElementVNode("button", {
|
|
28208
|
+
class: "btn",
|
|
28209
|
+
title: __props.theme === "light" ? "切换到深色主题" : "切换到浅色主题",
|
|
28210
|
+
onClick: _cache[0] || (_cache[0] = ($event) => emit("update:theme", __props.theme === "light" ? "dark" : "light"))
|
|
28211
|
+
}, vue.toDisplayString(__props.theme === "light" ? "🌙 深色" : "☀️ 浅色"), 9, _hoisted_5$2),
|
|
28085
28212
|
vue.createElementVNode("button", {
|
|
28086
28213
|
class: "btn",
|
|
28087
28214
|
onClick: resetView
|
|
@@ -28091,13 +28218,13 @@ const _sfc_main$2 = {
|
|
|
28091
28218
|
onClick: exportPng
|
|
28092
28219
|
}, "导出 PNG")
|
|
28093
28220
|
]),
|
|
28094
|
-
loading.value ? (vue.openBlock(), vue.createElementBlock("div",
|
|
28095
|
-
]);
|
|
28221
|
+
loading.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$2, "正在解析台区拓扑…")) : error.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7$2, vue.toDisplayString(error.value), 1)) : vue.createCommentVNode("", true)
|
|
28222
|
+
], 8, _hoisted_1$2);
|
|
28096
28223
|
};
|
|
28097
28224
|
}
|
|
28098
28225
|
};
|
|
28099
|
-
const TopoGraph = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-
|
|
28100
|
-
const _hoisted_1$1 =
|
|
28226
|
+
const TopoGraph = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-562b2247"]]);
|
|
28227
|
+
const _hoisted_1$1 = ["data-theme"];
|
|
28101
28228
|
const _hoisted_2$1 = { class: "panel-head" };
|
|
28102
28229
|
const _hoisted_3$1 = {
|
|
28103
28230
|
key: 0,
|
|
@@ -28149,7 +28276,9 @@ const _sfc_main$1 = {
|
|
|
28149
28276
|
node: { type: Object, default: null },
|
|
28150
28277
|
upstream: { type: Array, default: () => [] },
|
|
28151
28278
|
downstream: { type: Array, default: () => [] },
|
|
28152
|
-
stats: { type: Object, default: () => ({}) }
|
|
28279
|
+
stats: { type: Object, default: () => ({}) },
|
|
28280
|
+
/** 主题:'dark'(默认)| 'light' */
|
|
28281
|
+
theme: { type: String, default: "dark" }
|
|
28153
28282
|
},
|
|
28154
28283
|
emits: ["close", "jump"],
|
|
28155
28284
|
setup(__props, { emit: __emit }) {
|
|
@@ -28189,7 +28318,10 @@ const _sfc_main$1 = {
|
|
|
28189
28318
|
return Object.entries(byCat).map(([cat, count]) => ({ label: CAT_LABEL[cat] || cat, count })).sort((a2, b) => b.count - a2.count);
|
|
28190
28319
|
});
|
|
28191
28320
|
return (_ctx, _cache) => {
|
|
28192
|
-
return vue.openBlock(), vue.createElementBlock("div",
|
|
28321
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
28322
|
+
class: "panel",
|
|
28323
|
+
"data-theme": __props.theme
|
|
28324
|
+
}, [
|
|
28193
28325
|
vue.createElementVNode("div", _hoisted_2$1, [
|
|
28194
28326
|
vue.createElementVNode("span", null, vue.toDisplayString(headTitle.value), 1),
|
|
28195
28327
|
vue.createElementVNode("button", {
|
|
@@ -28284,12 +28416,12 @@ const _sfc_main$1 = {
|
|
|
28284
28416
|
vue.createTextVNode(" 鼠标悬浮节点可高亮上下游与连线。 ")
|
|
28285
28417
|
], -1))
|
|
28286
28418
|
]))
|
|
28287
|
-
]);
|
|
28419
|
+
], 8, _hoisted_1$1);
|
|
28288
28420
|
};
|
|
28289
28421
|
}
|
|
28290
28422
|
};
|
|
28291
|
-
const SidePanel = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-
|
|
28292
|
-
const _hoisted_1 =
|
|
28423
|
+
const SidePanel = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-547b7d57"]]);
|
|
28424
|
+
const _hoisted_1 = ["data-theme"];
|
|
28293
28425
|
const _hoisted_2 = { class: "panel-head" };
|
|
28294
28426
|
const _hoisted_3 = { class: "panel-body" };
|
|
28295
28427
|
const _hoisted_4 = {
|
|
@@ -28315,7 +28447,9 @@ const _sfc_main = {
|
|
|
28315
28447
|
distances: {
|
|
28316
28448
|
type: Array,
|
|
28317
28449
|
default: () => []
|
|
28318
|
-
}
|
|
28450
|
+
},
|
|
28451
|
+
/** 主题:'dark'(默认)| 'light' */
|
|
28452
|
+
theme: { type: String, default: "dark" }
|
|
28319
28453
|
},
|
|
28320
28454
|
emits: ["close", "jump"],
|
|
28321
28455
|
setup(__props, { emit: __emit }) {
|
|
@@ -28334,7 +28468,10 @@ const _sfc_main = {
|
|
|
28334
28468
|
return distance2 / maxDistance.value * 100;
|
|
28335
28469
|
}
|
|
28336
28470
|
return (_ctx, _cache) => {
|
|
28337
|
-
return vue.openBlock(), vue.createElementBlock("div",
|
|
28471
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
28472
|
+
class: "distance-top10",
|
|
28473
|
+
"data-theme": __props.theme
|
|
28474
|
+
}, [
|
|
28338
28475
|
vue.createElementVNode("div", _hoisted_2, [
|
|
28339
28476
|
_cache[1] || (_cache[1] = vue.createElementVNode("div", { class: "head-left" }, [
|
|
28340
28477
|
vue.createElementVNode("span", { class: "head-icon" }, "📏"),
|
|
@@ -28391,12 +28528,12 @@ const _sfc_main = {
|
|
|
28391
28528
|
}), 128))
|
|
28392
28529
|
]))
|
|
28393
28530
|
])
|
|
28394
|
-
]);
|
|
28531
|
+
], 8, _hoisted_1);
|
|
28395
28532
|
};
|
|
28396
28533
|
}
|
|
28397
28534
|
};
|
|
28398
|
-
const DistanceTop10 = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
28399
|
-
const VERSION = "0.1.
|
|
28535
|
+
const DistanceTop10 = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-438b6017"]]);
|
|
28536
|
+
const VERSION = "0.1.4";
|
|
28400
28537
|
const DESCRIPTION = "配电台区单线图拓扑成图引擎";
|
|
28401
28538
|
exports.DESCRIPTION = DESCRIPTION;
|
|
28402
28539
|
exports.DistanceTop10 = DistanceTop10;
|