@opendata-ai/openchart-vanilla 2.2.0 → 2.2.1
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/index.d.ts +4 -0
- package/dist/index.js +19 -13
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/graph/canvas-renderer.ts +13 -10
- package/src/graph-mount.ts +13 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opendata-ai/openchart-vanilla",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Vanilla JS renderer for openchart: SVG charts, HTML tables, force-directed graphs",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Riley Hilliard",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"typecheck": "tsc --noEmit"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@opendata-ai/openchart-core": "2.2.
|
|
50
|
-
"@opendata-ai/openchart-engine": "2.2.
|
|
49
|
+
"@opendata-ai/openchart-core": "2.2.1",
|
|
50
|
+
"@opendata-ai/openchart-engine": "2.2.1",
|
|
51
51
|
"d3-force": "^3.0.0",
|
|
52
52
|
"d3-quadtree": "^3.0.1"
|
|
53
53
|
},
|
|
@@ -18,15 +18,15 @@ import type { GraphRenderState, PositionedEdge, PositionedNode } from './types';
|
|
|
18
18
|
// Constants
|
|
19
19
|
// ---------------------------------------------------------------------------
|
|
20
20
|
|
|
21
|
-
const LABEL_FONT_MIN =
|
|
22
|
-
const LABEL_FONT_MAX =
|
|
21
|
+
const LABEL_FONT_MIN = 8;
|
|
22
|
+
const LABEL_FONT_MAX = 12;
|
|
23
23
|
const EDGE_ALPHA_DEFAULT = 0.35;
|
|
24
24
|
const EDGE_ALPHA_CONNECTED = 1.0;
|
|
25
25
|
const EDGE_ALPHA_DIMMED = 0.05;
|
|
26
26
|
const SEARCH_NON_MATCH_ALPHA = 0.15;
|
|
27
27
|
const GLOW_NODE_THRESHOLD = 2000;
|
|
28
|
-
const GLOW_RADIUS_MULTIPLIER = 1.
|
|
29
|
-
const GLOW_ALPHA = 0.
|
|
28
|
+
const GLOW_RADIUS_MULTIPLIER = 1.3;
|
|
29
|
+
const GLOW_ALPHA = 0.15;
|
|
30
30
|
const CULL_MARGIN = 50;
|
|
31
31
|
const TWO_PI = Math.PI * 2;
|
|
32
32
|
|
|
@@ -180,9 +180,11 @@ export class GraphCanvasRenderer {
|
|
|
180
180
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
181
181
|
ctx.clearRect(0, 0, cssWidth, cssHeight);
|
|
182
182
|
|
|
183
|
-
// Fill background
|
|
184
|
-
|
|
185
|
-
|
|
183
|
+
// Fill background (skip if transparent to let page background show through)
|
|
184
|
+
if (theme.colors.background !== 'transparent') {
|
|
185
|
+
ctx.fillStyle = theme.colors.background;
|
|
186
|
+
ctx.fillRect(0, 0, cssWidth, cssHeight);
|
|
187
|
+
}
|
|
186
188
|
|
|
187
189
|
ctx.translate(transform.x, transform.y);
|
|
188
190
|
ctx.scale(transform.k, transform.k);
|
|
@@ -638,7 +640,7 @@ export class GraphCanvasRenderer {
|
|
|
638
640
|
theme: GraphRenderState['theme'],
|
|
639
641
|
): void {
|
|
640
642
|
// Font size inversely scaled by zoom, clamped to readable range
|
|
641
|
-
const rawSize =
|
|
643
|
+
const rawSize = 10 / zoom;
|
|
642
644
|
const fontSize = Math.max(LABEL_FONT_MIN, Math.min(LABEL_FONT_MAX, rawSize));
|
|
643
645
|
|
|
644
646
|
ctx.font = `${fontSize}px ${theme.fonts.family}`;
|
|
@@ -660,8 +662,9 @@ export class GraphCanvasRenderer {
|
|
|
660
662
|
|
|
661
663
|
const labelY = node.y + node.radius + 3;
|
|
662
664
|
|
|
663
|
-
// Dark halo for readability
|
|
664
|
-
ctx.strokeStyle =
|
|
665
|
+
// Dark halo for readability (fall back to semi-transparent black when bg is transparent)
|
|
666
|
+
ctx.strokeStyle =
|
|
667
|
+
theme.colors.background === 'transparent' ? 'rgba(0, 0, 0, 0.7)' : theme.colors.background;
|
|
665
668
|
ctx.lineWidth = 3;
|
|
666
669
|
ctx.lineJoin = 'round';
|
|
667
670
|
ctx.strokeText(node.label, node.x, labelY);
|
package/src/graph-mount.ts
CHANGED
|
@@ -35,6 +35,10 @@ export interface GraphMountOptions {
|
|
|
35
35
|
theme?: ThemeConfig;
|
|
36
36
|
darkMode?: DarkMode;
|
|
37
37
|
responsive?: boolean;
|
|
38
|
+
/** Show the built-in tooltip on node/edge hover. Defaults to true. */
|
|
39
|
+
tooltip?: boolean;
|
|
40
|
+
/** Show the built-in legend. Defaults to true. */
|
|
41
|
+
legend?: boolean;
|
|
38
42
|
onNodeClick?: (node: Record<string, unknown>) => void;
|
|
39
43
|
onNodeDoubleClick?: (node: Record<string, unknown>) => void;
|
|
40
44
|
onNodeHover?: (node: Record<string, unknown> | null) => void;
|
|
@@ -278,10 +282,12 @@ export function createGraph(
|
|
|
278
282
|
wrapper.appendChild(canvas);
|
|
279
283
|
|
|
280
284
|
// Legend
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
+
if (options?.legend !== false) {
|
|
286
|
+
legendEl = document.createElement('div');
|
|
287
|
+
legendEl.className = 'viz-graph-legend';
|
|
288
|
+
renderLegend();
|
|
289
|
+
wrapper.appendChild(legendEl);
|
|
290
|
+
}
|
|
285
291
|
|
|
286
292
|
container.appendChild(wrapper);
|
|
287
293
|
|
|
@@ -447,7 +453,9 @@ export function createGraph(
|
|
|
447
453
|
function initInteraction(): void {
|
|
448
454
|
if (!canvas) return;
|
|
449
455
|
|
|
450
|
-
|
|
456
|
+
if (options?.tooltip !== false) {
|
|
457
|
+
tooltipManager = createTooltipManager(wrapper!);
|
|
458
|
+
}
|
|
451
459
|
|
|
452
460
|
interactionManager = new GraphInteractionManager(canvas, spatialIndex, {
|
|
453
461
|
onTransformChange(_transform) {
|