@andespindola/brainlink 0.1.0-beta.47 → 0.1.0-beta.48
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.
|
@@ -7,6 +7,8 @@ const renderNodeBudget = 900
|
|
|
7
7
|
const renderEdgeBudget = 2400
|
|
8
8
|
const clusterActivationNodeThreshold = 600
|
|
9
9
|
const clusterZoomThreshold = 0.18
|
|
10
|
+
const macroGalaxyZoomThreshold = 0.012
|
|
11
|
+
const massiveAutoFitMacroScale = 0.006
|
|
10
12
|
const clusterCellPixelSize = 64
|
|
11
13
|
const minNodePixelRadius = 2.3
|
|
12
14
|
const viewportPaddingPx = 280
|
|
@@ -45,6 +47,8 @@ const state = {
|
|
|
45
47
|
visibleNodeSpatial: { cellSize: 220, minX: 0, minY: 0, maxX: 0, maxY: 0, buckets: new Map() },
|
|
46
48
|
visibleEdgeByNode: new Map(),
|
|
47
49
|
overviewClusters: [],
|
|
50
|
+
macroCenter: { x: 0, y: 0 },
|
|
51
|
+
macroRepresentative: null,
|
|
48
52
|
filterWorker: null,
|
|
49
53
|
filterReady: false,
|
|
50
54
|
lastHoverHitAt: 0
|
|
@@ -245,6 +249,26 @@ const filteredNodes = () => {
|
|
|
245
249
|
return withPersistentHubNodes(localFilteredNodes(query))
|
|
246
250
|
}
|
|
247
251
|
|
|
252
|
+
const resolveMacroRepresentative = (nodes) => {
|
|
253
|
+
if (nodes.length === 0) {
|
|
254
|
+
return null
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
let best = nodes[0]
|
|
258
|
+
let bestDegree = state.nodeDegrees.get(best.id) ?? 0
|
|
259
|
+
|
|
260
|
+
for (let index = 1; index < nodes.length; index += 1) {
|
|
261
|
+
const node = nodes[index]
|
|
262
|
+
const degree = state.nodeDegrees.get(node.id) ?? 0
|
|
263
|
+
if (degree > bestDegree) {
|
|
264
|
+
best = node
|
|
265
|
+
bestDegree = degree
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return best
|
|
270
|
+
}
|
|
271
|
+
|
|
248
272
|
const recomputeVisibility = () => {
|
|
249
273
|
const nodes = filteredNodes()
|
|
250
274
|
const ids = new Set(nodes.map(node => node.id))
|
|
@@ -260,6 +284,14 @@ const recomputeVisibility = () => {
|
|
|
260
284
|
state.visibleNodeSpatial = createSpatialIndex(nodes)
|
|
261
285
|
state.visibleEdgeByNode = createVisibleEdgeLookup(limitedEdges)
|
|
262
286
|
state.overviewClusters = nodes.length > massiveGraphNodeThreshold ? buildOverviewClusters(nodes) : []
|
|
287
|
+
const bounds = graphBounds(nodes)
|
|
288
|
+
state.macroCenter = bounds
|
|
289
|
+
? {
|
|
290
|
+
x: (bounds.minX + bounds.maxX) / 2,
|
|
291
|
+
y: (bounds.minY + bounds.maxY) / 2
|
|
292
|
+
}
|
|
293
|
+
: { x: 0, y: 0 }
|
|
294
|
+
state.macroRepresentative = resolveMacroRepresentative(nodes)
|
|
263
295
|
markRenderDirty()
|
|
264
296
|
}
|
|
265
297
|
|
|
@@ -607,7 +639,10 @@ const fitView = (options = { useFiltered: true }) => {
|
|
|
607
639
|
const fitScale = Math.min(scaleX, scaleY)
|
|
608
640
|
const biasedScale = clampScale(fitScale * fitScaleBiasByNodeCount(nodes.length))
|
|
609
641
|
const scaleRange = autoFitScaleRangeByNodeCount(nodes.length)
|
|
610
|
-
const
|
|
642
|
+
const baselineScale = clampScale(Math.min(scaleRange.max, Math.max(scaleRange.min, biasedScale)))
|
|
643
|
+
const scale = nodes.length > massiveGraphNodeThreshold
|
|
644
|
+
? clampScale(Math.min(baselineScale, massiveAutoFitMacroScale))
|
|
645
|
+
: baselineScale
|
|
611
646
|
const centerX = (bounds.minX + bounds.maxX) / 2
|
|
612
647
|
const centerY = (bounds.minY + bounds.maxY) / 2
|
|
613
648
|
|
|
@@ -981,6 +1016,26 @@ const computeRenderVisibility = () => {
|
|
|
981
1016
|
if (state.visibleNodes.length > massiveGraphNodeThreshold) {
|
|
982
1017
|
const viewportNodes = viewportNodesFromSpatialIndex(viewport)
|
|
983
1018
|
const sourceNodes = viewportNodes.length > 0 ? viewportNodes : state.visibleNodes
|
|
1019
|
+
if (state.transform.scale <= macroGalaxyZoomThreshold) {
|
|
1020
|
+
const representative = state.macroRepresentative ?? sourceNodes[0] ?? null
|
|
1021
|
+
if (representative) {
|
|
1022
|
+
state.renderClusters = [
|
|
1023
|
+
{
|
|
1024
|
+
id: 'macro-galaxy',
|
|
1025
|
+
x: state.macroCenter.x,
|
|
1026
|
+
y: state.macroCenter.y,
|
|
1027
|
+
count: sourceNodes.length,
|
|
1028
|
+
representative
|
|
1029
|
+
}
|
|
1030
|
+
]
|
|
1031
|
+
state.renderNodes = [representative]
|
|
1032
|
+
} else {
|
|
1033
|
+
state.renderClusters = []
|
|
1034
|
+
state.renderNodes = []
|
|
1035
|
+
}
|
|
1036
|
+
state.renderEdges = []
|
|
1037
|
+
return
|
|
1038
|
+
}
|
|
984
1039
|
const sampleLimit = nodeBudgetForScale(state.transform.scale)
|
|
985
1040
|
const sampled = sourceNodes.length > sampleLimit
|
|
986
1041
|
? sampleVisibleNodes(Math.min(sampleLimit, renderNodeBudget), sourceNodes)
|
|
@@ -1167,19 +1222,22 @@ const render = now => {
|
|
|
1167
1222
|
if (state.renderClusters.length > 0) {
|
|
1168
1223
|
const safeScale = Math.max(state.transform.scale, 0.0001)
|
|
1169
1224
|
state.renderClusters.forEach(cluster => {
|
|
1170
|
-
const
|
|
1225
|
+
const isMacro = cluster.id === 'macro-galaxy'
|
|
1226
|
+
const radiusPx = isMacro
|
|
1227
|
+
? 10
|
|
1228
|
+
: Math.max(8, Math.min(28, 8 + Math.log2(cluster.count + 1) * 3))
|
|
1171
1229
|
const radius = radiusPx / safeScale
|
|
1172
|
-
const haloRadius = (radiusPx + 4) / safeScale
|
|
1230
|
+
const haloRadius = (radiusPx + (isMacro ? 8 : 4)) / safeScale
|
|
1173
1231
|
ctx.beginPath()
|
|
1174
1232
|
ctx.arc(cluster.x, cluster.y, haloRadius, 0, Math.PI * 2)
|
|
1175
|
-
ctx.fillStyle = graphTheme.nodeHalo
|
|
1233
|
+
ctx.fillStyle = isMacro ? 'rgba(243, 247, 251, 0.28)' : graphTheme.nodeHalo
|
|
1176
1234
|
ctx.fill()
|
|
1177
1235
|
ctx.beginPath()
|
|
1178
1236
|
ctx.arc(cluster.x, cluster.y, radius, 0, Math.PI * 2)
|
|
1179
|
-
ctx.fillStyle = graphTheme.node
|
|
1237
|
+
ctx.fillStyle = isMacro ? '#f3f7fb' : graphTheme.node
|
|
1180
1238
|
ctx.fill()
|
|
1181
1239
|
ctx.lineWidth = 1.4 / safeScale
|
|
1182
|
-
ctx.strokeStyle = graphTheme.nodeStroke
|
|
1240
|
+
ctx.strokeStyle = isMacro ? '#ffffff' : graphTheme.nodeStroke
|
|
1183
1241
|
ctx.stroke()
|
|
1184
1242
|
// Keep cluster markers minimal and faster to draw on large graphs.
|
|
1185
1243
|
})
|
package/package.json
CHANGED