@falkordb/canvas 0.0.41 → 0.0.42
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/canvas-types.d.ts +1 -1
- package/dist/canvas-types.d.ts.map +1 -1
- package/dist/canvas-utils.d.ts +1 -0
- package/dist/canvas-utils.d.ts.map +1 -1
- package/dist/canvas-utils.js +1 -1
- package/dist/canvas-utils.js.map +1 -1
- package/dist/canvas.d.ts +2 -0
- package/dist/canvas.d.ts.map +1 -1
- package/dist/canvas.js +244 -90
- package/dist/canvas.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/canvas-types.ts +1 -1
- package/src/canvas-utils.ts +1 -1
- package/src/canvas.ts +258 -102
- package/src/index.ts +1 -0
package/dist/canvas-types.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export interface ForceGraphConfig {
|
|
|
29
29
|
nodePointerAreaPaint: (node: GraphNode, color: string, ctx: CanvasRenderingContext2D) => void;
|
|
30
30
|
};
|
|
31
31
|
link?: {
|
|
32
|
-
linkCanvasObject: (link: GraphLink, ctx: CanvasRenderingContext2D) => void;
|
|
32
|
+
linkCanvasObject: (link: GraphLink, ctx: CanvasRenderingContext2D, globalScale: number) => void;
|
|
33
33
|
linkPointerAreaPaint: (link: GraphLink, color: string, ctx: CanvasRenderingContext2D) => void;
|
|
34
34
|
};
|
|
35
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-types.d.ts","sourceRoot":"","sources":["../src/canvas-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3D,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3D,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAChE,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAChE,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/C,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/C,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACrD,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IAC9C,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IAC9C,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,MAAM,EAAE,GAAG,IAAI,CAAC;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE;QACL,gBAAgB,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,wBAAwB,KAAK,IAAI,CAAC;QAC3E,oBAAoB,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,wBAAwB,KAAK,IAAI,CAAC;KAC/F,CAAC;IACF,IAAI,CAAC,EAAE;QACL,gBAAgB,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,wBAAwB,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"canvas-types.d.ts","sourceRoot":"","sources":["../src/canvas-types.ts"],"names":[],"mappings":"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"}
|
package/dist/canvas-utils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Data, GraphData, Node, GraphNode } from "./canvas-types.js";
|
|
2
2
|
export declare const LINK_DISTANCE = 45;
|
|
3
|
+
export declare const NODE_SIZE = 9;
|
|
3
4
|
/**
|
|
4
5
|
* Converts Data format to GraphData format
|
|
5
6
|
* Adds runtime properties (x, y, vx, vy, fx, fy, displayName, curve)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-utils.d.ts","sourceRoot":"","sources":["../src/canvas-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,SAAS,EACT,IAAI,EAEJ,SAAS,EAEV,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,aAAa,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"canvas-utils.d.ts","sourceRoot":"","sources":["../src/canvas-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,SAAS,EACT,IAAI,EAEJ,SAAS,EAEV,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,SAAS,IAAI,CAAC;AA0C3B;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,EACV,QAAQ,CAAC,EAAE;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACrC,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,GACnC,SAAS,CAgEX;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAkB1D;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,MAAM,KAAG,MAyDtD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,IAAI,EACV,aAAa,MAAM,EAAE,EACrB,uBAAuB,OAAO,WAS/B,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,MAAM,IAAI,EACV,aAAa,MAAM,EAAE,WAKtB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAClC,KAAK,wBAAwB,EAC7B,MAAM,MAAM,EACZ,WAAW,MAAM,KAChB,CAAC,MAAM,EAAE,MAAM,CAoDjB,CAAC"}
|
package/dist/canvas-utils.js
CHANGED
package/dist/canvas-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-utils.js","sourceRoot":"","sources":["../src/canvas-utils.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAChC,MAAM,SAAS,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"canvas-utils.js","sourceRoot":"","sources":["../src/canvas-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/canvas.d.ts
CHANGED
|
@@ -10,7 +10,9 @@ declare class FalkorDBCanvas extends HTMLElement {
|
|
|
10
10
|
private nodeMode;
|
|
11
11
|
private linkMode;
|
|
12
12
|
private nodeDegreeMap;
|
|
13
|
+
private nodeDisplayFontSize;
|
|
13
14
|
private relationshipsTextCache;
|
|
15
|
+
private onFontsLoadingDone;
|
|
14
16
|
private viewport;
|
|
15
17
|
constructor();
|
|
16
18
|
/**
|
package/dist/canvas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas.d.ts","sourceRoot":"","sources":["../src/canvas.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,IAAI,EACJ,kBAAkB,EAClB,SAAS,EAET,SAAS,EACT,gBAAgB,EAChB,aAAa,EAId,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"canvas.d.ts","sourceRoot":"","sources":["../src/canvas.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,IAAI,EACJ,kBAAkB,EAClB,SAAS,EAET,SAAS,EACT,gBAAgB,EAChB,aAAa,EAId,MAAM,mBAAmB,CAAC;AA6D3B,cAAM,cAAe,SAAQ,WAAW;IACtC,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,SAAS,CAA+B;IAEhD,OAAO,CAAC,cAAc,CAA+B;IAErD,OAAO,CAAC,cAAc,CAA+B;IAErD,OAAO,CAAC,IAAI,CAAuC;IAEnD,OAAO,CAAC,YAAY,CAAkB;IAEtC,OAAO,CAAC,MAAM,CAKZ;IAEF,OAAO,CAAC,QAAQ,CAA+B;IAE/C,OAAO,CAAC,QAAQ,CAA+B;IAE/C,OAAO,CAAC,aAAa,CAAkC;IAGvD,OAAO,CAAC,mBAAmB,CAAkC;IAE7D,OAAO,CAAC,sBAAsB,CAOhB;IAEd,OAAO,CAAC,kBAAkB,CAIxB;IAEF,OAAO,CAAC,QAAQ,CAAgB;;IAOhC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO;IAMzB;;;OAGG;IACH,OAAO,CAAC,GAAG;IAMX,iBAAiB;IAuBjB,oBAAoB;IAapB,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC;IAa3C,QAAQ,CAAC,KAAK,EAAE,MAAM;IAStB,SAAS,CAAC,MAAM,EAAE,MAAM;IASxB,kBAAkB,CAAC,KAAK,EAAE,MAAM;IAahC,kBAAkB,CAAC,KAAK,EAAE,MAAM;IAQhC,YAAY,CAAC,SAAS,EAAE,OAAO;IAO/B,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS;IAW1C,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,IAAI,EAAE,IAAI;IAmClB,WAAW,IAAI,aAAa;IAc5B,WAAW,CAAC,QAAQ,EAAE,aAAa;IAKnC,YAAY,IAAI,SAAS;IAIzB,YAAY,CAAC,IAAI,EAAE,SAAS;IAoB5B,QAAQ,IAAI,kBAAkB,GAAG,SAAS;IAInC,OAAO,IAAI,MAAM;IAIjB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAOvD,SAAS,CAAC,iBAAiB,SAAI,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO;IAkB7E,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,+BAA+B;IAUvC,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,oBAAoB;IAmE5B,OAAO,CAAC,MAAM;IAuBd,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,SAAS;IAoHjB,OAAO,CAAC,WAAW;IAkDnB,OAAO,CAAC,QAAQ;IAqEhB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,QAAQ;IA8ShB,OAAO,CAAC,WAAW;IA4InB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,gBAAgB;IA+CxB,OAAO,CAAC,mBAAmB;IAwF3B,OAAO,CAAC,mBAAmB;CAS5B;AAOD,eAAe,cAAc,CAAC"}
|
package/dist/canvas.js
CHANGED
|
@@ -8,6 +8,11 @@ const ARROW_WH_RATIO = 1.6;
|
|
|
8
8
|
const ARROW_VLEN_RATIO = 0.2;
|
|
9
9
|
// Multiplier to convert node size → cubic bezier control-point distance for self-loops
|
|
10
10
|
const SELF_LOOP_CURVE_FACTOR = 11.67;
|
|
11
|
+
// Base font size used for the initial measurement and for two-line text.
|
|
12
|
+
const NODE_FONT_SIZE_BASE = 2;
|
|
13
|
+
// Fraction of the chord width that single-line text should fill (0–1).
|
|
14
|
+
// Leaves (1 - ratio)/2 of the radius as horizontal padding on each side.
|
|
15
|
+
const NODE_TEXT_FILL_RATIO = 0.85;
|
|
11
16
|
// Force constants
|
|
12
17
|
const CHARGE_STRENGTH = -400;
|
|
13
18
|
const CENTER_STRENGTH = 0.03;
|
|
@@ -62,7 +67,14 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
62
67
|
this.nodeMode = 'replace';
|
|
63
68
|
this.linkMode = 'replace';
|
|
64
69
|
this.nodeDegreeMap = new Map();
|
|
70
|
+
// Per-node font size cache: computed once per node, read every frame.
|
|
71
|
+
this.nodeDisplayFontSize = new Map();
|
|
65
72
|
this.relationshipsTextCache = new Map();
|
|
73
|
+
this.onFontsLoadingDone = () => {
|
|
74
|
+
this.relationshipsTextCache.clear();
|
|
75
|
+
this.nodeDisplayFontSize.clear();
|
|
76
|
+
this.triggerRender();
|
|
77
|
+
};
|
|
66
78
|
this.attachShadow({ mode: "open" });
|
|
67
79
|
}
|
|
68
80
|
/**
|
|
@@ -97,9 +109,14 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
97
109
|
}
|
|
98
110
|
this.log('Component connected to DOM');
|
|
99
111
|
this.render();
|
|
112
|
+
// Text measurements taken before the custom font finishes loading use the
|
|
113
|
+
// fallback system font and produce wrong widths that get locked in the cache.
|
|
114
|
+
// Re-measure on every font-load batch (including the initial one).
|
|
115
|
+
document.fonts.addEventListener("loadingdone", this.onFontsLoadingDone);
|
|
100
116
|
}
|
|
101
117
|
disconnectedCallback() {
|
|
102
118
|
this.log('Component disconnected from DOM');
|
|
119
|
+
document.fonts.removeEventListener("loadingdone", this.onFontsLoadingDone);
|
|
103
120
|
if (this.resizeObserver) {
|
|
104
121
|
this.resizeObserver.disconnect();
|
|
105
122
|
this.resizeObserver = null;
|
|
@@ -477,7 +494,7 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
477
494
|
})
|
|
478
495
|
.linkCanvasObject((link, ctx, globalScale) => {
|
|
479
496
|
if (this.config.link) {
|
|
480
|
-
this.config.link.linkCanvasObject(link, ctx);
|
|
497
|
+
this.config.link.linkCanvasObject(link, ctx, globalScale);
|
|
481
498
|
}
|
|
482
499
|
else {
|
|
483
500
|
this.drawLink(link, ctx, globalScale);
|
|
@@ -541,8 +558,10 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
541
558
|
this.log('Force simulation setup complete');
|
|
542
559
|
}
|
|
543
560
|
drawNode(node, ctx) {
|
|
544
|
-
if (node.x
|
|
545
|
-
|
|
561
|
+
if (node.x === undefined || node.y === undefined) {
|
|
562
|
+
node.x = 0;
|
|
563
|
+
node.y = 0;
|
|
564
|
+
}
|
|
546
565
|
ctx.lineWidth = this.config.isNodeSelected?.(node) ? 1 : 0.5;
|
|
547
566
|
ctx.strokeStyle = this.config.foregroundColor;
|
|
548
567
|
ctx.fillStyle = node.color;
|
|
@@ -557,13 +576,30 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
557
576
|
ctx.fillStyle = getContrastTextColor(node.color);
|
|
558
577
|
ctx.textAlign = "center";
|
|
559
578
|
ctx.textBaseline = "middle";
|
|
560
|
-
ctx.font = "400 2px SofiaSans";
|
|
561
579
|
let [line1, line2] = node.displayName;
|
|
580
|
+
const textRadius = node.size - PADDING / 2;
|
|
562
581
|
if (!line1 && !line2) {
|
|
563
582
|
const text = getNodeDisplayText(node, this.config.captionsKeys, this.config.showPropertyKeyPrefix);
|
|
564
|
-
|
|
583
|
+
// Measure at the base (smallest) size — one cheap measurement.
|
|
584
|
+
ctx.font = `400 ${NODE_FONT_SIZE_BASE}px SofiaSans`;
|
|
565
585
|
[line1, line2] = wrapTextForCircularNode(ctx, text, textRadius);
|
|
586
|
+
let chosenSize = NODE_FONT_SIZE_BASE;
|
|
587
|
+
if (!line2) {
|
|
588
|
+
// Single-line: scale up so the text fills NODE_TEXT_FILL_RATIO of the
|
|
589
|
+
// available chord. Font metrics scale linearly so this is exact.
|
|
590
|
+
const measuredWidth = ctx.measureText(line1).width;
|
|
591
|
+
if (measuredWidth > 0) {
|
|
592
|
+
chosenSize = NODE_FONT_SIZE_BASE * (NODE_TEXT_FILL_RATIO * 2 * textRadius / measuredWidth);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
ctx.font = `400 ${chosenSize}px SofiaSans`;
|
|
566
596
|
node.displayName = [line1, line2];
|
|
597
|
+
this.nodeDisplayFontSize.set(node.id, chosenSize);
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
// Cache hit: the font size was stored when displayName was first computed.
|
|
601
|
+
const chosenSize = this.nodeDisplayFontSize.get(node.id) ?? NODE_FONT_SIZE_BASE;
|
|
602
|
+
ctx.font = `400 ${chosenSize}px SofiaSans`;
|
|
567
603
|
}
|
|
568
604
|
const textMetrics = ctx.measureText(line1);
|
|
569
605
|
const textHeight = textMetrics.actualBoundingBoxAscent +
|
|
@@ -577,8 +613,11 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
577
613
|
}
|
|
578
614
|
}
|
|
579
615
|
pointerNode(node, color, ctx) {
|
|
580
|
-
if (node.x
|
|
581
|
-
|
|
616
|
+
if (node.x === undefined || node.y === undefined) {
|
|
617
|
+
node.x = 0;
|
|
618
|
+
node.y = 0;
|
|
619
|
+
}
|
|
620
|
+
;
|
|
582
621
|
const radius = node.size + PADDING;
|
|
583
622
|
ctx.fillStyle = color;
|
|
584
623
|
ctx.beginPath();
|
|
@@ -588,25 +627,34 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
588
627
|
drawLink(link, ctx, globalScale) {
|
|
589
628
|
const start = link.source;
|
|
590
629
|
const end = link.target;
|
|
591
|
-
if (start.x
|
|
592
|
-
|
|
630
|
+
if (start.x === undefined || start.y === undefined || end.x === undefined || end.y === undefined) {
|
|
631
|
+
start.x = 0;
|
|
632
|
+
start.y = 0;
|
|
633
|
+
end.x = 0;
|
|
634
|
+
end.y = 0;
|
|
635
|
+
}
|
|
593
636
|
let textX;
|
|
594
637
|
let textY;
|
|
595
638
|
let angle;
|
|
639
|
+
const isLinkSelected = this.config.isLinkSelected?.(link) ?? false;
|
|
640
|
+
const arrowLen = isLinkSelected ? 4 : 2;
|
|
641
|
+
// Deferred arrowhead — drawn after the label so it is never covered by
|
|
642
|
+
// the label background rect (which happens for short links where the
|
|
643
|
+
// bezier midpoint and the arrow tip are at almost the same position).
|
|
644
|
+
let pendingArrow = null;
|
|
596
645
|
if (start.id === end.id) {
|
|
597
646
|
const nodeSize = start.size || 6;
|
|
598
647
|
const d = (link.curve || 0) * nodeSize * SELF_LOOP_CURVE_FACTOR;
|
|
599
|
-
ctx.lineWidth = (
|
|
648
|
+
ctx.lineWidth = (isLinkSelected ? 2 : 1) / globalScale;
|
|
600
649
|
ctx.setLineDash(this.config.linkLineDash?.(link) ?? []);
|
|
601
650
|
// The visible outer edge of the node border is nodeSize + strokeWidth
|
|
602
651
|
// (stroke is centered on nodeSize + strokeWidth/2, so outer edge = nodeSize + strokeWidth).
|
|
603
652
|
const nodeStrokeWidth = this.config.isNodeSelected?.(start) ? 1 : 0.5;
|
|
604
|
-
const borderRadius = nodeSize + nodeStrokeWidth;
|
|
653
|
+
const borderRadius = nodeSize + nodeStrokeWidth + PADDING;
|
|
605
654
|
// Binary search for tArrow near 1.0 where the curve is at distance borderRadius
|
|
606
655
|
// from the node center (i.e. on the outer edge of the node border stroke).
|
|
607
656
|
// Bezier parametric form: Bx(t)=sx+3(1-t)t²d, By(t)=sy-3(1-t)²td
|
|
608
657
|
// dist(t) = 3*(1-t)*t*|d|*sqrt(t² + (1-t)²)
|
|
609
|
-
const arrowLen = (this.config.isLinkSelected?.(link) ? 4 : 2) / globalScale;
|
|
610
658
|
const arrowHalfWidth = arrowLen / ARROW_WH_RATIO / 2;
|
|
611
659
|
let lo = 0.5, hi = 1.0;
|
|
612
660
|
const absD = Math.abs(d);
|
|
@@ -659,13 +707,7 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
659
707
|
if (tLen !== 0 && canReachBorder) {
|
|
660
708
|
const nx = tdx / tLen;
|
|
661
709
|
const ny = tdy / tLen;
|
|
662
|
-
|
|
663
|
-
ctx.beginPath();
|
|
664
|
-
ctx.moveTo(tipX, tipY);
|
|
665
|
-
ctx.lineTo(tipX - nx * arrowLen + ny * arrowHalfWidth, tipY - ny * arrowLen - nx * arrowHalfWidth);
|
|
666
|
-
ctx.lineTo(tipX - nx * arrowLen * (1 - ARROW_VLEN_RATIO), tipY - ny * arrowLen * (1 - ARROW_VLEN_RATIO));
|
|
667
|
-
ctx.lineTo(tipX - nx * arrowLen - ny * arrowHalfWidth, tipY - ny * arrowLen + nx * arrowHalfWidth);
|
|
668
|
-
ctx.fill();
|
|
710
|
+
pendingArrow = { tipX, tipY, nx, ny, arrowLen, arrowHalfWidth };
|
|
669
711
|
}
|
|
670
712
|
// Midpoint of cubic bezier: P0=(sx,sy), P1=(sx,sy-d), P2=(sx+d,sy), P3=(sx,sy)
|
|
671
713
|
textX = start.x + 0.375 * d;
|
|
@@ -708,22 +750,12 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
708
750
|
angle = -(Math.PI - angle);
|
|
709
751
|
if (angle < -Math.PI / 2)
|
|
710
752
|
angle = -(-Math.PI - angle);
|
|
711
|
-
//
|
|
712
|
-
// Scale arrow geometry by 1/globalScale so arrowheads remain visually
|
|
713
|
-
// consistent across zoom levels, matching ctx.lineWidth / globalScale.
|
|
714
|
-
const baseArrowLen = this.config.isLinkSelected?.(link) ? 4 : 2;
|
|
715
|
-
const arrowLen = baseArrowLen / globalScale;
|
|
753
|
+
// Draw regular link line and arrowhead
|
|
716
754
|
const arrowHalfWidth = arrowLen / ARROW_WH_RATIO / 2;
|
|
717
|
-
//
|
|
718
|
-
// Q(t) = (1-t)²·start + 2(1-t)t·control + t²·end
|
|
719
|
-
// is at distance borderRadius from the target node centre.
|
|
755
|
+
// Target-side clip: find t where bezier enters target node border + PADDING
|
|
720
756
|
const endNodeSize = end.size || 6;
|
|
721
|
-
const
|
|
722
|
-
const borderRadius = endNodeSize + endNodeStrokeWidth;
|
|
757
|
+
const borderRadius = endNodeSize + (this.config.isNodeSelected?.(end) ? 1 : 0.5) + PADDING;
|
|
723
758
|
const borderRadiusSq = borderRadius * borderRadius;
|
|
724
|
-
// When borderRadius is small relative to the chord length, the bezier and
|
|
725
|
-
// chord diverge only near t=1, so a linear approximation is accurate and
|
|
726
|
-
// avoids the per-frame search cost on large graphs.
|
|
727
759
|
let tArrow;
|
|
728
760
|
if (borderRadius / distance < 0.02) {
|
|
729
761
|
tArrow = Math.min(1, Math.max(0, 1 - borderRadius / distance));
|
|
@@ -747,55 +779,89 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
747
779
|
tArrow = (lo + hi) / 2;
|
|
748
780
|
}
|
|
749
781
|
const uArrow = 1 - tArrow;
|
|
750
|
-
// Tip = Q(tArrow)
|
|
751
782
|
const tipX = uArrow * uArrow * start.x + 2 * uArrow * tArrow * controlX + tArrow * tArrow * end.x;
|
|
752
783
|
const tipY = uArrow * uArrow * start.y + 2 * uArrow * tArrow * controlY + tArrow * tArrow * end.y;
|
|
753
|
-
//
|
|
754
|
-
|
|
755
|
-
const
|
|
756
|
-
const
|
|
784
|
+
// Source-side clip: find t where bezier exits source node border + PADDING
|
|
785
|
+
const startNodeSize = start.size || 6;
|
|
786
|
+
const srcBorderRadius = startNodeSize + (this.config.isNodeSelected?.(start) ? 1 : 0.5) + PADDING;
|
|
787
|
+
const srcBorderRadiusSq = srcBorderRadius * srcBorderRadius;
|
|
788
|
+
let tStart = 0;
|
|
789
|
+
if (srcBorderRadius / distance < 0.02) {
|
|
790
|
+
tStart = Math.min(0.5, srcBorderRadius / distance);
|
|
791
|
+
}
|
|
792
|
+
else {
|
|
793
|
+
let lo = 0.0, hi = 0.5;
|
|
794
|
+
for (let i = 0; i < 10; i++) {
|
|
795
|
+
const mid = (lo + hi) / 2;
|
|
796
|
+
const um = 1 - mid;
|
|
797
|
+
const qx = um * um * start.x + 2 * um * mid * controlX + mid * mid * end.x;
|
|
798
|
+
const qy = um * um * start.y + 2 * um * mid * controlY + mid * mid * end.y;
|
|
799
|
+
const dxSrc = qx - start.x;
|
|
800
|
+
const dySrc = qy - start.y;
|
|
801
|
+
if (dxSrc * dxSrc + dySrc * dySrc < srcBorderRadiusSq)
|
|
802
|
+
lo = mid;
|
|
803
|
+
else
|
|
804
|
+
hi = mid;
|
|
805
|
+
if (hi - lo < 1e-3)
|
|
806
|
+
break;
|
|
807
|
+
}
|
|
808
|
+
tStart = (lo + hi) / 2;
|
|
809
|
+
}
|
|
810
|
+
// Gap start point: Q(tStart)
|
|
811
|
+
const uS = 1 - tStart;
|
|
812
|
+
const gapStartX = uS * uS * start.x + 2 * uS * tStart * controlX + tStart * tStart * end.x;
|
|
813
|
+
const gapStartY = uS * uS * start.y + 2 * uS * tStart * controlY + tStart * tStart * end.y;
|
|
814
|
+
// Sub-bezier [tStart, tArrow] control point via De Casteljau:
|
|
815
|
+
// Right sub-bezier at tStart → NewP1 = lerp(control, end, tStart)
|
|
816
|
+
// Left sub-curve at tArrow' = (tArrow-tStart)/(1-tStart) → ctrl = lerp(gapStart, NewP1, tArrow')
|
|
817
|
+
const tArrowPrime = tStart < tArrow ? (tArrow - tStart) / (1 - tStart) : 0;
|
|
818
|
+
const newP1X = (1 - tStart) * controlX + tStart * end.x;
|
|
819
|
+
const newP1Y = (1 - tStart) * controlY + tStart * end.y;
|
|
820
|
+
const subCtrlX = (1 - tArrowPrime) * gapStartX + tArrowPrime * newP1X;
|
|
821
|
+
const subCtrlY = (1 - tArrowPrime) * gapStartY + tArrowPrime * newP1Y;
|
|
757
822
|
ctx.strokeStyle = link.color;
|
|
758
|
-
ctx.lineWidth = (
|
|
823
|
+
ctx.lineWidth = (isLinkSelected ? 2 : 1) / globalScale;
|
|
759
824
|
ctx.setLineDash(this.config.linkLineDash?.(link) ?? []);
|
|
760
825
|
ctx.beginPath();
|
|
761
|
-
ctx.moveTo(
|
|
762
|
-
ctx.quadraticCurveTo(
|
|
826
|
+
ctx.moveTo(gapStartX, gapStartY);
|
|
827
|
+
ctx.quadraticCurveTo(subCtrlX, subCtrlY, tipX, tipY);
|
|
763
828
|
ctx.stroke();
|
|
764
829
|
ctx.setLineDash([]);
|
|
765
|
-
// Arrowhead tangent at tArrow: Q'(t) = 2(1-t)(control-start) + 2t(end-control)
|
|
766
830
|
const atx = 2 * uArrow * (controlX - start.x) + 2 * tArrow * (end.x - controlX);
|
|
767
831
|
const aty = 2 * uArrow * (controlY - start.y) + 2 * tArrow * (end.y - controlY);
|
|
768
832
|
const atLen = Math.sqrt(atx * atx + aty * aty);
|
|
769
833
|
if (atLen !== 0) {
|
|
770
834
|
const nx = atx / atLen;
|
|
771
835
|
const ny = aty / atLen;
|
|
772
|
-
|
|
773
|
-
ctx.beginPath();
|
|
774
|
-
ctx.moveTo(tipX, tipY);
|
|
775
|
-
ctx.lineTo(tipX - nx * arrowLen + ny * arrowHalfWidth, tipY - ny * arrowLen - nx * arrowHalfWidth);
|
|
776
|
-
ctx.lineTo(tipX - nx * arrowLen * (1 - ARROW_VLEN_RATIO), tipY - ny * arrowLen * (1 - ARROW_VLEN_RATIO));
|
|
777
|
-
ctx.lineTo(tipX - nx * arrowLen - ny * arrowHalfWidth, tipY - ny * arrowLen + nx * arrowHalfWidth);
|
|
778
|
-
ctx.fill();
|
|
836
|
+
pendingArrow = { tipX, tipY, nx, ny, arrowLen, arrowHalfWidth };
|
|
779
837
|
}
|
|
780
838
|
}
|
|
781
|
-
ctx.font = "400 2px SofiaSans";
|
|
839
|
+
ctx.font = isLinkSelected ? "700 2px SofiaSans" : "400 2px SofiaSans";
|
|
782
840
|
ctx.textAlign = "center";
|
|
783
841
|
// Draw text with alphabetic baseline, positioned so visual center is at y=0
|
|
784
842
|
ctx.textBaseline = "alphabetic";
|
|
785
|
-
|
|
843
|
+
// Separate cache entries per weight so each state is measured with its own
|
|
844
|
+
// font, giving equal visual padding regardless of selection state.
|
|
845
|
+
const cacheKey = `${link.relationship}_${isLinkSelected ? "700" : "400"}`;
|
|
846
|
+
let cached = this.relationshipsTextCache.get(cacheKey);
|
|
786
847
|
if (!cached) {
|
|
848
|
+
// ctx.font is already set to the correct weight above; measure it directly.
|
|
787
849
|
const metrics = ctx.measureText(link.relationship);
|
|
788
|
-
// Use
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
//
|
|
792
|
-
const
|
|
850
|
+
// Use actual ink bounds for vertical metrics; fontBoundingBox* is the full
|
|
851
|
+
// line-box and adds excessive space for lighter weights.
|
|
852
|
+
// Use metrics.width for horizontal extent: actualBoundingBoxLeft/Right are
|
|
853
|
+
// unreliable with textAlign="center" and can double the value on some engines.
|
|
854
|
+
const inkAscent = metrics.actualBoundingBoxAscent ?? metrics.fontBoundingBoxAscent;
|
|
855
|
+
const inkDescent = metrics.actualBoundingBoxDescent ?? metrics.fontBoundingBoxDescent;
|
|
856
|
+
const inkWidth = metrics.width;
|
|
857
|
+
const bgPadding = 0.3;
|
|
793
858
|
cached = {
|
|
794
|
-
textWidth:
|
|
795
|
-
textHeight:
|
|
796
|
-
|
|
859
|
+
textWidth: inkWidth + bgPadding * 2,
|
|
860
|
+
textHeight: inkAscent + inkDescent + bgPadding * 2,
|
|
861
|
+
// Shift baseline up so the ink block is centred inside the bg rect.
|
|
862
|
+
textYOffset: (inkAscent - inkDescent) / 2,
|
|
797
863
|
};
|
|
798
|
-
this.relationshipsTextCache.set(
|
|
864
|
+
this.relationshipsTextCache.set(cacheKey, cached);
|
|
799
865
|
}
|
|
800
866
|
const { textWidth, textHeight, textYOffset } = cached;
|
|
801
867
|
ctx.save();
|
|
@@ -808,6 +874,17 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
808
874
|
ctx.fillStyle = getContrastTextColor(this.config.backgroundColor);
|
|
809
875
|
ctx.fillText(link.relationship, 0, textYOffset);
|
|
810
876
|
ctx.restore();
|
|
877
|
+
// Draw arrowhead last so it always appears on top of the label background.
|
|
878
|
+
if (pendingArrow) {
|
|
879
|
+
const { tipX, tipY, nx, ny, arrowLen: aLen, arrowHalfWidth: aHW } = pendingArrow;
|
|
880
|
+
ctx.fillStyle = link.color;
|
|
881
|
+
ctx.beginPath();
|
|
882
|
+
ctx.moveTo(tipX, tipY);
|
|
883
|
+
ctx.lineTo(tipX - nx * aLen + ny * aHW, tipY - ny * aLen - nx * aHW);
|
|
884
|
+
ctx.lineTo(tipX - nx * aLen * (1 - ARROW_VLEN_RATIO), tipY - ny * aLen * (1 - ARROW_VLEN_RATIO));
|
|
885
|
+
ctx.lineTo(tipX - nx * aLen - ny * aHW, tipY - ny * aLen + nx * aHW);
|
|
886
|
+
ctx.fill();
|
|
887
|
+
}
|
|
811
888
|
}
|
|
812
889
|
pointerLink(link, color, ctx) {
|
|
813
890
|
const start = link.source;
|
|
@@ -828,14 +905,38 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
828
905
|
}
|
|
829
906
|
ctx.beginPath();
|
|
830
907
|
if (start.id === end.id) {
|
|
831
|
-
// Self-loop: replicate
|
|
908
|
+
// Self-loop: replicate exact cubic bezier clip from drawLink
|
|
832
909
|
const nodeSize = start.size || 6;
|
|
833
910
|
const d = (link.curve || 0) * nodeSize * SELF_LOOP_CURVE_FACTOR;
|
|
911
|
+
const nodeStrokeWidth = this.config.isNodeSelected?.(start) ? 1 : 0.5;
|
|
912
|
+
const borderRadius = nodeSize + nodeStrokeWidth + PADDING;
|
|
913
|
+
const absD = Math.abs(d);
|
|
914
|
+
const maxReachableDist = 3 * 0.5 * 0.5 * absD * Math.sqrt(0.5);
|
|
915
|
+
const canReachBorder = absD > 0 && maxReachableDist >= borderRadius;
|
|
834
916
|
ctx.moveTo(start.x, start.y);
|
|
835
|
-
|
|
917
|
+
if (canReachBorder) {
|
|
918
|
+
let lo = 0.5, hi = 1.0;
|
|
919
|
+
for (let i = 0; i < 20; i++) {
|
|
920
|
+
const mid = (lo + hi) / 2;
|
|
921
|
+
const um = 1 - mid;
|
|
922
|
+
const dist = 3 * um * mid * absD * Math.sqrt(mid * mid + um * um);
|
|
923
|
+
if (dist > borderRadius)
|
|
924
|
+
lo = mid;
|
|
925
|
+
else
|
|
926
|
+
hi = mid;
|
|
927
|
+
}
|
|
928
|
+
const tArrow = (lo + hi) / 2;
|
|
929
|
+
const uArrow = 1 - tArrow;
|
|
930
|
+
const tipX = start.x + 3 * uArrow * tArrow * tArrow * d;
|
|
931
|
+
const tipY = start.y - 3 * uArrow * uArrow * tArrow * d;
|
|
932
|
+
ctx.bezierCurveTo(start.x, start.y - tArrow * d, start.x + tArrow * tArrow * d, start.y - 2 * tArrow * uArrow * d, tipX, tipY);
|
|
933
|
+
}
|
|
934
|
+
else {
|
|
935
|
+
ctx.bezierCurveTo(start.x, start.y - d, start.x + d, start.y, start.x, start.y);
|
|
936
|
+
}
|
|
836
937
|
}
|
|
837
938
|
else {
|
|
838
|
-
// Regular link: replicate
|
|
939
|
+
// Regular link: replicate exact quadratic bezier clip from drawLink
|
|
839
940
|
const dx = end.x - start.x;
|
|
840
941
|
const dy = end.y - start.y;
|
|
841
942
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
@@ -849,18 +950,71 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
849
950
|
const perpY = -dx / distance;
|
|
850
951
|
const controlX = (start.x + end.x) / 2 + perpX * curvature * distance;
|
|
851
952
|
const controlY = (start.y + end.y) / 2 + perpY * curvature * distance;
|
|
852
|
-
//
|
|
853
|
-
|
|
854
|
-
const
|
|
855
|
-
const
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
953
|
+
// Use the same borderRadius and binary-search clip as drawLink
|
|
954
|
+
const endNodeSize = end.size || 6;
|
|
955
|
+
const borderRadius = endNodeSize + (this.config.isNodeSelected?.(end) ? 1 : 0.5) + PADDING;
|
|
956
|
+
const borderRadiusSq = borderRadius * borderRadius;
|
|
957
|
+
let tArrow;
|
|
958
|
+
if (borderRadius / distance < 0.02) {
|
|
959
|
+
tArrow = Math.min(1, Math.max(0, 1 - borderRadius / distance));
|
|
960
|
+
}
|
|
961
|
+
else {
|
|
962
|
+
let lo = 0.5, hi = 1.0;
|
|
963
|
+
for (let i = 0; i < 10; i++) {
|
|
964
|
+
const mid = (lo + hi) / 2;
|
|
965
|
+
const um = 1 - mid;
|
|
966
|
+
const qx = um * um * start.x + 2 * um * mid * controlX + mid * mid * end.x;
|
|
967
|
+
const qy = um * um * start.y + 2 * um * mid * controlY + mid * mid * end.y;
|
|
968
|
+
const dxEnd = qx - end.x;
|
|
969
|
+
const dyEnd = qy - end.y;
|
|
970
|
+
if (dxEnd * dxEnd + dyEnd * dyEnd > borderRadiusSq)
|
|
971
|
+
lo = mid;
|
|
972
|
+
else
|
|
973
|
+
hi = mid;
|
|
974
|
+
if (hi - lo < 1e-3)
|
|
975
|
+
break;
|
|
976
|
+
}
|
|
977
|
+
tArrow = (lo + hi) / 2;
|
|
978
|
+
}
|
|
979
|
+
const uArrow = 1 - tArrow;
|
|
980
|
+
const tipX = uArrow * uArrow * start.x + 2 * uArrow * tArrow * controlX + tArrow * tArrow * end.x;
|
|
981
|
+
const tipY = uArrow * uArrow * start.y + 2 * uArrow * tArrow * controlY + tArrow * tArrow * end.y;
|
|
982
|
+
// Source-side clip: mirror of drawLink source gap
|
|
983
|
+
const startNodeSize = start.size || 6;
|
|
984
|
+
const srcBorderRadius = startNodeSize + (this.config.isNodeSelected?.(start) ? 1 : 0.5) + PADDING;
|
|
985
|
+
const srcBorderRadiusSq = srcBorderRadius * srcBorderRadius;
|
|
986
|
+
let tStart = 0;
|
|
987
|
+
if (srcBorderRadius / distance < 0.02) {
|
|
988
|
+
tStart = Math.min(0.5, srcBorderRadius / distance);
|
|
989
|
+
}
|
|
990
|
+
else {
|
|
991
|
+
let lo = 0.0, hi = 0.5;
|
|
992
|
+
for (let i = 0; i < 10; i++) {
|
|
993
|
+
const mid = (lo + hi) / 2;
|
|
994
|
+
const um = 1 - mid;
|
|
995
|
+
const qx = um * um * start.x + 2 * um * mid * controlX + mid * mid * end.x;
|
|
996
|
+
const qy = um * um * start.y + 2 * um * mid * controlY + mid * mid * end.y;
|
|
997
|
+
const dxSrc = qx - start.x;
|
|
998
|
+
const dySrc = qy - start.y;
|
|
999
|
+
if (dxSrc * dxSrc + dySrc * dySrc < srcBorderRadiusSq)
|
|
1000
|
+
lo = mid;
|
|
1001
|
+
else
|
|
1002
|
+
hi = mid;
|
|
1003
|
+
if (hi - lo < 1e-3)
|
|
1004
|
+
break;
|
|
1005
|
+
}
|
|
1006
|
+
tStart = (lo + hi) / 2;
|
|
1007
|
+
}
|
|
1008
|
+
const uS = 1 - tStart;
|
|
1009
|
+
const gapStartX = uS * uS * start.x + 2 * uS * tStart * controlX + tStart * tStart * end.x;
|
|
1010
|
+
const gapStartY = uS * uS * start.y + 2 * uS * tStart * controlY + tStart * tStart * end.y;
|
|
1011
|
+
const tArrowPrime = tStart < tArrow ? (tArrow - tStart) / (1 - tStart) : 0;
|
|
1012
|
+
const newP1X = (1 - tStart) * controlX + tStart * end.x;
|
|
1013
|
+
const newP1Y = (1 - tStart) * controlY + tStart * end.y;
|
|
1014
|
+
const subCtrlX = (1 - tArrowPrime) * gapStartX + tArrowPrime * newP1X;
|
|
1015
|
+
const subCtrlY = (1 - tArrowPrime) * gapStartY + tArrowPrime * newP1Y;
|
|
1016
|
+
ctx.moveTo(gapStartX, gapStartY);
|
|
1017
|
+
ctx.quadraticCurveTo(subCtrlX, subCtrlY, tipX, tipY);
|
|
864
1018
|
}
|
|
865
1019
|
}
|
|
866
1020
|
ctx.stroke();
|
|
@@ -987,28 +1141,28 @@ class FalkorDBCanvas extends HTMLElement {
|
|
|
987
1141
|
})
|
|
988
1142
|
.linkCanvasObject((link, ctx, globalScale) => {
|
|
989
1143
|
if (this.config.link) {
|
|
990
|
-
this.config.link.linkCanvasObject(link, ctx);
|
|
1144
|
+
this.config.link.linkCanvasObject(link, ctx, globalScale);
|
|
991
1145
|
}
|
|
992
1146
|
else {
|
|
993
1147
|
this.drawLink(link, ctx, globalScale);
|
|
994
1148
|
}
|
|
995
|
-
})
|
|
996
|
-
|
|
997
|
-
|
|
1149
|
+
});
|
|
1150
|
+
if (this.config.node) {
|
|
1151
|
+
this.graph.nodePointerAreaPaint((node, color, ctx) => {
|
|
998
1152
|
this.config.node.nodePointerAreaPaint(node, color, ctx);
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
else {
|
|
1156
|
+
this.graph.nodePointerAreaPaint();
|
|
1157
|
+
}
|
|
1158
|
+
if (this.config.link) {
|
|
1159
|
+
this.graph.linkPointerAreaPaint((link, color, ctx) => {
|
|
1006
1160
|
this.config.link.linkPointerAreaPaint(link, color, ctx);
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
}
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
else {
|
|
1164
|
+
this.graph.linkPointerAreaPaint();
|
|
1165
|
+
}
|
|
1012
1166
|
}
|
|
1013
1167
|
updateTooltipStyles() {
|
|
1014
1168
|
if (!this.shadowRoot)
|