@andespindola/brainlink 0.1.0-beta.105 → 0.1.0-beta.107
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 +1 -1
- package/dist/application/frontend/client-js.js +92 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -604,7 +604,7 @@ The graph UI shows:
|
|
|
604
604
|
- WebGL node and edge acceleration when supported, falling back to Canvas 2D without changing graph behavior
|
|
605
605
|
- compact macro-to-micro density progression so reset keeps the graph mass oriented and zoom-in separates local neighborhoods progressively
|
|
606
606
|
- graph camera treats hub-centered navigation as structural only when the hub is dominant; diffuse stress graphs reset and zoom around the full graph mass
|
|
607
|
-
- graph LOD progression: hierarchical rendering now follows one recursive graph-of-graphs standard whenever a graph has more than one hierarchy level; each level expands through intermediate subgraph sizes (instead of jumping directly to leaves), starts from a memory-hub-centered mesh, and each supernode can expand into another same-shape subgraph level (up to 999 children) with latent fade-in, aggregated real links and local sibling mesh links so org-heavy-like and stress-50k-like structures share the same layered behavior at different depths; for massive graphs the first expansion starts deeper in zoom and is additionally gated by focus readiness (screen-space isolation of the focused parent) so child levels open only when that subgraph is truly centered and separated in view
|
|
607
|
+
- graph LOD progression: hierarchical rendering now follows one recursive graph-of-graphs standard whenever a graph has more than one hierarchy level; each level expands through intermediate subgraph sizes (instead of jumping directly to leaves), starts from a memory-hub-centered mesh, and each supernode can expand into another same-shape subgraph level (up to 999 children) with latent fade-in, aggregated real links and local sibling mesh links so org-heavy-like and stress-50k-like structures share the same layered behavior at different depths; layered clusters also receive stronger perspective depth projection (Z-depth) with vertical camera tilt/parallax so expansion reads as a true depth field instead of a flat 2D switch; for massive graphs the first expansion starts deeper in zoom and is additionally gated by focus readiness (screen-space isolation of the focused parent) so child levels open only when that subgraph is truly centered and separated in view
|
|
608
608
|
|
|
609
609
|
The server indexes before starting by default. Use `--no-index` to skip that step:
|
|
610
610
|
|
|
@@ -31,6 +31,12 @@ const massiveEcosystemClusterScaleThreshold = 4.2
|
|
|
31
31
|
const ecosystemSubgraphScaleThreshold = 0.18
|
|
32
32
|
const ecosystemMicroScaleThreshold = 0.08
|
|
33
33
|
const ecosystemFocusedParentLimit = 2
|
|
34
|
+
const ecosystemDepthNear = 80
|
|
35
|
+
const ecosystemDepthFar = 2600
|
|
36
|
+
const ecosystemDepthPerspective = 620
|
|
37
|
+
const ecosystemDepthTiltY = 0.24
|
|
38
|
+
const ecosystemDepthMinScale = 0.24
|
|
39
|
+
const ecosystemDepthOpacityFloor = 0.2
|
|
34
40
|
const zoomRecoveryGuardMs = 4200
|
|
35
41
|
const zoomCapTargetViewportShare = 0.72
|
|
36
42
|
const meshEdgeScaleThreshold = 0.09
|
|
@@ -1153,6 +1159,84 @@ const selectHierarchicalEcosystemClusters = viewport => {
|
|
|
1153
1159
|
return [...hubClusters, ...visibleClusters]
|
|
1154
1160
|
}
|
|
1155
1161
|
|
|
1162
|
+
const ecosystemLevelIndexBySize = () => {
|
|
1163
|
+
const indexBySize = new Map()
|
|
1164
|
+
for (let index = 0; index < state.ecosystemLevelSizes.length; index += 1) {
|
|
1165
|
+
indexBySize.set(state.ecosystemLevelSizes[index], index)
|
|
1166
|
+
}
|
|
1167
|
+
return indexBySize
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
const ecosystemDepthForCluster = (cluster, levelIndexMap) => {
|
|
1171
|
+
if (cluster.isHub) {
|
|
1172
|
+
return ecosystemDepthNear
|
|
1173
|
+
}
|
|
1174
|
+
const maxLevelIndex = Math.max(state.ecosystemLevelSizes.length - 1, 0)
|
|
1175
|
+
const levelIndex = levelIndexMap.get(cluster.size) ?? 0
|
|
1176
|
+
const reverseIndex = Math.max(0, maxLevelIndex - levelIndex)
|
|
1177
|
+
const normalized = maxLevelIndex === 0 ? 0 : reverseIndex / maxLevelIndex
|
|
1178
|
+
return ecosystemDepthNear + normalized * (ecosystemDepthFar - ecosystemDepthNear)
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
const projectEcosystemPoint = (x, y, depth, anchor) => {
|
|
1182
|
+
const safeDepth = Math.max(0, depth)
|
|
1183
|
+
const factor = ecosystemDepthPerspective / (ecosystemDepthPerspective + safeDepth)
|
|
1184
|
+
const verticalTilt = safeDepth * ecosystemDepthTiltY
|
|
1185
|
+
return {
|
|
1186
|
+
x: anchor.x + (x - anchor.x) * factor,
|
|
1187
|
+
y: anchor.y + (y - anchor.y) * factor - verticalTilt,
|
|
1188
|
+
factor
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
const applyEcosystemDepthProjection = (clusters, edges, anchor) => {
|
|
1193
|
+
const levelIndexMap = ecosystemLevelIndexBySize()
|
|
1194
|
+
const projectedClusters = []
|
|
1195
|
+
const clusterById = new Map()
|
|
1196
|
+
|
|
1197
|
+
for (let index = 0; index < clusters.length; index += 1) {
|
|
1198
|
+
const cluster = clusters[index]
|
|
1199
|
+
const depth = ecosystemDepthForCluster(cluster, levelIndexMap)
|
|
1200
|
+
const projected = projectEcosystemPoint(cluster.x, cluster.y, depth, anchor)
|
|
1201
|
+
const baseOpacity = Number.isFinite(cluster.lodOpacity) ? cluster.lodOpacity : 1
|
|
1202
|
+
const depthScale = ecosystemDepthMinScale + (1 - ecosystemDepthMinScale) * projected.factor
|
|
1203
|
+
const depthOpacity = Math.max(
|
|
1204
|
+
ecosystemDepthOpacityFloor,
|
|
1205
|
+
Math.min(1, depthScale * 1.08)
|
|
1206
|
+
)
|
|
1207
|
+
const projectedCluster = {
|
|
1208
|
+
...cluster,
|
|
1209
|
+
x: projected.x,
|
|
1210
|
+
y: projected.y,
|
|
1211
|
+
lodOpacity: baseOpacity * depthOpacity,
|
|
1212
|
+
depth,
|
|
1213
|
+
depthScale
|
|
1214
|
+
}
|
|
1215
|
+
projectedClusters.push(projectedCluster)
|
|
1216
|
+
clusterById.set(projectedCluster.id, projectedCluster)
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
const projectedEdges = edges
|
|
1220
|
+
.map((edge) => {
|
|
1221
|
+
const sourceCluster = clusterById.get(edge.sourceCluster.id)
|
|
1222
|
+
const targetCluster = clusterById.get(edge.targetCluster.id)
|
|
1223
|
+
if (!sourceCluster || !targetCluster) {
|
|
1224
|
+
return null
|
|
1225
|
+
}
|
|
1226
|
+
return {
|
|
1227
|
+
...edge,
|
|
1228
|
+
sourceCluster,
|
|
1229
|
+
targetCluster
|
|
1230
|
+
}
|
|
1231
|
+
})
|
|
1232
|
+
.filter(Boolean)
|
|
1233
|
+
|
|
1234
|
+
return {
|
|
1235
|
+
clusters: projectedClusters,
|
|
1236
|
+
edges: projectedEdges
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1156
1240
|
const ecosystemSiblingEdgesForClusters = (clusters, existingEdges) => {
|
|
1157
1241
|
const byParent = new Map()
|
|
1158
1242
|
for (let index = 0; index < clusters.length; index += 1) {
|
|
@@ -2851,7 +2935,9 @@ const clusterRadiusPx = cluster => {
|
|
|
2851
2935
|
const size = Math.max(1, Math.min(ecosystemLevelNodeCap, cluster.size || cluster.count || 1))
|
|
2852
2936
|
const sizeBias = 0.56 + Math.log10(size + 1) * 0.28
|
|
2853
2937
|
const densityBias = Math.log10((cluster.count || 1) + 1) * 0.12
|
|
2854
|
-
|
|
2938
|
+
const radius = Math.max(0.62, Math.min(2.4, sizeBias + densityBias))
|
|
2939
|
+
const depthScale = Number.isFinite(cluster.depthScale) ? cluster.depthScale : 1
|
|
2940
|
+
return Math.max(0.56, Math.min(3.2, radius * depthScale))
|
|
2855
2941
|
}
|
|
2856
2942
|
return Math.max(8, Math.min(28, 8 + Math.log2(cluster.count + 1) * 3))
|
|
2857
2943
|
}
|
|
@@ -3029,8 +3115,11 @@ const computeRenderVisibility = () => {
|
|
|
3029
3115
|
) {
|
|
3030
3116
|
const clusters = selectHierarchicalEcosystemClusters(viewport)
|
|
3031
3117
|
.sort((left, right) => right.count - left.count)
|
|
3032
|
-
|
|
3033
|
-
|
|
3118
|
+
const edges = ecosystemEdgesForClusters(clusters)
|
|
3119
|
+
const projectionAnchor = ecosystemFocusPoint()
|
|
3120
|
+
const projected = applyEcosystemDepthProjection(clusters, edges, projectionAnchor)
|
|
3121
|
+
state.renderClusters = projected.clusters
|
|
3122
|
+
state.renderClusterEdges = projected.edges
|
|
3034
3123
|
state.renderNodes = []
|
|
3035
3124
|
state.renderEdges = []
|
|
3036
3125
|
return
|
package/package.json
CHANGED