@invinite-org/chartlang-adapter-kit 1.2.1 → 1.4.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/CHANGELOG.md +157 -0
- package/README.md +7 -0
- package/dist/canvas/index.d.ts +5 -0
- package/dist/canvas/index.d.ts.map +1 -0
- package/dist/canvas/index.js +5 -0
- package/dist/canvas/index.js.map +1 -0
- package/dist/canvas/mockContext.d.ts +168 -0
- package/dist/canvas/mockContext.d.ts.map +1 -0
- package/dist/canvas/mockContext.js +198 -0
- package/dist/canvas/mockContext.js.map +1 -0
- package/dist/canvas/paintPrimitive.d.ts +35 -0
- package/dist/canvas/paintPrimitive.d.ts.map +1 -0
- package/dist/canvas/paintPrimitive.js +171 -0
- package/dist/canvas/paintPrimitive.js.map +1 -0
- package/dist/canvas/renderCtx.d.ts +40 -0
- package/dist/canvas/renderCtx.d.ts.map +1 -0
- package/dist/canvas/renderCtx.js +4 -0
- package/dist/canvas/renderCtx.js.map +1 -0
- package/dist/capabilities/capabilities.d.ts +9 -7
- package/dist/capabilities/capabilities.d.ts.map +1 -1
- package/dist/capabilities/capabilities.js +14 -8
- package/dist/capabilities/capabilities.js.map +1 -1
- package/dist/geometry/_lib/arrowhead.d.ts +18 -0
- package/dist/geometry/_lib/arrowhead.d.ts.map +1 -0
- package/dist/geometry/_lib/arrowhead.js +38 -0
- package/dist/geometry/_lib/arrowhead.js.map +1 -0
- package/dist/geometry/_lib/bezier.d.ts +57 -0
- package/dist/geometry/_lib/bezier.d.ts.map +1 -0
- package/dist/geometry/_lib/bezier.js +84 -0
- package/dist/geometry/_lib/bezier.js.map +1 -0
- package/dist/geometry/_lib/chevron.d.ts +29 -0
- package/dist/geometry/_lib/chevron.d.ts.map +1 -0
- package/dist/geometry/_lib/chevron.js +37 -0
- package/dist/geometry/_lib/chevron.js.map +1 -0
- package/dist/geometry/_lib/dash.d.ts +30 -0
- package/dist/geometry/_lib/dash.d.ts.map +1 -0
- package/dist/geometry/_lib/dash.js +40 -0
- package/dist/geometry/_lib/dash.js.map +1 -0
- package/dist/geometry/_lib/fibLevels.d.ts +36 -0
- package/dist/geometry/_lib/fibLevels.d.ts.map +1 -0
- package/dist/geometry/_lib/fibLevels.js +44 -0
- package/dist/geometry/_lib/fibLevels.js.map +1 -0
- package/dist/geometry/_lib/gannLevels.d.ts +54 -0
- package/dist/geometry/_lib/gannLevels.d.ts.map +1 -0
- package/dist/geometry/_lib/gannLevels.js +88 -0
- package/dist/geometry/_lib/gannLevels.js.map +1 -0
- package/dist/geometry/_lib/lineExtend.d.ts +31 -0
- package/dist/geometry/_lib/lineExtend.d.ts.map +1 -0
- package/dist/geometry/_lib/lineExtend.js +48 -0
- package/dist/geometry/_lib/lineExtend.js.map +1 -0
- package/dist/geometry/_lib/namedPolyline.d.ts +25 -0
- package/dist/geometry/_lib/namedPolyline.d.ts.map +1 -0
- package/dist/geometry/_lib/namedPolyline.js +64 -0
- package/dist/geometry/_lib/namedPolyline.js.map +1 -0
- package/dist/geometry/_lib/pitchforkGeom.d.ts +46 -0
- package/dist/geometry/_lib/pitchforkGeom.d.ts.map +1 -0
- package/dist/geometry/_lib/pitchforkGeom.js +70 -0
- package/dist/geometry/_lib/pitchforkGeom.js.map +1 -0
- package/dist/geometry/_lib/shapeStyle.d.ts +21 -0
- package/dist/geometry/_lib/shapeStyle.d.ts.map +1 -0
- package/dist/geometry/_lib/shapeStyle.js +41 -0
- package/dist/geometry/_lib/shapeStyle.js.map +1 -0
- package/dist/geometry/_lib/strokeStyle.d.ts +34 -0
- package/dist/geometry/_lib/strokeStyle.d.ts.map +1 -0
- package/dist/geometry/_lib/strokeStyle.js +26 -0
- package/dist/geometry/_lib/strokeStyle.js.map +1 -0
- package/dist/geometry/_lib/textStyle.d.ts +70 -0
- package/dist/geometry/_lib/textStyle.d.ts.map +1 -0
- package/dist/geometry/_lib/textStyle.js +78 -0
- package/dist/geometry/_lib/textStyle.js.map +1 -0
- package/dist/geometry/decompose.d.ts +28 -0
- package/dist/geometry/decompose.d.ts.map +1 -0
- package/dist/geometry/decompose.js +176 -0
- package/dist/geometry/decompose.js.map +1 -0
- package/dist/geometry/index.d.ts +4 -0
- package/dist/geometry/index.d.ts.map +1 -0
- package/dist/geometry/index.js +5 -0
- package/dist/geometry/index.js.map +1 -0
- package/dist/geometry/kinds/annotations.d.ts +77 -0
- package/dist/geometry/kinds/annotations.d.ts.map +1 -0
- package/dist/geometry/kinds/annotations.js +219 -0
- package/dist/geometry/kinds/annotations.js.map +1 -0
- package/dist/geometry/kinds/boxes.d.ts +116 -0
- package/dist/geometry/kinds/boxes.d.ts.map +1 -0
- package/dist/geometry/kinds/boxes.js +285 -0
- package/dist/geometry/kinds/boxes.js.map +1 -0
- package/dist/geometry/kinds/channels.d.ts +72 -0
- package/dist/geometry/kinds/channels.d.ts.map +1 -0
- package/dist/geometry/kinds/channels.js +148 -0
- package/dist/geometry/kinds/channels.js.map +1 -0
- package/dist/geometry/kinds/containers.d.ts +54 -0
- package/dist/geometry/kinds/containers.d.ts.map +1 -0
- package/dist/geometry/kinds/containers.js +268 -0
- package/dist/geometry/kinds/containers.js.map +1 -0
- package/dist/geometry/kinds/curves.d.ts +53 -0
- package/dist/geometry/kinds/curves.d.ts.map +1 -0
- package/dist/geometry/kinds/curves.js +110 -0
- package/dist/geometry/kinds/curves.js.map +1 -0
- package/dist/geometry/kinds/cycles.d.ts +52 -0
- package/dist/geometry/kinds/cycles.d.ts.map +1 -0
- package/dist/geometry/kinds/cycles.js +158 -0
- package/dist/geometry/kinds/cycles.js.map +1 -0
- package/dist/geometry/kinds/elliott.d.ts +73 -0
- package/dist/geometry/kinds/elliott.d.ts.map +1 -0
- package/dist/geometry/kinds/elliott.js +116 -0
- package/dist/geometry/kinds/elliott.js.map +1 -0
- package/dist/geometry/kinds/fibonacci.d.ts +166 -0
- package/dist/geometry/kinds/fibonacci.d.ts.map +1 -0
- package/dist/geometry/kinds/fibonacci.js +458 -0
- package/dist/geometry/kinds/fibonacci.js.map +1 -0
- package/dist/geometry/kinds/freehand.d.ts +53 -0
- package/dist/geometry/kinds/freehand.d.ts.map +1 -0
- package/dist/geometry/kinds/freehand.js +115 -0
- package/dist/geometry/kinds/freehand.js.map +1 -0
- package/dist/geometry/kinds/gann.d.ts +63 -0
- package/dist/geometry/kinds/gann.d.ts.map +1 -0
- package/dist/geometry/kinds/gann.js +153 -0
- package/dist/geometry/kinds/gann.js.map +1 -0
- package/dist/geometry/kinds/lines.d.ts +90 -0
- package/dist/geometry/kinds/lines.d.ts.map +1 -0
- package/dist/geometry/kinds/lines.js +201 -0
- package/dist/geometry/kinds/lines.js.map +1 -0
- package/dist/geometry/kinds/marker.d.ts +21 -0
- package/dist/geometry/kinds/marker.d.ts.map +1 -0
- package/dist/geometry/kinds/marker.js +47 -0
- package/dist/geometry/kinds/marker.js.map +1 -0
- package/dist/geometry/kinds/patterns.d.ts +85 -0
- package/dist/geometry/kinds/patterns.d.ts.map +1 -0
- package/dist/geometry/kinds/patterns.js +133 -0
- package/dist/geometry/kinds/patterns.js.map +1 -0
- package/dist/geometry/kinds/pitchforks.d.ts +36 -0
- package/dist/geometry/kinds/pitchforks.d.ts.map +1 -0
- package/dist/geometry/kinds/pitchforks.js +109 -0
- package/dist/geometry/kinds/pitchforks.js.map +1 -0
- package/dist/geometry/project.d.ts +50 -0
- package/dist/geometry/project.d.ts.map +1 -0
- package/dist/geometry/project.js +62 -0
- package/dist/geometry/project.js.map +1 -0
- package/dist/geometry/types.d.ts +146 -0
- package/dist/geometry/types.d.ts.map +1 -0
- package/dist/geometry/types.js +4 -0
- package/dist/geometry/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +54 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/validation/validateEmission.d.ts.map +1 -1
- package/dist/validation/validateEmission.js +47 -0
- package/dist/validation/validateEmission.js.map +1 -1
- package/package.json +9 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrowhead.js","sourceRoot":"","sources":["../../../src/geometry/_lib/arrowhead.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAC/D,EAAE;AACF,iCAAiC;AACjC,+DAA+D;AAC/D,sEAAsE;AACtE,iEAAiE;AACjE,iCAAiC;AAIjC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACjC,MAAM,oBAAoB,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,4BAA4B;AAEtE;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,gBAAgB,CAC5B,IAAY,EACZ,EAAU,EACV,OAAe,sBAAsB;IAErC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,IAAI,GAAW;QACjB,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,oBAAoB,CAAC;QACvD,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,oBAAoB,CAAC;KAC1D,CAAC;IACF,MAAM,KAAK,GAAW;QAClB,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,oBAAoB,CAAC;QACvD,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,oBAAoB,CAAC;KAC1D,CAAC;IACF,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n//\n// Arrowhead geometry ported from\n// invinite/src/components/trading-chart/tools/arrow-tool.ts,\n// invinite/src/components/trading-chart/tools/arrow-marker-tool.ts,\n// commit 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite.\n// Re-licensed MIT for chartlang.\n\nimport type { Point2 } from \"../types.js\";\n\nconst DEFAULT_ARROWHEAD_SIZE = 8;\nconst ARROWHEAD_HALF_ANGLE = Math.PI / 6; // 30° each side → 60° total\n\n/**\n * Return the three vertices of a filled isoceles-triangle arrowhead at\n * `to` pointing along the `from → to` direction. The order is\n * `[tip, leftWing, rightWing]` so a caller paints a closed polyline\n * `moveTo(tip) → lineTo(left) → lineTo(right) → close`. Pure — no `ctx`.\n *\n * `size` defaults to 8 CSS px (the wing length).\n *\n * @since 1.3\n * @stable\n * @example\n * const tri = arrowheadPolygon({ x: 0, y: 0 }, { x: 100, y: 0 });\n * // tri[0] === { x: 100, y: 0 } (tip)\n * void tri;\n */\nexport function arrowheadPolygon(\n from: Point2,\n to: Point2,\n size: number = DEFAULT_ARROWHEAD_SIZE,\n): ReadonlyArray<Point2> {\n const angle = Math.atan2(to.y - from.y, to.x - from.x);\n const left: Point2 = {\n x: to.x - size * Math.cos(angle - ARROWHEAD_HALF_ANGLE),\n y: to.y - size * Math.sin(angle - ARROWHEAD_HALF_ANGLE),\n };\n const right: Point2 = {\n x: to.x - size * Math.cos(angle + ARROWHEAD_HALF_ANGLE),\n y: to.y - size * Math.sin(angle + ARROWHEAD_HALF_ANGLE),\n };\n return [to, left, right];\n}\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Point2 } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Evaluate a quadratic Bezier curve at parameter `t ∈ [0, 1]`. The
|
|
4
|
+
* curve interpolates `p0` (at `t = 0`) and `p2` (at `t = 1`) with `p1`
|
|
5
|
+
* as the off-curve control point. Endpoints are float-exact:
|
|
6
|
+
* `quadraticBezier(p0, p1, p2, 0) === p0` and `… 1) === p2`.
|
|
7
|
+
*
|
|
8
|
+
* @since 1.3
|
|
9
|
+
* @stable
|
|
10
|
+
* @example
|
|
11
|
+
* const mid = quadraticBezier({ x: 0, y: 0 }, { x: 1, y: 2 }, { x: 2, y: 0 }, 0.5);
|
|
12
|
+
* // mid.x === 1; mid.y === 1
|
|
13
|
+
* void mid;
|
|
14
|
+
*/
|
|
15
|
+
export declare function quadraticBezier(p0: Point2, p1: Point2, p2: Point2, t: number): Point2;
|
|
16
|
+
/**
|
|
17
|
+
* Evaluate a cubic Bezier curve at parameter `t ∈ [0, 1]`. The curve
|
|
18
|
+
* interpolates `p0` (at `t = 0`) and `p3` (at `t = 1`) with `p1` and
|
|
19
|
+
* `p2` as the two off-curve control points. Endpoints are float-exact.
|
|
20
|
+
*
|
|
21
|
+
* @since 1.3
|
|
22
|
+
* @stable
|
|
23
|
+
* @example
|
|
24
|
+
* const start = cubicBezier(
|
|
25
|
+
* { x: 0, y: 0 }, { x: 1, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 0 }, 0,
|
|
26
|
+
* );
|
|
27
|
+
* // start === { x: 0, y: 0 }
|
|
28
|
+
* void start;
|
|
29
|
+
*/
|
|
30
|
+
export declare function cubicBezier(p0: Point2, p1: Point2, p2: Point2, p3: Point2, t: number): Point2;
|
|
31
|
+
/**
|
|
32
|
+
* Sample a quadratic Bezier into `samples + 1` points evenly spaced in
|
|
33
|
+
* parameter `t ∈ [0, 1]`. The first sample is `p0`, the last is `p2`.
|
|
34
|
+
*
|
|
35
|
+
* @since 1.3
|
|
36
|
+
* @stable
|
|
37
|
+
* @example
|
|
38
|
+
* const pts = sampleQuadratic({ x: 0, y: 0 }, { x: 1, y: 2 }, { x: 2, y: 0 }, 4);
|
|
39
|
+
* // pts.length === 5; pts[0] === { x: 0, y: 0 }; pts[4] === { x: 2, y: 0 }
|
|
40
|
+
* void pts;
|
|
41
|
+
*/
|
|
42
|
+
export declare function sampleQuadratic(p0: Point2, p1: Point2, p2: Point2, samples: number): ReadonlyArray<Point2>;
|
|
43
|
+
/**
|
|
44
|
+
* Sample a cubic Bezier into `samples + 1` points evenly spaced in
|
|
45
|
+
* parameter `t ∈ [0, 1]`. Mirrors {@link sampleQuadratic}.
|
|
46
|
+
*
|
|
47
|
+
* @since 1.3
|
|
48
|
+
* @stable
|
|
49
|
+
* @example
|
|
50
|
+
* const pts = sampleCubic(
|
|
51
|
+
* { x: 0, y: 0 }, { x: 1, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 0 }, 8,
|
|
52
|
+
* );
|
|
53
|
+
* // pts.length === 9; pts[0] === { x: 0, y: 0 }; pts[8] === { x: 3, y: 0 }
|
|
54
|
+
* void pts;
|
|
55
|
+
*/
|
|
56
|
+
export declare function sampleCubic(p0: Point2, p1: Point2, p2: Point2, p3: Point2, samples: number): ReadonlyArray<Point2>;
|
|
57
|
+
//# sourceMappingURL=bezier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bezier.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/bezier.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAMrF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ7F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC3B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,GAChB,aAAa,CAAC,MAAM,CAAC,CAMvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACvB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,GAChB,aAAa,CAAC,MAAM,CAAC,CAMvB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Copyright (c) 2026 Invinite. Licensed under the MIT License.
|
|
2
|
+
// See the LICENSE file in the repo root for full license text.
|
|
3
|
+
/**
|
|
4
|
+
* Evaluate a quadratic Bezier curve at parameter `t ∈ [0, 1]`. The
|
|
5
|
+
* curve interpolates `p0` (at `t = 0`) and `p2` (at `t = 1`) with `p1`
|
|
6
|
+
* as the off-curve control point. Endpoints are float-exact:
|
|
7
|
+
* `quadraticBezier(p0, p1, p2, 0) === p0` and `… 1) === p2`.
|
|
8
|
+
*
|
|
9
|
+
* @since 1.3
|
|
10
|
+
* @stable
|
|
11
|
+
* @example
|
|
12
|
+
* const mid = quadraticBezier({ x: 0, y: 0 }, { x: 1, y: 2 }, { x: 2, y: 0 }, 0.5);
|
|
13
|
+
* // mid.x === 1; mid.y === 1
|
|
14
|
+
* void mid;
|
|
15
|
+
*/
|
|
16
|
+
export function quadraticBezier(p0, p1, p2, t) {
|
|
17
|
+
const u = 1 - t;
|
|
18
|
+
return {
|
|
19
|
+
x: u * u * p0.x + 2 * u * t * p1.x + t * t * p2.x,
|
|
20
|
+
y: u * u * p0.y + 2 * u * t * p1.y + t * t * p2.y,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Evaluate a cubic Bezier curve at parameter `t ∈ [0, 1]`. The curve
|
|
25
|
+
* interpolates `p0` (at `t = 0`) and `p3` (at `t = 1`) with `p1` and
|
|
26
|
+
* `p2` as the two off-curve control points. Endpoints are float-exact.
|
|
27
|
+
*
|
|
28
|
+
* @since 1.3
|
|
29
|
+
* @stable
|
|
30
|
+
* @example
|
|
31
|
+
* const start = cubicBezier(
|
|
32
|
+
* { x: 0, y: 0 }, { x: 1, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 0 }, 0,
|
|
33
|
+
* );
|
|
34
|
+
* // start === { x: 0, y: 0 }
|
|
35
|
+
* void start;
|
|
36
|
+
*/
|
|
37
|
+
export function cubicBezier(p0, p1, p2, p3, t) {
|
|
38
|
+
const u = 1 - t;
|
|
39
|
+
const uu = u * u;
|
|
40
|
+
const tt = t * t;
|
|
41
|
+
return {
|
|
42
|
+
x: uu * u * p0.x + 3 * uu * t * p1.x + 3 * u * tt * p2.x + tt * t * p3.x,
|
|
43
|
+
y: uu * u * p0.y + 3 * uu * t * p1.y + 3 * u * tt * p2.y + tt * t * p3.y,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Sample a quadratic Bezier into `samples + 1` points evenly spaced in
|
|
48
|
+
* parameter `t ∈ [0, 1]`. The first sample is `p0`, the last is `p2`.
|
|
49
|
+
*
|
|
50
|
+
* @since 1.3
|
|
51
|
+
* @stable
|
|
52
|
+
* @example
|
|
53
|
+
* const pts = sampleQuadratic({ x: 0, y: 0 }, { x: 1, y: 2 }, { x: 2, y: 0 }, 4);
|
|
54
|
+
* // pts.length === 5; pts[0] === { x: 0, y: 0 }; pts[4] === { x: 2, y: 0 }
|
|
55
|
+
* void pts;
|
|
56
|
+
*/
|
|
57
|
+
export function sampleQuadratic(p0, p1, p2, samples) {
|
|
58
|
+
const out = [];
|
|
59
|
+
for (let i = 0; i <= samples; i++) {
|
|
60
|
+
out.push(quadraticBezier(p0, p1, p2, i / samples));
|
|
61
|
+
}
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Sample a cubic Bezier into `samples + 1` points evenly spaced in
|
|
66
|
+
* parameter `t ∈ [0, 1]`. Mirrors {@link sampleQuadratic}.
|
|
67
|
+
*
|
|
68
|
+
* @since 1.3
|
|
69
|
+
* @stable
|
|
70
|
+
* @example
|
|
71
|
+
* const pts = sampleCubic(
|
|
72
|
+
* { x: 0, y: 0 }, { x: 1, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 0 }, 8,
|
|
73
|
+
* );
|
|
74
|
+
* // pts.length === 9; pts[0] === { x: 0, y: 0 }; pts[8] === { x: 3, y: 0 }
|
|
75
|
+
* void pts;
|
|
76
|
+
*/
|
|
77
|
+
export function sampleCubic(p0, p1, p2, p3, samples) {
|
|
78
|
+
const out = [];
|
|
79
|
+
for (let i = 0; i <= samples; i++) {
|
|
80
|
+
out.push(cubicBezier(p0, p1, p2, p3, i / samples));
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=bezier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bezier.js","sourceRoot":"","sources":["../../../src/geometry/_lib/bezier.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAI/D;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAAC,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,CAAS;IACzE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,OAAO;QACH,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QACjD,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;KACpD,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,CAAS;IACjF,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,OAAO;QACH,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QACxE,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;KAC3E,CAAC;AACN,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC3B,EAAU,EACV,EAAU,EACV,EAAU,EACV,OAAe;IAEf,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CACvB,EAAU,EACV,EAAU,EACV,EAAU,EACV,EAAU,EACV,OAAe;IAEf,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nimport type { Point2 } from \"../types.js\";\n\n/**\n * Evaluate a quadratic Bezier curve at parameter `t ∈ [0, 1]`. The\n * curve interpolates `p0` (at `t = 0`) and `p2` (at `t = 1`) with `p1`\n * as the off-curve control point. Endpoints are float-exact:\n * `quadraticBezier(p0, p1, p2, 0) === p0` and `… 1) === p2`.\n *\n * @since 1.3\n * @stable\n * @example\n * const mid = quadraticBezier({ x: 0, y: 0 }, { x: 1, y: 2 }, { x: 2, y: 0 }, 0.5);\n * // mid.x === 1; mid.y === 1\n * void mid;\n */\nexport function quadraticBezier(p0: Point2, p1: Point2, p2: Point2, t: number): Point2 {\n const u = 1 - t;\n return {\n x: u * u * p0.x + 2 * u * t * p1.x + t * t * p2.x,\n y: u * u * p0.y + 2 * u * t * p1.y + t * t * p2.y,\n };\n}\n\n/**\n * Evaluate a cubic Bezier curve at parameter `t ∈ [0, 1]`. The curve\n * interpolates `p0` (at `t = 0`) and `p3` (at `t = 1`) with `p1` and\n * `p2` as the two off-curve control points. Endpoints are float-exact.\n *\n * @since 1.3\n * @stable\n * @example\n * const start = cubicBezier(\n * { x: 0, y: 0 }, { x: 1, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 0 }, 0,\n * );\n * // start === { x: 0, y: 0 }\n * void start;\n */\nexport function cubicBezier(p0: Point2, p1: Point2, p2: Point2, p3: Point2, t: number): Point2 {\n const u = 1 - t;\n const uu = u * u;\n const tt = t * t;\n return {\n x: uu * u * p0.x + 3 * uu * t * p1.x + 3 * u * tt * p2.x + tt * t * p3.x,\n y: uu * u * p0.y + 3 * uu * t * p1.y + 3 * u * tt * p2.y + tt * t * p3.y,\n };\n}\n\n/**\n * Sample a quadratic Bezier into `samples + 1` points evenly spaced in\n * parameter `t ∈ [0, 1]`. The first sample is `p0`, the last is `p2`.\n *\n * @since 1.3\n * @stable\n * @example\n * const pts = sampleQuadratic({ x: 0, y: 0 }, { x: 1, y: 2 }, { x: 2, y: 0 }, 4);\n * // pts.length === 5; pts[0] === { x: 0, y: 0 }; pts[4] === { x: 2, y: 0 }\n * void pts;\n */\nexport function sampleQuadratic(\n p0: Point2,\n p1: Point2,\n p2: Point2,\n samples: number,\n): ReadonlyArray<Point2> {\n const out: Point2[] = [];\n for (let i = 0; i <= samples; i++) {\n out.push(quadraticBezier(p0, p1, p2, i / samples));\n }\n return out;\n}\n\n/**\n * Sample a cubic Bezier into `samples + 1` points evenly spaced in\n * parameter `t ∈ [0, 1]`. Mirrors {@link sampleQuadratic}.\n *\n * @since 1.3\n * @stable\n * @example\n * const pts = sampleCubic(\n * { x: 0, y: 0 }, { x: 1, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 0 }, 8,\n * );\n * // pts.length === 9; pts[0] === { x: 0, y: 0 }; pts[8] === { x: 3, y: 0 }\n * void pts;\n */\nexport function sampleCubic(\n p0: Point2,\n p1: Point2,\n p2: Point2,\n p3: Point2,\n samples: number,\n): ReadonlyArray<Point2> {\n const out: Point2[] = [];\n for (let i = 0; i <= samples; i++) {\n out.push(cubicBezier(p0, p1, p2, p3, i / samples));\n }\n return out;\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Point2 } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Vertical direction of a chevron glyph. `"up"` puts the tip above the
|
|
4
|
+
* anchor (smaller y); `"down"` puts the tip below (larger y).
|
|
5
|
+
*
|
|
6
|
+
* @since 1.3
|
|
7
|
+
* @stable
|
|
8
|
+
* @example
|
|
9
|
+
* const d: ChevronDirection = "up";
|
|
10
|
+
* void d;
|
|
11
|
+
*/
|
|
12
|
+
export type ChevronDirection = "up" | "down";
|
|
13
|
+
/**
|
|
14
|
+
* Return the three vertices of a filled triangle chevron glyph centred
|
|
15
|
+
* on `at`, pointing up or down. The order is `[tip, baseLeft,
|
|
16
|
+
* baseRight]` so a caller paints a closed polyline. Pure — no `ctx`.
|
|
17
|
+
* Consumed by the `arrow-mark-up` / `arrow-mark-down` decomposers.
|
|
18
|
+
*
|
|
19
|
+
* `baseWidth` defaults to 12 CSS px, `height` to 10 CSS px.
|
|
20
|
+
*
|
|
21
|
+
* @since 1.3
|
|
22
|
+
* @stable
|
|
23
|
+
* @example
|
|
24
|
+
* const tri = chevronPolygon({ x: 100, y: 100 }, "up");
|
|
25
|
+
* // tri[0].y === 95 (tip is half the height above the anchor)
|
|
26
|
+
* void tri;
|
|
27
|
+
*/
|
|
28
|
+
export declare function chevronPolygon(at: Point2, direction: ChevronDirection, baseWidth?: number, height?: number): ReadonlyArray<Point2>;
|
|
29
|
+
//# sourceMappingURL=chevron.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chevron.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/chevron.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAK1C;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,MAAM,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC1B,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,gBAAgB,EAC3B,SAAS,GAAE,MAA2B,EACtC,MAAM,GAAE,MAAuB,GAChC,aAAa,CAAC,MAAM,CAAC,CAUvB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Copyright (c) 2026 Invinite. Licensed under the MIT License.
|
|
2
|
+
// See the LICENSE file in the repo root for full license text.
|
|
3
|
+
//
|
|
4
|
+
// Chevron glyph geometry ported from
|
|
5
|
+
// invinite/src/components/trading-chart/tools/arrow-mark-up-tool.ts,
|
|
6
|
+
// invinite/src/components/trading-chart/tools/arrow-mark-down-tool.ts,
|
|
7
|
+
// commit 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite.
|
|
8
|
+
// Re-licensed MIT for chartlang.
|
|
9
|
+
const DEFAULT_BASE_WIDTH = 12;
|
|
10
|
+
const DEFAULT_HEIGHT = 10;
|
|
11
|
+
/**
|
|
12
|
+
* Return the three vertices of a filled triangle chevron glyph centred
|
|
13
|
+
* on `at`, pointing up or down. The order is `[tip, baseLeft,
|
|
14
|
+
* baseRight]` so a caller paints a closed polyline. Pure — no `ctx`.
|
|
15
|
+
* Consumed by the `arrow-mark-up` / `arrow-mark-down` decomposers.
|
|
16
|
+
*
|
|
17
|
+
* `baseWidth` defaults to 12 CSS px, `height` to 10 CSS px.
|
|
18
|
+
*
|
|
19
|
+
* @since 1.3
|
|
20
|
+
* @stable
|
|
21
|
+
* @example
|
|
22
|
+
* const tri = chevronPolygon({ x: 100, y: 100 }, "up");
|
|
23
|
+
* // tri[0].y === 95 (tip is half the height above the anchor)
|
|
24
|
+
* void tri;
|
|
25
|
+
*/
|
|
26
|
+
export function chevronPolygon(at, direction, baseWidth = DEFAULT_BASE_WIDTH, height = DEFAULT_HEIGHT) {
|
|
27
|
+
const halfWidth = baseWidth / 2;
|
|
28
|
+
const halfHeight = height / 2;
|
|
29
|
+
const tipY = direction === "up" ? at.y - halfHeight : at.y + halfHeight;
|
|
30
|
+
const baseY = direction === "up" ? at.y + halfHeight : at.y - halfHeight;
|
|
31
|
+
return [
|
|
32
|
+
{ x: at.x, y: tipY },
|
|
33
|
+
{ x: at.x - halfWidth, y: baseY },
|
|
34
|
+
{ x: at.x + halfWidth, y: baseY },
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=chevron.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chevron.js","sourceRoot":"","sources":["../../../src/geometry/_lib/chevron.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAC/D,EAAE;AACF,qCAAqC;AACrC,uEAAuE;AACvE,yEAAyE;AACzE,iEAAiE;AACjE,iCAAiC;AAIjC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,cAAc,GAAG,EAAE,CAAC;AAc1B;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAC1B,EAAU,EACV,SAA2B,EAC3B,YAAoB,kBAAkB,EACtC,SAAiB,cAAc;IAE/B,MAAM,SAAS,GAAG,SAAS,GAAG,CAAC,CAAC;IAChC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC;IACxE,MAAM,KAAK,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC;IACzE,OAAO;QACH,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE;QACpB,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE;QACjC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE;KACpC,CAAC;AACN,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n//\n// Chevron glyph geometry ported from\n// invinite/src/components/trading-chart/tools/arrow-mark-up-tool.ts,\n// invinite/src/components/trading-chart/tools/arrow-mark-down-tool.ts,\n// commit 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite.\n// Re-licensed MIT for chartlang.\n\nimport type { Point2 } from \"../types.js\";\n\nconst DEFAULT_BASE_WIDTH = 12;\nconst DEFAULT_HEIGHT = 10;\n\n/**\n * Vertical direction of a chevron glyph. `\"up\"` puts the tip above the\n * anchor (smaller y); `\"down\"` puts the tip below (larger y).\n *\n * @since 1.3\n * @stable\n * @example\n * const d: ChevronDirection = \"up\";\n * void d;\n */\nexport type ChevronDirection = \"up\" | \"down\";\n\n/**\n * Return the three vertices of a filled triangle chevron glyph centred\n * on `at`, pointing up or down. The order is `[tip, baseLeft,\n * baseRight]` so a caller paints a closed polyline. Pure — no `ctx`.\n * Consumed by the `arrow-mark-up` / `arrow-mark-down` decomposers.\n *\n * `baseWidth` defaults to 12 CSS px, `height` to 10 CSS px.\n *\n * @since 1.3\n * @stable\n * @example\n * const tri = chevronPolygon({ x: 100, y: 100 }, \"up\");\n * // tri[0].y === 95 (tip is half the height above the anchor)\n * void tri;\n */\nexport function chevronPolygon(\n at: Point2,\n direction: ChevronDirection,\n baseWidth: number = DEFAULT_BASE_WIDTH,\n height: number = DEFAULT_HEIGHT,\n): ReadonlyArray<Point2> {\n const halfWidth = baseWidth / 2;\n const halfHeight = height / 2;\n const tipY = direction === \"up\" ? at.y - halfHeight : at.y + halfHeight;\n const baseY = direction === \"up\" ? at.y + halfHeight : at.y - halfHeight;\n return [\n { x: at.x, y: tipY },\n { x: at.x - halfWidth, y: baseY },\n { x: at.x + halfWidth, y: baseY },\n ];\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { LineStyle } from "@invinite-org/chartlang-core";
|
|
2
|
+
/**
|
|
3
|
+
* Canonical `setLineDash` segment array for each {@link LineStyle}.
|
|
4
|
+
* Copied (not moved) from the canvas2d adapter's `render/lineDash.ts`,
|
|
5
|
+
* which still serves the surviving plot renderers there. Decomposers
|
|
6
|
+
* map a `LineStyle` to a `StrokeStyle.dash` through this helper.
|
|
7
|
+
*
|
|
8
|
+
* `"solid"` → `[]`, `"dashed"` → `[6, 4]`, `"dotted"` → `[2, 4]`.
|
|
9
|
+
*
|
|
10
|
+
* @since 1.3
|
|
11
|
+
* @stable
|
|
12
|
+
* @example
|
|
13
|
+
* const d = dashPattern("dashed"); // [6, 4]
|
|
14
|
+
* void d;
|
|
15
|
+
*/
|
|
16
|
+
export declare function dashPattern(style: LineStyle): ReadonlyArray<number>;
|
|
17
|
+
/**
|
|
18
|
+
* The `setLineDash` segment array for a solid stroke — an empty array.
|
|
19
|
+
* Shared by the decomposers that emit always-solid primitives (fib
|
|
20
|
+
* arcs, gann/pitchfork rays, container borders) so the `"solid"` dash
|
|
21
|
+
* constant lives in one place instead of a per-file re-declaration.
|
|
22
|
+
*
|
|
23
|
+
* @since 1.3
|
|
24
|
+
* @stable
|
|
25
|
+
* @example
|
|
26
|
+
* const d = SOLID_DASH; // []
|
|
27
|
+
* void d;
|
|
28
|
+
*/
|
|
29
|
+
export declare const SOLID_DASH: ReadonlyArray<number>;
|
|
30
|
+
//# sourceMappingURL=dash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dash.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/dash.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CASnE;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC,MAAM,CAAM,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright (c) 2026 Invinite. Licensed under the MIT License.
|
|
2
|
+
// See the LICENSE file in the repo root for full license text.
|
|
3
|
+
/**
|
|
4
|
+
* Canonical `setLineDash` segment array for each {@link LineStyle}.
|
|
5
|
+
* Copied (not moved) from the canvas2d adapter's `render/lineDash.ts`,
|
|
6
|
+
* which still serves the surviving plot renderers there. Decomposers
|
|
7
|
+
* map a `LineStyle` to a `StrokeStyle.dash` through this helper.
|
|
8
|
+
*
|
|
9
|
+
* `"solid"` → `[]`, `"dashed"` → `[6, 4]`, `"dotted"` → `[2, 4]`.
|
|
10
|
+
*
|
|
11
|
+
* @since 1.3
|
|
12
|
+
* @stable
|
|
13
|
+
* @example
|
|
14
|
+
* const d = dashPattern("dashed"); // [6, 4]
|
|
15
|
+
* void d;
|
|
16
|
+
*/
|
|
17
|
+
export function dashPattern(style) {
|
|
18
|
+
switch (style) {
|
|
19
|
+
case "solid":
|
|
20
|
+
return [];
|
|
21
|
+
case "dashed":
|
|
22
|
+
return [6, 4];
|
|
23
|
+
case "dotted":
|
|
24
|
+
return [2, 4];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The `setLineDash` segment array for a solid stroke — an empty array.
|
|
29
|
+
* Shared by the decomposers that emit always-solid primitives (fib
|
|
30
|
+
* arcs, gann/pitchfork rays, container borders) so the `"solid"` dash
|
|
31
|
+
* constant lives in one place instead of a per-file re-declaration.
|
|
32
|
+
*
|
|
33
|
+
* @since 1.3
|
|
34
|
+
* @stable
|
|
35
|
+
* @example
|
|
36
|
+
* const d = SOLID_DASH; // []
|
|
37
|
+
* void d;
|
|
38
|
+
*/
|
|
39
|
+
export const SOLID_DASH = [];
|
|
40
|
+
//# sourceMappingURL=dash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dash.js","sourceRoot":"","sources":["../../../src/geometry/_lib/dash.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAI/D;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,KAAgB;IACxC,QAAQ,KAAK,EAAE,CAAC;QACZ,KAAK,OAAO;YACR,OAAO,EAAE,CAAC;QACd,KAAK,QAAQ;YACT,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAClB,KAAK,QAAQ;YACT,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtB,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,UAAU,GAA0B,EAAE,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\nimport type { LineStyle } from \"@invinite-org/chartlang-core\";\n\n/**\n * Canonical `setLineDash` segment array for each {@link LineStyle}.\n * Copied (not moved) from the canvas2d adapter's `render/lineDash.ts`,\n * which still serves the surviving plot renderers there. Decomposers\n * map a `LineStyle` to a `StrokeStyle.dash` through this helper.\n *\n * `\"solid\"` → `[]`, `\"dashed\"` → `[6, 4]`, `\"dotted\"` → `[2, 4]`.\n *\n * @since 1.3\n * @stable\n * @example\n * const d = dashPattern(\"dashed\"); // [6, 4]\n * void d;\n */\nexport function dashPattern(style: LineStyle): ReadonlyArray<number> {\n switch (style) {\n case \"solid\":\n return [];\n case \"dashed\":\n return [6, 4];\n case \"dotted\":\n return [2, 4];\n }\n}\n\n/**\n * The `setLineDash` segment array for a solid stroke — an empty array.\n * Shared by the decomposers that emit always-solid primitives (fib\n * arcs, gann/pitchfork rays, container borders) so the `\"solid\"` dash\n * constant lives in one place instead of a per-file re-declaration.\n *\n * @since 1.3\n * @stable\n * @example\n * const d = SOLID_DASH; // []\n * void d;\n */\nexport const SOLID_DASH: ReadonlyArray<number> = [];\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Fibonacci level ratios shared by every fib decomposer
|
|
3
|
+
* (`fibRetracement`, `fibTrendExtension`, `fibChannel`, `fibSpeedFan`,
|
|
4
|
+
* `fibSpeedArcs`, …). Frozen so per-kind decomposers cannot accidentally
|
|
5
|
+
* mutate the shared array. Source: invinite's
|
|
6
|
+
* `src/components/trading-chart/tools/fib-*` tools.
|
|
7
|
+
*
|
|
8
|
+
* Order is monotonic. Both the 0 and 1 endpoints are included so a
|
|
9
|
+
* retracement decomposer that needs the bracket lines (the 0% and 100%
|
|
10
|
+
* anchor levels) doesn't have to splice them in.
|
|
11
|
+
*
|
|
12
|
+
* @since 1.3
|
|
13
|
+
* @stable
|
|
14
|
+
* @example
|
|
15
|
+
* for (const level of FIB_LEVELS) {
|
|
16
|
+
* // Stroke a horizontal line at `from.price + level * (to.price - from.price)`.
|
|
17
|
+
* void level;
|
|
18
|
+
* }
|
|
19
|
+
*/
|
|
20
|
+
export declare const FIB_LEVELS: ReadonlyArray<number>;
|
|
21
|
+
/**
|
|
22
|
+
* Format a Fibonacci ratio for display alongside its level line.
|
|
23
|
+
* Integer ratios (`0`, `1`, `2`) render with one decimal place (`"0.0"`,
|
|
24
|
+
* `"1.0"`, `"2.0"`); fractional ratios render with three (`"0.236"`,
|
|
25
|
+
* `"0.618"`, `"1.272"`). Matches the Pine-style label convention used
|
|
26
|
+
* by the invinite fib tools.
|
|
27
|
+
*
|
|
28
|
+
* @since 1.3
|
|
29
|
+
* @stable
|
|
30
|
+
* @example
|
|
31
|
+
* formatLevel(0); // "0.0"
|
|
32
|
+
* formatLevel(0.618); // "0.618"
|
|
33
|
+
* formatLevel(1.272); // "1.272"
|
|
34
|
+
*/
|
|
35
|
+
export declare function formatLevel(level: number): string;
|
|
36
|
+
//# sourceMappingURL=fibLevels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fibLevels.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/fibLevels.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,UAAU,EAAE,aAAa,CAAC,MAAM,CAI3C,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright (c) 2026 Invinite. Licensed under the MIT License.
|
|
2
|
+
// See the LICENSE file in the repo root for full license text.
|
|
3
|
+
/**
|
|
4
|
+
* Canonical Fibonacci level ratios shared by every fib decomposer
|
|
5
|
+
* (`fibRetracement`, `fibTrendExtension`, `fibChannel`, `fibSpeedFan`,
|
|
6
|
+
* `fibSpeedArcs`, …). Frozen so per-kind decomposers cannot accidentally
|
|
7
|
+
* mutate the shared array. Source: invinite's
|
|
8
|
+
* `src/components/trading-chart/tools/fib-*` tools.
|
|
9
|
+
*
|
|
10
|
+
* Order is monotonic. Both the 0 and 1 endpoints are included so a
|
|
11
|
+
* retracement decomposer that needs the bracket lines (the 0% and 100%
|
|
12
|
+
* anchor levels) doesn't have to splice them in.
|
|
13
|
+
*
|
|
14
|
+
* @since 1.3
|
|
15
|
+
* @stable
|
|
16
|
+
* @example
|
|
17
|
+
* for (const level of FIB_LEVELS) {
|
|
18
|
+
* // Stroke a horizontal line at `from.price + level * (to.price - from.price)`.
|
|
19
|
+
* void level;
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
export const FIB_LEVELS = Object.freeze([
|
|
23
|
+
0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.272,
|
|
24
|
+
// biome-ignore lint/suspicious/noApproximativeNumericConstant: canonical fib ratio, not √2.
|
|
25
|
+
1.414, 1.618, 2.0, 2.618, 4.236,
|
|
26
|
+
]);
|
|
27
|
+
/**
|
|
28
|
+
* Format a Fibonacci ratio for display alongside its level line.
|
|
29
|
+
* Integer ratios (`0`, `1`, `2`) render with one decimal place (`"0.0"`,
|
|
30
|
+
* `"1.0"`, `"2.0"`); fractional ratios render with three (`"0.236"`,
|
|
31
|
+
* `"0.618"`, `"1.272"`). Matches the Pine-style label convention used
|
|
32
|
+
* by the invinite fib tools.
|
|
33
|
+
*
|
|
34
|
+
* @since 1.3
|
|
35
|
+
* @stable
|
|
36
|
+
* @example
|
|
37
|
+
* formatLevel(0); // "0.0"
|
|
38
|
+
* formatLevel(0.618); // "0.618"
|
|
39
|
+
* formatLevel(1.272); // "1.272"
|
|
40
|
+
*/
|
|
41
|
+
export function formatLevel(level) {
|
|
42
|
+
return level === Math.floor(level) ? level.toFixed(1) : level.toFixed(3);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=fibLevels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fibLevels.js","sourceRoot":"","sources":["../../../src/geometry/_lib/fibLevels.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,UAAU,GAA0B,MAAM,CAAC,MAAM,CAAC;IAC3D,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK;IAC5C,4FAA4F;IAC5F,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK;CAClC,CAAC,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACrC,OAAO,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n\n/**\n * Canonical Fibonacci level ratios shared by every fib decomposer\n * (`fibRetracement`, `fibTrendExtension`, `fibChannel`, `fibSpeedFan`,\n * `fibSpeedArcs`, …). Frozen so per-kind decomposers cannot accidentally\n * mutate the shared array. Source: invinite's\n * `src/components/trading-chart/tools/fib-*` tools.\n *\n * Order is monotonic. Both the 0 and 1 endpoints are included so a\n * retracement decomposer that needs the bracket lines (the 0% and 100%\n * anchor levels) doesn't have to splice them in.\n *\n * @since 1.3\n * @stable\n * @example\n * for (const level of FIB_LEVELS) {\n * // Stroke a horizontal line at `from.price + level * (to.price - from.price)`.\n * void level;\n * }\n */\nexport const FIB_LEVELS: ReadonlyArray<number> = Object.freeze([\n 0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.272,\n // biome-ignore lint/suspicious/noApproximativeNumericConstant: canonical fib ratio, not √2.\n 1.414, 1.618, 2.0, 2.618, 4.236,\n]);\n\n/**\n * Format a Fibonacci ratio for display alongside its level line.\n * Integer ratios (`0`, `1`, `2`) render with one decimal place (`\"0.0\"`,\n * `\"1.0\"`, `\"2.0\"`); fractional ratios render with three (`\"0.236\"`,\n * `\"0.618\"`, `\"1.272\"`). Matches the Pine-style label convention used\n * by the invinite fib tools.\n *\n * @since 1.3\n * @stable\n * @example\n * formatLevel(0); // \"0.0\"\n * formatLevel(0.618); // \"0.618\"\n * formatLevel(1.272); // \"1.272\"\n */\nexport function formatLevel(level: number): string {\n return level === Math.floor(level) ? level.toFixed(1) : level.toFixed(3);\n}\n"]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Gann box subdivision ratios. Each box decomposer emits one
|
|
3
|
+
* horizontal + one vertical stroke at each ratio (including 0 and 1.0
|
|
4
|
+
* for the outer rectangle). The 1/4 subdivisions match the upstream
|
|
5
|
+
* invinite default and are the pinned Phase-3 wire shape.
|
|
6
|
+
*
|
|
7
|
+
* @since 1.3
|
|
8
|
+
* @stable
|
|
9
|
+
* @example
|
|
10
|
+
* import { GANN_LEVELS } from "./gannLevels.js";
|
|
11
|
+
* for (const level of GANN_LEVELS) void level;
|
|
12
|
+
*/
|
|
13
|
+
export declare const GANN_LEVELS: ReadonlyArray<number>;
|
|
14
|
+
/**
|
|
15
|
+
* Canonical Gann fan slope ratios. Each entry is the slope multiplier
|
|
16
|
+
* applied to the (a→b) direction vector — the 1×1 ray points at b, 1×2
|
|
17
|
+
* doubles the slope, 2×1 halves it, etc. The 9-entry tuple matches the
|
|
18
|
+
* upstream invinite default `FibGannLevel` set.
|
|
19
|
+
*
|
|
20
|
+
* @since 1.3
|
|
21
|
+
* @stable
|
|
22
|
+
* @example
|
|
23
|
+
* import { GANN_FAN_RATIOS } from "./gannLevels.js";
|
|
24
|
+
* for (const r of GANN_FAN_RATIOS) void r;
|
|
25
|
+
*/
|
|
26
|
+
export declare const GANN_FAN_RATIOS: ReadonlyArray<number>;
|
|
27
|
+
/**
|
|
28
|
+
* Human-readable label for each {@link GANN_FAN_RATIOS} entry. Order
|
|
29
|
+
* matches the ratios array so a decomposer can co-index them. Ratios
|
|
30
|
+
* greater than 1 render as `"1x<n>"`; ratios less than 1 render as
|
|
31
|
+
* `"<n>x1"`; 1×1 is the identity.
|
|
32
|
+
*
|
|
33
|
+
* @since 1.3
|
|
34
|
+
* @stable
|
|
35
|
+
* @example
|
|
36
|
+
* import { GANN_FAN_LABELS } from "./gannLevels.js";
|
|
37
|
+
* for (const label of GANN_FAN_LABELS) void label;
|
|
38
|
+
*/
|
|
39
|
+
export declare const GANN_FAN_LABELS: ReadonlyArray<string>;
|
|
40
|
+
/**
|
|
41
|
+
* Map a fan ratio to its kebab label. Ratios `>= 1` render as
|
|
42
|
+
* `"1x<n>"`; ratios `< 1` render as `"<n>x1"` where `n = round(1 /
|
|
43
|
+
* ratio)`. Used when fan labels are enabled.
|
|
44
|
+
*
|
|
45
|
+
* @since 1.3
|
|
46
|
+
* @stable
|
|
47
|
+
* @example
|
|
48
|
+
* import { formatGannRatio } from "./gannLevels.js";
|
|
49
|
+
* formatGannRatio(1); // "1x1"
|
|
50
|
+
* formatGannRatio(2); // "1x2"
|
|
51
|
+
* formatGannRatio(0.5); // "2x1"
|
|
52
|
+
*/
|
|
53
|
+
export declare function formatGannRatio(ratio: number): string;
|
|
54
|
+
//# sourceMappingURL=gannLevels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gannLevels.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/gannLevels.ts"],"names":[],"mappings":"AAWA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,MAAM,CAA0C,CAAC;AAEzF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,MAAM,CAUhD,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,MAAM,CAUhD,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGrD"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Copyright (c) 2026 Invinite. Licensed under the MIT License.
|
|
2
|
+
// See the LICENSE file in the repo root for full license text.
|
|
3
|
+
//
|
|
4
|
+
// Gann box subdivision + fan-slope tables moved verbatim from the
|
|
5
|
+
// canvas2d adapter's renderer helper
|
|
6
|
+
// examples/canvas2d-adapter/src/render/draw/gannLevels.ts.
|
|
7
|
+
// The originating subdivision + slope conventions are invinite's
|
|
8
|
+
// gann-box / gann-fan tools (commit
|
|
9
|
+
// 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite); re-licensed
|
|
10
|
+
// MIT for chartlang.
|
|
11
|
+
/**
|
|
12
|
+
* Canonical Gann box subdivision ratios. Each box decomposer emits one
|
|
13
|
+
* horizontal + one vertical stroke at each ratio (including 0 and 1.0
|
|
14
|
+
* for the outer rectangle). The 1/4 subdivisions match the upstream
|
|
15
|
+
* invinite default and are the pinned Phase-3 wire shape.
|
|
16
|
+
*
|
|
17
|
+
* @since 1.3
|
|
18
|
+
* @stable
|
|
19
|
+
* @example
|
|
20
|
+
* import { GANN_LEVELS } from "./gannLevels.js";
|
|
21
|
+
* for (const level of GANN_LEVELS) void level;
|
|
22
|
+
*/
|
|
23
|
+
export const GANN_LEVELS = Object.freeze([0, 0.25, 0.5, 0.75, 1]);
|
|
24
|
+
/**
|
|
25
|
+
* Canonical Gann fan slope ratios. Each entry is the slope multiplier
|
|
26
|
+
* applied to the (a→b) direction vector — the 1×1 ray points at b, 1×2
|
|
27
|
+
* doubles the slope, 2×1 halves it, etc. The 9-entry tuple matches the
|
|
28
|
+
* upstream invinite default `FibGannLevel` set.
|
|
29
|
+
*
|
|
30
|
+
* @since 1.3
|
|
31
|
+
* @stable
|
|
32
|
+
* @example
|
|
33
|
+
* import { GANN_FAN_RATIOS } from "./gannLevels.js";
|
|
34
|
+
* for (const r of GANN_FAN_RATIOS) void r;
|
|
35
|
+
*/
|
|
36
|
+
export const GANN_FAN_RATIOS = Object.freeze([
|
|
37
|
+
1,
|
|
38
|
+
2,
|
|
39
|
+
3,
|
|
40
|
+
0.5,
|
|
41
|
+
1 / 3,
|
|
42
|
+
4,
|
|
43
|
+
0.25,
|
|
44
|
+
8,
|
|
45
|
+
0.125,
|
|
46
|
+
]);
|
|
47
|
+
/**
|
|
48
|
+
* Human-readable label for each {@link GANN_FAN_RATIOS} entry. Order
|
|
49
|
+
* matches the ratios array so a decomposer can co-index them. Ratios
|
|
50
|
+
* greater than 1 render as `"1x<n>"`; ratios less than 1 render as
|
|
51
|
+
* `"<n>x1"`; 1×1 is the identity.
|
|
52
|
+
*
|
|
53
|
+
* @since 1.3
|
|
54
|
+
* @stable
|
|
55
|
+
* @example
|
|
56
|
+
* import { GANN_FAN_LABELS } from "./gannLevels.js";
|
|
57
|
+
* for (const label of GANN_FAN_LABELS) void label;
|
|
58
|
+
*/
|
|
59
|
+
export const GANN_FAN_LABELS = Object.freeze([
|
|
60
|
+
"1x1",
|
|
61
|
+
"1x2",
|
|
62
|
+
"1x3",
|
|
63
|
+
"2x1",
|
|
64
|
+
"3x1",
|
|
65
|
+
"1x4",
|
|
66
|
+
"4x1",
|
|
67
|
+
"1x8",
|
|
68
|
+
"8x1",
|
|
69
|
+
]);
|
|
70
|
+
/**
|
|
71
|
+
* Map a fan ratio to its kebab label. Ratios `>= 1` render as
|
|
72
|
+
* `"1x<n>"`; ratios `< 1` render as `"<n>x1"` where `n = round(1 /
|
|
73
|
+
* ratio)`. Used when fan labels are enabled.
|
|
74
|
+
*
|
|
75
|
+
* @since 1.3
|
|
76
|
+
* @stable
|
|
77
|
+
* @example
|
|
78
|
+
* import { formatGannRatio } from "./gannLevels.js";
|
|
79
|
+
* formatGannRatio(1); // "1x1"
|
|
80
|
+
* formatGannRatio(2); // "1x2"
|
|
81
|
+
* formatGannRatio(0.5); // "2x1"
|
|
82
|
+
*/
|
|
83
|
+
export function formatGannRatio(ratio) {
|
|
84
|
+
if (ratio >= 1)
|
|
85
|
+
return `1x${Math.round(ratio)}`;
|
|
86
|
+
return `${Math.round(1 / ratio)}x1`;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=gannLevels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gannLevels.js","sourceRoot":"","sources":["../../../src/geometry/_lib/gannLevels.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAC/D,EAAE;AACF,kEAAkE;AAClE,qCAAqC;AACrC,6DAA6D;AAC7D,iEAAiE;AACjE,oCAAoC;AACpC,qEAAqE;AACrE,qBAAqB;AAErB;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,WAAW,GAA0B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAEzF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAA0B,MAAM,CAAC,MAAM,CAAC;IAChE,CAAC;IACD,CAAC;IACD,CAAC;IACD,GAAG;IACH,CAAC,GAAG,CAAC;IACL,CAAC;IACD,IAAI;IACJ,CAAC;IACD,KAAK;CACR,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAA0B,MAAM,CAAC,MAAM,CAAC;IAChE,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACR,CAAC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IACzC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;IAChD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;AACxC,CAAC","sourcesContent":["// Copyright (c) 2026 Invinite. Licensed under the MIT License.\n// See the LICENSE file in the repo root for full license text.\n//\n// Gann box subdivision + fan-slope tables moved verbatim from the\n// canvas2d adapter's renderer helper\n// examples/canvas2d-adapter/src/render/draw/gannLevels.ts.\n// The originating subdivision + slope conventions are invinite's\n// gann-box / gann-fan tools (commit\n// 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite); re-licensed\n// MIT for chartlang.\n\n/**\n * Canonical Gann box subdivision ratios. Each box decomposer emits one\n * horizontal + one vertical stroke at each ratio (including 0 and 1.0\n * for the outer rectangle). The 1/4 subdivisions match the upstream\n * invinite default and are the pinned Phase-3 wire shape.\n *\n * @since 1.3\n * @stable\n * @example\n * import { GANN_LEVELS } from \"./gannLevels.js\";\n * for (const level of GANN_LEVELS) void level;\n */\nexport const GANN_LEVELS: ReadonlyArray<number> = Object.freeze([0, 0.25, 0.5, 0.75, 1]);\n\n/**\n * Canonical Gann fan slope ratios. Each entry is the slope multiplier\n * applied to the (a→b) direction vector — the 1×1 ray points at b, 1×2\n * doubles the slope, 2×1 halves it, etc. The 9-entry tuple matches the\n * upstream invinite default `FibGannLevel` set.\n *\n * @since 1.3\n * @stable\n * @example\n * import { GANN_FAN_RATIOS } from \"./gannLevels.js\";\n * for (const r of GANN_FAN_RATIOS) void r;\n */\nexport const GANN_FAN_RATIOS: ReadonlyArray<number> = Object.freeze([\n 1,\n 2,\n 3,\n 0.5,\n 1 / 3,\n 4,\n 0.25,\n 8,\n 0.125,\n]);\n\n/**\n * Human-readable label for each {@link GANN_FAN_RATIOS} entry. Order\n * matches the ratios array so a decomposer can co-index them. Ratios\n * greater than 1 render as `\"1x<n>\"`; ratios less than 1 render as\n * `\"<n>x1\"`; 1×1 is the identity.\n *\n * @since 1.3\n * @stable\n * @example\n * import { GANN_FAN_LABELS } from \"./gannLevels.js\";\n * for (const label of GANN_FAN_LABELS) void label;\n */\nexport const GANN_FAN_LABELS: ReadonlyArray<string> = Object.freeze([\n \"1x1\",\n \"1x2\",\n \"1x3\",\n \"2x1\",\n \"3x1\",\n \"1x4\",\n \"4x1\",\n \"1x8\",\n \"8x1\",\n]);\n\n/**\n * Map a fan ratio to its kebab label. Ratios `>= 1` render as\n * `\"1x<n>\"`; ratios `< 1` render as `\"<n>x1\"` where `n = round(1 /\n * ratio)`. Used when fan labels are enabled.\n *\n * @since 1.3\n * @stable\n * @example\n * import { formatGannRatio } from \"./gannLevels.js\";\n * formatGannRatio(1); // \"1x1\"\n * formatGannRatio(2); // \"1x2\"\n * formatGannRatio(0.5); // \"2x1\"\n */\nexport function formatGannRatio(ratio: number): string {\n if (ratio >= 1) return `1x${Math.round(ratio)}`;\n return `${Math.round(1 / ratio)}x1`;\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Point2, Viewport } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Project the segment `(a, b)` to the viewport edges in the directions
|
|
4
|
+
* `opts.extendLeft` / `opts.extendRight`. Used by the `line`
|
|
5
|
+
* decomposer (when its `LineDrawStyle` flags are set) and by
|
|
6
|
+
* `horizontal-ray` (always extends right).
|
|
7
|
+
*
|
|
8
|
+
* The projection walks the parametric line `p(t) = a + t·(b − a)` and
|
|
9
|
+
* solves for the `t` that hits `x = 0` (left edge) or
|
|
10
|
+
* `x = view.pxWidth` (right edge). A purely vertical segment
|
|
11
|
+
* (`dx === 0`) cannot intersect the x-edges, so the segment is returned
|
|
12
|
+
* unchanged (the stroke clips at the viewport boundary).
|
|
13
|
+
*
|
|
14
|
+
* @since 1.3
|
|
15
|
+
* @stable
|
|
16
|
+
* @example
|
|
17
|
+
* declare const view: Viewport;
|
|
18
|
+
* const a: Point2 = { x: 100, y: 100 };
|
|
19
|
+
* const b: Point2 = { x: 200, y: 200 };
|
|
20
|
+
* const seg = extendLineSegment(a, b, { extendRight: true }, view);
|
|
21
|
+
* // seg.from === a; seg.to.x === view.pxWidth
|
|
22
|
+
* void seg;
|
|
23
|
+
*/
|
|
24
|
+
export declare function extendLineSegment(a: Point2, b: Point2, opts: {
|
|
25
|
+
readonly extendLeft?: boolean | undefined;
|
|
26
|
+
readonly extendRight?: boolean | undefined;
|
|
27
|
+
}, view: Viewport): {
|
|
28
|
+
readonly from: Point2;
|
|
29
|
+
readonly to: Point2;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=lineExtend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineExtend.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/lineExtend.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAC7B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,IAAI,EAAE;IAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,EAC/F,IAAI,EAAE,QAAQ,GACf;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAkBhD"}
|