@invinite-org/chartlang-adapter-kit 1.3.0 → 1.5.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 +68 -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/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 +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/interaction/domWiring.d.ts +90 -0
- package/dist/interaction/domWiring.d.ts.map +1 -0
- package/dist/interaction/domWiring.js +113 -0
- package/dist/interaction/domWiring.js.map +1 -0
- package/dist/interaction/index.d.ts +5 -0
- package/dist/interaction/index.d.ts.map +1 -0
- package/dist/interaction/index.js +5 -0
- package/dist/interaction/index.js.map +1 -0
- package/dist/interaction/viewController.d.ts +120 -0
- package/dist/interaction/viewController.d.ts.map +1 -0
- package/dist/interaction/viewController.js +112 -0
- package/dist/interaction/viewController.js.map +1 -0
- package/package.json +8 -1
|
@@ -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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
// Geometry ported from
|
|
5
|
+
// invinite/src/components/trading-chart/tools/lib/geometry.ts
|
|
6
|
+
// (`extendSegmentPx`), commit
|
|
7
|
+
// 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite.
|
|
8
|
+
// Re-licensed MIT for chartlang.
|
|
9
|
+
/**
|
|
10
|
+
* Project the segment `(a, b)` to the viewport edges in the directions
|
|
11
|
+
* `opts.extendLeft` / `opts.extendRight`. Used by the `line`
|
|
12
|
+
* decomposer (when its `LineDrawStyle` flags are set) and by
|
|
13
|
+
* `horizontal-ray` (always extends right).
|
|
14
|
+
*
|
|
15
|
+
* The projection walks the parametric line `p(t) = a + t·(b − a)` and
|
|
16
|
+
* solves for the `t` that hits `x = 0` (left edge) or
|
|
17
|
+
* `x = view.pxWidth` (right edge). A purely vertical segment
|
|
18
|
+
* (`dx === 0`) cannot intersect the x-edges, so the segment is returned
|
|
19
|
+
* unchanged (the stroke clips at the viewport boundary).
|
|
20
|
+
*
|
|
21
|
+
* @since 1.3
|
|
22
|
+
* @stable
|
|
23
|
+
* @example
|
|
24
|
+
* declare const view: Viewport;
|
|
25
|
+
* const a: Point2 = { x: 100, y: 100 };
|
|
26
|
+
* const b: Point2 = { x: 200, y: 200 };
|
|
27
|
+
* const seg = extendLineSegment(a, b, { extendRight: true }, view);
|
|
28
|
+
* // seg.from === a; seg.to.x === view.pxWidth
|
|
29
|
+
* void seg;
|
|
30
|
+
*/
|
|
31
|
+
export function extendLineSegment(a, b, opts, view) {
|
|
32
|
+
const dx = b.x - a.x;
|
|
33
|
+
const dy = b.y - a.y;
|
|
34
|
+
if (dx === 0)
|
|
35
|
+
return { from: a, to: b };
|
|
36
|
+
let from = a;
|
|
37
|
+
let to = b;
|
|
38
|
+
if (opts.extendLeft === true) {
|
|
39
|
+
const t = -a.x / dx;
|
|
40
|
+
from = { x: 0, y: a.y + t * dy };
|
|
41
|
+
}
|
|
42
|
+
if (opts.extendRight === true) {
|
|
43
|
+
const t = (view.pxWidth - b.x) / dx;
|
|
44
|
+
to = { x: view.pxWidth, y: b.y + t * dy };
|
|
45
|
+
}
|
|
46
|
+
return { from, to };
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=lineExtend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineExtend.js","sourceRoot":"","sources":["../../../src/geometry/_lib/lineExtend.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAC/D,EAAE;AACF,uBAAuB;AACvB,gEAAgE;AAChE,kCAAkC;AAClC,4DAA4D;AAC5D,iCAAiC;AAIjC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,iBAAiB,CAC7B,CAAS,EACT,CAAS,EACT,IAA+F,EAC/F,IAAc;IAEd,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;IAExC,IAAI,IAAI,GAAW,CAAC,CAAC;IACrB,IAAI,EAAE,GAAW,CAAC,CAAC;IAEnB,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACpB,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC;IACrC,CAAC;IACD,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACpC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC;IAC9C,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACxB,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// Geometry ported from\n// invinite/src/components/trading-chart/tools/lib/geometry.ts\n// (`extendSegmentPx`), commit\n// 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite.\n// Re-licensed MIT for chartlang.\n\nimport type { Point2, Viewport } from \"../types.js\";\n\n/**\n * Project the segment `(a, b)` to the viewport edges in the directions\n * `opts.extendLeft` / `opts.extendRight`. Used by the `line`\n * decomposer (when its `LineDrawStyle` flags are set) and by\n * `horizontal-ray` (always extends right).\n *\n * The projection walks the parametric line `p(t) = a + t·(b − a)` and\n * solves for the `t` that hits `x = 0` (left edge) or\n * `x = view.pxWidth` (right edge). A purely vertical segment\n * (`dx === 0`) cannot intersect the x-edges, so the segment is returned\n * unchanged (the stroke clips at the viewport boundary).\n *\n * @since 1.3\n * @stable\n * @example\n * declare const view: Viewport;\n * const a: Point2 = { x: 100, y: 100 };\n * const b: Point2 = { x: 200, y: 200 };\n * const seg = extendLineSegment(a, b, { extendRight: true }, view);\n * // seg.from === a; seg.to.x === view.pxWidth\n * void seg;\n */\nexport function extendLineSegment(\n a: Point2,\n b: Point2,\n opts: { readonly extendLeft?: boolean | undefined; readonly extendRight?: boolean | undefined },\n view: Viewport,\n): { readonly from: Point2; readonly to: Point2 } {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n if (dx === 0) return { from: a, to: b };\n\n let from: Point2 = a;\n let to: Point2 = b;\n\n if (opts.extendLeft === true) {\n const t = -a.x / dx;\n from = { x: 0, y: a.y + t * dy };\n }\n if (opts.extendRight === true) {\n const t = (view.pxWidth - b.x) / dx;\n to = { x: view.pxWidth, y: b.y + t * dy };\n }\n\n return { from, to };\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { LineDrawStyle } from "@invinite-org/chartlang-core";
|
|
2
|
+
import type { DrawPrimitive, Point2 } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Reduce an open labelled polyline to `DrawPrimitive[]`: one open
|
|
5
|
+
* `polyline` through `points` plus one `text` primitive per vertex,
|
|
6
|
+
* each label `LABEL_OFFSET_PX = 6 px` above its anchor with
|
|
7
|
+
* `align: "center"` / `baseline: "bottom"`. Consumed by the harmonic
|
|
8
|
+
* pattern decomposers (Tasks 2–3). Returns `[]` when `points` is empty.
|
|
9
|
+
*
|
|
10
|
+
* `points.length === labels.length` is a structural contract: every
|
|
11
|
+
* vertex carries exactly one label (X / A / B / C / D / S / H / …).
|
|
12
|
+
*
|
|
13
|
+
* @since 1.3
|
|
14
|
+
* @stable
|
|
15
|
+
* @example
|
|
16
|
+
* const prims = namedPolylinePrimitives(
|
|
17
|
+
* [{ x: 0, y: 0 }, { x: 10, y: 5 }],
|
|
18
|
+
* ["X", "A"],
|
|
19
|
+
* {},
|
|
20
|
+
* );
|
|
21
|
+
* // prims[0].kind === "polyline"; prims[1].kind === "text"
|
|
22
|
+
* void prims;
|
|
23
|
+
*/
|
|
24
|
+
export declare function namedPolylinePrimitives(points: ReadonlyArray<Point2>, labels: ReadonlyArray<string>, style: LineDrawStyle): ReadonlyArray<DrawPrimitive>;
|
|
25
|
+
//# sourceMappingURL=namedPolyline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namedPolyline.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/namedPolyline.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQzD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CACnC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,EAC7B,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,EAC7B,KAAK,EAAE,aAAa,GACrB,aAAa,CAAC,aAAa,CAAC,CAyB9B"}
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
// Open-polyline + per-vertex label composition mirrors invinite's
|
|
5
|
+
// pattern tools' `renderConnectedLegs` + `renderPointLabel` helpers:
|
|
6
|
+
// invinite/src/components/trading-chart/tools/xabcd-pattern-tool.ts
|
|
7
|
+
// invinite/src/components/trading-chart/tools/abcd-pattern-tool.ts
|
|
8
|
+
// (and the other 3 pattern tools), commit
|
|
9
|
+
// 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite.
|
|
10
|
+
// Re-licensed MIT for chartlang.
|
|
11
|
+
import { dashPattern } from "./dash.js";
|
|
12
|
+
const DEFAULT_COLOR = "#f59e0b";
|
|
13
|
+
const DEFAULT_LINE_WIDTH = 1;
|
|
14
|
+
const LABEL_FONT = "11px sans-serif";
|
|
15
|
+
const LABEL_OFFSET_PX = 6;
|
|
16
|
+
/**
|
|
17
|
+
* Reduce an open labelled polyline to `DrawPrimitive[]`: one open
|
|
18
|
+
* `polyline` through `points` plus one `text` primitive per vertex,
|
|
19
|
+
* each label `LABEL_OFFSET_PX = 6 px` above its anchor with
|
|
20
|
+
* `align: "center"` / `baseline: "bottom"`. Consumed by the harmonic
|
|
21
|
+
* pattern decomposers (Tasks 2–3). Returns `[]` when `points` is empty.
|
|
22
|
+
*
|
|
23
|
+
* `points.length === labels.length` is a structural contract: every
|
|
24
|
+
* vertex carries exactly one label (X / A / B / C / D / S / H / …).
|
|
25
|
+
*
|
|
26
|
+
* @since 1.3
|
|
27
|
+
* @stable
|
|
28
|
+
* @example
|
|
29
|
+
* const prims = namedPolylinePrimitives(
|
|
30
|
+
* [{ x: 0, y: 0 }, { x: 10, y: 5 }],
|
|
31
|
+
* ["X", "A"],
|
|
32
|
+
* {},
|
|
33
|
+
* );
|
|
34
|
+
* // prims[0].kind === "polyline"; prims[1].kind === "text"
|
|
35
|
+
* void prims;
|
|
36
|
+
*/
|
|
37
|
+
export function namedPolylinePrimitives(points, labels, style) {
|
|
38
|
+
if (points.length === 0)
|
|
39
|
+
return [];
|
|
40
|
+
const color = style.color ?? DEFAULT_COLOR;
|
|
41
|
+
const lineWidth = style.lineWidth ?? DEFAULT_LINE_WIDTH;
|
|
42
|
+
const out = [
|
|
43
|
+
{
|
|
44
|
+
kind: "polyline",
|
|
45
|
+
points,
|
|
46
|
+
closed: false,
|
|
47
|
+
stroke: { color, width: lineWidth, dash: dashPattern("solid") },
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
for (let i = 0; i < points.length; i++) {
|
|
51
|
+
out.push({
|
|
52
|
+
kind: "text",
|
|
53
|
+
x: points[i].x,
|
|
54
|
+
y: points[i].y - LABEL_OFFSET_PX,
|
|
55
|
+
text: labels[i],
|
|
56
|
+
color,
|
|
57
|
+
font: LABEL_FONT,
|
|
58
|
+
align: "center",
|
|
59
|
+
baseline: "bottom",
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=namedPolyline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namedPolyline.js","sourceRoot":"","sources":["../../../src/geometry/_lib/namedPolyline.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAC/D,EAAE;AACF,kEAAkE;AAClE,qEAAqE;AACrE,sEAAsE;AACtE,qEAAqE;AACrE,4CAA4C;AAC5C,0DAA0D;AAC1D,iCAAiC;AAKjC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,aAAa,GAAG,SAAS,CAAC;AAChC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,MAAM,UAAU,GAAG,iBAAiB,CAAC;AACrC,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,uBAAuB,CACnC,MAA6B,EAC7B,MAA6B,EAC7B,KAAoB;IAEpB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,aAAa,CAAC;IAC3C,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,kBAAkB,CAAC;IACxD,MAAM,GAAG,GAAoB;QACzB;YACI,IAAI,EAAE,UAAU;YAChB,MAAM;YACN,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE;SAClE;KACJ,CAAC;IACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,GAAG,CAAC,IAAI,CAAC;YACL,IAAI,EAAE,MAAM;YACZ,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACd,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe;YAChC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YACf,KAAK;YACL,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,QAAQ;SACrB,CAAC,CAAC;IACP,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//\n// Open-polyline + per-vertex label composition mirrors invinite's\n// pattern tools' `renderConnectedLegs` + `renderPointLabel` helpers:\n// invinite/src/components/trading-chart/tools/xabcd-pattern-tool.ts\n// invinite/src/components/trading-chart/tools/abcd-pattern-tool.ts\n// (and the other 3 pattern tools), commit\n// 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite.\n// Re-licensed MIT for chartlang.\n\nimport type { LineDrawStyle } from \"@invinite-org/chartlang-core\";\n\nimport type { DrawPrimitive, Point2 } from \"../types.js\";\nimport { dashPattern } from \"./dash.js\";\n\nconst DEFAULT_COLOR = \"#f59e0b\";\nconst DEFAULT_LINE_WIDTH = 1;\nconst LABEL_FONT = \"11px sans-serif\";\nconst LABEL_OFFSET_PX = 6;\n\n/**\n * Reduce an open labelled polyline to `DrawPrimitive[]`: one open\n * `polyline` through `points` plus one `text` primitive per vertex,\n * each label `LABEL_OFFSET_PX = 6 px` above its anchor with\n * `align: \"center\"` / `baseline: \"bottom\"`. Consumed by the harmonic\n * pattern decomposers (Tasks 2–3). Returns `[]` when `points` is empty.\n *\n * `points.length === labels.length` is a structural contract: every\n * vertex carries exactly one label (X / A / B / C / D / S / H / …).\n *\n * @since 1.3\n * @stable\n * @example\n * const prims = namedPolylinePrimitives(\n * [{ x: 0, y: 0 }, { x: 10, y: 5 }],\n * [\"X\", \"A\"],\n * {},\n * );\n * // prims[0].kind === \"polyline\"; prims[1].kind === \"text\"\n * void prims;\n */\nexport function namedPolylinePrimitives(\n points: ReadonlyArray<Point2>,\n labels: ReadonlyArray<string>,\n style: LineDrawStyle,\n): ReadonlyArray<DrawPrimitive> {\n if (points.length === 0) return [];\n const color = style.color ?? DEFAULT_COLOR;\n const lineWidth = style.lineWidth ?? DEFAULT_LINE_WIDTH;\n const out: DrawPrimitive[] = [\n {\n kind: \"polyline\",\n points,\n closed: false,\n stroke: { color, width: lineWidth, dash: dashPattern(\"solid\") },\n },\n ];\n for (let i = 0; i < points.length; i++) {\n out.push({\n kind: \"text\",\n x: points[i].x,\n y: points[i].y - LABEL_OFFSET_PX,\n text: labels[i],\n color,\n font: LABEL_FONT,\n align: \"center\",\n baseline: \"bottom\",\n });\n }\n return out;\n}\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { PitchforkState } from "@invinite-org/chartlang-core";
|
|
2
|
+
import type { Point2 } from "../types.js";
|
|
3
|
+
type PitchforkVariant = PitchforkState["variant"];
|
|
4
|
+
/**
|
|
5
|
+
* Per-variant median-origin point — the first endpoint of the
|
|
6
|
+
* pitchfork's median rail in pixel space. A decomposer draws three
|
|
7
|
+
* lines: the median (origin → target → +extension) and two parallel
|
|
8
|
+
* handles through `b` and `c` offset by the same `target - origin`
|
|
9
|
+
* vector.
|
|
10
|
+
*
|
|
11
|
+
* Variants:
|
|
12
|
+
* - `standard` — origin = `a`; target = `mid(b, c)`.
|
|
13
|
+
* - `schiff` — origin = `(a.x, mid(a.y, midBC.y))`; target = `mid(b, c)`.
|
|
14
|
+
* - `modifiedSchiff` — origin = `mid(a, b)`; target = `mid(b, c)`.
|
|
15
|
+
* - `inside` — origin = `mid(b, c)`; target = `midBC + (c - midAB)`.
|
|
16
|
+
*
|
|
17
|
+
* @since 1.3
|
|
18
|
+
* @stable
|
|
19
|
+
* @example
|
|
20
|
+
* import { medianOriginFor } from "./pitchforkGeom.js";
|
|
21
|
+
* const origin = medianOriginFor(
|
|
22
|
+
* "standard",
|
|
23
|
+
* { x: 0, y: 0 }, { x: 10, y: 10 }, { x: 20, y: 0 },
|
|
24
|
+
* );
|
|
25
|
+
* void origin;
|
|
26
|
+
*/
|
|
27
|
+
export declare function medianOriginFor(variant: PitchforkVariant, a: Point2, b: Point2, c: Point2): Point2;
|
|
28
|
+
/**
|
|
29
|
+
* Per-variant median-target point — the second endpoint of the
|
|
30
|
+
* pitchfork's median rail. A decomposer uses it to compute the
|
|
31
|
+
* extension vector `target - origin` reused for the two parallel handle
|
|
32
|
+
* rails.
|
|
33
|
+
*
|
|
34
|
+
* @since 1.3
|
|
35
|
+
* @stable
|
|
36
|
+
* @example
|
|
37
|
+
* import { medianTargetFor } from "./pitchforkGeom.js";
|
|
38
|
+
* const target = medianTargetFor(
|
|
39
|
+
* "standard",
|
|
40
|
+
* { x: 0, y: 0 }, { x: 10, y: 10 }, { x: 20, y: 0 },
|
|
41
|
+
* );
|
|
42
|
+
* void target;
|
|
43
|
+
*/
|
|
44
|
+
export declare function medianTargetFor(variant: PitchforkVariant, a: Point2, b: Point2, c: Point2): Point2;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=pitchforkGeom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pitchforkGeom.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/pitchforkGeom.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,KAAK,gBAAgB,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAC3B,OAAO,EAAE,gBAAgB,EACzB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACV,MAAM,CAYR;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC3B,OAAO,EAAE,gBAAgB,EACzB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACV,MAAM,CAOR"}
|
|
@@ -0,0 +1,70 @@
|
|
|
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
|
+
// Median-origin + median-target formulas moved verbatim from the
|
|
5
|
+
// canvas2d adapter's renderer helper
|
|
6
|
+
// examples/canvas2d-adapter/src/render/draw/pitchforkGeom.ts.
|
|
7
|
+
// The originating math is invinite's pitchfork-geometry lib (commit
|
|
8
|
+
// 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite); re-licensed
|
|
9
|
+
// MIT for chartlang.
|
|
10
|
+
/**
|
|
11
|
+
* Per-variant median-origin point — the first endpoint of the
|
|
12
|
+
* pitchfork's median rail in pixel space. A decomposer draws three
|
|
13
|
+
* lines: the median (origin → target → +extension) and two parallel
|
|
14
|
+
* handles through `b` and `c` offset by the same `target - origin`
|
|
15
|
+
* vector.
|
|
16
|
+
*
|
|
17
|
+
* Variants:
|
|
18
|
+
* - `standard` — origin = `a`; target = `mid(b, c)`.
|
|
19
|
+
* - `schiff` — origin = `(a.x, mid(a.y, midBC.y))`; target = `mid(b, c)`.
|
|
20
|
+
* - `modifiedSchiff` — origin = `mid(a, b)`; target = `mid(b, c)`.
|
|
21
|
+
* - `inside` — origin = `mid(b, c)`; target = `midBC + (c - midAB)`.
|
|
22
|
+
*
|
|
23
|
+
* @since 1.3
|
|
24
|
+
* @stable
|
|
25
|
+
* @example
|
|
26
|
+
* import { medianOriginFor } from "./pitchforkGeom.js";
|
|
27
|
+
* const origin = medianOriginFor(
|
|
28
|
+
* "standard",
|
|
29
|
+
* { x: 0, y: 0 }, { x: 10, y: 10 }, { x: 20, y: 0 },
|
|
30
|
+
* );
|
|
31
|
+
* void origin;
|
|
32
|
+
*/
|
|
33
|
+
export function medianOriginFor(variant, a, b, c) {
|
|
34
|
+
const midBC = { x: (b.x + c.x) / 2, y: (b.y + c.y) / 2 };
|
|
35
|
+
if (variant === "schiff") {
|
|
36
|
+
return { x: a.x, y: (a.y + midBC.y) / 2 };
|
|
37
|
+
}
|
|
38
|
+
if (variant === "modifiedSchiff") {
|
|
39
|
+
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
40
|
+
}
|
|
41
|
+
if (variant === "inside") {
|
|
42
|
+
return midBC;
|
|
43
|
+
}
|
|
44
|
+
return a;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Per-variant median-target point — the second endpoint of the
|
|
48
|
+
* pitchfork's median rail. A decomposer uses it to compute the
|
|
49
|
+
* extension vector `target - origin` reused for the two parallel handle
|
|
50
|
+
* rails.
|
|
51
|
+
*
|
|
52
|
+
* @since 1.3
|
|
53
|
+
* @stable
|
|
54
|
+
* @example
|
|
55
|
+
* import { medianTargetFor } from "./pitchforkGeom.js";
|
|
56
|
+
* const target = medianTargetFor(
|
|
57
|
+
* "standard",
|
|
58
|
+
* { x: 0, y: 0 }, { x: 10, y: 10 }, { x: 20, y: 0 },
|
|
59
|
+
* );
|
|
60
|
+
* void target;
|
|
61
|
+
*/
|
|
62
|
+
export function medianTargetFor(variant, a, b, c) {
|
|
63
|
+
const midBC = { x: (b.x + c.x) / 2, y: (b.y + c.y) / 2 };
|
|
64
|
+
if (variant === "inside") {
|
|
65
|
+
const midAB = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
66
|
+
return { x: midBC.x + (c.x - midAB.x), y: midBC.y + (c.y - midAB.y) };
|
|
67
|
+
}
|
|
68
|
+
return midBC;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=pitchforkGeom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pitchforkGeom.js","sourceRoot":"","sources":["../../../src/geometry/_lib/pitchforkGeom.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAC/D,EAAE;AACF,iEAAiE;AACjE,qCAAqC;AACrC,gEAAgE;AAChE,oEAAoE;AACpE,qEAAqE;AACrE,qBAAqB;AAQrB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,eAAe,CAC3B,OAAyB,EACzB,CAAS,EACT,CAAS,EACT,CAAS;IAET,MAAM,KAAK,GAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACjE,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAC9C,CAAC;IACD,IAAI,OAAO,KAAK,gBAAgB,EAAE,CAAC;QAC/B,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACtD,CAAC;IACD,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAC3B,OAAyB,EACzB,CAAS,EACT,CAAS,EACT,CAAS;IAET,MAAM,KAAK,GAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACjE,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACvB,MAAM,KAAK,GAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QACjE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,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// Median-origin + median-target formulas moved verbatim from the\n// canvas2d adapter's renderer helper\n// examples/canvas2d-adapter/src/render/draw/pitchforkGeom.ts.\n// The originating math is invinite's pitchfork-geometry lib (commit\n// 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite); re-licensed\n// MIT for chartlang.\n\nimport type { PitchforkState } from \"@invinite-org/chartlang-core\";\n\nimport type { Point2 } from \"../types.js\";\n\ntype PitchforkVariant = PitchforkState[\"variant\"];\n\n/**\n * Per-variant median-origin point — the first endpoint of the\n * pitchfork's median rail in pixel space. A decomposer draws three\n * lines: the median (origin → target → +extension) and two parallel\n * handles through `b` and `c` offset by the same `target - origin`\n * vector.\n *\n * Variants:\n * - `standard` — origin = `a`; target = `mid(b, c)`.\n * - `schiff` — origin = `(a.x, mid(a.y, midBC.y))`; target = `mid(b, c)`.\n * - `modifiedSchiff` — origin = `mid(a, b)`; target = `mid(b, c)`.\n * - `inside` — origin = `mid(b, c)`; target = `midBC + (c - midAB)`.\n *\n * @since 1.3\n * @stable\n * @example\n * import { medianOriginFor } from \"./pitchforkGeom.js\";\n * const origin = medianOriginFor(\n * \"standard\",\n * { x: 0, y: 0 }, { x: 10, y: 10 }, { x: 20, y: 0 },\n * );\n * void origin;\n */\nexport function medianOriginFor(\n variant: PitchforkVariant,\n a: Point2,\n b: Point2,\n c: Point2,\n): Point2 {\n const midBC: Point2 = { x: (b.x + c.x) / 2, y: (b.y + c.y) / 2 };\n if (variant === \"schiff\") {\n return { x: a.x, y: (a.y + midBC.y) / 2 };\n }\n if (variant === \"modifiedSchiff\") {\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n }\n if (variant === \"inside\") {\n return midBC;\n }\n return a;\n}\n\n/**\n * Per-variant median-target point — the second endpoint of the\n * pitchfork's median rail. A decomposer uses it to compute the\n * extension vector `target - origin` reused for the two parallel handle\n * rails.\n *\n * @since 1.3\n * @stable\n * @example\n * import { medianTargetFor } from \"./pitchforkGeom.js\";\n * const target = medianTargetFor(\n * \"standard\",\n * { x: 0, y: 0 }, { x: 10, y: 10 }, { x: 20, y: 0 },\n * );\n * void target;\n */\nexport function medianTargetFor(\n variant: PitchforkVariant,\n a: Point2,\n b: Point2,\n c: Point2,\n): Point2 {\n const midBC: Point2 = { x: (b.x + c.x) / 2, y: (b.y + c.y) / 2 };\n if (variant === \"inside\") {\n const midAB: Point2 = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n return { x: midBC.x + (c.x - midAB.x), y: midBC.y + (c.y - midAB.y) };\n }\n return midBC;\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ShapeStyle } from "@invinite-org/chartlang-core";
|
|
2
|
+
import type { FillStyle, StrokeStyle } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolved {@link ShapeStyle} → IR styles. `stroke` is always present
|
|
5
|
+
* (defaults `"#000000"` / `1` / solid); `fill` is present only when the
|
|
6
|
+
* source `style.fill` is set, with `alpha` defaulting to `1`. The
|
|
7
|
+
* box / shape decomposers map this straight onto a `polyline` / `arc`
|
|
8
|
+
* primitive's `stroke` / `fill`. Pure — no `ctx`.
|
|
9
|
+
*
|
|
10
|
+
* @since 1.3
|
|
11
|
+
* @stable
|
|
12
|
+
* @example
|
|
13
|
+
* const r = resolveShapeStyle({ stroke: "#3b82f6", fill: "#dbeafe", fillAlpha: 0.4 });
|
|
14
|
+
* // r.stroke.color === "#3b82f6"; r.fill?.alpha === 0.4
|
|
15
|
+
* void r;
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveShapeStyle(style: ShapeStyle): {
|
|
18
|
+
readonly stroke: StrokeStyle;
|
|
19
|
+
readonly fill?: FillStyle;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=shapeStyle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shapeStyle.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/shapeStyle.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG;IAClD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;CAC7B,CAaA"}
|