@yggy-tech/graphraum 0.34.0 → 0.35.0
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 +11 -16
- package/dist/index.d.ts +11 -2
- package/dist/index.js +77 -45
- package/package.json +54 -55
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<picture>
|
|
3
3
|
<source media="(prefers-color-scheme: dark)" srcset="./docs/src/assets/logo-dark.svg">
|
|
4
|
-
<img src="./docs/src/assets/logo-light.svg" alt="graphraum
|
|
4
|
+
<img src="./docs/src/assets/logo-light.svg" alt="graphraum" width="128" height="128">
|
|
5
5
|
</picture>
|
|
6
6
|
<br>
|
|
7
7
|
<strong>graphraum</strong>
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
# graphraum
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
yggy's WebGL engine for interactive node-edge graphs in 2D and 3D.
|
|
15
15
|
|
|
16
|
-
graphraum
|
|
16
|
+
graphraum renders graphs, accepts positions from any layout engine, and keeps the hot path outside a component framework. Nodes use one instanced mesh, edges use one batched geometry, and rendering happens on demand.
|
|
17
17
|
|
|
18
18
|
> Pre-1.0 development. The API will continue to evolve while the rendering and visual contracts are proven.
|
|
19
19
|
|
|
@@ -47,25 +47,20 @@ Repository decisions and agent instructions live in [`AGENTS.md`](./AGENTS.md).
|
|
|
47
47
|
|
|
48
48
|
## Install
|
|
49
49
|
|
|
50
|
-
graphraum is currently published to the GitHub Packages npm registry. Configure the `@domudev` scope and authenticate with a classic GitHub token that has `read:packages` permission:
|
|
51
|
-
|
|
52
|
-
```ini
|
|
53
|
-
# .npmrc
|
|
54
|
-
@domudev:registry=https://npm.pkg.github.com
|
|
55
|
-
//npm.pkg.github.com/:_authToken=${GITHUB_PACKAGES_TOKEN}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Then install it with Bun:
|
|
59
|
-
|
|
60
50
|
```sh
|
|
61
|
-
|
|
51
|
+
npm install @yggy-tech/graphraum
|
|
52
|
+
yarn add @yggy-tech/graphraum
|
|
53
|
+
pnpm add @yggy-tech/graphraum
|
|
54
|
+
bun add @yggy-tech/graphraum
|
|
62
55
|
```
|
|
63
56
|
|
|
64
|
-
|
|
57
|
+
Use the line for your package manager.
|
|
58
|
+
|
|
59
|
+
Publishing is automated with semantic-release after CI succeeds on `main`. Commit types determine the next version, semantic-release creates the `v<version>` tag and GitHub Release, and the package is published to npm. Do not manually edit the package version or create routine release tags.
|
|
65
60
|
|
|
66
61
|
## Documentation
|
|
67
62
|
|
|
68
|
-
The [documentation](https://
|
|
63
|
+
The [documentation](https://yggy-tech.github.io/graphraum/), [API reference](https://yggy-tech.github.io/graphraum/reference/api/), and the live [playground](https://yggy-tech.github.io/graphraum/playground/) with the Prove benchmark are published on GitHub Pages. Run them locally with:
|
|
69
64
|
|
|
70
65
|
```sh
|
|
71
66
|
bun install --cwd docs
|
package/dist/index.d.ts
CHANGED
|
@@ -72,6 +72,14 @@ interface GraphraumData<NodeAttributes = undefined, EdgeAttributes = undefined>
|
|
|
72
72
|
nodes: readonly GraphraumNode<NodeAttributes>[];
|
|
73
73
|
edges: readonly GraphraumEdge<EdgeAttributes>[];
|
|
74
74
|
}
|
|
75
|
+
interface GraphraumSetDataOptions {
|
|
76
|
+
/**
|
|
77
|
+
* Fit the camera to the new data (default `true`). `false` replaces the data and leaves the camera
|
|
78
|
+
* where it is, for hosts that pass a full snapshot on every change. On a graph that never had a
|
|
79
|
+
* fit the camera keeps its initial pose, so call `fitView()` once after the first data.
|
|
80
|
+
*/
|
|
81
|
+
fit?: boolean;
|
|
82
|
+
}
|
|
75
83
|
interface GraphraumDataPatch<NodeAttributes = undefined, EdgeAttributes = undefined> {
|
|
76
84
|
addedNodes?: readonly GraphraumNode<NodeAttributes>[];
|
|
77
85
|
addedEdges?: readonly GraphraumEdge<EdgeAttributes>[];
|
|
@@ -531,7 +539,8 @@ declare class Graphraum<NodeAttributes = undefined, EdgeAttributes = undefined>
|
|
|
531
539
|
private readonly focusListeners;
|
|
532
540
|
private lastHoveredNodeId;
|
|
533
541
|
constructor(container: HTMLElement, options?: GraphraumOptions<NodeAttributes, EdgeAttributes>);
|
|
534
|
-
|
|
542
|
+
/** Replaces the whole graph. Fits the camera unless `options.fit` is `false`. */
|
|
543
|
+
setData(data: GraphraumData<NodeAttributes, EdgeAttributes>, options?: GraphraumSetDataOptions): void;
|
|
535
544
|
/** Merge a topology patch without fitting or resetting the current camera. */
|
|
536
545
|
applyDataPatch(patch: GraphraumDataPatch<NodeAttributes, EdgeAttributes>): void;
|
|
537
546
|
private canAppendDataPatch;
|
|
@@ -851,4 +860,4 @@ declare function isTransparentGraphraumBackground(background: GraphraumBackgroun
|
|
|
851
860
|
/** Defines typed, serializable graph visuals without coupling application data to the render loop. */
|
|
852
861
|
declare function defineVisuals<NodeAttributes = undefined, EdgeAttributes = undefined>(visuals: GraphraumVisualMapper<NodeAttributes, EdgeAttributes>): GraphraumVisualMapper<NodeAttributes, EdgeAttributes>;
|
|
853
862
|
//#endregion
|
|
854
|
-
export { type CompiledGraphraumPresentation, DEFAULT_ENDPOINT_ATTACH, DEFAULT_ENDPOINT_CLEARANCE, DEFAULT_FORCE_SETTINGS, type EndpointAttach, type EndpointOutline, type ForceLayoutRequest, type ForceSettings, type GraphologyEdgeAttributes, type GraphologyNodeAttributes, type GraphologyRenderer, Graphraum, type GraphraumAutoOrbitOptions, type GraphraumAutoOrbitStatus, type GraphraumBackground, type GraphraumColor, type GraphraumData, type GraphraumDataPatch, type GraphraumDiagnostics, type GraphraumEdge, type GraphraumEdgeEncoding, type GraphraumEdgeMarker, type GraphraumEdgeMarkerEnd, type GraphraumEdgePath, type GraphraumEdgeState, type GraphraumEdgeStyle, type GraphraumEdgeVisual, type GraphraumFlyToOptions, type GraphraumLabelCandidate, type GraphraumLayoutPositions, type GraphraumMode, type GraphraumNode, type GraphraumNodeEncoding, type GraphraumNodeGeometry, type GraphraumNodeShape, type GraphraumNodeState, type GraphraumNodeUpdate, type GraphraumNodeVisual, type GraphraumOptions, GraphraumOverlay, type GraphraumOverlayNode, type GraphraumOverlayOptions, type GraphraumPatternBackground, type GraphraumPickHit, type GraphraumPosition, type GraphraumPresentation, type GraphraumPresentationAction, type GraphraumPresentationProperty, type GraphraumPropertyValue, type GraphraumScreenPosition, type GraphraumTheme, type GraphraumThemeName, type GraphraumVisualMapper, type LabelBudgetCandidate, type RichNodePolicy, type SelectBudgetedLabelIdsInput, type SelectFocusLabelIdsInput, attachPointOnOutline, bindGraphology, boundOverlayIds, computeClusteredForcePositions, computeForcePositions, createForceSimulation, defineVisuals, forceIterationCount, graphraumEdgePaths, graphraumNodeShapes, graphraumTheme, graphraumThemeDark, graphraumThemeLight, graphraumThemes, isTransparentGraphraumBackground, normalizeGraphraumBackground, orderFocusNodeIds, resolveGraphraumTheme, selectBudgetedLabelIds, selectFocusLabelIds, selectRichNodeIds, trimEdgeEndpoints };
|
|
863
|
+
export { type CompiledGraphraumPresentation, DEFAULT_ENDPOINT_ATTACH, DEFAULT_ENDPOINT_CLEARANCE, DEFAULT_FORCE_SETTINGS, type EndpointAttach, type EndpointOutline, type ForceLayoutRequest, type ForceSettings, type GraphologyEdgeAttributes, type GraphologyNodeAttributes, type GraphologyRenderer, Graphraum, type GraphraumAutoOrbitOptions, type GraphraumAutoOrbitStatus, type GraphraumBackground, type GraphraumColor, type GraphraumData, type GraphraumDataPatch, type GraphraumDiagnostics, type GraphraumEdge, type GraphraumEdgeEncoding, type GraphraumEdgeMarker, type GraphraumEdgeMarkerEnd, type GraphraumEdgePath, type GraphraumEdgeState, type GraphraumEdgeStyle, type GraphraumEdgeVisual, type GraphraumFlyToOptions, type GraphraumLabelCandidate, type GraphraumLayoutPositions, type GraphraumMode, type GraphraumNode, type GraphraumNodeEncoding, type GraphraumNodeGeometry, type GraphraumNodeShape, type GraphraumNodeState, type GraphraumNodeUpdate, type GraphraumNodeVisual, type GraphraumOptions, GraphraumOverlay, type GraphraumOverlayNode, type GraphraumOverlayOptions, type GraphraumPatternBackground, type GraphraumPickHit, type GraphraumPosition, type GraphraumPresentation, type GraphraumPresentationAction, type GraphraumPresentationProperty, type GraphraumPropertyValue, type GraphraumScreenPosition, type GraphraumSetDataOptions, type GraphraumTheme, type GraphraumThemeName, type GraphraumVisualMapper, type LabelBudgetCandidate, type RichNodePolicy, type SelectBudgetedLabelIdsInput, type SelectFocusLabelIdsInput, attachPointOnOutline, bindGraphology, boundOverlayIds, computeClusteredForcePositions, computeForcePositions, createForceSimulation, defineVisuals, forceIterationCount, graphraumEdgePaths, graphraumNodeShapes, graphraumTheme, graphraumThemeDark, graphraumThemeLight, graphraumThemes, isTransparentGraphraumBackground, normalizeGraphraumBackground, orderFocusNodeIds, resolveGraphraumTheme, selectBudgetedLabelIds, selectFocusLabelIds, selectRichNodeIds, trimEdgeEndpoints };
|
package/dist/index.js
CHANGED
|
@@ -124,6 +124,14 @@ function outlineRadius(outline, headingX, headingY) {
|
|
|
124
124
|
return low;
|
|
125
125
|
}
|
|
126
126
|
/**
|
|
127
|
+
* How far an edge end stops short of a 3D node's center, in world units: the outline radius (stroke
|
|
128
|
+
* included) less `clearance`. The renderer applies it on screen, where the camera-facing outline
|
|
129
|
+
* is, so it is exact for circles from every view. Other shapes use their radius along +x.
|
|
130
|
+
*/
|
|
131
|
+
function outlineReach(outline, clearance = DEFAULT_ENDPOINT_CLEARANCE) {
|
|
132
|
+
return Math.max(0, outlineRadius(outline, 1, 0) - Math.max(clearance, 0));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
127
135
|
* Walk from the node center toward the far point and stop on the outline,
|
|
128
136
|
* then pull back by `clearance` so the stroke is not stabbed.
|
|
129
137
|
*
|
|
@@ -1333,34 +1341,40 @@ function packEdgeInstances(input) {
|
|
|
1333
1341
|
let x2 = input.endpointPositions[base + 3] ?? 0;
|
|
1334
1342
|
let y2 = input.endpointPositions[base + 4] ?? 0;
|
|
1335
1343
|
let z2 = input.endpointPositions[base + 5] ?? 0;
|
|
1344
|
+
let trimSource = 0;
|
|
1345
|
+
let trimTarget = 0;
|
|
1336
1346
|
if (attach === "boundary" && input.nodeOutlines && input.edgeNodeIndices) {
|
|
1337
1347
|
const sourceIndex = input.edgeNodeIndices[edgeIndex * 2] ?? 0;
|
|
1338
1348
|
const targetIndex = input.edgeNodeIndices[edgeIndex * 2 + 1] ?? 0;
|
|
1339
1349
|
const sourceOutline = input.nodeOutlines[sourceIndex] ?? {};
|
|
1340
1350
|
const targetOutline = input.nodeOutlines[targetIndex] ?? {};
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
clearance
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1351
|
+
if (input.mode === "3d") {
|
|
1352
|
+
trimSource = outlineReach(sourceOutline, clearance);
|
|
1353
|
+
trimTarget = outlineReach(targetOutline, clearance);
|
|
1354
|
+
} else {
|
|
1355
|
+
const trimmed = trimEdgeEndpoints({
|
|
1356
|
+
attach,
|
|
1357
|
+
clearance,
|
|
1358
|
+
source: {
|
|
1359
|
+
x: x1,
|
|
1360
|
+
y: y1,
|
|
1361
|
+
z: z1
|
|
1362
|
+
},
|
|
1363
|
+
target: {
|
|
1364
|
+
x: x2,
|
|
1365
|
+
y: y2,
|
|
1366
|
+
z: z2
|
|
1367
|
+
},
|
|
1368
|
+
sourceOutline,
|
|
1369
|
+
targetOutline
|
|
1370
|
+
});
|
|
1371
|
+
x1 = trimmed.source.x;
|
|
1372
|
+
y1 = trimmed.source.y;
|
|
1373
|
+
z1 = trimmed.source.z ?? 0;
|
|
1374
|
+
x2 = trimmed.target.x;
|
|
1375
|
+
y2 = trimmed.target.y;
|
|
1376
|
+
z2 = trimmed.target.z ?? 0;
|
|
1377
|
+
}
|
|
1364
1378
|
}
|
|
1365
1379
|
const { color, opacity } = resolveEdgePaint(edgeIndex, visual, input.defaults, input.tier, input.edgeStates);
|
|
1366
1380
|
const width = input.tier === "overview" ? input.defaults.width : visual.width ?? input.defaults.width;
|
|
@@ -1396,7 +1410,9 @@ function packEdgeInstances(input) {
|
|
|
1396
1410
|
color,
|
|
1397
1411
|
width,
|
|
1398
1412
|
opacity,
|
|
1399
|
-
style
|
|
1413
|
+
style,
|
|
1414
|
+
trimStart: index === 0 ? trimSource : 0,
|
|
1415
|
+
trimEnd: index === segmentSpans - 1 ? trimTarget : 0
|
|
1400
1416
|
});
|
|
1401
1417
|
}
|
|
1402
1418
|
if (input.tier === "overview") continue;
|
|
@@ -1421,7 +1437,8 @@ function packEdgeInstances(input) {
|
|
|
1421
1437
|
dz: fromSource ? (first.z ?? 0) - (second.z ?? 0) : (last.z ?? 0) - (previous.z ?? 0),
|
|
1422
1438
|
color,
|
|
1423
1439
|
size: markerSize,
|
|
1424
|
-
opacity
|
|
1440
|
+
opacity,
|
|
1441
|
+
trim: fromSource ? trimSource : trimTarget
|
|
1425
1442
|
});
|
|
1426
1443
|
};
|
|
1427
1444
|
if (ends === "source" || ends === "both") add("source");
|
|
@@ -1494,6 +1511,7 @@ attribute vec3 instanceEndB;
|
|
|
1494
1511
|
attribute vec4 instanceColor;
|
|
1495
1512
|
attribute float instanceWidth;
|
|
1496
1513
|
attribute float instanceStyle;
|
|
1514
|
+
attribute vec2 instanceTrim;
|
|
1497
1515
|
|
|
1498
1516
|
varying vec4 edgeColor;
|
|
1499
1517
|
varying float edgeKind;
|
|
@@ -1517,6 +1535,18 @@ void main() {
|
|
|
1517
1535
|
vec2 delta = viewB.xy - viewA.xy;
|
|
1518
1536
|
float len = length(delta);
|
|
1519
1537
|
vec2 dir = len > 0.0001 ? delta / len : vec2(1.0, 0.0);
|
|
1538
|
+
// 3D boundary ends (see trimViewSegment): stop on the camera-facing outline. A trimmed end
|
|
1539
|
+
// keeps its node's depth, where the billboard is, so it meets the rim from every view.
|
|
1540
|
+
if (instanceTrim.x + instanceTrim.y > 0.0) {
|
|
1541
|
+
if (len - instanceTrim.x - instanceTrim.y <= 0.0) {
|
|
1542
|
+
gl_Position = vec4(0.0, 0.0, 2.0, 1.0); // hidden behind its nodes: clip it away
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
1545
|
+
viewA.xy += dir * instanceTrim.x;
|
|
1546
|
+
viewB.xy -= dir * instanceTrim.y;
|
|
1547
|
+
delta = viewB.xy - viewA.xy;
|
|
1548
|
+
len = length(delta);
|
|
1549
|
+
}
|
|
1520
1550
|
vec2 perp = vec2(-dir.y, dir.x);
|
|
1521
1551
|
vec2 mid = (viewA.xy + viewB.xy) * 0.5;
|
|
1522
1552
|
vec2 offset = dir * position.x * len + perp * position.y * instanceWidth;
|
|
@@ -1531,8 +1561,10 @@ void main() {
|
|
|
1531
1561
|
vec2 dir = dirLen > 0.0001 ? dirVec / dirLen : vec2(1.0, 0.0);
|
|
1532
1562
|
vec2 perp = vec2(-dir.y, dir.x);
|
|
1533
1563
|
float t = position.x + 0.5;
|
|
1564
|
+
// 3D boundary ends pull the apex back onto the camera-facing outline (see markerApexInView).
|
|
1565
|
+
vec2 apex = viewA.xy - dir * instanceTrim.x;
|
|
1534
1566
|
vec2 offset = dir * instanceWidth * (t - 1.0) + perp * position.y * instanceWidth;
|
|
1535
|
-
viewPosition = vec4(
|
|
1567
|
+
viewPosition = vec4(apex + offset, viewA.z, 1.0);
|
|
1536
1568
|
}
|
|
1537
1569
|
|
|
1538
1570
|
gl_Position = projectionMatrix * viewPosition;
|
|
@@ -1565,6 +1597,16 @@ void main() {
|
|
|
1565
1597
|
${OUTPUT_COLOR_SPACE_FRAGMENT}
|
|
1566
1598
|
}
|
|
1567
1599
|
`;
|
|
1600
|
+
/** Per-instance attributes of the edge geometry; updates mark each of them dirty. */
|
|
1601
|
+
const EDGE_INSTANCE_ATTRIBUTES = [
|
|
1602
|
+
"instanceKind",
|
|
1603
|
+
"instanceEndA",
|
|
1604
|
+
"instanceEndB",
|
|
1605
|
+
"instanceColor",
|
|
1606
|
+
"instanceWidth",
|
|
1607
|
+
"instanceStyle",
|
|
1608
|
+
"instanceTrim"
|
|
1609
|
+
];
|
|
1568
1610
|
function createEdgeGeometry(capacity) {
|
|
1569
1611
|
const geometry = new PlaneGeometry(1, 1);
|
|
1570
1612
|
geometry.setAttribute("instanceKind", new InstancedBufferAttribute(new Float32Array(capacity), 1));
|
|
@@ -1573,6 +1615,7 @@ function createEdgeGeometry(capacity) {
|
|
|
1573
1615
|
geometry.setAttribute("instanceColor", new InstancedBufferAttribute(new Float32Array(capacity * 4), 4));
|
|
1574
1616
|
geometry.setAttribute("instanceWidth", new InstancedBufferAttribute(new Float32Array(capacity), 1));
|
|
1575
1617
|
geometry.setAttribute("instanceStyle", new InstancedBufferAttribute(new Float32Array(capacity), 1));
|
|
1618
|
+
geometry.setAttribute("instanceTrim", new InstancedBufferAttribute(new Float32Array(capacity * 2), 2));
|
|
1576
1619
|
return geometry;
|
|
1577
1620
|
}
|
|
1578
1621
|
function createEdgeMaterial() {
|
|
@@ -1602,6 +1645,7 @@ function writeEdgeSegmentInstance(geometry, slot, segment) {
|
|
|
1602
1645
|
writeEdgeColorSlots(color, slot, 1, segment);
|
|
1603
1646
|
width.setX(slot, segment.width);
|
|
1604
1647
|
style.setX(slot, encodeEdgeStyle(segment.style));
|
|
1648
|
+
getInstancedAttribute(geometry, "instanceTrim").setXY(slot, segment.trimStart, segment.trimEnd);
|
|
1605
1649
|
}
|
|
1606
1650
|
function writeEdgeMarkerInstance(geometry, slot, marker) {
|
|
1607
1651
|
const kind = getInstancedAttribute(geometry, "instanceKind");
|
|
@@ -1616,6 +1660,7 @@ function writeEdgeMarkerInstance(geometry, slot, marker) {
|
|
|
1616
1660
|
writeEdgeColorSlots(color, slot, 1, marker);
|
|
1617
1661
|
width.setX(slot, marker.size);
|
|
1618
1662
|
style.setX(slot, 0);
|
|
1663
|
+
getInstancedAttribute(geometry, "instanceTrim").setXY(slot, marker.trim, 0);
|
|
1619
1664
|
}
|
|
1620
1665
|
/** Writes one color and opacity into `count` consecutive instance slots starting at `start`. */
|
|
1621
1666
|
function writeEdgeColorSlots(color, start, count, paint) {
|
|
@@ -1624,14 +1669,6 @@ function writeEdgeColorSlots(color, start, count, paint) {
|
|
|
1624
1669
|
}
|
|
1625
1670
|
//#endregion
|
|
1626
1671
|
//#region src/edge-viewport-patch.ts
|
|
1627
|
-
const EDGE_INSTANCE_ATTRIBUTES$1 = [
|
|
1628
|
-
"instanceKind",
|
|
1629
|
-
"instanceEndA",
|
|
1630
|
-
"instanceEndB",
|
|
1631
|
-
"instanceColor",
|
|
1632
|
-
"instanceWidth",
|
|
1633
|
-
"instanceStyle"
|
|
1634
|
-
];
|
|
1635
1672
|
/** Records GPU slot ranges for each visible edge after a full viewport materialize. */
|
|
1636
1673
|
function buildVisibleEdgeLayouts(segments, markers, segmentInstanceCount) {
|
|
1637
1674
|
const layouts = /* @__PURE__ */ new Map();
|
|
@@ -1719,7 +1756,7 @@ function patchVisibleEdgeInstances(geometry, input, pickableSegments) {
|
|
|
1719
1756
|
ok: true,
|
|
1720
1757
|
pickableSegments: nextPickable
|
|
1721
1758
|
};
|
|
1722
|
-
for (const name of EDGE_INSTANCE_ATTRIBUTES
|
|
1759
|
+
for (const name of EDGE_INSTANCE_ATTRIBUTES) {
|
|
1723
1760
|
const attribute = geometry.getAttribute(name);
|
|
1724
1761
|
attribute.addUpdateRange(dirtySlotStart * attribute.itemSize, (dirtySlotEnd - dirtySlotStart + 1) * attribute.itemSize);
|
|
1725
1762
|
attribute.needsUpdate = true;
|
|
@@ -2725,14 +2762,6 @@ const FLIGHT_CANCEL_EVENTS = [
|
|
|
2725
2762
|
"pointerdown",
|
|
2726
2763
|
"wheel"
|
|
2727
2764
|
];
|
|
2728
|
-
const EDGE_INSTANCE_ATTRIBUTES = [
|
|
2729
|
-
"instanceKind",
|
|
2730
|
-
"instanceEndA",
|
|
2731
|
-
"instanceEndB",
|
|
2732
|
-
"instanceColor",
|
|
2733
|
-
"instanceWidth",
|
|
2734
|
-
"instanceStyle"
|
|
2735
|
-
];
|
|
2736
2765
|
/** A small, explicit WebGL graph renderer: one instanced node mesh and one batched edge geometry. */
|
|
2737
2766
|
var Graphraum = class {
|
|
2738
2767
|
container;
|
|
@@ -2853,8 +2882,11 @@ var Graphraum = class {
|
|
|
2853
2882
|
this.resizeObserver.observe(container);
|
|
2854
2883
|
this.resize();
|
|
2855
2884
|
}
|
|
2856
|
-
|
|
2857
|
-
|
|
2885
|
+
/** Replaces the whole graph. Fits the camera unless `options.fit` is `false`. */
|
|
2886
|
+
setData(data, options = {}) {
|
|
2887
|
+
const { fit = true } = options;
|
|
2888
|
+
if (typeof fit !== "boolean") throw new Error("setData option fit must be a boolean.");
|
|
2889
|
+
this.replaceData(data, fit);
|
|
2858
2890
|
}
|
|
2859
2891
|
/** Merge a topology patch without fitting or resetting the current camera. */
|
|
2860
2892
|
applyDataPatch(patch) {
|
package/package.json
CHANGED
|
@@ -1,57 +1,56 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
2
|
+
"name": "@yggy-tech/graphraum",
|
|
3
|
+
"version": "0.35.0",
|
|
4
|
+
"description": "yggy's WebGL engine for interactive graphs in 2D and 3D",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"packageManager": "bun@1.3.1",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/yggy-tech/graphraum.git"
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsdown",
|
|
27
|
+
"check": "biome check . && tsc --noEmit",
|
|
28
|
+
"dev": "vite examples/benchmark",
|
|
29
|
+
"docs:build": "bun run --cwd docs build",
|
|
30
|
+
"docs:archive": "bun run docs/scripts/build-release-archives.ts",
|
|
31
|
+
"docs:check": "bun run --cwd docs check",
|
|
32
|
+
"docs:dev": "bun run --cwd docs dev",
|
|
33
|
+
"docs:test": "bun run --cwd docs test",
|
|
34
|
+
"prepack": "bun run build",
|
|
35
|
+
"release": "semantic-release",
|
|
36
|
+
"test": "vitest run src examples --exclude 'docs/**'"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"bun": ">=1.2.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"graphology": "^0.26.0",
|
|
43
|
+
"three": "^0.185.1"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@biomejs/biome": "^2.5.5",
|
|
47
|
+
"@commitlint/cli": "^21.2.1",
|
|
48
|
+
"@commitlint/config-conventional": "^21.2.0",
|
|
49
|
+
"@types/three": "^0.185.1",
|
|
50
|
+
"semantic-release": "^25.0.8",
|
|
51
|
+
"tsdown": "^0.22.13",
|
|
52
|
+
"typescript": "^6.0.3",
|
|
53
|
+
"vite": "^8.1.5",
|
|
54
|
+
"vitest": "^4.1.10"
|
|
55
|
+
}
|
|
57
56
|
}
|