@yannelli/paseo-linear-plugin 1.1.0-beta.3 → 1.1.0-beta.4
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/OVERVIEW.md +2 -2
- package/README.md +4 -3
- package/client/graph-camera.tsx +28 -8
- package/client/graph-labels.ts +7 -4
- package/client/live-cursor.tsx +76 -49
- package/client/live-graph.tsx +53 -26
- package/client/plugin-icon.tsx +41 -9
- package/client/settings-icon.tsx +57 -8
- package/client/web.ts +32 -0
- package/index.client.tsx +134 -79
- package/package.json +1 -1
- package/shared/custom-icon.ts +40 -0
- package/shared/graph-camera.ts +28 -8
- package/shared/graph-geometry.ts +30 -19
package/shared/graph-geometry.ts
CHANGED
|
@@ -6,31 +6,36 @@ export interface Point {
|
|
|
6
6
|
y: number;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export interface Route {
|
|
10
|
-
points:
|
|
9
|
+
export interface Route<P extends Point = Point> {
|
|
10
|
+
points: P[];
|
|
11
11
|
/** Each point's share of the whole distance, from 0 to 1. */
|
|
12
12
|
stops: number[];
|
|
13
13
|
length: number;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
/** Where a route is at a share of its distance, from 0 to 1. */
|
|
17
|
-
export function pointAt(path: Route
|
|
16
|
+
/** Where a route is at a share of its distance, from 0 to 1. Mixes every number of the points. */
|
|
17
|
+
export function pointAt<P extends Point>(path: Route<P>, share: number): P {
|
|
18
18
|
const at = Math.min(1, Math.max(0, share));
|
|
19
19
|
for (let index = 1; index < path.stops.length; index += 1) {
|
|
20
20
|
const stop = path.stops[index] as number;
|
|
21
21
|
if (at > stop) continue;
|
|
22
22
|
const before = path.stops[index - 1] as number;
|
|
23
|
-
const from = path.points[index - 1] as
|
|
24
|
-
const to = path.points[index] as
|
|
23
|
+
const from = path.points[index - 1] as P;
|
|
24
|
+
const to = path.points[index] as P;
|
|
25
25
|
const part = stop > before ? (at - before) / (stop - before) : 1;
|
|
26
|
-
|
|
26
|
+
const mixed: Record<string, unknown> = { ...(to as object) };
|
|
27
|
+
for (const [key, value] of Object.entries(to as object)) {
|
|
28
|
+
const start = (from as Record<string, unknown>)[key];
|
|
29
|
+
if (typeof value === "number" && typeof start === "number") mixed[key] = start + (value - start) * part;
|
|
30
|
+
}
|
|
31
|
+
return mixed as P;
|
|
27
32
|
}
|
|
28
|
-
return path.points[path.points.length - 1] as
|
|
33
|
+
return path.points[path.points.length - 1] as P;
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
/** A route through the points without zero-length steps, or null when there is nowhere to go. */
|
|
32
|
-
export function route(points: readonly
|
|
33
|
-
const kept:
|
|
37
|
+
export function route<P extends Point>(points: readonly P[]): Route<P> | null {
|
|
38
|
+
const kept: P[] = [];
|
|
34
39
|
const steps = [0];
|
|
35
40
|
for (const point of points) {
|
|
36
41
|
const last = kept[kept.length - 1];
|
|
@@ -84,21 +89,27 @@ export interface PlacedLabel {
|
|
|
84
89
|
short: boolean;
|
|
85
90
|
}
|
|
86
91
|
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
export interface Rect {
|
|
93
|
+
left: number;
|
|
94
|
+
top: number;
|
|
95
|
+
right: number;
|
|
96
|
+
bottom: number;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Places labels in request order at the first spot that overlaps no node, other obstacle, or
|
|
100
|
+
// placed label, moved inside the box when it would cross an edge. Others are hidden.
|
|
89
101
|
export function placeLabels(
|
|
90
102
|
requests: readonly LabelRequest[],
|
|
91
103
|
width: number,
|
|
92
104
|
height: number,
|
|
93
|
-
|
|
105
|
+
obstacles: readonly ({ at: Point; radius: number } | Rect)[] = [],
|
|
94
106
|
gap = 3,
|
|
95
107
|
): Map<string, PlacedLabel> {
|
|
96
|
-
const placed =
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}));
|
|
108
|
+
const placed: Rect[] = obstacles.map((shape) =>
|
|
109
|
+
"at" in shape
|
|
110
|
+
? { left: shape.at.x - shape.radius, right: shape.at.x + shape.radius, top: shape.at.y - shape.radius, bottom: shape.at.y + shape.radius }
|
|
111
|
+
: { ...shape },
|
|
112
|
+
);
|
|
102
113
|
const shown = new Map<string, PlacedLabel>();
|
|
103
114
|
for (const request of requests) {
|
|
104
115
|
const tries = [{ ...request, short: false }];
|