@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,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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
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
|
+
// Stroke + fill semantics ported from the per-tool style application
|
|
5
|
+
// in invinite/src/components/trading-chart/tools/rectangle-tool.ts,
|
|
6
|
+
// triangle-tool.ts, rotated-rectangle-tool.ts (commit
|
|
7
|
+
// 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite). Re-licensed
|
|
8
|
+
// MIT for chartlang.
|
|
9
|
+
import { dashPattern } from "./dash.js";
|
|
10
|
+
const DEFAULT_STROKE = "#000000";
|
|
11
|
+
const DEFAULT_LINE_WIDTH = 1;
|
|
12
|
+
const DEFAULT_FILL_ALPHA = 1;
|
|
13
|
+
/**
|
|
14
|
+
* Resolved {@link ShapeStyle} → IR styles. `stroke` is always present
|
|
15
|
+
* (defaults `"#000000"` / `1` / solid); `fill` is present only when the
|
|
16
|
+
* source `style.fill` is set, with `alpha` defaulting to `1`. The
|
|
17
|
+
* box / shape decomposers map this straight onto a `polyline` / `arc`
|
|
18
|
+
* primitive's `stroke` / `fill`. Pure — no `ctx`.
|
|
19
|
+
*
|
|
20
|
+
* @since 1.3
|
|
21
|
+
* @stable
|
|
22
|
+
* @example
|
|
23
|
+
* const r = resolveShapeStyle({ stroke: "#3b82f6", fill: "#dbeafe", fillAlpha: 0.4 });
|
|
24
|
+
* // r.stroke.color === "#3b82f6"; r.fill?.alpha === 0.4
|
|
25
|
+
* void r;
|
|
26
|
+
*/
|
|
27
|
+
export function resolveShapeStyle(style) {
|
|
28
|
+
const stroke = {
|
|
29
|
+
color: style.stroke ?? DEFAULT_STROKE,
|
|
30
|
+
width: style.lineWidth ?? DEFAULT_LINE_WIDTH,
|
|
31
|
+
dash: dashPattern(style.lineStyle ?? "solid"),
|
|
32
|
+
};
|
|
33
|
+
if (style.fill === undefined) {
|
|
34
|
+
return { stroke };
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
stroke,
|
|
38
|
+
fill: { color: style.fill, alpha: style.fillAlpha ?? DEFAULT_FILL_ALPHA },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=shapeStyle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shapeStyle.js","sourceRoot":"","sources":["../../../src/geometry/_lib/shapeStyle.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAC/D,EAAE;AACF,qEAAqE;AACrE,oEAAoE;AACpE,sDAAsD;AACtD,qEAAqE;AACrE,qBAAqB;AAKrB,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,cAAc,GAAG,SAAS,CAAC;AACjC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAiB;IAI/C,MAAM,MAAM,GAAgB;QACxB,KAAK,EAAE,KAAK,CAAC,MAAM,IAAI,cAAc;QACrC,KAAK,EAAE,KAAK,CAAC,SAAS,IAAI,kBAAkB;QAC5C,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC;KAChD,CAAC;IACF,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IACtB,CAAC;IACD,OAAO;QACH,MAAM;QACN,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,SAAS,IAAI,kBAAkB,EAAE;KAC5E,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// Stroke + fill semantics ported from the per-tool style application\n// in invinite/src/components/trading-chart/tools/rectangle-tool.ts,\n// triangle-tool.ts, rotated-rectangle-tool.ts (commit\n// 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite). Re-licensed\n// MIT for chartlang.\n\nimport type { ShapeStyle } from \"@invinite-org/chartlang-core\";\n\nimport type { FillStyle, StrokeStyle } from \"../types.js\";\nimport { dashPattern } from \"./dash.js\";\n\nconst DEFAULT_STROKE = \"#000000\";\nconst DEFAULT_LINE_WIDTH = 1;\nconst DEFAULT_FILL_ALPHA = 1;\n\n/**\n * Resolved {@link ShapeStyle} → IR styles. `stroke` is always present\n * (defaults `\"#000000\"` / `1` / solid); `fill` is present only when the\n * source `style.fill` is set, with `alpha` defaulting to `1`. The\n * box / shape decomposers map this straight onto a `polyline` / `arc`\n * primitive's `stroke` / `fill`. Pure — no `ctx`.\n *\n * @since 1.3\n * @stable\n * @example\n * const r = resolveShapeStyle({ stroke: \"#3b82f6\", fill: \"#dbeafe\", fillAlpha: 0.4 });\n * // r.stroke.color === \"#3b82f6\"; r.fill?.alpha === 0.4\n * void r;\n */\nexport function resolveShapeStyle(style: ShapeStyle): {\n readonly stroke: StrokeStyle;\n readonly fill?: FillStyle;\n} {\n const stroke: StrokeStyle = {\n color: style.stroke ?? DEFAULT_STROKE,\n width: style.lineWidth ?? DEFAULT_LINE_WIDTH,\n dash: dashPattern(style.lineStyle ?? \"solid\"),\n };\n if (style.fill === undefined) {\n return { stroke };\n }\n return {\n stroke,\n fill: { color: style.fill, alpha: style.fillAlpha ?? DEFAULT_FILL_ALPHA },\n };\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { StrokeStyle } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The line-style inputs every line-family decomposer reads off its
|
|
4
|
+
* drawing state — the structural shape shared by `lines`, `curves`,
|
|
5
|
+
* `channels`, and `cycles`.
|
|
6
|
+
*
|
|
7
|
+
* @since 1.3
|
|
8
|
+
* @stable
|
|
9
|
+
* @example
|
|
10
|
+
* const style: LineStyleInput = { color: "#000000", lineStyle: "dashed" };
|
|
11
|
+
* void style;
|
|
12
|
+
*/
|
|
13
|
+
export type LineStyleInput = {
|
|
14
|
+
readonly color?: string | undefined;
|
|
15
|
+
readonly lineWidth?: number | undefined;
|
|
16
|
+
readonly lineStyle?: "solid" | "dashed" | "dotted" | undefined;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Resolve a {@link LineStyleInput} into a {@link StrokeStyle}, applying
|
|
20
|
+
* the family defaults: colour falls back to `defaultColor` (black for
|
|
21
|
+
* most kinds; the `cycles` decomposers pass their own accent), width to
|
|
22
|
+
* `1`, and the dash array is derived from `lineStyle` via
|
|
23
|
+
* {@link dashPattern}. Extracted so the four line-family `kinds/` files
|
|
24
|
+
* share one resolver instead of byte-identical copies.
|
|
25
|
+
*
|
|
26
|
+
* @since 1.3
|
|
27
|
+
* @stable
|
|
28
|
+
* @example
|
|
29
|
+
* const s = strokeOf({ lineStyle: "dashed" });
|
|
30
|
+
* // { color: "#000000", width: 1, dash: [6, 4] }
|
|
31
|
+
* void s;
|
|
32
|
+
*/
|
|
33
|
+
export declare function strokeOf(style: LineStyleInput, defaultColor?: string): StrokeStyle;
|
|
34
|
+
//# sourceMappingURL=strokeStyle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strokeStyle.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/strokeStyle.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,GAAG;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;CAClE,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,YAAY,SAAY,GAAG,WAAW,CAMrF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright (c) 2026 Invinite. Licensed under the MIT License.
|
|
2
|
+
// See the LICENSE file in the repo root for full license text.
|
|
3
|
+
import { dashPattern } from "./dash.js";
|
|
4
|
+
/**
|
|
5
|
+
* Resolve a {@link LineStyleInput} into a {@link StrokeStyle}, applying
|
|
6
|
+
* the family defaults: colour falls back to `defaultColor` (black for
|
|
7
|
+
* most kinds; the `cycles` decomposers pass their own accent), width to
|
|
8
|
+
* `1`, and the dash array is derived from `lineStyle` via
|
|
9
|
+
* {@link dashPattern}. Extracted so the four line-family `kinds/` files
|
|
10
|
+
* share one resolver instead of byte-identical copies.
|
|
11
|
+
*
|
|
12
|
+
* @since 1.3
|
|
13
|
+
* @stable
|
|
14
|
+
* @example
|
|
15
|
+
* const s = strokeOf({ lineStyle: "dashed" });
|
|
16
|
+
* // { color: "#000000", width: 1, dash: [6, 4] }
|
|
17
|
+
* void s;
|
|
18
|
+
*/
|
|
19
|
+
export function strokeOf(style, defaultColor = "#000000") {
|
|
20
|
+
return {
|
|
21
|
+
color: style.color ?? defaultColor,
|
|
22
|
+
width: style.lineWidth ?? 1,
|
|
23
|
+
dash: dashPattern(style.lineStyle ?? "solid"),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=strokeStyle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strokeStyle.js","sourceRoot":"","sources":["../../../src/geometry/_lib/strokeStyle.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAG/D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAmBxC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAqB,EAAE,YAAY,GAAG,SAAS;IACpE,OAAO;QACH,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,YAAY;QAClC,KAAK,EAAE,KAAK,CAAC,SAAS,IAAI,CAAC;QAC3B,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC;KAChD,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\nimport type { StrokeStyle } from \"../types.js\";\nimport { dashPattern } from \"./dash.js\";\n\n/**\n * The line-style inputs every line-family decomposer reads off its\n * drawing state — the structural shape shared by `lines`, `curves`,\n * `channels`, and `cycles`.\n *\n * @since 1.3\n * @stable\n * @example\n * const style: LineStyleInput = { color: \"#000000\", lineStyle: \"dashed\" };\n * void style;\n */\nexport type LineStyleInput = {\n readonly color?: string | undefined;\n readonly lineWidth?: number | undefined;\n readonly lineStyle?: \"solid\" | \"dashed\" | \"dotted\" | undefined;\n};\n\n/**\n * Resolve a {@link LineStyleInput} into a {@link StrokeStyle}, applying\n * the family defaults: colour falls back to `defaultColor` (black for\n * most kinds; the `cycles` decomposers pass their own accent), width to\n * `1`, and the dash array is derived from `lineStyle` via\n * {@link dashPattern}. Extracted so the four line-family `kinds/` files\n * share one resolver instead of byte-identical copies.\n *\n * @since 1.3\n * @stable\n * @example\n * const s = strokeOf({ lineStyle: \"dashed\" });\n * // { color: \"#000000\", width: 1, dash: [6, 4] }\n * void s;\n */\nexport function strokeOf(style: LineStyleInput, defaultColor = \"#000000\"): StrokeStyle {\n return {\n color: style.color ?? defaultColor,\n width: style.lineWidth ?? 1,\n dash: dashPattern(style.lineStyle ?? \"solid\"),\n };\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { TextOpts } from "@invinite-org/chartlang-core";
|
|
2
|
+
/**
|
|
3
|
+
* Pixel size each named {@link TextOpts.size} keyword maps to.
|
|
4
|
+
* `"normal"` (12 px) is the default when `size` is omitted.
|
|
5
|
+
*
|
|
6
|
+
* @since 1.3
|
|
7
|
+
* @stable
|
|
8
|
+
* @example
|
|
9
|
+
* const px = SIZE_TO_PX.normal; // 12
|
|
10
|
+
* void px;
|
|
11
|
+
*/
|
|
12
|
+
export declare const SIZE_TO_PX: Readonly<Record<NonNullable<TextOpts["size"]>, number>>;
|
|
13
|
+
/**
|
|
14
|
+
* Map each {@link TextOpts.halign} keyword to the IR `text` primitive's
|
|
15
|
+
* `align` value.
|
|
16
|
+
*
|
|
17
|
+
* @since 1.3
|
|
18
|
+
* @stable
|
|
19
|
+
* @example
|
|
20
|
+
* const a = HALIGN_TO_TEXTALIGN.center; // "center"
|
|
21
|
+
* void a;
|
|
22
|
+
*/
|
|
23
|
+
export declare const HALIGN_TO_TEXTALIGN: Readonly<Record<NonNullable<TextOpts["halign"]>, "left" | "center" | "right">>;
|
|
24
|
+
/**
|
|
25
|
+
* Map each {@link TextOpts.valign} keyword to the IR `text` primitive's
|
|
26
|
+
* `baseline` value.
|
|
27
|
+
*
|
|
28
|
+
* @since 1.3
|
|
29
|
+
* @stable
|
|
30
|
+
* @example
|
|
31
|
+
* const b = VALIGN_TO_TEXTBASELINE.middle; // "middle"
|
|
32
|
+
* void b;
|
|
33
|
+
*/
|
|
34
|
+
export declare const VALIGN_TO_TEXTBASELINE: Readonly<Record<NonNullable<TextOpts["valign"]>, "top" | "middle" | "bottom">>;
|
|
35
|
+
/**
|
|
36
|
+
* Concrete text-state derived from {@link TextOpts}, mapped directly
|
|
37
|
+
* onto the IR `text` primitive's `font` / `align` / `baseline` /
|
|
38
|
+
* `color` fields.
|
|
39
|
+
*
|
|
40
|
+
* @since 1.3
|
|
41
|
+
* @stable
|
|
42
|
+
* @example
|
|
43
|
+
* const s: ResolvedTextOpts = {
|
|
44
|
+
* font: "12px sans-serif",
|
|
45
|
+
* align: "center",
|
|
46
|
+
* baseline: "middle",
|
|
47
|
+
* color: "#000000",
|
|
48
|
+
* };
|
|
49
|
+
* void s;
|
|
50
|
+
*/
|
|
51
|
+
export type ResolvedTextOpts = {
|
|
52
|
+
readonly font: string;
|
|
53
|
+
readonly align: "left" | "center" | "right";
|
|
54
|
+
readonly baseline: "top" | "middle" | "bottom";
|
|
55
|
+
readonly color: string;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Resolve a {@link TextOpts} bag into the four IR text-state values.
|
|
59
|
+
* Missing fields fall back to `"normal"` size (12 px), `"center"`
|
|
60
|
+
* halign, `"middle"` valign, and `"#000000"` color. Pure — no `ctx`.
|
|
61
|
+
*
|
|
62
|
+
* @since 1.3
|
|
63
|
+
* @stable
|
|
64
|
+
* @example
|
|
65
|
+
* const r = resolveTextOpts({ size: "large", color: "#10b981" });
|
|
66
|
+
* // r.font === "16px sans-serif"
|
|
67
|
+
* void r;
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveTextOpts(opts: TextOpts): ResolvedTextOpts;
|
|
70
|
+
//# sourceMappingURL=textStyle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textStyle.d.ts","sourceRoot":"","sources":["../../../src/geometry/_lib/textStyle.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAI7D;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAM9E,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CACtC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC,CAKvE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CACzC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAKvE,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,gBAAgB,CAQhE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
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
|
+
// `TextOpts` → text-state derivation ported from
|
|
5
|
+
// invinite/src/components/trading-chart/tools/text-tool.ts,
|
|
6
|
+
// invinite/src/components/trading-chart/tools/marker-tool.ts,
|
|
7
|
+
// commit 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite.
|
|
8
|
+
// Re-licensed MIT for chartlang.
|
|
9
|
+
const DEFAULT_COLOR = "#000000";
|
|
10
|
+
/**
|
|
11
|
+
* Pixel size each named {@link TextOpts.size} keyword maps to.
|
|
12
|
+
* `"normal"` (12 px) is the default when `size` is omitted.
|
|
13
|
+
*
|
|
14
|
+
* @since 1.3
|
|
15
|
+
* @stable
|
|
16
|
+
* @example
|
|
17
|
+
* const px = SIZE_TO_PX.normal; // 12
|
|
18
|
+
* void px;
|
|
19
|
+
*/
|
|
20
|
+
export const SIZE_TO_PX = {
|
|
21
|
+
tiny: 8,
|
|
22
|
+
small: 10,
|
|
23
|
+
normal: 12,
|
|
24
|
+
large: 16,
|
|
25
|
+
huge: 20,
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Map each {@link TextOpts.halign} keyword to the IR `text` primitive's
|
|
29
|
+
* `align` value.
|
|
30
|
+
*
|
|
31
|
+
* @since 1.3
|
|
32
|
+
* @stable
|
|
33
|
+
* @example
|
|
34
|
+
* const a = HALIGN_TO_TEXTALIGN.center; // "center"
|
|
35
|
+
* void a;
|
|
36
|
+
*/
|
|
37
|
+
export const HALIGN_TO_TEXTALIGN = {
|
|
38
|
+
left: "left",
|
|
39
|
+
center: "center",
|
|
40
|
+
right: "right",
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Map each {@link TextOpts.valign} keyword to the IR `text` primitive's
|
|
44
|
+
* `baseline` value.
|
|
45
|
+
*
|
|
46
|
+
* @since 1.3
|
|
47
|
+
* @stable
|
|
48
|
+
* @example
|
|
49
|
+
* const b = VALIGN_TO_TEXTBASELINE.middle; // "middle"
|
|
50
|
+
* void b;
|
|
51
|
+
*/
|
|
52
|
+
export const VALIGN_TO_TEXTBASELINE = {
|
|
53
|
+
top: "top",
|
|
54
|
+
middle: "middle",
|
|
55
|
+
bottom: "bottom",
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Resolve a {@link TextOpts} bag into the four IR text-state values.
|
|
59
|
+
* Missing fields fall back to `"normal"` size (12 px), `"center"`
|
|
60
|
+
* halign, `"middle"` valign, and `"#000000"` color. Pure — no `ctx`.
|
|
61
|
+
*
|
|
62
|
+
* @since 1.3
|
|
63
|
+
* @stable
|
|
64
|
+
* @example
|
|
65
|
+
* const r = resolveTextOpts({ size: "large", color: "#10b981" });
|
|
66
|
+
* // r.font === "16px sans-serif"
|
|
67
|
+
* void r;
|
|
68
|
+
*/
|
|
69
|
+
export function resolveTextOpts(opts) {
|
|
70
|
+
const sizePx = SIZE_TO_PX[opts.size ?? "normal"];
|
|
71
|
+
return {
|
|
72
|
+
font: `${sizePx}px sans-serif`,
|
|
73
|
+
align: HALIGN_TO_TEXTALIGN[opts.halign ?? "center"],
|
|
74
|
+
baseline: VALIGN_TO_TEXTBASELINE[opts.valign ?? "middle"],
|
|
75
|
+
color: opts.color ?? DEFAULT_COLOR,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=textStyle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textStyle.js","sourceRoot":"","sources":["../../../src/geometry/_lib/textStyle.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAC/D,EAAE;AACF,iDAAiD;AACjD,8DAA8D;AAC9D,gEAAgE;AAChE,iEAAiE;AACjE,iCAAiC;AAIjC,MAAM,aAAa,GAAG,SAAS,CAAC;AAEhC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,UAAU,GAA4D;IAC/E,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;CACX,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAE5B;IACA,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;CACjB,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAE/B;IACA,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;CACnB,CAAC;AAyBF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,IAAc;IAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC;IACjD,OAAO;QACH,IAAI,EAAE,GAAG,MAAM,eAAe;QAC9B,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC;QACnD,QAAQ,EAAE,sBAAsB,CAAC,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC;QACzD,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,aAAa;KACrC,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// `TextOpts` → text-state derivation ported from\n// invinite/src/components/trading-chart/tools/text-tool.ts,\n// invinite/src/components/trading-chart/tools/marker-tool.ts,\n// commit 078f41fe2569d659d5aba726da8bcb5d3e2ced02, © Invinite.\n// Re-licensed MIT for chartlang.\n\nimport type { TextOpts } from \"@invinite-org/chartlang-core\";\n\nconst DEFAULT_COLOR = \"#000000\";\n\n/**\n * Pixel size each named {@link TextOpts.size} keyword maps to.\n * `\"normal\"` (12 px) is the default when `size` is omitted.\n *\n * @since 1.3\n * @stable\n * @example\n * const px = SIZE_TO_PX.normal; // 12\n * void px;\n */\nexport const SIZE_TO_PX: Readonly<Record<NonNullable<TextOpts[\"size\"]>, number>> = {\n tiny: 8,\n small: 10,\n normal: 12,\n large: 16,\n huge: 20,\n};\n\n/**\n * Map each {@link TextOpts.halign} keyword to the IR `text` primitive's\n * `align` value.\n *\n * @since 1.3\n * @stable\n * @example\n * const a = HALIGN_TO_TEXTALIGN.center; // \"center\"\n * void a;\n */\nexport const HALIGN_TO_TEXTALIGN: Readonly<\n Record<NonNullable<TextOpts[\"halign\"]>, \"left\" | \"center\" | \"right\">\n> = {\n left: \"left\",\n center: \"center\",\n right: \"right\",\n};\n\n/**\n * Map each {@link TextOpts.valign} keyword to the IR `text` primitive's\n * `baseline` value.\n *\n * @since 1.3\n * @stable\n * @example\n * const b = VALIGN_TO_TEXTBASELINE.middle; // \"middle\"\n * void b;\n */\nexport const VALIGN_TO_TEXTBASELINE: Readonly<\n Record<NonNullable<TextOpts[\"valign\"]>, \"top\" | \"middle\" | \"bottom\">\n> = {\n top: \"top\",\n middle: \"middle\",\n bottom: \"bottom\",\n};\n\n/**\n * Concrete text-state derived from {@link TextOpts}, mapped directly\n * onto the IR `text` primitive's `font` / `align` / `baseline` /\n * `color` fields.\n *\n * @since 1.3\n * @stable\n * @example\n * const s: ResolvedTextOpts = {\n * font: \"12px sans-serif\",\n * align: \"center\",\n * baseline: \"middle\",\n * color: \"#000000\",\n * };\n * void s;\n */\nexport type ResolvedTextOpts = {\n readonly font: string;\n readonly align: \"left\" | \"center\" | \"right\";\n readonly baseline: \"top\" | \"middle\" | \"bottom\";\n readonly color: string;\n};\n\n/**\n * Resolve a {@link TextOpts} bag into the four IR text-state values.\n * Missing fields fall back to `\"normal\"` size (12 px), `\"center\"`\n * halign, `\"middle\"` valign, and `\"#000000\"` color. Pure — no `ctx`.\n *\n * @since 1.3\n * @stable\n * @example\n * const r = resolveTextOpts({ size: \"large\", color: \"#10b981\" });\n * // r.font === \"16px sans-serif\"\n * void r;\n */\nexport function resolveTextOpts(opts: TextOpts): ResolvedTextOpts {\n const sizePx = SIZE_TO_PX[opts.size ?? \"normal\"];\n return {\n font: `${sizePx}px sans-serif`,\n align: HALIGN_TO_TEXTALIGN[opts.halign ?? \"center\"],\n baseline: VALIGN_TO_TEXTBASELINE[opts.valign ?? \"middle\"],\n color: opts.color ?? DEFAULT_COLOR,\n };\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DrawingEmission } from "../types.js";
|
|
2
|
+
import type { DrawPrimitive, Viewport } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Reduce a {@link DrawingEmission} to a flat, renderer-agnostic
|
|
5
|
+
* {@link DrawPrimitive} list against `view`. Pure — no `ctx`, no library
|
|
6
|
+
* types — so every adapter shares one geometry derivation and paints
|
|
7
|
+
* the result with its own sink.
|
|
8
|
+
*
|
|
9
|
+
* The switch is **exhaustive over all 63 `DrawingKind`s**: the 20 basic
|
|
10
|
+
* kinds (Task 1), the 20 curve / freehand / channel / fibonacci kinds
|
|
11
|
+
* (Task 2), and the 23 gann / pitchfork / pattern / elliott / cycle /
|
|
12
|
+
* container / table kinds (Task 3). The `default` arm is a `const
|
|
13
|
+
* _exhaustive: never` guard — it compiles only because every literal has
|
|
14
|
+
* a `case`, so adding a future `DrawingKind` to core fails `pnpm
|
|
15
|
+
* typecheck` here until a decomposer is added. `op: "remove"` is handled
|
|
16
|
+
* by each adapter's drawing-state map (this function operates on whatever
|
|
17
|
+
* `state` it is handed).
|
|
18
|
+
*
|
|
19
|
+
* @since 1.3
|
|
20
|
+
* @stable
|
|
21
|
+
* @example
|
|
22
|
+
* declare const e: DrawingEmission;
|
|
23
|
+
* declare const v: Viewport;
|
|
24
|
+
* const prims = decomposeDrawing(e, v);
|
|
25
|
+
* void prims;
|
|
26
|
+
*/
|
|
27
|
+
export declare function decomposeDrawing(e: DrawingEmission, view: Viewport): ReadonlyArray<DrawPrimitive>;
|
|
28
|
+
//# sourceMappingURL=decompose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decompose.d.ts","sourceRoot":"","sources":["../../src/geometry/decompose.ts"],"names":[],"mappings":"AAqEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAuEnD,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,GAAG,aAAa,CAAC,aAAa,CAAC,CAsIjG"}
|