@hpcc-js/graph 3.3.0 → 3.3.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hpcc-js/graph",
3
- "version": "3.3.0",
3
+ "version": "3.3.2",
4
4
  "description": "hpcc-js - Viz Graph",
5
5
  "type": "module",
6
6
  "main": "./dist/index.umd.cjs",
@@ -44,6 +44,9 @@
44
44
  "@hpcc-js/react": "^3.2.1",
45
45
  "@hpcc-js/util": "^3.3.0"
46
46
  },
47
+ "optionalPeerDependencies": {
48
+ "react": ">=18.0.0"
49
+ },
47
50
  "devDependencies": {
48
51
  "@hpcc-js/esbuild-plugins": "^1.4.0",
49
52
  "@hpcc-js/wasm-graphviz": "1.6.1",
@@ -70,5 +73,5 @@
70
73
  "url": "https://github.com/hpcc-systems/Visualization/issues"
71
74
  },
72
75
  "homepage": "https://github.com/hpcc-systems/Visualization",
73
- "gitHead": "220704148d2a9cc72a4bfa5160107d6fdf37c914"
76
+ "gitHead": "a44813b7ce9c2bbf98a239f88005993513b8be13"
74
77
  }
@@ -564,9 +564,6 @@ export class GraphT<SG extends SubgraphBaseProps, V extends VertexBaseProps, E e
564
564
  moveEdgePlaceholder(ep: EdgePlaceholder<V, E>, transition: boolean): this {
565
565
  const edgeLayout = {
566
566
  ...this._layoutAlgo.edgePath(ep as any, this.edgeArcDepth()),
567
- markerStart: `url(#${this.id()}_circleFoot)`,
568
- markerEnd: `url(#${this.id()}_arrowHead)`,
569
-
570
567
  };
571
568
  const context = this;
572
569
  if (this._edgeRenderer && ep.element) {
@@ -877,57 +874,6 @@ export class GraphT<SG extends SubgraphBaseProps, V extends VertexBaseProps, E e
877
874
  return this;
878
875
  }
879
876
 
880
- addMarkers(clearFirst: boolean = false) {
881
- if (clearFirst) {
882
- this._svgDefs.select("#" + this._id + "_arrowHead").remove();
883
- this._svgDefs.select("#" + this._id + "_circleFoot").remove();
884
- this._svgDefs.select("#" + this._id + "_circleHead").remove();
885
- }
886
- this._svgDefs.append("marker")
887
- .attr("class", "marker")
888
- .attr("id", this._id + "_arrowHead")
889
- .attr("viewBox", "0 0 10 10")
890
- .attr("refX", 10)
891
- .attr("refY", 5)
892
- .attr("markerWidth", 8)
893
- .attr("markerHeight", 8)
894
- .attr("markerUnits", "strokeWidth")
895
- .attr("orient", "auto")
896
- .append("polyline")
897
- .attr("points", "0,0 10,5 0,10 1,5")
898
- ;
899
- this._svgDefs.append("marker")
900
- .attr("class", "marker")
901
- .attr("id", this._id + "_circleFoot")
902
- .attr("viewBox", "0 0 10 10")
903
- .attr("refX", 1)
904
- .attr("refY", 5)
905
- .attr("markerWidth", 7)
906
- .attr("markerHeight", 7)
907
- .attr("markerUnits", "strokeWidth")
908
- .attr("orient", "auto")
909
- .append("circle")
910
- .attr("cx", 5)
911
- .attr("cy", 5)
912
- .attr("r", 4)
913
- ;
914
- this._svgDefs.append("marker")
915
- .attr("class", "marker")
916
- .attr("id", this._id + "_circleHead")
917
- .attr("viewBox", "0 0 10 10")
918
- .attr("refX", 9)
919
- .attr("refY", 5)
920
- .attr("markerWidth", 7)
921
- .attr("markerHeight", 7)
922
- .attr("markerUnits", "strokeWidth")
923
- .attr("orient", "auto")
924
- .append("circle")
925
- .attr("cx", 5)
926
- .attr("cy", 5)
927
- .attr("r", 4)
928
- ;
929
- }
930
-
931
877
  enter(domNode, element) {
932
878
  super.enter(domNode, element);
933
879
 
@@ -936,7 +882,6 @@ export class GraphT<SG extends SubgraphBaseProps, V extends VertexBaseProps, E e
936
882
  this._centroidFilter = new SVGGlowFilter(this._svgDefs, this._id + "_glow");
937
883
  this._svgDefsCat = this._svgDefs.append("g");
938
884
  this._svgDefsAnn = this._svgDefs.append("g");
939
- this.addMarkers();
940
885
  this._subgraphG = this._renderElement.append("g");
941
886
  this._edgeG = this._renderElement.append("g");
942
887
  this._vertexG = this._renderElement.append("g");
@@ -2,7 +2,6 @@ import { Graph2 as GraphCollection } from "@hpcc-js/util";
2
2
  import { curveBasis as d3CurveBasis, curveCardinal as d3CurveCardinal, line as d3Line } from "d3-shape";
3
3
  import { EdgePlaceholder, SubgraphPlaceholder, VertexPlaceholder } from "./placeholders.ts";
4
4
  import { EdgeLayout } from "./tree.ts";
5
- import { intersection } from "./pathIntersection.ts";
6
5
 
7
6
  export type Point = [number, number];
8
7
 
@@ -105,8 +104,8 @@ export class Layout implements ILayout {
105
104
  edgeLine(ep: EdgePlaceholder): Line {
106
105
  const sPos = { ...this._graph.projectPlacholder(ep.source), w: ep.source?.renderResult?.extent?.width ?? 0, h: ep.source?.renderResult?.extent?.height ?? 0 };
107
106
  const tPos = { ...this._graph.projectPlacholder(ep.target), w: ep.target?.renderResult?.extent?.width ?? 0, h: ep.target?.renderResult?.extent?.height ?? 0 };
108
- const sIntersect = intersection(sPos, { start: sPos, end: tPos });
109
- const tIntersect = intersection(tPos, { start: sPos, end: tPos });
107
+ const sIntersect = ep.source.renderResult?.intersection ? ep.source.renderResult.intersection(sPos, { start: sPos, end: tPos }) : null;
108
+ const tIntersect = ep.target.renderResult?.intersection ? ep.target.renderResult.intersection(tPos, { start: sPos, end: tPos }) : null;
110
109
  return {
111
110
  source: {
112
111
  x: sIntersect ? sIntersect.x : sPos.x,
@@ -33,8 +33,6 @@ export interface EdgeBaseProps<V extends VertexBaseProps = VertexBaseProps> exte
33
33
  stroke?: string;
34
34
  path?: string;
35
35
  fontFamily?: string;
36
- markerStart?: string;
37
- markerEnd?: string;
38
36
  }
39
37
 
40
38
  export interface HierarchyBase<SG extends SubgraphBaseProps, V extends VertexBaseProps> {
@@ -1,13 +1,17 @@
1
1
  import type { HTMLTemplateResult, SVGTemplateResult } from "lit-html";
2
+ import type { Pos, Segment, Extent } from "./intersection.ts";
2
3
 
3
4
  export type TemplateResult = HTMLTemplateResult | SVGTemplateResult;
5
+ export type IntersectionFunc = (pos: Pos, line: Segment) => Pos | null;
4
6
  export type TemplateResultEx = TemplateResult & {
5
- extent?: { width: number, height: number };
7
+ extent?: Extent;
8
+ intersection: IntersectionFunc;
6
9
  };
7
- export function extend(result: TemplateResult, width: number, height: number): TemplateResultEx {
10
+ export function extend(result: TemplateResult, width: number, height: number, intersection: IntersectionFunc = (pos: Pos, line: Segment) => null): TemplateResultEx {
8
11
  return {
9
12
  ...result,
10
- extent: { width, height }
13
+ extent: { width, height },
14
+ intersection
11
15
  };
12
16
  }
13
17
  export type Component<T> = (props: T) => TemplateResult;
@@ -0,0 +1,15 @@
1
+ import { svg } from "lit-html";
2
+ import type { SubgraphBaseProps, EdgeBaseProps, VertexBaseProps } from "../common/layouts/placeholders.ts";
3
+ import { GraphHtmlT } from "./graphHtmlT.ts";
4
+
5
+ export interface EdgeProps<V extends VertexBaseProps> extends EdgeBaseProps<V> {
6
+ graphInstance: GraphHtmlT<SubgraphBaseProps, V, EdgeProps<V>>;
7
+ }
8
+
9
+ export const edge = ({
10
+ graphInstance,
11
+ strokeWidth,
12
+ path
13
+ }: EdgeProps<VertexBaseProps>) => {
14
+ return svg`<path d="${path}" marker-start="url(#${graphInstance.id()}_source${graphInstance.sourceMarker()})" marker-end="url(#${graphInstance.id()}_target${graphInstance.targetMarker()})" style="stroke-width:${strokeWidth}px"></path>`;
15
+ };
@@ -1,9 +1,11 @@
1
1
  import { GraphHtmlT, SubgraphBaseProps, EdgeBaseProps } from "./graphHtmlT.ts";
2
2
  import { vertex, VertexProps } from "./vertex.ts";
3
+ import { edge, EdgeProps } from "./edge.ts";
4
+ import { Vertex } from "@hpcc-js/util";
3
5
 
4
- export class GraphHtml extends GraphHtmlT<SubgraphBaseProps, VertexProps, EdgeBaseProps> {
6
+ export class GraphHtml extends GraphHtmlT<SubgraphBaseProps, VertexProps, EdgeProps<VertexProps>> {
5
7
  constructor() {
6
- super(undefined, vertex);
8
+ super(undefined, vertex, edge);
7
9
  }
8
10
 
9
11
  }
@@ -33,11 +33,9 @@ const defaultVertexRenderer = ({
33
33
 
34
34
  const defaultEdgeRenderer = ({
35
35
  strokeWidth,
36
- path,
37
- markerStart,
38
- markerEnd,
36
+ path
39
37
  }: EdgeBaseProps<VertexBaseProps>) => {
40
- return svg`<path d="${path}" marker-start="${markerStart}" marker-end="${markerEnd}" style="stroke-width:${strokeWidth}px"></path>`;
38
+ return svg`<path d="${path}" style="stroke-width:${strokeWidth}px"></path>`;
41
39
  };
42
40
 
43
41
  export class GraphHtmlT<SG extends SubgraphBaseProps, V extends VertexBaseProps, E extends EdgeBaseProps<V>> extends GraphT<SG, V, E> {
@@ -45,5 +43,75 @@ export class GraphHtmlT<SG extends SubgraphBaseProps, V extends VertexBaseProps,
45
43
  constructor(subgraphRenderer: Component<SG> = defaultSubgraphRenderer, vertexRenderer: Component<V> = defaultVertexRenderer, edgeRenderer: Component<E> = defaultEdgeRenderer) {
46
44
  super(adapter(subgraphRenderer), adapter<V>(vertexRenderer), adapter(edgeRenderer));
47
45
  }
46
+
47
+ enterMarkers(clearFirst: boolean = false) {
48
+ if (clearFirst) {
49
+ this._svgDefs.select("#" + this._id + "_sourceDot").remove();
50
+ this._svgDefs.select("#" + this._id + "_targetDot").remove();
51
+ this._svgDefs.select("#" + this._id + "_targetArrow").remove();
52
+ }
53
+ this._svgDefs.append("marker")
54
+ .attr("class", "marker")
55
+ .attr("id", this._id + "_sourceDot")
56
+ .attr("refX", 1)
57
+ .attr("refY", 3)
58
+ .attr("markerWidth", 6)
59
+ .attr("markerHeight", 6)
60
+ .attr("markerUnits", "strokeWidth")
61
+ .attr("orient", "auto")
62
+ .append("circle")
63
+ .attr("cx", 3)
64
+ .attr("cy", 3)
65
+ .attr("r", 1.5)
66
+ .attr("fill", "context-stroke")
67
+ .attr("stroke", "context-stroke")
68
+ ;
69
+ this._svgDefs.append("marker")
70
+ .attr("class", "marker")
71
+ .attr("id", this._id + "_targetDot")
72
+ .attr("refX", 5)
73
+ .attr("refY", 3)
74
+ .attr("markerWidth", 6)
75
+ .attr("markerHeight", 6)
76
+ .attr("markerUnits", "strokeWidth")
77
+ .attr("orient", "auto")
78
+ .append("circle")
79
+ .attr("cx", 3)
80
+ .attr("cy", 3)
81
+ .attr("r", 1.5)
82
+ .attr("fill", "context-stroke")
83
+ .attr("stroke", "context-stroke")
84
+ ;
85
+ this._svgDefs.append("marker")
86
+ .attr("class", "marker")
87
+ .attr("id", this._id + "_targetArrow")
88
+ .attr("viewBox", "0 0 10 10")
89
+ .attr("refX", 10)
90
+ .attr("refY", 5)
91
+ .attr("markerWidth", 5)
92
+ .attr("markerHeight", 5)
93
+ .attr("markerUnits", "strokeWidth")
94
+ .attr("orient", "auto")
95
+ .append("polyline")
96
+ .attr("points", "0,0 10,5 0,10 0,5")
97
+ .attr("fill", "context-stroke")
98
+ .attr("stroke", "context-stroke")
99
+ ;
100
+ }
101
+
102
+ enter(domNode, element) {
103
+ super.enter(domNode, element);
104
+ this.enterMarkers();
105
+ }
48
106
  }
49
107
  GraphHtmlT.prototype._class += " graph_GraphHtmlT";
108
+
109
+ export interface GraphHtmlT<SG extends SubgraphBaseProps, V extends VertexBaseProps, E extends EdgeBaseProps<V>> extends GraphT<SG, V, E> {
110
+ sourceMarker(): "Dot" | "None";
111
+ sourceMarker(_: "Dot" | "None"): this;
112
+ targetMarker(): "Arrow" | "Dot" | "None";
113
+ targetMarker(_: "Arrow" | "Dot" | "None"): this;
114
+ }
115
+
116
+ GraphHtmlT.prototype.publish("sourceMarker", "Dot", "set", "Target Marker", ["Dot", "None"]);
117
+ GraphHtmlT.prototype.publish("targetMarker", "Arrow", "set", "Target Marker", ["Arrow", "Dot", "None"]);
package/src/html/icon.ts CHANGED
@@ -59,6 +59,6 @@ export function icon({
59
59
  <g>
60
60
  ${shapeTpl}
61
61
  ${imageTpl}
62
- </g>`, shapeTpl.extent.width, shapeTpl.extent.height);
62
+ </g>`, shapeTpl.extent.width, shapeTpl.extent.height, shapeTpl.intersection);
63
63
  };
64
64
 
@@ -0,0 +1,110 @@
1
+ export interface Pos {
2
+ x: number;
3
+ y: number;
4
+ }
5
+
6
+ export interface Extent {
7
+ width: number;
8
+ height: number;
9
+ }
10
+
11
+ export interface Segment {
12
+ start: Pos;
13
+ end: Pos;
14
+ }
15
+
16
+ export interface Rectangle {
17
+ x: number;
18
+ y: number;
19
+ width: number;
20
+ height: number;
21
+ }
22
+
23
+ function segmentSegment(s1: Segment, s2: Segment): Pos | undefined {
24
+ const { x: x1, y: y1 } = s1.start;
25
+ const { x: x2, y: y2 } = s1.end;
26
+ const { x: x3, y: y3 } = s2.start;
27
+ const { x: x4, y: y4 } = s2.end;
28
+
29
+ const denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
30
+ if (denom === 0) {
31
+ // Parallel lines ---
32
+ return undefined;
33
+ }
34
+
35
+ const t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom;
36
+ const u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / denom;
37
+
38
+ if (t > 0 && t < 1 && u > 0 && u < 1) {
39
+ return {
40
+ x: x1 + t * (x2 - x1),
41
+ y: y1 + t * (y2 - y1)
42
+ };
43
+ }
44
+
45
+ return undefined;
46
+ }
47
+
48
+ function rectEdges(rect: Rectangle): Segment[] {
49
+ const r = {
50
+ topLeft: { x: rect.x - rect.width / 2, y: rect.y - rect.height / 2 },
51
+ topRight: { x: rect.x + rect.width / 2, y: rect.y - rect.height / 2 },
52
+ bottomRight: { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 },
53
+ bottomLeft: { x: rect.x - rect.width / 2, y: rect.y + rect.height / 2 }
54
+ };
55
+ return [
56
+ { start: r.bottomLeft, end: r.topLeft },
57
+ { start: r.topLeft, end: r.topRight },
58
+ { start: r.topRight, end: r.bottomRight },
59
+ { start: r.bottomRight, end: r.bottomLeft },
60
+ ];
61
+ }
62
+
63
+ export function rectangleSegment(rect: Rectangle, line: Segment): Pos | undefined {
64
+ for (const edge of rectEdges(rect)) {
65
+ const intersectionPoint = segmentSegment(edge, line);
66
+ if (intersectionPoint) {
67
+ return intersectionPoint;
68
+ }
69
+ }
70
+ return undefined;
71
+ }
72
+
73
+ function sortSegment(pos: Pos, line: Segment): Segment {
74
+ const distStart = Math.hypot(line.start.x - pos.x, line.start.y - pos.y);
75
+ const distEnd = Math.hypot(line.end.x - pos.x, line.end.y - pos.y);
76
+
77
+ if (distStart <= distEnd) {
78
+ return line;
79
+ } else {
80
+ return { start: line.end, end: line.start };
81
+ }
82
+ }
83
+
84
+ export function circleSegment(pos: Pos, r: number, line: Segment): Pos | undefined {
85
+ line = sortSegment(pos, line);
86
+ const { x: x1, y: y1 } = line.start;
87
+ const { x: x2, y: y2 } = line.end;
88
+
89
+ const dx = x2 - x1;
90
+ const dy = y2 - y1;
91
+
92
+ const a = dx * dx + dy * dy;
93
+ const b = 2 * (dx * (x1 - pos.x) + dy * (y1 - pos.y));
94
+ const c = (x1 - pos.x) * (x1 - pos.x) + (y1 - pos.y) * (y1 - pos.y) - r * r;
95
+
96
+ const discriminant = b * b - 4 * a * c;
97
+
98
+ if (discriminant < 0) {
99
+ return undefined;
100
+ }
101
+
102
+ const t1 = (-b + Math.sqrt(discriminant)) / (2 * a);
103
+
104
+ if (t1 >= 0 && t1 <= 1) {
105
+ return {
106
+ x: x1 + t1 * dx,
107
+ y: y1 + t1 * dy
108
+ };
109
+ }
110
+ }
package/src/html/shape.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { svg } from "lit-html";
2
2
  import { extend } from "./component.ts";
3
+ import { circleSegment, rectangleSegment } from "./intersection.ts";
3
4
 
4
5
  export const DEFAULT_SHAPE_SIZE = 32;
5
6
 
@@ -27,7 +28,9 @@ export const circle = ({
27
28
  stroke=${stroke}
28
29
  stroke-width=${strokeWidth}
29
30
  shape-rendering=${shapeRendering}
30
- />`, diameter, diameter);
31
+ />`, diameter, diameter, (pos, line) => {
32
+ return circleSegment(pos, diameter / 2, line);
33
+ });
31
34
  };
32
35
 
33
36
  export interface RectangleProps extends BaseProps {
@@ -57,7 +60,9 @@ export const rectangle = ({
57
60
  stroke=${stroke}
58
61
  stroke-width=${strokeWidth}
59
62
  shape-rendering=${shapeRendering}
60
- />`, width, height);
63
+ />`, width, height, (pos, line) => {
64
+ return rectangleSegment({ x: pos.x, y: pos.y, width, height }, line);
65
+ });
61
66
  };
62
67
 
63
68
  export interface SquareProps extends BaseProps {
@@ -36,6 +36,10 @@ export const TextBox = ({
36
36
 
37
37
  return extend(svg`\
38
38
  ${rectTpl}
39
- ${textTpl}`, rectTpl.extent.width, rectTpl.extent.height);
39
+ ${textTpl}`,
40
+ rectTpl.extent.width,
41
+ rectTpl.extent.height,
42
+ rectTpl.intersection
43
+ );
40
44
  };
41
45
 
@@ -18,7 +18,6 @@ export interface VertexProps extends VertexBaseProps {
18
18
  }
19
19
 
20
20
  export const vertex: Component<VertexProps> = ({
21
- id,
22
21
  text,
23
22
  textBox,
24
23
  textBoxAnnotationsE = [],
@@ -61,5 +60,8 @@ ${textBoxTpl}
61
60
  <g transform="translate(${iconAnnotationsTpl.extent.width / 2 + xIconAnnotationOffset} ${yIconOffset - yIconAnnotationOffset})">
62
61
  ${iconAnnotationsTpl}
63
62
  </g>
64
- `, textBoxTpl.extent.width, textBoxTpl.extent.height);
63
+ `, textBoxTpl.extent.width, textBoxTpl.extent.height, (pos, line) => {
64
+ return iconTpl.intersection({ x: pos.x, y: yIconOffset + pos.y }, line) ??
65
+ textBoxTpl.intersection({ x: pos.x, y: pos.y }, line);
66
+ });
65
67
  };
@@ -112,7 +112,6 @@ export declare class GraphT<SG extends SubgraphBaseProps, V extends VertexBasePr
112
112
  subgraphRenderer(): RendererT<SG>;
113
113
  subgraphRenderer(_: RendererT<SG>): this;
114
114
  updateSubgraphs(): this;
115
- addMarkers(clearFirst?: boolean): void;
116
115
  enter(domNode: any, element: any): void;
117
116
  protected forceDirectedOptions(): FDOptions;
118
117
  private layoutOptions;
@@ -28,8 +28,6 @@ export interface EdgeBaseProps<V extends VertexBaseProps = VertexBaseProps> exte
28
28
  stroke?: string;
29
29
  path?: string;
30
30
  fontFamily?: string;
31
- markerStart?: string;
32
- markerEnd?: string;
33
31
  }
34
32
  export interface HierarchyBase<SG extends SubgraphBaseProps, V extends VertexBaseProps> {
35
33
  id: string | number;
@@ -1,10 +1,10 @@
1
1
  import type { HTMLTemplateResult, SVGTemplateResult } from "lit-html";
2
+ import type { Pos, Segment, Extent } from "./intersection.ts";
2
3
  export type TemplateResult = HTMLTemplateResult | SVGTemplateResult;
4
+ export type IntersectionFunc = (pos: Pos, line: Segment) => Pos | null;
3
5
  export type TemplateResultEx = TemplateResult & {
4
- extent?: {
5
- width: number;
6
- height: number;
7
- };
6
+ extent?: Extent;
7
+ intersection: IntersectionFunc;
8
8
  };
9
- export declare function extend(result: TemplateResult, width: number, height: number): TemplateResultEx;
9
+ export declare function extend(result: TemplateResult, width: number, height: number, intersection?: IntersectionFunc): TemplateResultEx;
10
10
  export type Component<T> = (props: T) => TemplateResult;
@@ -0,0 +1,6 @@
1
+ import type { SubgraphBaseProps, EdgeBaseProps, VertexBaseProps } from "../common/layouts/placeholders.ts";
2
+ import { GraphHtmlT } from "./graphHtmlT.ts";
3
+ export interface EdgeProps<V extends VertexBaseProps> extends EdgeBaseProps<V> {
4
+ graphInstance: GraphHtmlT<SubgraphBaseProps, V, EdgeProps<V>>;
5
+ }
6
+ export declare const edge: ({ graphInstance, strokeWidth, path }: EdgeProps<VertexBaseProps>) => import("lit-html").TemplateResult<2>;
@@ -1,5 +1,6 @@
1
- import { GraphHtmlT, SubgraphBaseProps, EdgeBaseProps } from "./graphHtmlT.ts";
1
+ import { GraphHtmlT, SubgraphBaseProps } from "./graphHtmlT.ts";
2
2
  import { VertexProps } from "./vertex.ts";
3
- export declare class GraphHtml extends GraphHtmlT<SubgraphBaseProps, VertexProps, EdgeBaseProps> {
3
+ import { EdgeProps } from "./edge.ts";
4
+ export declare class GraphHtml extends GraphHtmlT<SubgraphBaseProps, VertexProps, EdgeProps<VertexProps>> {
4
5
  constructor();
5
6
  }
@@ -6,4 +6,12 @@ export { html, svg, EdgeBaseProps, SubgraphBaseProps, VertexBaseProps };
6
6
  export declare function adapter<T extends BaseProps>(component: Component<T>): RendererT<T>;
7
7
  export declare class GraphHtmlT<SG extends SubgraphBaseProps, V extends VertexBaseProps, E extends EdgeBaseProps<V>> extends GraphT<SG, V, E> {
8
8
  constructor(subgraphRenderer?: Component<SG>, vertexRenderer?: Component<V>, edgeRenderer?: Component<E>);
9
+ enterMarkers(clearFirst?: boolean): void;
10
+ enter(domNode: any, element: any): void;
11
+ }
12
+ export interface GraphHtmlT<SG extends SubgraphBaseProps, V extends VertexBaseProps, E extends EdgeBaseProps<V>> extends GraphT<SG, V, E> {
13
+ sourceMarker(): "Dot" | "None";
14
+ sourceMarker(_: "Dot" | "None"): this;
15
+ targetMarker(): "Arrow" | "Dot" | "None";
16
+ targetMarker(_: "Arrow" | "Dot" | "None"): this;
9
17
  }
@@ -0,0 +1,20 @@
1
+ export interface Pos {
2
+ x: number;
3
+ y: number;
4
+ }
5
+ export interface Extent {
6
+ width: number;
7
+ height: number;
8
+ }
9
+ export interface Segment {
10
+ start: Pos;
11
+ end: Pos;
12
+ }
13
+ export interface Rectangle {
14
+ x: number;
15
+ y: number;
16
+ width: number;
17
+ height: number;
18
+ }
19
+ export declare function rectangleSegment(rect: Rectangle, line: Segment): Pos | undefined;
20
+ export declare function circleSegment(pos: Pos, r: number, line: Segment): Pos | undefined;
@@ -1,67 +0,0 @@
1
- export interface Pos {
2
- x: number;
3
- y: number;
4
- }
5
-
6
- export interface Segment {
7
- start: Pos;
8
- end: Pos;
9
- }
10
-
11
- export interface Rectangle {
12
- topLeft: Pos;
13
- topRight: Pos;
14
- bottomLeft: Pos;
15
- bottomRight: Pos;
16
- }
17
-
18
- export interface Rectangle2 {
19
- x: number;
20
- y: number;
21
- w: number;
22
- h: number;
23
- }
24
-
25
- function rectEdges(rect: Rectangle) {
26
- return [
27
- { start: rect.topLeft, end: rect.topRight },
28
- { start: rect.topRight, end: rect.bottomRight },
29
- { start: rect.bottomRight, end: rect.bottomLeft },
30
- { start: rect.bottomLeft, end: rect.topLeft }
31
- ];
32
- }
33
-
34
- function lineIntersection(segment1: Segment, segment2: Segment) {
35
- const { x: x1, y: y1 } = segment1.start;
36
- const { x: x2, y: y2 } = segment1.end;
37
- const { x: x3, y: y3 } = segment2.start;
38
- const { x: x4, y: y4 } = segment2.end;
39
-
40
- const denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
41
- if (denom === 0) return null; // Parallel lines
42
-
43
- const t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom;
44
- const u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / denom;
45
-
46
- if (t > 0 && t < 1 && u > 0 && u < 1) {
47
- return {
48
- x: x1 + t * (x2 - x1),
49
- y: y1 + t * (y2 - y1)
50
- };
51
- }
52
-
53
- return null; // No intersection
54
- }
55
-
56
- export function intersection(rect: Rectangle2, line: Segment) {
57
- for (const edge of rectEdges({
58
- topLeft: { x: rect.x - rect.w / 2, y: rect.y - rect.h / 2 },
59
- topRight: { x: rect.x + rect.w / 2, y: rect.y - rect.h / 2 },
60
- bottomRight: { x: rect.x + rect.w / 2, y: rect.y + rect.h / 2 },
61
- bottomLeft: { x: rect.x - rect.w / 2, y: rect.y + rect.h / 2 }
62
- })) {
63
- const intersectionPoint = lineIntersection(edge, line);
64
- if (intersectionPoint) return intersectionPoint;
65
- }
66
- return null;
67
- }
@@ -1,24 +0,0 @@
1
- export interface Pos {
2
- x: number;
3
- y: number;
4
- }
5
- export interface Segment {
6
- start: Pos;
7
- end: Pos;
8
- }
9
- export interface Rectangle {
10
- topLeft: Pos;
11
- topRight: Pos;
12
- bottomLeft: Pos;
13
- bottomRight: Pos;
14
- }
15
- export interface Rectangle2 {
16
- x: number;
17
- y: number;
18
- w: number;
19
- h: number;
20
- }
21
- export declare function intersection(rect: Rectangle2, line: Segment): {
22
- x: number;
23
- y: number;
24
- };