@fusion.dev/helix-graph 0.148.0 → 0.149.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
CHANGED
|
@@ -66,7 +66,8 @@ first.
|
|
|
66
66
|
and the labels in the theme's face, and draws them again when the theme
|
|
67
67
|
changes.
|
|
68
68
|
- Answers the frame's pan and zoom buttons and keys, and tells the renderer which
|
|
69
|
-
gestures the frame's `gestures` lets it take.
|
|
69
|
+
gestures the frame's `gestures` lets it take. Once the drawing has moved, it
|
|
70
|
+
calls the frame's `moved()`, and screen readers hear which way it went.
|
|
70
71
|
- Draws only what changed when the page hands the frame new notes or links, and
|
|
71
72
|
draws the frame's `signal()`s.
|
|
72
73
|
- Fades out a snapshot drawn on the server by `graphSnapshot` once the renderer
|
|
@@ -397,3 +398,8 @@ Sigma 3 is a peer dependency.
|
|
|
397
398
|
bun run --filter @fusion.dev/helix-graph build
|
|
398
399
|
bun run --filter @fusion.dev/helix-graph test
|
|
399
400
|
```
|
|
401
|
+
|
|
402
|
+
The specs in `src/sigma/sigma-scene.dom.spec.ts` draw with Sigma in WebGL, so
|
|
403
|
+
they run in a browser only, with `bun run specs:browser graph`. They check that
|
|
404
|
+
the drawing frames and rings the note chosen in the list, and moves with the
|
|
405
|
+
frame's keys.
|
|
@@ -312,11 +312,13 @@ export const connectGraph = (frame, driver, options = {}) => {
|
|
|
312
312
|
const inline = (to === 'end' ? 1 : to === 'start' ? -1 : 0) * (isRtl(frame) ? -1 : 1);
|
|
313
313
|
const block = to === 'down' ? 1 : to === 'up' ? -1 : 0;
|
|
314
314
|
driver.panBy(inline * width * by, block * height * by, !still());
|
|
315
|
+
graph.moved?.();
|
|
315
316
|
};
|
|
316
317
|
const handleZoom = (event) => {
|
|
317
318
|
const { by } = event.detail;
|
|
318
319
|
if (by !== 0) {
|
|
319
320
|
driver.zoomBy(by > 0 ? 1 : -1, !still());
|
|
321
|
+
graph.moved?.();
|
|
320
322
|
}
|
|
321
323
|
};
|
|
322
324
|
frame.addEventListener(HelixGraphPartChangeEvent.eventName, handlePartChange);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ViewportGestureMode } from '@fusion.dev/helix-core';
|
|
2
2
|
import type { GraphGroup } from '../connect-graph/connect-graph.js';
|
|
3
3
|
import { type GraphLooks } from '../connect-graph/looks.js';
|
|
4
4
|
/** Where a note is on screen and how large, or nothing where it is not drawn. */
|
|
@@ -48,14 +48,20 @@ export declare const chromeOver: (container: HTMLElement) => Box[];
|
|
|
48
48
|
/** Whether a box overlaps none of `others`. */
|
|
49
49
|
export declare const clearOf: (box: Box, others: readonly Box[]) => boolean;
|
|
50
50
|
/**
|
|
51
|
-
* Where a note's name starts,
|
|
52
|
-
* where after it would run under the frame's
|
|
53
|
-
* `box` gives the name's box for a start.
|
|
51
|
+
* Where a note's name starts, its left edge on screen: after the note in
|
|
52
|
+
* reading order, or before it where after it would run under the frame's
|
|
53
|
+
* controls or off the drawing. `box` gives the name's box for a start.
|
|
54
|
+
*
|
|
55
|
+
* **After is to the left on a right-to-left page**, `rightToLeft`, as a
|
|
56
|
+
* reader there looks for what follows a mark. The name is drawn from its left
|
|
57
|
+
* edge either way, with `textAlign` set to `left`: a canvas aligns text to its
|
|
58
|
+
* start by default, which on a right-to-left page is the right, so a name
|
|
59
|
+
* given its left edge was drawn ending there, over its own note.
|
|
54
60
|
*/
|
|
55
61
|
export declare const nameStart: (at: {
|
|
56
62
|
radius: number;
|
|
57
63
|
x: number;
|
|
58
|
-
}, width: number, box: (start: number) => Box, avoid: readonly Box[], room: number) => number;
|
|
64
|
+
}, width: number, box: (start: number) => Box, avoid: readonly Box[], room: number, rightToLeft?: boolean) => number;
|
|
59
65
|
/** A note to name over the drawing: its name, and whether it is the one the reader is on. */
|
|
60
66
|
export interface Named {
|
|
61
67
|
id: string;
|
package/dist/overlay/overlay.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRtl } from '@fusion.dev/helix-core';
|
|
1
2
|
import { mixRgb, rgbOf } from '../connect-graph/looks.js';
|
|
2
3
|
const SPEED = 340;
|
|
3
4
|
const QUICKEST = 450;
|
|
@@ -288,8 +289,10 @@ export const clearOf = (box, others) => others.every((other) => box.right < othe
|
|
|
288
289
|
box.left > other.right ||
|
|
289
290
|
box.bottom < other.top ||
|
|
290
291
|
box.top > other.bottom);
|
|
291
|
-
export const nameStart = (at, width, box, avoid, room) => {
|
|
292
|
-
const
|
|
292
|
+
export const nameStart = (at, width, box, avoid, room, rightToLeft = false) => {
|
|
293
|
+
const right = at.x + at.radius + 4;
|
|
294
|
+
const left = at.x - at.radius - 4 - width;
|
|
295
|
+
const [after, before] = rightToLeft ? [left, right] : [right, left];
|
|
293
296
|
const fits = (start) => {
|
|
294
297
|
const placed = box(start);
|
|
295
298
|
return placed.left >= 0 && placed.right <= room && clearOf(placed, avoid);
|
|
@@ -297,7 +300,6 @@ export const nameStart = (at, width, box, avoid, room) => {
|
|
|
297
300
|
if (fits(after)) {
|
|
298
301
|
return after;
|
|
299
302
|
}
|
|
300
|
-
const before = at.x - at.radius - 4 - width;
|
|
301
303
|
return fits(before) ? before : after;
|
|
302
304
|
};
|
|
303
305
|
export const namesOver = (container, onScreen) => {
|
|
@@ -311,6 +313,8 @@ export const namesOver = (container, onScreen) => {
|
|
|
311
313
|
return;
|
|
312
314
|
}
|
|
313
315
|
taken = chromeOver(container);
|
|
316
|
+
const rightToLeft = isRtl(container);
|
|
317
|
+
context.textAlign = 'left';
|
|
314
318
|
for (const { id, name, strong } of named) {
|
|
315
319
|
const at = onScreen(id);
|
|
316
320
|
if (!at || looks.node(id).hidden) {
|
|
@@ -325,7 +329,7 @@ export const namesOver = (container, onScreen) => {
|
|
|
325
329
|
right: start + width + 2,
|
|
326
330
|
top: y - 13,
|
|
327
331
|
});
|
|
328
|
-
const x = nameStart(at, width, boxAt, taken, container.clientWidth);
|
|
332
|
+
const x = nameStart(at, width, boxAt, taken, container.clientWidth, rightToLeft);
|
|
329
333
|
const box = boxAt(x);
|
|
330
334
|
if (!clearOf(box, taken) && !strong) {
|
|
331
335
|
continue;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRtl } from '@fusion.dev/helix-core';
|
|
1
2
|
import { pixelsOf } from '../connect-graph/sizes.js';
|
|
2
3
|
import { chromeOver, clearOf, ease, gesturesHeld, groupsOver, nameStart, signalsOver, } from '../overlay/overlay.js';
|
|
3
4
|
import { EMPHASES, HelixNodeProgram, MATERIALS, SHAPES } from './node-program.js';
|
|
@@ -22,14 +23,14 @@ const SAMPLE = 250;
|
|
|
22
23
|
const STILL = 0.004;
|
|
23
24
|
const HELD = 2;
|
|
24
25
|
const IDLE = 2000;
|
|
25
|
-
const hoverOf = (looks) => (context, data, settings) => {
|
|
26
|
+
const hoverOf = (looks, rightToLeft) => (context, data, settings) => {
|
|
26
27
|
if (!data.label) {
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
30
|
const size = settings.labelSize;
|
|
30
31
|
context.font = `${settings.labelWeight} ${size}px ${settings.labelFont}`;
|
|
31
32
|
const width = context.measureText(data.label).width;
|
|
32
|
-
const x = data.x + data.size + 2;
|
|
33
|
+
const x = rightToLeft() ? data.x - data.size - 2 - width : data.x + data.size + 2;
|
|
33
34
|
const height = size + 8;
|
|
34
35
|
context.save();
|
|
35
36
|
context.shadowBlur = 8;
|
|
@@ -40,6 +41,7 @@ const hoverOf = (looks) => (context, data, settings) => {
|
|
|
40
41
|
context.fill();
|
|
41
42
|
context.restore();
|
|
42
43
|
context.fillStyle = looks.ink;
|
|
44
|
+
context.textAlign = 'left';
|
|
43
45
|
context.fillText(data.label, x, data.y + size / 3);
|
|
44
46
|
};
|
|
45
47
|
const GROW = 300;
|
|
@@ -66,6 +68,7 @@ const labelOf = (looks, claim, start) => (context, data, settings) => {
|
|
|
66
68
|
context.lineJoin = 'round';
|
|
67
69
|
context.lineWidth = 3;
|
|
68
70
|
context.strokeStyle = looks.ground;
|
|
71
|
+
context.textAlign = 'left';
|
|
69
72
|
context.strokeText(data.label, x, y);
|
|
70
73
|
context.fillStyle = strong ? looks.ink : looks.quiet;
|
|
71
74
|
context.fillText(data.label, x, y);
|
|
@@ -121,8 +124,10 @@ export const sigmaDriver = (sigma, options = {}) => {
|
|
|
121
124
|
}
|
|
122
125
|
return free || must;
|
|
123
126
|
};
|
|
127
|
+
let rightToLeft = false;
|
|
124
128
|
const clear = () => {
|
|
125
129
|
taken = chromeOver(container);
|
|
130
|
+
rightToLeft = isRtl(container);
|
|
126
131
|
};
|
|
127
132
|
sigma.on('beforeRender', clear);
|
|
128
133
|
const held = gesturesHeld(container);
|
|
@@ -240,8 +245,8 @@ export const sigmaDriver = (sigma, options = {}) => {
|
|
|
240
245
|
sigma.setSetting('labelFont', looks.font);
|
|
241
246
|
sigma.setSetting('labelRenderedSizeThreshold', 0);
|
|
242
247
|
sigma.setSetting('labelGridCellSize', naming === 'all' ? 8 : 130);
|
|
243
|
-
sigma.setSetting('defaultDrawNodeLabel', labelOf(looks, claim, (at, width, box) => nameStart(at, width, box, taken, container.clientWidth)));
|
|
244
|
-
sigma.setSetting('defaultDrawNodeHover', hoverOf(looks));
|
|
248
|
+
sigma.setSetting('defaultDrawNodeLabel', labelOf(looks, claim, (at, width, box) => nameStart(at, width, box, taken, container.clientWidth, rightToLeft)));
|
|
249
|
+
sigma.setSetting('defaultDrawNodeHover', hoverOf(looks, () => rightToLeft));
|
|
245
250
|
sigma.setSetting('nodeReducer', (node, data) => {
|
|
246
251
|
const look = looks.node(node);
|
|
247
252
|
const grown = look.selected ? 1.5 : look.raised ? 1.25 : 1;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-graph",
|
|
3
3
|
"description": "Connects the Helix Graph frame to a graph renderer: Sigma.js, cosmos.gl, three.js, or a driver of your own.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.149.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -55,12 +55,12 @@
|
|
|
55
55
|
},
|
|
56
56
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@fusion.dev/helix-core": "0.
|
|
58
|
+
"@fusion.dev/helix-core": "0.149.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@cosmos.gl/graph": "^3.4.2",
|
|
62
|
-
"@fusion.dev/helix-headless": "0.
|
|
63
|
-
"@fusion.dev/helix-testing": "0.
|
|
62
|
+
"@fusion.dev/helix-headless": "0.149.0",
|
|
63
|
+
"@fusion.dev/helix-testing": "0.149.0",
|
|
64
64
|
"@types/bun": "^1.3.0",
|
|
65
65
|
"@types/three": "^0.186.0",
|
|
66
66
|
"d3-force-3d": "^3.0.6",
|