topo-engine 0.1.5 → 0.1.6

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/dist/style.css CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  /* —— 主题变量:dark 为默认值,light 由 [data-theme='light'] 覆盖 —— */
3
- .topo-wrap[data-v-c213df91] {
3
+ .topo-wrap[data-v-b02bff98] {
4
4
  --tp-bg: #050505;
5
5
  --tp-toolbar-bg: rgba(20, 20, 20, 0.88);
6
6
  --tp-toolbar-border: #333;
@@ -19,7 +19,7 @@
19
19
  overflow: hidden;
20
20
  background: var(--tp-bg);
21
21
  }
22
- .topo-wrap[data-theme='light'][data-v-c213df91] {
22
+ .topo-wrap[data-theme='light'][data-v-b02bff98] {
23
23
  --tp-bg: #ffffff;
24
24
  --tp-toolbar-bg: rgba(255, 255, 255, 0.92);
25
25
  --tp-toolbar-border: #d9d9d9;
@@ -33,11 +33,11 @@
33
33
  --tp-text: #555;
34
34
  --tp-error: #d32f2f;
35
35
  }
36
- .topo-container[data-v-c213df91] {
36
+ .topo-container[data-v-b02bff98] {
37
37
  width: 100%;
38
38
  height: 100%;
39
39
  }
40
- .topo-toolbar[data-v-c213df91] {
40
+ .topo-toolbar[data-v-b02bff98] {
41
41
  position: absolute;
42
42
  top: 10px;
43
43
  left: 12px;
@@ -52,14 +52,14 @@
52
52
  color: var(--tp-text);
53
53
  z-index: 10;
54
54
  }
55
- .topo-title[data-v-c213df91] {
55
+ .topo-title[data-v-b02bff98] {
56
56
  color: var(--tp-title);
57
57
  font-weight: 600;
58
58
  }
59
- .topo-meta[data-v-c213df91] {
59
+ .topo-meta[data-v-b02bff98] {
60
60
  color: var(--tp-meta);
61
61
  }
62
- .btn[data-v-c213df91] {
62
+ .btn[data-v-b02bff98] {
63
63
  margin-left: 4px;
64
64
  padding: 3px 10px;
65
65
  border: 1px solid var(--tp-btn-border);
@@ -69,12 +69,12 @@
69
69
  cursor: pointer;
70
70
  font-size: 12px;
71
71
  }
72
- .btn[data-v-c213df91]:hover {
72
+ .btn[data-v-b02bff98]:hover {
73
73
  border-color: var(--tp-accent);
74
74
  color: var(--tp-accent);
75
75
  }
76
- .topo-loading[data-v-c213df91],
77
- .topo-error[data-v-c213df91] {
76
+ .topo-loading[data-v-b02bff98],
77
+ .topo-error[data-v-b02bff98] {
78
78
  position: absolute;
79
79
  inset: 0;
80
80
  display: flex;
@@ -85,7 +85,7 @@
85
85
  z-index: 5;
86
86
  background: var(--tp-overlay-bg);
87
87
  }
88
- .topo-error[data-v-c213df91] {
88
+ .topo-error[data-v-b02bff98] {
89
89
  color: var(--tp-error);
90
90
  }
91
91
 
@@ -54,6 +54,13 @@ class TopoApi {
54
54
  _assertReady() {
55
55
  if (!this._graph) throw new Error("[TopoApi] 图实例未就绪,请等待渲染完成");
56
56
  }
57
+ /** 画布中心兼容取值:G6 v5 getCanvasCenter 返回数组 [x,y,z],历史代码按 {x,y} 对象使用 */
58
+ _canvasCenterXY() {
59
+ const c = this._graph.getCanvasCenter();
60
+ if (Array.isArray(c)) return { x: c[0], y: c[1] };
61
+ if (c && typeof c === "object") return { x: c.x || 0, y: c.y || 0 };
62
+ return { x: 0, y: 0 };
63
+ }
57
64
  /** 安全合并 style:保留现有字段,只覆盖传入字段 */
58
65
  _safeNodeStyle(nodeId, style) {
59
66
  try {
@@ -373,7 +380,7 @@ class TopoApi {
373
380
  try {
374
381
  this._graph.focusElement(nodeId);
375
382
  } catch {
376
- const center = this._graph.getCanvasCenter();
383
+ const center = this._canvasCenterXY();
377
384
  this._graph.translateTo({ x: center.x - p.x * (zoom || this._graph.getZoom()), y: center.y - p.y * (zoom || this._graph.getZoom()) });
378
385
  }
379
386
  }
@@ -381,7 +388,7 @@ class TopoApi {
381
388
  getViewport() {
382
389
  this._assertReady();
383
390
  const zoom = this._graph.getZoom();
384
- const center = this._graph.getCanvasCenter();
391
+ const center = this._canvasCenterXY();
385
392
  return { zoom, center };
386
393
  }
387
394
  // ============================================================
@@ -754,11 +761,25 @@ class TopoApi {
754
761
  if (!container) return;
755
762
  const pos = this._layout.pos.get(nodeId);
756
763
  if (!pos) return;
757
- const zoom = this._graph.getZoom();
758
- const canvasCenter = this._graph.getCanvasCenter();
759
- const containerRect = container.getBoundingClientRect();
760
- const screenX = containerRect.left + canvasCenter.x + pos.x * zoom;
761
- const screenY = containerRect.top + canvasCenter.y + pos.y * zoom;
764
+ let client = null;
765
+ try {
766
+ if (typeof this._graph.getClientByCanvas === "function") {
767
+ const r = this._graph.getClientByCanvas([pos.x, pos.y]);
768
+ client = Array.isArray(r) ? { x: r[0], y: r[1] } : r;
769
+ }
770
+ } catch (e2) {
771
+ }
772
+ let screenX, screenY;
773
+ if (client && isFinite(client.x)) {
774
+ screenX = client.x;
775
+ screenY = client.y;
776
+ } else {
777
+ const zoom = this._graph.getZoom();
778
+ const canvasCenter = this._canvasCenterXY();
779
+ const containerRect = container.getBoundingClientRect();
780
+ screenX = containerRect.left + canvasCenter.x + pos.x * zoom;
781
+ screenY = containerRect.top + canvasCenter.y + pos.y * zoom;
782
+ }
762
783
  const el = document.createElement("div");
763
784
  el.className = "topo-card";
764
785
  el.dataset.nodeId = nodeId;
@@ -28190,6 +28211,34 @@ const _sfc_main$2 = {
28190
28211
  const id2 = evt.target.id;
28191
28212
  selectNodeWithInfo(id2);
28192
28213
  });
28214
+ function hitTestNodeAtCanvas(evt) {
28215
+ const c = evt && (evt.canvas || evt.viewport) || {};
28216
+ const cx = c.x, cy = c.y;
28217
+ if (cx == null || cy == null) return null;
28218
+ let best = null, bestD = Infinity;
28219
+ let all = [];
28220
+ try {
28221
+ all = graph.getNodeData();
28222
+ } catch {
28223
+ return null;
28224
+ }
28225
+ for (const nd of all || []) {
28226
+ if (nd && nd.data && nd.data.isStationFrame) continue;
28227
+ const st = nd && nd.style;
28228
+ if (!st || st.x == null || st.y == null) continue;
28229
+ const size = st.size || [0, 0];
28230
+ const w = size[0] || 0, h = size[1] || 0;
28231
+ if (w <= 0 || h <= 0) continue;
28232
+ if (cx >= st.x - w / 2 && cx <= st.x + w / 2 && cy >= st.y - h / 2 && cy <= st.y + h / 2) {
28233
+ const d2 = Math.abs(cx - st.x) + Math.abs(cy - st.y);
28234
+ if (d2 < bestD) {
28235
+ bestD = d2;
28236
+ best = nd.id;
28237
+ }
28238
+ }
28239
+ }
28240
+ return best;
28241
+ }
28193
28242
  graph.on("node:pointerenter", (evt) => {
28194
28243
  const id2 = evt.target.id;
28195
28244
  const data3 = graph.getNodeData(id2);
@@ -28212,6 +28261,11 @@ const _sfc_main$2 = {
28212
28261
  api._emit("edge:click", { edgeId: id2, source: src, target: tgt });
28213
28262
  });
28214
28263
  graph.on("canvas:click", (evt) => {
28264
+ const hitId = hitTestNodeAtCanvas(evt);
28265
+ if (hitId) {
28266
+ selectNodeWithInfo(hitId);
28267
+ return;
28268
+ }
28215
28269
  if (selectedId) {
28216
28270
  const data3 = graph.getNodeData(selectedId);
28217
28271
  const existing = data3 && data3.style || {};
@@ -28224,7 +28278,8 @@ const _sfc_main$2 = {
28224
28278
  });
28225
28279
  graph.on("viewportchange", (evt) => {
28226
28280
  const zoom = graph.getZoom();
28227
- const center = graph.getCanvasCenter();
28281
+ const raw2 = graph.getCanvasCenter();
28282
+ const center = Array.isArray(raw2) ? { x: raw2[0], y: raw2[1] } : raw2;
28228
28283
  api._emit("viewport:change", { zoom, center });
28229
28284
  });
28230
28285
  graph.render().then(() => {
@@ -28336,7 +28391,7 @@ const _sfc_main$2 = {
28336
28391
  };
28337
28392
  }
28338
28393
  };
28339
- const TopoGraph = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-c213df91"]]);
28394
+ const TopoGraph = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-b02bff98"]]);
28340
28395
  const _hoisted_1$1 = ["data-theme"];
28341
28396
  const _hoisted_2$1 = { class: "panel-head" };
28342
28397
  const _hoisted_3$1 = {
@@ -28646,7 +28701,7 @@ const _sfc_main = {
28646
28701
  }
28647
28702
  };
28648
28703
  const DistanceTop10 = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-438b6017"]]);
28649
- const VERSION = "0.1.5";
28704
+ const VERSION = "0.1.6";
28650
28705
  const DESCRIPTION = "配电台区单线图拓扑成图引擎";
28651
28706
  exports.DESCRIPTION = DESCRIPTION;
28652
28707
  exports.DistanceTop10 = DistanceTop10;