topo-engine 0.1.3 → 0.1.5
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 +56 -7
- package/dist/index.d.ts +5 -0
- package/dist/style.css +11 -11
- package/dist/topo-engine.cjs +126 -10
- package/dist/topo-engine.cjs.map +1 -1
- package/dist/topo-engine.js +126 -10
- package/dist/topo-engine.js.map +1 -1
- package/dist/topo-engine.umd.cjs +126 -10
- package/dist/topo-engine.umd.cjs.map +1 -1
- package/package.json +1 -1
package/dist/topo-engine.js
CHANGED
|
@@ -1214,6 +1214,53 @@ const SYMBOL_SPEC = {
|
|
|
1214
1214
|
function getSymbolSpec(cat) {
|
|
1215
1215
|
return SYMBOL_SPEC[cat] || SYMBOL_SPEC.other;
|
|
1216
1216
|
}
|
|
1217
|
+
function buildCustomerMap(customerData) {
|
|
1218
|
+
const map = /* @__PURE__ */ new Map();
|
|
1219
|
+
if (!Array.isArray(customerData)) return map;
|
|
1220
|
+
for (const entry of customerData) {
|
|
1221
|
+
if (entry && entry.psrId && Array.isArray(entry.consumerList)) {
|
|
1222
|
+
map.set(String(entry.psrId), entry.consumerList);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
return map;
|
|
1226
|
+
}
|
|
1227
|
+
const METER_CELL_W = 26;
|
|
1228
|
+
const METER_CELL_H = 38;
|
|
1229
|
+
const METER_GAP = 4;
|
|
1230
|
+
const METER_PAD = 6;
|
|
1231
|
+
const MAX_COLS = 5;
|
|
1232
|
+
const SHOW_NAME_LIMIT = 20;
|
|
1233
|
+
function injectCustomers(model, customerMap) {
|
|
1234
|
+
for (const node of model.nodes) {
|
|
1235
|
+
if (node.cat !== "meterBox") continue;
|
|
1236
|
+
const customers = customerMap.get(node.psrId);
|
|
1237
|
+
if (!customers || customers.length === 0) continue;
|
|
1238
|
+
node._customers = customers;
|
|
1239
|
+
if (customers.length === 1) {
|
|
1240
|
+
node._meterBoxMode = "single";
|
|
1241
|
+
node._meterBoxW = 30;
|
|
1242
|
+
node._meterBoxH = 38;
|
|
1243
|
+
} else {
|
|
1244
|
+
const showName = customers.length <= SHOW_NAME_LIMIT;
|
|
1245
|
+
const cols = Math.min(customers.length, MAX_COLS);
|
|
1246
|
+
const rows = Math.ceil(customers.length / cols);
|
|
1247
|
+
const cellW = METER_CELL_W;
|
|
1248
|
+
const cellH = showName ? METER_CELL_H : METER_CELL_W;
|
|
1249
|
+
node._meterBoxMode = "grid";
|
|
1250
|
+
node._meterBoxCols = cols;
|
|
1251
|
+
node._meterBoxRows = rows;
|
|
1252
|
+
node._meterBoxShowName = showName;
|
|
1253
|
+
node._meterBoxW = METER_PAD * 2 + cols * cellW + (cols - 1) * METER_GAP;
|
|
1254
|
+
node._meterBoxH = METER_PAD * 2 + rows * cellH + (rows - 1) * METER_GAP;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
function getMeterBoxSize(node) {
|
|
1259
|
+
if (node._meterBoxW != null && node._meterBoxH != null) {
|
|
1260
|
+
return { w: node._meterBoxW, h: node._meterBoxH };
|
|
1261
|
+
}
|
|
1262
|
+
return null;
|
|
1263
|
+
}
|
|
1217
1264
|
function stationPlans(model) {
|
|
1218
1265
|
const nodesById = new Map(model.nodes.map((n) => [n.id, n]));
|
|
1219
1266
|
const plans = [];
|
|
@@ -1265,6 +1312,10 @@ function stationInner(plan, model, band = 50, nodeMap) {
|
|
|
1265
1312
|
const nmap = nodeMap || new Map(model.nodes.map((n) => [n.id, n]));
|
|
1266
1313
|
const specOf = (id2) => {
|
|
1267
1314
|
const n = nmap.get(id2);
|
|
1315
|
+
if (n && n.cat === "meterBox") {
|
|
1316
|
+
const dim = getMeterBoxSize(n);
|
|
1317
|
+
if (dim) return dim;
|
|
1318
|
+
}
|
|
1268
1319
|
const s2 = getSymbolSpec(n ? n.cat : "other");
|
|
1269
1320
|
return { w: s2.w, h: s2.h };
|
|
1270
1321
|
};
|
|
@@ -1922,6 +1973,10 @@ function computeOrthogonalLayout(model, opts = {}) {
|
|
|
1922
1973
|
const sz = (id2) => {
|
|
1923
1974
|
const n = extNodeMap.get(id2);
|
|
1924
1975
|
if (n && n._size) return n._size;
|
|
1976
|
+
if (n && n.cat === "meterBox") {
|
|
1977
|
+
const dim = getMeterBoxSize(n);
|
|
1978
|
+
if (dim) return dim;
|
|
1979
|
+
}
|
|
1925
1980
|
const spec = getSymbolSpec(n ? n.cat : "other");
|
|
1926
1981
|
return { w: spec.w, h: spec.h };
|
|
1927
1982
|
};
|
|
@@ -2520,22 +2575,30 @@ function buildGraphData(model, layout) {
|
|
|
2520
2575
|
const nodes = model.nodes.map((n) => {
|
|
2521
2576
|
const spec = getSymbolSpec(n.cat);
|
|
2522
2577
|
const busW = layout.stationBusWidth && layout.stationBusWidth.get(n.id);
|
|
2523
|
-
const
|
|
2578
|
+
const meterBoxDim = n.cat === "meterBox" ? getMeterBoxSize(n) : null;
|
|
2579
|
+
const w = busW || (meterBoxDim ? meterBoxDim.w : spec.w);
|
|
2580
|
+
const h = meterBoxDim ? meterBoxDim.h : spec.h;
|
|
2524
2581
|
const p = layout.pos.get(n.id) || { x: 0, y: 0 };
|
|
2525
2582
|
return {
|
|
2526
2583
|
id: n.id,
|
|
2527
|
-
data: { ...n, width: w, height:
|
|
2584
|
+
data: { ...n, width: w, height: h },
|
|
2528
2585
|
style: {
|
|
2529
2586
|
x: p.x,
|
|
2530
2587
|
y: p.y,
|
|
2531
|
-
size: [w,
|
|
2588
|
+
size: [w, h],
|
|
2532
2589
|
// 自定义字段(进 attributes,供 svg-symbol 节点绘制使用)
|
|
2533
2590
|
cat: n.cat,
|
|
2534
|
-
labelText: n.cat === "bus" || n.cat === "cableTerminal" ? "" : n.shortName || "",
|
|
2591
|
+
labelText: n.cat === "bus" || n.cat === "cableTerminal" || n.cat === "consumer" ? "" : n.shortName || "",
|
|
2535
2592
|
rotate: layout.stationRotate && layout.stationRotate.get(n.id) || 0,
|
|
2536
2593
|
highlight: 0,
|
|
2537
2594
|
cursor: "pointer",
|
|
2538
|
-
_nodeId: n.id
|
|
2595
|
+
_nodeId: n.id,
|
|
2596
|
+
// 计量箱客户数据
|
|
2597
|
+
_meterBoxMode: n._meterBoxMode || null,
|
|
2598
|
+
_meterBoxCols: n._meterBoxCols || 0,
|
|
2599
|
+
_meterBoxRows: n._meterBoxRows || 0,
|
|
2600
|
+
_meterBoxShowName: n._meterBoxShowName || false,
|
|
2601
|
+
_customers: n._customers || null
|
|
2539
2602
|
}
|
|
2540
2603
|
};
|
|
2541
2604
|
});
|
|
@@ -27787,8 +27850,45 @@ function drawStationTerminal(attributes, group) {
|
|
|
27787
27850
|
group.appendChild(new Polygon({ style: { points: [[0, -5], [0, 5], [9, 0]], fill: "none", stroke: C2.red, lineWidth: 1.4 } }));
|
|
27788
27851
|
}
|
|
27789
27852
|
function drawMeterBox(attributes, group) {
|
|
27790
|
-
|
|
27791
|
-
|
|
27853
|
+
const [w, h] = attributes.size;
|
|
27854
|
+
if (attributes._meterBoxMode === "single") {
|
|
27855
|
+
group.appendChild(new Circle({ style: { cx: 0, cy: -3, r: 11, fill: "none", stroke: C2.white, lineWidth: 1.6 } }));
|
|
27856
|
+
group.appendChild(new Line({ style: { x1: 0, y1: -14, x2: 0, y2: -7, stroke: C2.white, lineWidth: 1.6 } }));
|
|
27857
|
+
const name = attributes._customers && attributes._customers[0] ? attributes._customers[0].realConsName || attributes._customers[0].consName || "" : "";
|
|
27858
|
+
if (name) {
|
|
27859
|
+
group.appendChild(new Text({ style: { text: name, x: 0, y: 12, fontSize: 8, fill: C2.white, fontFamily: FONT, textAlign: "center", textBaseline: "middle" } }));
|
|
27860
|
+
}
|
|
27861
|
+
} else if (attributes._meterBoxMode === "grid" && attributes._customers) {
|
|
27862
|
+
group.appendChild(new Rect({ style: { x: -w / 2, y: -h / 2, width: w, height: h, fill: C2.meterFill, stroke: C2.meterText, lineWidth: 0.9, radius: 2 } }));
|
|
27863
|
+
const cols = attributes._meterBoxCols || 5;
|
|
27864
|
+
const customers = attributes._customers;
|
|
27865
|
+
const showName = attributes._meterBoxShowName;
|
|
27866
|
+
const cellW = METER_CELL_W;
|
|
27867
|
+
const cellH = showName ? METER_CELL_H : METER_CELL_W;
|
|
27868
|
+
const gridW = cols * cellW + (cols - 1) * METER_GAP;
|
|
27869
|
+
const rows = attributes._meterBoxRows || Math.ceil(customers.length / cols);
|
|
27870
|
+
const gridH = rows * cellH + (rows - 1) * METER_GAP;
|
|
27871
|
+
const startX = -gridW / 2;
|
|
27872
|
+
const startY = -gridH / 2;
|
|
27873
|
+
const meterR = 9;
|
|
27874
|
+
for (let i = 0; i < customers.length; i++) {
|
|
27875
|
+
const row2 = Math.floor(i / cols);
|
|
27876
|
+
const col = i % cols;
|
|
27877
|
+
const cx = startX + col * (cellW + METER_GAP) + cellW / 2;
|
|
27878
|
+
const cy = startY + row2 * (cellH + METER_GAP) + cellW / 2;
|
|
27879
|
+
group.appendChild(new Circle({ style: { cx, cy, r: meterR, fill: "none", stroke: C2.meterText, lineWidth: 0.8 } }));
|
|
27880
|
+
group.appendChild(new Line({ style: { x1: cx, y1: cy - meterR, x2: cx, y2: cy - meterR + 4, stroke: C2.meterText, lineWidth: 0.8 } }));
|
|
27881
|
+
if (showName) {
|
|
27882
|
+
const name = customers[i].realConsName || customers[i].consName || "";
|
|
27883
|
+
if (name) {
|
|
27884
|
+
group.appendChild(new Text({ style: { text: name, x: cx, y: cy + meterR + 6, fontSize: 7, fill: C2.meterText, fontFamily: FONT, textAlign: "center", textBaseline: "middle" } }));
|
|
27885
|
+
}
|
|
27886
|
+
}
|
|
27887
|
+
}
|
|
27888
|
+
} else {
|
|
27889
|
+
group.appendChild(new Rect({ style: { x: -9.5, y: -9.5, width: 19, height: 19, fill: C2.meterFill, stroke: C2.meterText, lineWidth: 0.9 } }));
|
|
27890
|
+
text(attributes, group, "JX", 0, 0.5, 7.5, C2.meterText);
|
|
27891
|
+
}
|
|
27792
27892
|
}
|
|
27793
27893
|
function drawConsumer(attributes, group) {
|
|
27794
27894
|
group.appendChild(new Circle({ style: { cx: 0, cy: 0, r: 12.5, fill: "none", stroke: C2.white, lineWidth: 1.8 } }));
|
|
@@ -27914,8 +28014,10 @@ const _sfc_main$2 = {
|
|
|
27914
28014
|
props: {
|
|
27915
28015
|
dataUrl: { type: String, default: "" },
|
|
27916
28016
|
data: { type: Object, default: null },
|
|
28017
|
+
/** 客户数据(计量箱关联的用户列表),直接传入 JSON 数组 */
|
|
28018
|
+
customerData: { type: Array, default: null },
|
|
27917
28019
|
/** 主题:'dark'(默认,黑底 SCADA 风)| 'light'(白底);支持 v-model:theme 双向绑定 */
|
|
27918
|
-
theme: { type: String, default: "
|
|
28020
|
+
theme: { type: String, default: "light" }
|
|
27919
28021
|
},
|
|
27920
28022
|
emits: ["node-select", "loaded", "top-distances", "update:theme"],
|
|
27921
28023
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
@@ -28031,6 +28133,10 @@ const _sfc_main$2 = {
|
|
|
28031
28133
|
lastRaw.value = raw;
|
|
28032
28134
|
const theme = applyTheme();
|
|
28033
28135
|
model = parseTopo(raw);
|
|
28136
|
+
if (props.customerData && props.customerData.length) {
|
|
28137
|
+
const customerMap = buildCustomerMap(props.customerData);
|
|
28138
|
+
injectCustomers(model, customerMap);
|
|
28139
|
+
}
|
|
28034
28140
|
nodeByIdMap = new Map(model.nodes.map((n) => [n.id, n]));
|
|
28035
28141
|
title.value = String(model.title || "").replace(/\.+$/, "");
|
|
28036
28142
|
stats.value = model.stats;
|
|
@@ -28162,6 +28268,13 @@ const _sfc_main$2 = {
|
|
|
28162
28268
|
if (lastRaw.value) render(lastRaw.value);
|
|
28163
28269
|
}
|
|
28164
28270
|
);
|
|
28271
|
+
watch(
|
|
28272
|
+
() => props.customerData,
|
|
28273
|
+
() => {
|
|
28274
|
+
if (lastRaw.value) render(lastRaw.value);
|
|
28275
|
+
},
|
|
28276
|
+
{ deep: true }
|
|
28277
|
+
);
|
|
28165
28278
|
onBeforeUnmount(() => {
|
|
28166
28279
|
if (api) {
|
|
28167
28280
|
api.destroy();
|
|
@@ -28221,7 +28334,7 @@ const _sfc_main$2 = {
|
|
|
28221
28334
|
};
|
|
28222
28335
|
}
|
|
28223
28336
|
};
|
|
28224
|
-
const TopoGraph = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-
|
|
28337
|
+
const TopoGraph = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-c213df91"]]);
|
|
28225
28338
|
const _hoisted_1$1 = ["data-theme"];
|
|
28226
28339
|
const _hoisted_2$1 = { class: "panel-head" };
|
|
28227
28340
|
const _hoisted_3$1 = {
|
|
@@ -28531,7 +28644,7 @@ const _sfc_main = {
|
|
|
28531
28644
|
}
|
|
28532
28645
|
};
|
|
28533
28646
|
const DistanceTop10 = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-438b6017"]]);
|
|
28534
|
-
const VERSION = "0.1.
|
|
28647
|
+
const VERSION = "0.1.5";
|
|
28535
28648
|
const DESCRIPTION = "配电台区单线图拓扑成图引擎";
|
|
28536
28649
|
export {
|
|
28537
28650
|
DESCRIPTION,
|
|
@@ -28543,11 +28656,14 @@ export {
|
|
|
28543
28656
|
TopoGraph,
|
|
28544
28657
|
VERSION,
|
|
28545
28658
|
assertOrthogonal,
|
|
28659
|
+
buildCustomerMap,
|
|
28546
28660
|
buildGraphData,
|
|
28547
28661
|
calculateTopDistances,
|
|
28548
28662
|
computeOrthogonalLayout,
|
|
28549
28663
|
edgeStyle,
|
|
28664
|
+
getMeterBoxSize,
|
|
28550
28665
|
getSymbolSpec,
|
|
28666
|
+
injectCustomers,
|
|
28551
28667
|
parseTopo
|
|
28552
28668
|
};
|
|
28553
28669
|
//# sourceMappingURL=topo-engine.js.map
|