aifastdb-devplan 1.5.0 → 1.6.2
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/autopilot.d.ts +58 -0
- package/dist/autopilot.d.ts.map +1 -0
- package/dist/autopilot.js +250 -0
- package/dist/autopilot.js.map +1 -0
- package/dist/dev-plan-document-store.d.ts +15 -1
- package/dist/dev-plan-document-store.d.ts.map +1 -1
- package/dist/dev-plan-document-store.js +122 -0
- package/dist/dev-plan-document-store.js.map +1 -1
- package/dist/dev-plan-factory.d.ts +69 -3
- package/dist/dev-plan-factory.d.ts.map +1 -1
- package/dist/dev-plan-factory.js +113 -19
- package/dist/dev-plan-factory.js.map +1 -1
- package/dist/dev-plan-graph-store.d.ts +79 -1
- package/dist/dev-plan-graph-store.d.ts.map +1 -1
- package/dist/dev-plan-graph-store.js +420 -3
- package/dist/dev-plan-graph-store.js.map +1 -1
- package/dist/dev-plan-interface.d.ts +24 -1
- package/dist/dev-plan-interface.d.ts.map +1 -1
- package/dist/dev-plan-migrate.d.ts +1 -0
- package/dist/dev-plan-migrate.d.ts.map +1 -1
- package/dist/dev-plan-migrate.js +28 -2
- package/dist/dev-plan-migrate.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/index.d.ts +3 -0
- package/dist/mcp-server/index.d.ts.map +1 -1
- package/dist/mcp-server/index.js +397 -4
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/types.d.ts +160 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -1
- package/dist/types.js.map +1 -1
- package/dist/visualize/graph-canvas/api-compat.d.ts +20 -0
- package/dist/visualize/graph-canvas/api-compat.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/api-compat.js +344 -0
- package/dist/visualize/graph-canvas/api-compat.js.map +1 -0
- package/dist/visualize/graph-canvas/clusterer.d.ts +16 -0
- package/dist/visualize/graph-canvas/clusterer.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/clusterer.js +460 -0
- package/dist/visualize/graph-canvas/clusterer.js.map +1 -0
- package/dist/visualize/graph-canvas/core.d.ts +11 -0
- package/dist/visualize/graph-canvas/core.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/core.js +1136 -0
- package/dist/visualize/graph-canvas/core.js.map +1 -0
- package/dist/visualize/graph-canvas/index.d.ts +22 -0
- package/dist/visualize/graph-canvas/index.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/index.js +69 -0
- package/dist/visualize/graph-canvas/index.js.map +1 -0
- package/dist/visualize/graph-canvas/interaction.d.ts +13 -0
- package/dist/visualize/graph-canvas/interaction.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/interaction.js +457 -0
- package/dist/visualize/graph-canvas/interaction.js.map +1 -0
- package/dist/visualize/graph-canvas/layout-worker.d.ts +17 -0
- package/dist/visualize/graph-canvas/layout-worker.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/layout-worker.js +577 -0
- package/dist/visualize/graph-canvas/layout-worker.js.map +1 -0
- package/dist/visualize/graph-canvas/lod.d.ts +10 -0
- package/dist/visualize/graph-canvas/lod.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/lod.js +111 -0
- package/dist/visualize/graph-canvas/lod.js.map +1 -0
- package/dist/visualize/graph-canvas/renderer.d.ts +12 -0
- package/dist/visualize/graph-canvas/renderer.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/renderer.js +813 -0
- package/dist/visualize/graph-canvas/renderer.js.map +1 -0
- package/dist/visualize/graph-canvas/spatial-index.d.ts +13 -0
- package/dist/visualize/graph-canvas/spatial-index.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/spatial-index.js +482 -0
- package/dist/visualize/graph-canvas/spatial-index.js.map +1 -0
- package/dist/visualize/graph-canvas/styles.d.ts +11 -0
- package/dist/visualize/graph-canvas/styles.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/styles.js +152 -0
- package/dist/visualize/graph-canvas/styles.js.map +1 -0
- package/dist/visualize/graph-canvas/viewport.d.ts +17 -0
- package/dist/visualize/graph-canvas/viewport.d.ts.map +1 -0
- package/dist/visualize/graph-canvas/viewport.js +385 -0
- package/dist/visualize/graph-canvas/viewport.js.map +1 -0
- package/dist/visualize/server.js +737 -7
- package/dist/visualize/server.js.map +1 -1
- package/dist/visualize/template-core.d.ts +9 -0
- package/dist/visualize/template-core.d.ts.map +1 -0
- package/dist/visualize/template-core.js +714 -0
- package/dist/visualize/template-core.js.map +1 -0
- package/dist/visualize/template-data-loading.d.ts +7 -0
- package/dist/visualize/template-data-loading.d.ts.map +1 -0
- package/dist/visualize/template-data-loading.js +677 -0
- package/dist/visualize/template-data-loading.js.map +1 -0
- package/dist/visualize/template-detail-panel.d.ts +14 -0
- package/dist/visualize/template-detail-panel.d.ts.map +1 -0
- package/dist/visualize/template-detail-panel.js +553 -0
- package/dist/visualize/template-detail-panel.js.map +1 -0
- package/dist/visualize/template-graph-3d.d.ts +7 -0
- package/dist/visualize/template-graph-3d.d.ts.map +1 -0
- package/dist/visualize/template-graph-3d.js +1112 -0
- package/dist/visualize/template-graph-3d.js.map +1 -0
- package/dist/visualize/template-graph-vis.d.ts +8 -0
- package/dist/visualize/template-graph-vis.d.ts.map +1 -0
- package/dist/visualize/template-graph-vis.js +1204 -0
- package/dist/visualize/template-graph-vis.js.map +1 -0
- package/dist/visualize/template-html.d.ts +9 -0
- package/dist/visualize/template-html.d.ts.map +1 -0
- package/dist/visualize/template-html.js +484 -0
- package/dist/visualize/template-html.js.map +1 -0
- package/dist/visualize/template-pages.d.ts +7 -0
- package/dist/visualize/template-pages.d.ts.map +1 -0
- package/dist/visualize/template-pages.js +806 -0
- package/dist/visualize/template-pages.js.map +1 -0
- package/dist/visualize/template-stats-modal.d.ts +7 -0
- package/dist/visualize/template-stats-modal.d.ts.map +1 -0
- package/dist/visualize/template-stats-modal.js +406 -0
- package/dist/visualize/template-stats-modal.js.map +1 -0
- package/dist/visualize/template-styles.d.ts +9 -0
- package/dist/visualize/template-styles.d.ts.map +1 -0
- package/dist/visualize/template-styles.js +487 -0
- package/dist/visualize/template-styles.js.map +1 -0
- package/dist/visualize/template.d.ts +14 -3
- package/dist/visualize/template.d.ts.map +1 -1
- package/dist/visualize/template.js +38 -2889
- package/dist/visualize/template.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/renderer.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAEH,8CA8xBC;AA9xBD,SAAgB,iBAAiB;IAC/B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4xBR,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SpatialIndex — 内联 R-tree 空间索引 (无外部依赖)
|
|
3
|
+
*
|
|
4
|
+
* 轻量级 R-tree 实现,支持:
|
|
5
|
+
* - bulk insert (STR 批量构建)
|
|
6
|
+
* - viewport search (矩形范围查询)
|
|
7
|
+
* - point query (hit-test)
|
|
8
|
+
* - 动态 insert/remove/update
|
|
9
|
+
*
|
|
10
|
+
* 基于简化版 rbush 算法,优化为图谱节点场景。
|
|
11
|
+
*/
|
|
12
|
+
export declare function getSpatialIndexScript(): string;
|
|
13
|
+
//# sourceMappingURL=spatial-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spatial-index.d.ts","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/spatial-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,wBAAgB,qBAAqB,IAAI,MAAM,CAkd9C"}
|
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SpatialIndex — 内联 R-tree 空间索引 (无外部依赖)
|
|
4
|
+
*
|
|
5
|
+
* 轻量级 R-tree 实现,支持:
|
|
6
|
+
* - bulk insert (STR 批量构建)
|
|
7
|
+
* - viewport search (矩形范围查询)
|
|
8
|
+
* - point query (hit-test)
|
|
9
|
+
* - 动态 insert/remove/update
|
|
10
|
+
*
|
|
11
|
+
* 基于简化版 rbush 算法,优化为图谱节点场景。
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.getSpatialIndexScript = getSpatialIndexScript;
|
|
15
|
+
function getSpatialIndexScript() {
|
|
16
|
+
return `
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// SpatialIndex — Lightweight R-tree for viewport culling & hit-test
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Minimal R-tree implementation optimized for graph nodes.
|
|
23
|
+
* Supports bulk load, search, point query, insert, remove.
|
|
24
|
+
*/
|
|
25
|
+
function SpatialIndex() {
|
|
26
|
+
this._maxEntries = 16; // max children per node
|
|
27
|
+
this._minEntries = 4; // min children per node (for split)
|
|
28
|
+
this._root = this._createNode([]);
|
|
29
|
+
this._nodeIdToItem = {}; // nodeId → leaf item (for O(1) remove/update)
|
|
30
|
+
|
|
31
|
+
// Edge spatial index — separate R-tree for edges
|
|
32
|
+
this._edgeRoot = this._createNode([]);
|
|
33
|
+
this._edgeIdToItem = {}; // edgeId → leaf item
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ── Node structure ────────────────────────────────────────────────────────
|
|
37
|
+
SpatialIndex.prototype._createNode = function(children) {
|
|
38
|
+
return {
|
|
39
|
+
children: children,
|
|
40
|
+
height: 1, // 1 = leaf
|
|
41
|
+
leaf: true,
|
|
42
|
+
minX: Infinity,
|
|
43
|
+
minY: Infinity,
|
|
44
|
+
maxX: -Infinity,
|
|
45
|
+
maxY: -Infinity,
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// ── Build from nodes (bulk load) ──────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Build the R-tree from all graph nodes.
|
|
53
|
+
* Uses Sort-Tile-Recursive (STR) bulk loading for optimal tree structure.
|
|
54
|
+
* @param {Array} nodes — [{id, x, y, _radius, ...}, ...]
|
|
55
|
+
*/
|
|
56
|
+
SpatialIndex.prototype.buildFromNodes = function(nodes) {
|
|
57
|
+
this._nodeIdToItem = {};
|
|
58
|
+
if (!nodes || nodes.length === 0) {
|
|
59
|
+
this._root = this._createNode([]);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Create leaf items with AABB
|
|
64
|
+
var items = [];
|
|
65
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
66
|
+
var n = nodes[i];
|
|
67
|
+
var r = n._radius || 10;
|
|
68
|
+
var item = {
|
|
69
|
+
minX: n.x - r,
|
|
70
|
+
minY: n.y - r,
|
|
71
|
+
maxX: n.x + r,
|
|
72
|
+
maxY: n.y + r,
|
|
73
|
+
_nodeId: n.id,
|
|
74
|
+
_node: n,
|
|
75
|
+
};
|
|
76
|
+
n._aabb = item; // back-reference
|
|
77
|
+
items.push(item);
|
|
78
|
+
this._nodeIdToItem[n.id] = item;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Build tree using STR bulk loading
|
|
82
|
+
this._root = this._buildSTR(items, 0, items.length - 1, 0);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
SpatialIndex.prototype._buildSTR = function(items, left, right, level) {
|
|
86
|
+
var N = right - left + 1;
|
|
87
|
+
var M = this._maxEntries;
|
|
88
|
+
|
|
89
|
+
if (N <= M) {
|
|
90
|
+
// Fits in one leaf node
|
|
91
|
+
var node = this._createNode(items.slice(left, right + 1));
|
|
92
|
+
this._calcBBox(node);
|
|
93
|
+
return node;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Sort by X, then divide into vertical slices
|
|
97
|
+
if (level % 2 === 0) {
|
|
98
|
+
items.sort(function(a, b) { return a.minX - b.minX; });
|
|
99
|
+
} else {
|
|
100
|
+
items.sort(function(a, b) { return a.minY - b.minY; });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
var S = Math.ceil(N / M);
|
|
104
|
+
var children = [];
|
|
105
|
+
|
|
106
|
+
for (var i = left; i <= right; i += S) {
|
|
107
|
+
var end = Math.min(i + S - 1, right);
|
|
108
|
+
if (end - i + 1 <= M) {
|
|
109
|
+
var child = this._createNode(items.slice(i, end + 1));
|
|
110
|
+
this._calcBBox(child);
|
|
111
|
+
children.push(child);
|
|
112
|
+
} else {
|
|
113
|
+
children.push(this._buildSTR(items, i, end, level + 1));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
var node = this._createNode(children);
|
|
118
|
+
node.leaf = false;
|
|
119
|
+
node.height = children[0].height + 1;
|
|
120
|
+
this._calcBBox(node);
|
|
121
|
+
return node;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
SpatialIndex.prototype._calcBBox = function(node) {
|
|
125
|
+
var children = node.children;
|
|
126
|
+
node.minX = Infinity;
|
|
127
|
+
node.minY = Infinity;
|
|
128
|
+
node.maxX = -Infinity;
|
|
129
|
+
node.maxY = -Infinity;
|
|
130
|
+
for (var i = 0; i < children.length; i++) {
|
|
131
|
+
var c = children[i];
|
|
132
|
+
if (c.minX < node.minX) node.minX = c.minX;
|
|
133
|
+
if (c.minY < node.minY) node.minY = c.minY;
|
|
134
|
+
if (c.maxX > node.maxX) node.maxX = c.maxX;
|
|
135
|
+
if (c.maxY > node.maxY) node.maxY = c.maxY;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// ── Search (viewport query) ──────────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Find all items intersecting the given AABB.
|
|
143
|
+
* @param {{minX, minY, maxX, maxY}} bbox
|
|
144
|
+
* @returns {Array} array of items with _nodeId and _node references
|
|
145
|
+
*/
|
|
146
|
+
SpatialIndex.prototype.search = function(bbox) {
|
|
147
|
+
var result = [];
|
|
148
|
+
this._searchNode(this._root, bbox, result);
|
|
149
|
+
return result;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
SpatialIndex.prototype._searchNode = function(node, bbox, result) {
|
|
153
|
+
if (!this._intersects(node, bbox)) return;
|
|
154
|
+
|
|
155
|
+
var children = node.children;
|
|
156
|
+
if (node.leaf) {
|
|
157
|
+
for (var i = 0; i < children.length; i++) {
|
|
158
|
+
if (this._intersects(children[i], bbox)) {
|
|
159
|
+
result.push(children[i]);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
for (var i = 0; i < children.length; i++) {
|
|
164
|
+
this._searchNode(children[i], bbox, result);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
SpatialIndex.prototype._intersects = function(a, b) {
|
|
170
|
+
return a.minX <= b.maxX && a.maxX >= b.minX &&
|
|
171
|
+
a.minY <= b.maxY && a.maxY >= b.minY;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// ── Point Query (hit-test) ───────────────────────────────────────────────
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Find all items containing the given point.
|
|
178
|
+
* @param {number} x - World X
|
|
179
|
+
* @param {number} y - World Y
|
|
180
|
+
* @returns {Array} items at this point
|
|
181
|
+
*/
|
|
182
|
+
SpatialIndex.prototype.pointQuery = function(x, y) {
|
|
183
|
+
var point = { minX: x, minY: y, maxX: x, maxY: y };
|
|
184
|
+
return this.search(point);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// ── Dynamic updates ──────────────────────────────────────────────────────
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Update a node's position in the spatial index.
|
|
191
|
+
* @param {Object} node — graph node with .id, .x, .y, ._radius
|
|
192
|
+
*/
|
|
193
|
+
SpatialIndex.prototype.updateNode = function(node) {
|
|
194
|
+
var item = this._nodeIdToItem[node.id];
|
|
195
|
+
if (!item) return;
|
|
196
|
+
var r = node._radius || 10;
|
|
197
|
+
item.minX = node.x - r;
|
|
198
|
+
item.minY = node.y - r;
|
|
199
|
+
item.maxX = node.x + r;
|
|
200
|
+
item.maxY = node.y + r;
|
|
201
|
+
node._aabb = item;
|
|
202
|
+
// Note: for optimal performance with frequent updates (e.g., during layout),
|
|
203
|
+
// we defer tree rebalancing. The tree stays valid but suboptimal.
|
|
204
|
+
// Call rebuildFromNodes() when layout stabilizes.
|
|
205
|
+
this._markAncestorsDirty();
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
SpatialIndex.prototype._markAncestorsDirty = function() {
|
|
209
|
+
// Simple approach: recalculate root bbox (propagation optimization deferred)
|
|
210
|
+
this._calcBBoxRecursive(this._root);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
SpatialIndex.prototype._calcBBoxRecursive = function(node) {
|
|
214
|
+
if (node.leaf) {
|
|
215
|
+
this._calcBBox(node);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
for (var i = 0; i < node.children.length; i++) {
|
|
219
|
+
this._calcBBoxRecursive(node.children[i]);
|
|
220
|
+
}
|
|
221
|
+
this._calcBBox(node);
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Remove a node from the spatial index.
|
|
226
|
+
*/
|
|
227
|
+
SpatialIndex.prototype.removeNode = function(nodeId) {
|
|
228
|
+
var item = this._nodeIdToItem[nodeId];
|
|
229
|
+
if (!item) return;
|
|
230
|
+
this._removeItem(this._root, item);
|
|
231
|
+
delete this._nodeIdToItem[nodeId];
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
SpatialIndex.prototype._removeItem = function(node, item) {
|
|
235
|
+
if (node.leaf) {
|
|
236
|
+
var idx = node.children.indexOf(item);
|
|
237
|
+
if (idx >= 0) {
|
|
238
|
+
node.children.splice(idx, 1);
|
|
239
|
+
this._calcBBox(node);
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
for (var i = 0; i < node.children.length; i++) {
|
|
245
|
+
if (this._intersects(node.children[i], item)) {
|
|
246
|
+
if (this._removeItem(node.children[i], item)) {
|
|
247
|
+
if (node.children[i].children.length === 0) {
|
|
248
|
+
node.children.splice(i, 1);
|
|
249
|
+
}
|
|
250
|
+
this._calcBBox(node);
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return false;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Rebuild the tree (call after many updates/removes for optimal performance).
|
|
260
|
+
*/
|
|
261
|
+
SpatialIndex.prototype.rebuild = function(nodes) {
|
|
262
|
+
this.buildFromNodes(nodes);
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Get the total number of items in the index.
|
|
267
|
+
*/
|
|
268
|
+
SpatialIndex.prototype.size = function() {
|
|
269
|
+
return Object.keys(this._nodeIdToItem).length;
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// ============================================================================
|
|
273
|
+
// Edge Spatial Index — R-tree for edges (AABB = bounding box of from→to)
|
|
274
|
+
// ============================================================================
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Build the edge R-tree from all edges.
|
|
278
|
+
* Edge AABB = bounding box of (fromNode, toNode) positions.
|
|
279
|
+
* @param {Array} edges — [{id, from, to, ...}, ...]
|
|
280
|
+
* @param {Object} nodeMap — { nodeId → node }
|
|
281
|
+
*/
|
|
282
|
+
SpatialIndex.prototype.buildEdgeIndex = function(edges, nodeMap) {
|
|
283
|
+
this._edgeIdToItem = {};
|
|
284
|
+
if (!edges || edges.length === 0) {
|
|
285
|
+
this._edgeRoot = this._createNode([]);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
var items = [];
|
|
290
|
+
for (var i = 0; i < edges.length; i++) {
|
|
291
|
+
var e = edges[i];
|
|
292
|
+
var fromNode = nodeMap[e.from];
|
|
293
|
+
var toNode = nodeMap[e.to];
|
|
294
|
+
if (!fromNode || !toNode) continue;
|
|
295
|
+
|
|
296
|
+
var item = this._calcEdgeAABB(e, fromNode, toNode);
|
|
297
|
+
items.push(item);
|
|
298
|
+
this._edgeIdToItem[e.id] = item;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (items.length === 0) {
|
|
302
|
+
this._edgeRoot = this._createNode([]);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
this._edgeRoot = this._buildSTR(items, 0, items.length - 1, 0);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Calculate AABB for an edge based on its endpoint node positions.
|
|
311
|
+
*/
|
|
312
|
+
SpatialIndex.prototype._calcEdgeAABB = function(edge, fromNode, toNode) {
|
|
313
|
+
var pad = 2; // small padding for line width
|
|
314
|
+
var minX = Math.min(fromNode.x, toNode.x) - pad;
|
|
315
|
+
var minY = Math.min(fromNode.y, toNode.y) - pad;
|
|
316
|
+
var maxX = Math.max(fromNode.x, toNode.x) + pad;
|
|
317
|
+
var maxY = Math.max(fromNode.y, toNode.y) + pad;
|
|
318
|
+
return {
|
|
319
|
+
minX: minX,
|
|
320
|
+
minY: minY,
|
|
321
|
+
maxX: maxX,
|
|
322
|
+
maxY: maxY,
|
|
323
|
+
_edgeId: edge.id,
|
|
324
|
+
_edge: edge,
|
|
325
|
+
};
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Search for edges whose AABB intersects the given bounding box.
|
|
330
|
+
* @param {{minX, minY, maxX, maxY}} bbox
|
|
331
|
+
* @returns {Array} items with _edgeId and _edge references
|
|
332
|
+
*/
|
|
333
|
+
SpatialIndex.prototype.searchEdges = function(bbox) {
|
|
334
|
+
var result = [];
|
|
335
|
+
this._searchNode(this._edgeRoot, bbox, result);
|
|
336
|
+
return result;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Update edge AABBs when a node moves.
|
|
341
|
+
* @param {string} nodeId — the node that moved
|
|
342
|
+
* @param {Object} nodeEdges — { nodeId → [edge, ...] } adjacency list
|
|
343
|
+
* @param {Object} nodeMap — { nodeId → node }
|
|
344
|
+
*/
|
|
345
|
+
SpatialIndex.prototype.updateEdgesForNode = function(nodeId, nodeEdges, nodeMap) {
|
|
346
|
+
var edges = nodeEdges[nodeId] || [];
|
|
347
|
+
for (var i = 0; i < edges.length; i++) {
|
|
348
|
+
var e = edges[i];
|
|
349
|
+
var item = this._edgeIdToItem[e.id];
|
|
350
|
+
if (!item) continue;
|
|
351
|
+
var fromNode = nodeMap[e.from];
|
|
352
|
+
var toNode = nodeMap[e.to];
|
|
353
|
+
if (!fromNode || !toNode) continue;
|
|
354
|
+
var pad = 2;
|
|
355
|
+
item.minX = Math.min(fromNode.x, toNode.x) - pad;
|
|
356
|
+
item.minY = Math.min(fromNode.y, toNode.y) - pad;
|
|
357
|
+
item.maxX = Math.max(fromNode.x, toNode.x) + pad;
|
|
358
|
+
item.maxY = Math.max(fromNode.y, toNode.y) + pad;
|
|
359
|
+
}
|
|
360
|
+
// Propagate changes up (simple approach)
|
|
361
|
+
this._calcBBoxRecursive(this._edgeRoot);
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Get the number of edges in the edge index.
|
|
366
|
+
*/
|
|
367
|
+
SpatialIndex.prototype.edgeSize = function() {
|
|
368
|
+
return Object.keys(this._edgeIdToItem).length;
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
// ============================================================================
|
|
372
|
+
// Incremental Insert (Phase-8C) — add single items without full rebuild
|
|
373
|
+
// ============================================================================
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Insert a single node into the R-tree incrementally.
|
|
377
|
+
* Uses simple insertion into the best-fit leaf.
|
|
378
|
+
* @param {Object} node — graph node with .id, .x, .y, ._radius
|
|
379
|
+
*/
|
|
380
|
+
SpatialIndex.prototype.insertNode = function(node) {
|
|
381
|
+
var r = node._radius || 10;
|
|
382
|
+
var item = {
|
|
383
|
+
minX: node.x - r,
|
|
384
|
+
minY: node.y - r,
|
|
385
|
+
maxX: node.x + r,
|
|
386
|
+
maxY: node.y + r,
|
|
387
|
+
_nodeId: node.id,
|
|
388
|
+
_node: node,
|
|
389
|
+
};
|
|
390
|
+
node._aabb = item;
|
|
391
|
+
this._nodeIdToItem[node.id] = item;
|
|
392
|
+
this._insertItem(this._root, item);
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Insert a single edge into the edge R-tree incrementally.
|
|
397
|
+
* @param {Object} edge — graph edge
|
|
398
|
+
* @param {Object} fromNode — source node
|
|
399
|
+
* @param {Object} toNode — target node
|
|
400
|
+
*/
|
|
401
|
+
SpatialIndex.prototype.insertEdge = function(edge, fromNode, toNode) {
|
|
402
|
+
var item = this._calcEdgeAABB(edge, fromNode, toNode);
|
|
403
|
+
this._edgeIdToItem[edge.id] = item;
|
|
404
|
+
this._insertItem(this._edgeRoot, item);
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Insert an item into an R-tree node (simple greedy insert).
|
|
409
|
+
* Finds the leaf with minimum area enlargement and adds the item.
|
|
410
|
+
*/
|
|
411
|
+
SpatialIndex.prototype._insertItem = function(root, item) {
|
|
412
|
+
var node = root;
|
|
413
|
+
|
|
414
|
+
// Traverse to find best leaf
|
|
415
|
+
while (!node.leaf) {
|
|
416
|
+
var bestChild = null;
|
|
417
|
+
var bestEnlargement = Infinity;
|
|
418
|
+
var bestArea = Infinity;
|
|
419
|
+
|
|
420
|
+
for (var i = 0; i < node.children.length; i++) {
|
|
421
|
+
var child = node.children[i];
|
|
422
|
+
var area = this._area(child);
|
|
423
|
+
var enlargement = this._enlargedArea(child, item) - area;
|
|
424
|
+
|
|
425
|
+
if (enlargement < bestEnlargement || (enlargement === bestEnlargement && area < bestArea)) {
|
|
426
|
+
bestEnlargement = enlargement;
|
|
427
|
+
bestArea = area;
|
|
428
|
+
bestChild = child;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
node = bestChild;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Add to leaf
|
|
435
|
+
node.children.push(item);
|
|
436
|
+
|
|
437
|
+
// Split if needed
|
|
438
|
+
if (node.children.length > this._maxEntries) {
|
|
439
|
+
this._splitNode(node);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Update bounding boxes up the tree
|
|
443
|
+
this._calcBBoxRecursive(root);
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
SpatialIndex.prototype._area = function(node) {
|
|
447
|
+
return (node.maxX - node.minX) * (node.maxY - node.minY);
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
SpatialIndex.prototype._enlargedArea = function(node, item) {
|
|
451
|
+
var minX = Math.min(node.minX, item.minX);
|
|
452
|
+
var minY = Math.min(node.minY, item.minY);
|
|
453
|
+
var maxX = Math.max(node.maxX, item.maxX);
|
|
454
|
+
var maxY = Math.max(node.maxY, item.maxY);
|
|
455
|
+
return (maxX - minX) * (maxY - minY);
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Split an overfull leaf into two halves (simple median split).
|
|
460
|
+
*/
|
|
461
|
+
SpatialIndex.prototype._splitNode = function(node) {
|
|
462
|
+
var items = node.children;
|
|
463
|
+
// Sort by center X
|
|
464
|
+
items.sort(function(a, b) {
|
|
465
|
+
return (a.minX + a.maxX) - (b.minX + b.maxX);
|
|
466
|
+
});
|
|
467
|
+
var mid = Math.ceil(items.length / 2);
|
|
468
|
+
node.children = items.slice(0, mid);
|
|
469
|
+
this._calcBBox(node);
|
|
470
|
+
// The remaining items need to go into a sibling —
|
|
471
|
+
// for simplicity, just keep them in the same node but in a new child
|
|
472
|
+
// This is a simplified split; full R-tree split would restructure parent
|
|
473
|
+
// For incremental adds, this is sufficient; periodic rebuild() restores optimal structure
|
|
474
|
+
var overflow = items.slice(mid);
|
|
475
|
+
for (var i = 0; i < overflow.length; i++) {
|
|
476
|
+
node.children.push(overflow[i]);
|
|
477
|
+
}
|
|
478
|
+
this._calcBBox(node);
|
|
479
|
+
};
|
|
480
|
+
`;
|
|
481
|
+
}
|
|
482
|
+
//# sourceMappingURL=spatial-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spatial-index.js","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/spatial-index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAEH,sDAkdC;AAldD,SAAgB,qBAAqB;IACnC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgdR,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StyleManager — DevPlan 节点/边样式系统
|
|
3
|
+
*
|
|
4
|
+
* 迁移自 vis-network 的样式规则:
|
|
5
|
+
* - 5 种节点类型样式 (project/module/main-task/sub-task/document)
|
|
6
|
+
* - 4 种状态颜色 (completed/in_progress/pending/cancelled)
|
|
7
|
+
* - 动态大小规则 (基于度数 sqrt 曲线)
|
|
8
|
+
* - 6 种边类型样式
|
|
9
|
+
*/
|
|
10
|
+
export declare function getStylesScript(): string;
|
|
11
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wBAAgB,eAAe,IAAI,MAAM,CA0IxC"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* StyleManager — DevPlan 节点/边样式系统
|
|
4
|
+
*
|
|
5
|
+
* 迁移自 vis-network 的样式规则:
|
|
6
|
+
* - 5 种节点类型样式 (project/module/main-task/sub-task/document)
|
|
7
|
+
* - 4 种状态颜色 (completed/in_progress/pending/cancelled)
|
|
8
|
+
* - 动态大小规则 (基于度数 sqrt 曲线)
|
|
9
|
+
* - 6 种边类型样式
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getStylesScript = getStylesScript;
|
|
13
|
+
function getStylesScript() {
|
|
14
|
+
return `
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// StyleManager — Node & Edge Styles
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
function StyleManager() {
|
|
20
|
+
// 从统一配置加载颜色 (如果 getUnifiedNodeStyle 可用)
|
|
21
|
+
var _uni = (typeof getUnifiedNodeStyle === 'function') ? getUnifiedNodeStyle() : null;
|
|
22
|
+
|
|
23
|
+
// Status colors
|
|
24
|
+
this.STATUS_COLORS = _uni ? _uni.statusGeneric : {
|
|
25
|
+
completed: { bg: '#059669', border: '#047857', font: '#d1fae5' },
|
|
26
|
+
in_progress: { bg: '#7c3aed', border: '#6d28d9', font: '#ddd6fe' },
|
|
27
|
+
pending: { bg: '#4b5563', border: '#374151', font: '#d1d5db' },
|
|
28
|
+
cancelled: { bg: '#92400e', border: '#78350f', font: '#fde68a' },
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// 统一样式缓存 (供 getNodeStyle 使用)
|
|
32
|
+
this._uniStyle = _uni;
|
|
33
|
+
|
|
34
|
+
// Node sizing rules by type
|
|
35
|
+
this.NODE_SIZE_RULES = {
|
|
36
|
+
'project': { min: 35, max: 65, baseFont: 16, maxFont: 22, scale: 3.5 },
|
|
37
|
+
'module': { min: 20, max: 45, baseFont: 12, maxFont: 16, scale: 2.8 },
|
|
38
|
+
'main-task': { min: 14, max: 38, baseFont: 11, maxFont: 15, scale: 2.2 },
|
|
39
|
+
'sub-task': { min: 7, max: 18, baseFont: 8, maxFont: 11, scale: 1.5 },
|
|
40
|
+
'document': { min: 12, max: 30, baseFont: 9, maxFont: 13, scale: 1.8 },
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Node type shapes
|
|
44
|
+
this.NODE_SHAPES = {
|
|
45
|
+
'project': 'star',
|
|
46
|
+
'module': 'diamond',
|
|
47
|
+
'main-task': 'circle',
|
|
48
|
+
'sub-task': 'circle',
|
|
49
|
+
'document': 'box',
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Node type colors (for non-status-based types) — 从统一配置读取
|
|
53
|
+
this.NODE_COLORS = _uni ? {
|
|
54
|
+
'project': _uni.project,
|
|
55
|
+
'module': _uni.module,
|
|
56
|
+
'document': _uni.document,
|
|
57
|
+
} : {
|
|
58
|
+
'project': { bg: '#f59e0b', border: '#d97706', font: '#fff' },
|
|
59
|
+
'module': { bg: '#ff6600', border: '#cc5200', font: '#fff3e0' },
|
|
60
|
+
'document': { bg: '#2563eb', border: '#1d4ed8', font: '#dbeafe' },
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Edge styles by label
|
|
64
|
+
this.EDGE_STYLES = {
|
|
65
|
+
'has_main_task': { width: 2, color: '#4b5563', highlightColor: '#93c5fd', dashes: null, arrows: true },
|
|
66
|
+
'has_sub_task': { width: 1, color: '#4b5563', highlightColor: '#818cf8', dashes: null, arrows: true },
|
|
67
|
+
'has_document': { width: 1, color: '#4b5563', highlightColor: '#60a5fa', dashes: [5, 5], arrows: true },
|
|
68
|
+
'module_has_task':{ width: 1.5, color: '#4b5563', highlightColor: '#ff8533', dashes: [2, 4], arrows: true },
|
|
69
|
+
'task_has_doc': { width: 1.5, color: '#4b5563', highlightColor: '#f59e0b', dashes: [4, 3], arrows: true },
|
|
70
|
+
'doc_has_child': { width: 1.5, color: '#4b5563', highlightColor: '#c084fc', dashes: [6, 3], arrows: true },
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
this.EDGE_DEFAULT = { width: 1, color: '#4b5563', highlightColor: '#9ca3af', dashes: null, arrows: false };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Compute node size and font size based on type and degree.
|
|
78
|
+
*/
|
|
79
|
+
StyleManager.prototype._calcNodeSize = function(type, degree) {
|
|
80
|
+
var rule = this.NODE_SIZE_RULES[type] || { min: 10, max: 22, baseFont: 10, maxFont: 13, scale: 1.0 };
|
|
81
|
+
var size = rule.min + rule.scale * Math.sqrt(degree || 0);
|
|
82
|
+
size = Math.max(rule.min, Math.min(size, rule.max));
|
|
83
|
+
var sizeRatio = (size - rule.min) / (rule.max - rule.min || 1);
|
|
84
|
+
var fontSize = Math.round(rule.baseFont + sizeRatio * (rule.maxFont - rule.baseFont));
|
|
85
|
+
return { size: Math.round(size), fontSize: fontSize };
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get style for a node.
|
|
90
|
+
* @param {Object} node
|
|
91
|
+
* @returns {Object} { shape, radius, bgColor, borderColor, borderWidth, fontColor, fontSize }
|
|
92
|
+
*/
|
|
93
|
+
StyleManager.prototype.getNodeStyle = function(node) {
|
|
94
|
+
var type = node.type || 'default';
|
|
95
|
+
var props = node.properties || {};
|
|
96
|
+
var status = props.status || 'pending';
|
|
97
|
+
var degree = node.degree || 0;
|
|
98
|
+
|
|
99
|
+
var ns = this._calcNodeSize(type, degree);
|
|
100
|
+
var shape = this.NODE_SHAPES[type] || 'circle';
|
|
101
|
+
|
|
102
|
+
// Determine colors — 从统一配置读取
|
|
103
|
+
var colors;
|
|
104
|
+
if (type === 'project' || type === 'module' || type === 'document') {
|
|
105
|
+
colors = this.NODE_COLORS[type] || this.STATUS_COLORS.pending;
|
|
106
|
+
} else if (type === 'main-task') {
|
|
107
|
+
// 主任务: 从统一配置读取状态颜色
|
|
108
|
+
var _mt = this._uniStyle ? this._uniStyle.mainTask : null;
|
|
109
|
+
colors = (_mt && _mt[status]) || (_mt && _mt.pending) || this.STATUS_COLORS[status] || this.STATUS_COLORS.pending;
|
|
110
|
+
} else {
|
|
111
|
+
// 子任务: 从统一配置读取状态颜色 (completed=亮绿色)
|
|
112
|
+
var _st = this._uniStyle ? this._uniStyle.subTask : null;
|
|
113
|
+
colors = (_st && _st[status]) || (_st && _st.pending) || this.STATUS_COLORS[status] || this.STATUS_COLORS.pending;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
shape: shape,
|
|
118
|
+
radius: ns.size,
|
|
119
|
+
bgColor: colors.bg,
|
|
120
|
+
borderColor: colors.border,
|
|
121
|
+
borderWidth: type === 'project' ? 3 : (type === 'sub-task' ? 1 : 2),
|
|
122
|
+
fontColor: colors.font,
|
|
123
|
+
fontSize: ns.fontSize,
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get style for an edge.
|
|
129
|
+
* @param {Object} edge
|
|
130
|
+
* @returns {Object} { width, color, highlightColor, dashes, arrows }
|
|
131
|
+
*/
|
|
132
|
+
StyleManager.prototype.getEdgeStyle = function(edge) {
|
|
133
|
+
var label = edge.label || edge._label || '';
|
|
134
|
+
return this.EDGE_STYLES[label] || this.EDGE_DEFAULT;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Apply styles to all nodes and edges (batch).
|
|
139
|
+
*/
|
|
140
|
+
StyleManager.prototype.applyAllStyles = function(nodes, edges) {
|
|
141
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
142
|
+
var style = this.getNodeStyle(nodes[i]);
|
|
143
|
+
nodes[i]._style = style;
|
|
144
|
+
nodes[i]._radius = style.radius;
|
|
145
|
+
}
|
|
146
|
+
for (var i = 0; i < edges.length; i++) {
|
|
147
|
+
edges[i]._style = this.getEdgeStyle(edges[i]);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
`;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/styles.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAEH,0CA0IC;AA1ID,SAAgB,eAAe;IAC7B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwIR,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ViewportManager — 平移/缩放/手势 + 世界↔屏幕坐标变换
|
|
3
|
+
*
|
|
4
|
+
* 管理 2D 视口变换矩阵:
|
|
5
|
+
* screenX = worldX * scale + offsetX
|
|
6
|
+
* screenY = worldY * scale + offsetY
|
|
7
|
+
*
|
|
8
|
+
* 支持:
|
|
9
|
+
* - 鼠标拖拽平移
|
|
10
|
+
* - 滚轮缩放 (以鼠标位置为中心)
|
|
11
|
+
* - 触摸双指缩放
|
|
12
|
+
* - fit() 自适应视口
|
|
13
|
+
* - zoomTo() 定位到特定坐标
|
|
14
|
+
* - 惯性平移 (inertia)
|
|
15
|
+
*/
|
|
16
|
+
export declare function getViewportScript(): string;
|
|
17
|
+
//# sourceMappingURL=viewport.d.ts.map
|