openalgo-charts 2.5.1 → 2.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -19
- package/dist/draw/index.d.ts +940 -806
- package/dist/index.d.ts +94 -15
- package/dist/openalgo-charts.draw.mjs +1 -1
- package/dist/openalgo-charts.draw.mjs.map +1 -1
- package/dist/openalgo-charts.mjs +1 -1
- package/dist/openalgo-charts.mjs.map +1 -1
- package/dist/openalgo-charts.standalone.js +1 -1
- package/dist/openalgo-charts.standalone.js.map +1 -1
- package/dist/openalgo-charts.widget.mjs +1 -1
- package/dist/openalgo-charts.widget.mjs.map +1 -1
- package/dist/openalgo-charts.workspace.mjs +1 -1
- package/dist/openalgo-charts.workspace.mjs.map +1 -1
- package/dist/widget/index.d.ts +61 -2
- package/dist/workspace/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/draw/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AlertDrawingValue, AlertDrawingLevel, PrimitiveRenderContext, IPrimitive,
|
|
1
|
+
import { AlertDrawingValue, AlertDrawingLevel, PrimitiveRenderContext, Bar, IPrimitive, DataLayer, AlertDrawingInfo, PrimitiveHost, ZOrder, PrimitiveHit } from 'openalgo-charts';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The per-tool settings schema: what a host may show in a drawing's settings
|
|
@@ -35,6 +35,8 @@ interface SettingsField {
|
|
|
35
35
|
label: string;
|
|
36
36
|
}>;
|
|
37
37
|
group?: FieldGroup;
|
|
38
|
+
/** Value displayed when the drawing has not overridden this setting. */
|
|
39
|
+
defaultValue?: string | number | boolean;
|
|
38
40
|
}
|
|
39
41
|
interface SettingsSchema {
|
|
40
42
|
fields: SettingsField[];
|
|
@@ -111,9 +113,8 @@ declare function composeSettings(parts: ReadonlyArray<readonly SettingsField[] |
|
|
|
111
113
|
/** The value at a dot path, or `undefined` when unset or the path is not one the model has. */
|
|
112
114
|
declare function readDrawingSetting(d: Drawing, path: string): unknown;
|
|
113
115
|
/**
|
|
114
|
-
* Every field of a schema read off a drawing, keyed by path.
|
|
115
|
-
*
|
|
116
|
-
* each control in its "default" state rather than guessing.
|
|
116
|
+
* Every field of a schema read off a drawing, keyed by path. Unset fields use
|
|
117
|
+
* their declared default value, or remain `undefined` when no default exists.
|
|
117
118
|
*/
|
|
118
119
|
declare function readDrawingSettings(d: Drawing, schema: SettingsSchema): Record<string, unknown>;
|
|
119
120
|
/**
|
|
@@ -424,775 +425,222 @@ interface DrawingTool {
|
|
|
424
425
|
distance(x: number, y: number, c: HitContext): number | null;
|
|
425
426
|
}
|
|
426
427
|
|
|
427
|
-
/**
|
|
428
|
-
* Built-in drawing tools + the tool registry. Same philosophy as the chart-type
|
|
429
|
-
* and indicator registries: a tool is a descriptor, the layer just runs it, and
|
|
430
|
-
* `registerDrawingTool` makes a custom one first-class.
|
|
431
|
-
*
|
|
432
|
-
* `draw` receives anchors already in device px; `distance` receives them in
|
|
433
|
-
* media px, the same space as the incoming cursor.
|
|
434
|
-
*
|
|
435
|
-
* Text lives in `drawing.text` (a `DrawingText`), never in the style bag: a
|
|
436
|
-
* shape's outline colour and its label colour are two decisions, and a tool
|
|
437
|
-
* that prints only a readout (a fib ladder, a measure chip) still reads its
|
|
438
|
-
* face from there. Ladders read `FibLevel[]` and stroke each level in its own
|
|
439
|
-
* colour, taken from the shared palette in levels.ts.
|
|
440
|
-
*
|
|
441
|
-
* Every tool declares `settings`: the fields a host may show for it. The
|
|
442
|
-
* schema is a contract, not a wish list. A field is declared only when this
|
|
443
|
-
* file reads it, because a control with nothing behind it is a defect.
|
|
444
|
-
*/
|
|
428
|
+
/** Time-anchored analysis drawings use the owning pane's bars, never a tier cache. */
|
|
445
429
|
|
|
446
|
-
declare
|
|
447
|
-
declare
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
430
|
+
declare const ANCHORED_VWAP: DrawingTool;
|
|
431
|
+
declare const FIXED_RANGE_VOLUME_PROFILE: DrawingTool;
|
|
432
|
+
|
|
433
|
+
/** Pure OHLCV analysis. Inputs are sorted by ascending UTC timestamp. */
|
|
434
|
+
|
|
435
|
+
/** Partial results have unavailable anchor history, missing volume or unusable prices. */
|
|
436
|
+
type AnalysisStatus = 'ready' | 'partial' | 'missing-volume' | 'zero-volume' | 'empty' | 'invalid-data';
|
|
437
|
+
type AnchoredVwapSource = 'hlc3' | 'close' | 'hl2' | 'ohlc4';
|
|
438
|
+
interface AnchoredVwapOptions {
|
|
439
|
+
source?: AnchoredVwapSource;
|
|
440
|
+
}
|
|
441
|
+
interface AnchoredVwapPoint {
|
|
442
|
+
time: number;
|
|
443
|
+
value: number;
|
|
444
|
+
/** Volume-weighted population standard deviation of the selected source. */
|
|
445
|
+
deviation: number;
|
|
446
|
+
/** Do not connect a line across an omitted observation. */
|
|
447
|
+
breakBefore: boolean;
|
|
448
|
+
}
|
|
449
|
+
interface AnchoredVwapResult {
|
|
450
|
+
status: AnalysisStatus;
|
|
451
|
+
/** The requested anchor precedes the earliest supplied bar. */
|
|
452
|
+
historyPartial: boolean;
|
|
453
|
+
points: AnchoredVwapPoint[];
|
|
454
|
+
missingVolumeBars: number;
|
|
455
|
+
invalidPriceBars: number;
|
|
456
|
+
}
|
|
457
|
+
interface FixedRangeVolumeProfileOptions {
|
|
458
|
+
/** Requested price rows, rounded and clamped to 4..200. Fewer rows are used when prices cannot represent distinct edges. Default 48. */
|
|
459
|
+
rows?: number;
|
|
460
|
+
/** Percentage of volume in the contiguous area around the POC, 1..100. Default 70. */
|
|
461
|
+
valueArea?: number;
|
|
462
|
+
}
|
|
463
|
+
interface AnalysisProfileRow {
|
|
464
|
+
low: number;
|
|
465
|
+
high: number;
|
|
466
|
+
volume: number;
|
|
467
|
+
valueArea: boolean;
|
|
468
|
+
}
|
|
469
|
+
interface FixedRangeVolumeProfileResult {
|
|
470
|
+
status: AnalysisStatus;
|
|
471
|
+
/** The requested range begins before the earliest supplied bar. */
|
|
472
|
+
historyPartial: boolean;
|
|
473
|
+
rows: AnalysisProfileRow[];
|
|
474
|
+
totalVolume: number;
|
|
475
|
+
/** Midpoint of the largest row. Ties choose the lower price. */
|
|
476
|
+
poc: number | null;
|
|
477
|
+
valueAreaLow: number | null;
|
|
478
|
+
valueAreaHigh: number | null;
|
|
479
|
+
missingVolumeBars: number;
|
|
480
|
+
invalidPriceBars: number;
|
|
457
481
|
}
|
|
458
482
|
/**
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
* shortcuts apply. The library installs no listener, because only the host
|
|
463
|
-
* knows whether the chart has focus, a dialog is open, or the user is typing.
|
|
464
|
-
*
|
|
465
|
-
* Modifiers must match exactly: `Alt+T` will not fire for `Ctrl+Alt+T`, so a
|
|
466
|
-
* tool shortcut cannot shadow a browser or host chord. `metaKey` (Cmd) is
|
|
467
|
-
* treated as Ctrl, which is what a Mac user expects.
|
|
468
|
-
*/
|
|
469
|
-
declare function matchDrawingShortcut(e: ShortcutEvent): string | null;
|
|
470
|
-
/** Every registered tool that has a shortcut, as `id -> shortcut`. */
|
|
471
|
-
declare function drawingShortcuts(): Record<string, string>;
|
|
472
|
-
/**
|
|
473
|
-
* The settings a host may show for a tool: the tool's own declaration, else
|
|
474
|
-
* the line fields, which every stroked custom tool reads. This is a registry
|
|
475
|
-
* lookup, which is why it lives here and not in schema.ts: that module stays
|
|
476
|
-
* free of any import that could loop back into this one.
|
|
477
|
-
*/
|
|
478
|
-
declare function drawingSettingsSchema(toolId: string): SettingsSchema;
|
|
479
|
-
declare const TREND_LINE: DrawingTool;
|
|
480
|
-
declare const RAY: DrawingTool;
|
|
481
|
-
declare const EXTENDED_LINE: DrawingTool;
|
|
482
|
-
declare const ARROW: DrawingTool;
|
|
483
|
-
declare const HORIZONTAL_LINE: DrawingTool;
|
|
484
|
-
declare const HORIZONTAL_RAY: DrawingTool;
|
|
485
|
-
declare const VERTICAL_LINE: DrawingTool;
|
|
486
|
-
declare const CROSS_LINE: DrawingTool;
|
|
487
|
-
declare const RECTANGLE: DrawingTool;
|
|
488
|
-
declare const ELLIPSE: DrawingTool;
|
|
489
|
-
declare const PARALLEL_CHANNEL: DrawingTool;
|
|
490
|
-
declare const FIB_RETRACEMENT: DrawingTool;
|
|
491
|
-
declare const FIB_EXTENSION: DrawingTool;
|
|
492
|
-
declare const MEASURE: DrawingTool;
|
|
493
|
-
declare const LONG_POSITION: DrawingTool;
|
|
494
|
-
declare const SHORT_POSITION: DrawingTool;
|
|
495
|
-
declare const TEXT: DrawingTool;
|
|
496
|
-
/**
|
|
497
|
-
* Path: click each vertex, double-click to finish, arrowhead on the last leg.
|
|
498
|
-
* The arrow is what separates it from `polyline`: a path points somewhere.
|
|
499
|
-
*/
|
|
500
|
-
declare const PATH: DrawingTool;
|
|
501
|
-
/**
|
|
502
|
-
* Brush: freehand ink. Press, drag, release. The anchors are the thinned
|
|
503
|
-
* samples of the gesture and the spline between them is what is stroked, so
|
|
504
|
-
* the ink stays a curve after the thinning that keeps a stroke small.
|
|
483
|
+
* Accumulate from the first bar at or after the anchor, including the live tail.
|
|
484
|
+
* Missing volume is omitted and reported; zero volume adds no statistical weight.
|
|
485
|
+
* Recompute on each call so mutations of the forming candle are always visible.
|
|
505
486
|
*/
|
|
506
|
-
declare
|
|
487
|
+
declare function anchoredVwapAnalysis(bars: readonly Bar[], anchorTime: number, options?: AnchoredVwapOptions): AnchoredVwapResult;
|
|
507
488
|
/**
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
489
|
+
* Estimate a volume histogram over the inclusive timestamp range. Each candle's
|
|
490
|
+
* volume is uniform over low..high; this is not trade-by-trade volume. Difference
|
|
491
|
+
* arrays distribute interior rows without visiting each row per candle. Row
|
|
492
|
+
* lookup is bounded by 200 edges: O(bars log(rows) + rows).
|
|
511
493
|
*/
|
|
512
|
-
declare
|
|
494
|
+
declare function fixedRangeVolumeProfileAnalysis(bars: readonly Bar[], fromTime: number, toTime: number, options?: FixedRangeVolumeProfileOptions): FixedRangeVolumeProfileResult;
|
|
495
|
+
|
|
513
496
|
/**
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
497
|
+
* Clipboard transfer for drawings: the layer between the drawing model and the
|
|
498
|
+
* OS clipboard.
|
|
499
|
+
*
|
|
500
|
+
* Two things make this more than `JSON.stringify`:
|
|
501
|
+
*
|
|
502
|
+
* 1. **The OS clipboard is shared with everything else on the machine.** A
|
|
503
|
+
* paste can arrive from a spreadsheet, another application, or a hand-edited
|
|
504
|
+
* copy of our own payload. So the payload is written under a namespaced key
|
|
505
|
+
* and everything read back is validated field by field before it can reach
|
|
506
|
+
* the model. Foreign text is *not ours* and is ignored, never an exception
|
|
507
|
+
* the host has to catch on every Ctrl+V.
|
|
508
|
+
* 2. **Clipboard access is async and permission-gated.** `navigator.clipboard`
|
|
509
|
+
* rejects when the document is not focused, the page is not secure, or the
|
|
510
|
+
* user denied the permission. Copy must still work inside the tab, so every
|
|
511
|
+
* write also lands in a module-level in-memory clipboard which is shared by
|
|
512
|
+
* every controller in the page. That is what makes chart-to-chart paste work
|
|
513
|
+
* with the permission denied, and it is why the memory store is a singleton
|
|
514
|
+
* rather than per-controller state.
|
|
515
|
+
*
|
|
516
|
+
* The payload body is a drawings document (`DrawingsDocument`), so a copy made
|
|
517
|
+
* by a 1.9.x build (a version 1 body carrying the old style-bag text fields)
|
|
518
|
+
* is upgraded by the same migration a saved layout goes through.
|
|
517
519
|
*/
|
|
518
|
-
|
|
520
|
+
|
|
519
521
|
/**
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
+
* Top-level key of the JSON payload. Namespaced so a paste of arbitrary text,
|
|
523
|
+
* or of JSON belonging to some other application, is recognisable as not ours
|
|
524
|
+
* by looking at one property.
|
|
522
525
|
*/
|
|
523
|
-
declare const
|
|
526
|
+
declare const DRAWING_CLIPBOARD_KEY = "openalgo-charts/drawings";
|
|
524
527
|
/**
|
|
525
|
-
*
|
|
526
|
-
*
|
|
528
|
+
* Payload format version. Tracks the model version, since the body *is* a
|
|
529
|
+
* drawings document: version 1 carried 1.9.x drawings, version 2 carries the
|
|
530
|
+
* split text and levelled fibs.
|
|
527
531
|
*/
|
|
528
|
-
declare const
|
|
532
|
+
declare const DRAWING_CLIPBOARD_VERSION: number;
|
|
533
|
+
/** The async slice of `navigator.clipboard` this module uses. */
|
|
534
|
+
interface ClipboardPort {
|
|
535
|
+
writeText(text: string): Promise<void>;
|
|
536
|
+
readText(): Promise<string>;
|
|
537
|
+
}
|
|
538
|
+
/** Test seam: drop whatever the in-memory clipboard is holding. */
|
|
539
|
+
declare function clearMemoryClipboard(): void;
|
|
540
|
+
/** `navigator.clipboard` when the browser exposes it, else null. */
|
|
541
|
+
declare function systemClipboard(): ClipboardPort | null;
|
|
542
|
+
/** Deep copy of the persisted fields, so a clone shares nothing with its source. */
|
|
543
|
+
declare function cloneDrawing(d: Drawing): Drawing;
|
|
544
|
+
/** Serialise drawings into the namespaced payload written to the clipboard. */
|
|
545
|
+
declare function encodeClipboardPayload(drawings: readonly Drawing[]): string;
|
|
529
546
|
/**
|
|
530
|
-
*
|
|
531
|
-
*
|
|
547
|
+
* Validate one entry into a drawing with no id. Returns null for anything that
|
|
548
|
+
* cannot be rendered: an unknown tool would throw inside the controller, and a
|
|
549
|
+
* NaN anchor produces a drawing that can never be drawn or hit-tested again.
|
|
550
|
+
* Accepts the 1.9.x shape too, lifting its text fields into `text`.
|
|
532
551
|
*/
|
|
533
|
-
declare
|
|
552
|
+
declare function sanitizeDrawing(value: unknown): Omit<Drawing, 'id'> | null;
|
|
534
553
|
/**
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
554
|
+
* Parse clipboard text into drawings, or null when the text is not ours or is
|
|
555
|
+
* not usable. All-or-nothing on purpose: a payload with one corrupt entry is a
|
|
556
|
+
* corrupt payload, and pasting the other nine silently would be worse than
|
|
557
|
+
* pasting none.
|
|
538
558
|
*/
|
|
539
|
-
declare
|
|
559
|
+
declare function decodeClipboardPayload(text: unknown): Omit<Drawing, 'id'>[] | null;
|
|
560
|
+
interface DrawingClipboardOptions {
|
|
561
|
+
/** Where to read and write. Defaults to `navigator.clipboard` when present. */
|
|
562
|
+
port?: ClipboardPort | null;
|
|
563
|
+
/**
|
|
564
|
+
* Keep a copy in the shared in-memory clipboard so copy and paste keep
|
|
565
|
+
* working when the OS clipboard is unavailable or the permission is refused.
|
|
566
|
+
* Default true. Set false to make a failed system write a failed copy, which
|
|
567
|
+
* a host that must not silently lose cross-tab transfer may prefer.
|
|
568
|
+
*/
|
|
569
|
+
fallbackToMemory?: boolean;
|
|
570
|
+
}
|
|
540
571
|
/**
|
|
541
|
-
*
|
|
542
|
-
*
|
|
572
|
+
* The clipboard as the controller sees it: drawings in, drawings out, no
|
|
573
|
+
* exceptions escaping. Every failure mode (no clipboard API, refused
|
|
574
|
+
* permission, foreign text, corrupt payload) reduces to `false` or `null`.
|
|
543
575
|
*/
|
|
544
|
-
declare
|
|
545
|
-
|
|
546
|
-
|
|
576
|
+
declare class DrawingClipboard {
|
|
577
|
+
private _port;
|
|
578
|
+
private _fallback;
|
|
579
|
+
/** Why the last operation did not reach the OS clipboard, if it did not. */
|
|
580
|
+
private _lastError;
|
|
581
|
+
constructor(options?: DrawingClipboardOptions);
|
|
582
|
+
/** Swap the port at runtime (a host granting permission later, or a test). */
|
|
583
|
+
setPort(port: ClipboardPort | null): void;
|
|
584
|
+
/**
|
|
585
|
+
* Turn the in-memory backstop off or on. With it off, a refused system write
|
|
586
|
+
* is a failed copy, which is what a host wants when a cut that cannot reach
|
|
587
|
+
* the OS clipboard must not delete the drawing.
|
|
588
|
+
*/
|
|
589
|
+
setFallbackToMemory(enabled: boolean): void;
|
|
590
|
+
/**
|
|
591
|
+
* Why the OS clipboard was not used by the last call, or null when it was.
|
|
592
|
+
* Set on a successful copy too, when the payload reached memory but not the
|
|
593
|
+
* system clipboard: that copy works in this tab and will not appear in
|
|
594
|
+
* another, which is exactly what a host wants to be able to tell the user.
|
|
595
|
+
*/
|
|
596
|
+
lastError(): string | null;
|
|
597
|
+
/**
|
|
598
|
+
* Write drawings out. Resolves true when the payload is retrievable by a
|
|
599
|
+
* later `read()` (through the system clipboard, or through memory when the
|
|
600
|
+
* fallback is on), false when it is not, so a caller doing a cut knows
|
|
601
|
+
* whether it is safe to delete the original.
|
|
602
|
+
*/
|
|
603
|
+
write(drawings: readonly Drawing[]): Promise<boolean>;
|
|
604
|
+
/**
|
|
605
|
+
* Read drawings back, or null when there is nothing of ours to paste. The
|
|
606
|
+
* system clipboard wins when it holds our payload, so a copy made in another
|
|
607
|
+
* tab beats a stale in-tab one; memory is consulted when the read fails or
|
|
608
|
+
* returns something that is not ours. That last case can paste an older copy
|
|
609
|
+
* after the user has copied unrelated text elsewhere, which is the deliberate
|
|
610
|
+
* trade: losing the copy whenever a browser refuses the read half of the
|
|
611
|
+
* permission would be the worse surprise.
|
|
612
|
+
*/
|
|
613
|
+
read(): Promise<Omit<Drawing, 'id'>[] | null>;
|
|
614
|
+
}
|
|
615
|
+
|
|
547
616
|
/**
|
|
548
|
-
*
|
|
617
|
+
* Drawing controller: the interaction and persistence layer over
|
|
618
|
+
* `DrawingLayer`. It is **headless**: no DOM, no toolbar. A host sets the
|
|
619
|
+
* active tool (from its own button, a shortcut, a command palette) and the
|
|
620
|
+
* controller runs placement, selection, dragging, undo, and serialisation.
|
|
549
621
|
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
* wide enough to hold a sentence covers several.
|
|
554
|
-
*/
|
|
555
|
-
declare const NOTE: DrawingTool;
|
|
556
|
-
/**
|
|
557
|
-
* Balloon: a speech bubble sitting above its anchor, tail pointing down.
|
|
622
|
+
* It listens on the chart's event bus (`click`, `crosshair:move`, `drag`,
|
|
623
|
+
* `drag:end`) rather than the single-slot `subscribeClick`/`subscribeDrag`
|
|
624
|
+
* callbacks, so a host keeps using those for its own order lines.
|
|
558
625
|
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
626
|
+
* Selection is a list. Every method that edits takes the whole list into one
|
|
627
|
+
* undo entry, so a multi-drag, a batch delete or a paste of ten shapes is one
|
|
628
|
+
* Ctrl+Z, which is what the hand that did it expects.
|
|
562
629
|
*/
|
|
563
|
-
|
|
630
|
+
|
|
564
631
|
/**
|
|
565
|
-
*
|
|
632
|
+
* The slice of the chart this controller needs.
|
|
566
633
|
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
* The one annotation anchored to *time* rather than to a level: the post is
|
|
576
|
-
* vertical so the plate can clear the price action entirely while the foot
|
|
577
|
-
* still names an exact bar. Useful for events, which happen at a moment and
|
|
578
|
-
* not at a price.
|
|
579
|
-
*/
|
|
580
|
-
declare const SIGNPOST: DrawingTool;
|
|
581
|
-
/**
|
|
582
|
-
* Price note: the anchored price, with the user's text under it.
|
|
583
|
-
*
|
|
584
|
-
* The price is read off the anchor rather than typed, so dragging the note
|
|
585
|
-
* re-reads it. A typed price is a number that was true once, which on a chart
|
|
586
|
-
* is worse than no number at all.
|
|
587
|
-
*/
|
|
588
|
-
declare const PRICE_NOTE: DrawingTool;
|
|
589
|
-
/**
|
|
590
|
-
* Table: rows of text in a grid, anchored top-left.
|
|
591
|
-
*
|
|
592
|
-
* Cells come from the text: a newline starts a row and a pipe separates
|
|
593
|
-
* columns, so a whole table is one editable string and survives `getState`
|
|
594
|
-
* with no new shape in the drawing model. The first row is drawn as a header
|
|
595
|
-
* because a table on a chart is nearly always labelled.
|
|
596
|
-
*/
|
|
597
|
-
declare const TABLE: DrawingTool;
|
|
598
|
-
/**
|
|
599
|
-
* Measurers. `measure` reports price *and* time together; these two constrain it
|
|
600
|
-
* to one axis, which is what you want when the other one is noise: sizing a
|
|
601
|
-
* retracement without caring how long it took, or counting bars to an event
|
|
602
|
-
* without caring where price went.
|
|
603
|
-
*/
|
|
604
|
-
declare const PRICE_RANGE: DrawingTool;
|
|
605
|
-
declare const DATE_RANGE: DrawingTool;
|
|
606
|
-
/**
|
|
607
|
-
* Position forecast: project a move from an anchor. Two anchors give the
|
|
608
|
-
* projected leg; the shape extends the same slope past the target as a dashed
|
|
609
|
-
* cone, so the drawing says "if this continues" rather than just marking a line.
|
|
610
|
-
*/
|
|
611
|
-
declare const FORECAST: DrawingTool;
|
|
612
|
-
/**
|
|
613
|
-
* Circle from centre + a radius handle. The radius is measured in *pixels*, so
|
|
614
|
-
* it stays a circle on screen instead of the ellipse the two axes' differing
|
|
615
|
-
* scales would otherwise produce.
|
|
616
|
-
*/
|
|
617
|
-
declare const CIRCLE: DrawingTool;
|
|
618
|
-
declare const TRIANGLE: DrawingTool;
|
|
619
|
-
/** Free-form polyline: click each vertex, double-click to finish. */
|
|
620
|
-
declare const POLYLINE: DrawingTool;
|
|
621
|
-
/** Arc through three anchors: the middle one is on the curve, not a handle. */
|
|
622
|
-
declare const ARC: DrawingTool;
|
|
623
|
-
/** Quadratic curve: the middle anchor is a control handle, off the curve. */
|
|
624
|
-
declare const CURVE: DrawingTool;
|
|
625
|
-
declare const ARROW_UP: DrawingTool;
|
|
626
|
-
declare const ARROW_DOWN: DrawingTool;
|
|
627
|
-
declare const ARROW_LEFT: DrawingTool;
|
|
628
|
-
declare const ARROW_RIGHT: DrawingTool;
|
|
629
|
-
/** Highlighter: the brush with a fat, translucent stroke. */
|
|
630
|
-
declare const HIGHLIGHTER: DrawingTool;
|
|
631
|
-
/** Fib channel: fib levels spread across a trend leg, parallel to it. */
|
|
632
|
-
declare const FIB_CHANNEL: DrawingTool;
|
|
633
|
-
/**
|
|
634
|
-
* Fib time zone: vertical lines at Fibonacci multiples of the base leg's width.
|
|
635
|
-
* Its levels count bars rather than divide a leg, so they carry no convention
|
|
636
|
-
* colour and fall back to the drawing's own.
|
|
637
|
-
*/
|
|
638
|
-
declare const FIB_TIME_ZONE: DrawingTool;
|
|
639
|
-
/** Rays from the anchor at fib fractions of the leg: the speed resistance fan. */
|
|
640
|
-
declare const FIB_FAN: DrawingTool;
|
|
641
|
-
/**
|
|
642
|
-
* Gann fan: rays from one anchor at the classic price/time angles. A level's
|
|
643
|
-
* ratio is price per unit of time, so the 1x1 is 1, the 1x2 is 0.5 and the
|
|
644
|
-
* 2x1 is 2; each angle keeps its own colour from the cycle palette.
|
|
645
|
-
*/
|
|
646
|
-
declare const GANN_FAN: DrawingTool;
|
|
647
|
-
/**
|
|
648
|
-
* Gann box: the drawn rectangle divided at its levels on both axes, plus the
|
|
649
|
-
* 1x1 diagonal. Ratio 0 is the first anchor's price and time, ratio 1 the
|
|
650
|
-
* second's, so the box reads like a retracement laid over a date range.
|
|
651
|
-
*/
|
|
652
|
-
declare const GANN_BOX: DrawingTool;
|
|
653
|
-
declare const BUILTIN_DRAWING_TOOLS: readonly DrawingTool[];
|
|
654
|
-
/** Register every built-in tool. Idempotent; called on tier import. */
|
|
655
|
-
declare function registerBuiltinDrawingTools(): void;
|
|
656
|
-
|
|
657
|
-
/**
|
|
658
|
-
* The shared level palette for the Fibonacci and Gann family.
|
|
659
|
-
*
|
|
660
|
-
* Every ladder tool (retracement, extension, channel, fan, time zone, the Gann
|
|
661
|
-
* fan and box) strokes a list of ratios, and each ratio has a colour the eye
|
|
662
|
-
* expects: 0.618 reads as one thing across every tool, not a different hue per
|
|
663
|
-
* tool. Before this module each tool would have restated those colours, and
|
|
664
|
-
* restated colours drift. This is the one statement; tools take their defaults
|
|
665
|
-
* from it and hosts seed a newly added level from it.
|
|
666
|
-
*
|
|
667
|
-
* Pure: no DOM, no registry. Safe to import from a worker or a settings panel.
|
|
668
|
-
*/
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* The colour of a ratio that is an anchor rather than a level (0, 1, 2, 3 are
|
|
672
|
-
* where the measured leg starts and ends, or whole multiples of it) and of any
|
|
673
|
-
* ratio the convention does not name. Neutral on purpose: it is the reference
|
|
674
|
-
* the coloured levels are read against.
|
|
675
|
-
*/
|
|
676
|
-
declare const LEVEL_NEUTRAL = "#787b86";
|
|
677
|
-
/**
|
|
678
|
-
* The conventional colour for a Fibonacci ratio. Anchors (0, 1, 2, 3) and any
|
|
679
|
-
* ratio without a convention come back {@link LEVEL_NEUTRAL}, so a host can call
|
|
680
|
-
* this for every new level and always get a usable colour.
|
|
681
|
-
*/
|
|
682
|
-
declare function levelColor(ratio: number): string;
|
|
683
|
-
/**
|
|
684
|
-
* A short sequence of colours that stay distinguishable side by side, for
|
|
685
|
-
* tools whose levels are positions rather than ratios: the angles of a Gann
|
|
686
|
-
* fan, the repeats of a cycle. Index `i` wraps, so any count is safe.
|
|
687
|
-
*/
|
|
688
|
-
declare const CYCLE_PALETTE: readonly string[];
|
|
689
|
-
/** The `i`th cycle colour. Wraps in both directions; a negative index is fine. */
|
|
690
|
-
declare function cycleColor(i: number): string;
|
|
691
|
-
/** `0.618` as `61.8%`: the text a level prints when it carries no label. */
|
|
692
|
-
declare function formatRatio(ratio: number): string;
|
|
693
|
-
/**
|
|
694
|
-
* The label for a Gann angle stored as a price-per-time ratio: `1` is the 1x1,
|
|
695
|
-
* `0.5` the 1x2, `2` the 2x1. Ratios that are not clean reciprocals fall back
|
|
696
|
-
* to the ratio itself, which is still true, just less idiomatic.
|
|
697
|
-
*/
|
|
698
|
-
declare function gannLabel(ratio: number): string;
|
|
699
|
-
/** A mutable copy of a default ladder, for a fresh drawing's own `style.levels`. */
|
|
700
|
-
declare function cloneLevels(levels: readonly FibLevel[]): FibLevel[];
|
|
701
|
-
/** Retracement and extension: the classic ladder, coloured by convention. */
|
|
702
|
-
declare const DEFAULT_FIB: readonly FibLevel[];
|
|
703
|
-
/** Speed fan: rays at the fractions of the leg. No 0 ray, it would be flat. */
|
|
704
|
-
declare const DEFAULT_FIB_FAN: readonly FibLevel[];
|
|
705
|
-
/** Gann box: quarters plus the golden pair, applied to both axes of the box. */
|
|
706
|
-
declare const DEFAULT_GANN_BOX: readonly FibLevel[];
|
|
707
|
-
/**
|
|
708
|
-
* Gann fan: the classic angles as price-per-time ratios, 1x8 up to 8x1. These
|
|
709
|
-
* are positions in a sequence rather than Fibonacci ratios, so they take the
|
|
710
|
-
* cycle palette.
|
|
711
|
-
*/
|
|
712
|
-
declare const DEFAULT_GANN_FAN: readonly FibLevel[];
|
|
713
|
-
/**
|
|
714
|
-
* Time zones count bars along the Fibonacci sequence, so `ratio` here is a
|
|
715
|
-
* multiple of the anchor leg, not a fraction of it. No colour is set: there is
|
|
716
|
-
* no convention for "the 13 line", so every zone takes the drawing's own colour
|
|
717
|
-
* until the user gives one its own.
|
|
718
|
-
*/
|
|
719
|
-
declare const DEFAULT_FIB_TIME_ZONE: readonly FibLevel[];
|
|
720
|
-
|
|
721
|
-
/**
|
|
722
|
-
* Glyphs for the drawing tools and for host chrome, as path data.
|
|
723
|
-
*
|
|
724
|
-
* The engine ships no DOM, and this does not change that: an icon here is a
|
|
725
|
-
* string of SVG path commands, not an element. The host still builds its own
|
|
726
|
-
* toolbar, flyouts and rail; what it no longer has to do is draw every glyph
|
|
727
|
-
* before it can show them. `icon-svg.ts` turns these into markup strings for a
|
|
728
|
-
* host that wants the convenience; this file is the single source both of them
|
|
729
|
-
* and every other surface read from.
|
|
730
|
-
*
|
|
731
|
-
* That was the real cost of leaving them out. Every adopter drew their own set,
|
|
732
|
-
* each drifted on stroke weight, grid and visual density independently, and the
|
|
733
|
-
* result read as sixty icons rather than as one set, however carefully any
|
|
734
|
-
* single glyph was made. A shipped set is worth more than a better glyph.
|
|
735
|
-
*
|
|
736
|
-
* # Two tiers, one weight
|
|
737
|
-
*
|
|
738
|
-
* Tool glyphs live on a 24-unit grid and are shown at 24px in the rail. Host
|
|
739
|
-
* chrome (undo, close, the settings tab rail) is shown at 16px beside them, and
|
|
740
|
-
* a 24-grid glyph scaled to 16 lands its 2-unit stroke on 1.33 pixels, blurred
|
|
741
|
-
* across two rows on every edge. So chrome has its own registry drawn on a
|
|
742
|
-
* 16-unit grid with a 1.5 stroke. The two strokes are deliberately not in exact
|
|
743
|
-
* proportion: a small glyph needs a slightly heavier relative stroke than a
|
|
744
|
-
* large one to read as the same weight, and `tests/draw-icons.test.ts` holds
|
|
745
|
-
* the chrome tier inside that band rather than at parity.
|
|
746
|
-
*
|
|
747
|
-
* # The grid
|
|
748
|
-
*
|
|
749
|
-
* Every glyph is authored to the same constraints, and `tests/draw-icons.test.ts`
|
|
750
|
-
* enforces all of them mechanically, because a set of this size cannot be kept
|
|
751
|
-
* consistent by review:
|
|
752
|
-
*
|
|
753
|
-
* - **One viewBox per tier.** 24 by 24 for tools, 16 by 16 for chrome, so a
|
|
754
|
-
* host sets the size once per surface.
|
|
755
|
-
* - **A margin all round.** Live area 2 to 22 on the tool grid, 1 to 15 on the
|
|
756
|
-
* chrome grid. Without it, glyphs that happen to reach the edge look larger
|
|
757
|
-
* than their neighbours and the rail reads as ragged.
|
|
758
|
-
* - **Integer coordinates.** With `STROKE` of 2, an orthogonal edge centred on
|
|
759
|
-
* an integer covers exactly two device pixels at 1:1, which is what makes it
|
|
760
|
-
* crisp. Half-unit coordinates were the previous set's crispness bug: at a
|
|
761
|
-
* 1.5 stroke on integers, nothing landed on a pixel boundary at any size.
|
|
762
|
-
* - **One stroke weight per tier.** Three different weights across identically
|
|
763
|
-
* sized boxes is the single most visible tell of a set assembled rather than
|
|
764
|
-
* drawn.
|
|
765
|
-
*
|
|
766
|
-
* # Rendering
|
|
767
|
-
*
|
|
768
|
-
* Tool glyphs are crispest at 24px, and at any integer multiple of it. At 18px
|
|
769
|
-
* the 0.75 scale puts a 2-unit stroke on 1.5 device pixels and every edge is
|
|
770
|
-
* anti-aliased across two rows: that is a host sizing choice, not something the
|
|
771
|
-
* path data can fix. Prefer 24, or 12 with a heavier weight. Chrome glyphs are
|
|
772
|
-
* drawn for 16px and its multiples.
|
|
773
|
-
*/
|
|
774
|
-
/** The viewBox every glyph is authored in. */
|
|
775
|
-
declare const ICON_VIEWBOX = "0 0 24 24";
|
|
776
|
-
/**
|
|
777
|
-
* Stroke width in viewBox units. Paths carry no presentation attributes, so a
|
|
778
|
-
* host that wants a lighter set overrides this once rather than editing glyphs.
|
|
779
|
-
*/
|
|
780
|
-
declare const ICON_STROKE = 2;
|
|
781
|
-
/**
|
|
782
|
-
* The attribute bag a tier hands its host. Structural, so the markup builders
|
|
783
|
-
* in `icon-svg.ts` take either tier's bag through one signature.
|
|
784
|
-
*/
|
|
785
|
-
interface IconAttrs {
|
|
786
|
-
readonly viewBox: string;
|
|
787
|
-
readonly fill: 'none';
|
|
788
|
-
readonly stroke: 'currentColor';
|
|
789
|
-
readonly strokeWidth: number;
|
|
790
|
-
readonly strokeLinecap: 'round';
|
|
791
|
-
readonly strokeLinejoin: 'round';
|
|
792
|
-
}
|
|
793
|
-
/** Attributes a host should apply to the `<svg>`, so every set matches. */
|
|
794
|
-
declare const ICON_ATTRS: {
|
|
795
|
-
readonly viewBox: "0 0 24 24";
|
|
796
|
-
readonly fill: "none";
|
|
797
|
-
readonly stroke: "currentColor";
|
|
798
|
-
readonly strokeWidth: 2;
|
|
799
|
-
readonly strokeLinecap: "round";
|
|
800
|
-
readonly strokeLinejoin: "round";
|
|
801
|
-
};
|
|
802
|
-
/**
|
|
803
|
-
* Path data by tool id, plus a few keys a host toolbar needs that are not
|
|
804
|
-
* themselves tools (`cursor`, the group headers).
|
|
805
|
-
*
|
|
806
|
-
* Values are the `d` attribute of one `<path>`. Multiple subpaths are joined
|
|
807
|
-
* into the same string rather than split across elements, so a host renders one
|
|
808
|
-
* node per glyph.
|
|
809
|
-
*/
|
|
810
|
-
declare const DRAWING_TOOL_ICONS: Readonly<Record<string, string>>;
|
|
811
|
-
/**
|
|
812
|
-
* The glyph for a tool, or `undefined` when it has none.
|
|
813
|
-
*
|
|
814
|
-
* Undefined rather than a placeholder: a host that renders an empty box has a
|
|
815
|
-
* visible gap to fix, while one handed a question mark ships it.
|
|
816
|
-
*/
|
|
817
|
-
declare function drawingToolIcon(toolId: string): string | undefined;
|
|
818
|
-
/** Every id this set covers, for a host building a palette from it. */
|
|
819
|
-
declare function drawingToolIconIds(): string[];
|
|
820
|
-
/** The viewBox every chrome glyph is authored in. */
|
|
821
|
-
declare const CHROME_ICON_VIEWBOX = "0 0 16 16";
|
|
822
|
-
/**
|
|
823
|
-
* Chrome stroke width in viewBox units. Not the tool stroke scaled (that would
|
|
824
|
-
* be 1.33): at 16px a glyph needs a touch more relative weight than at 24px to
|
|
825
|
-
* read as the same line, and 1.5 is where the two rails match by eye.
|
|
826
|
-
*/
|
|
827
|
-
declare const CHROME_ICON_STROKE = 1.5;
|
|
828
|
-
/** Attributes a host should apply to the `<svg>` around a chrome glyph. */
|
|
829
|
-
declare const CHROME_ICON_ATTRS: {
|
|
830
|
-
readonly viewBox: "0 0 16 16";
|
|
831
|
-
readonly fill: "none";
|
|
832
|
-
readonly stroke: "currentColor";
|
|
833
|
-
readonly strokeWidth: 1.5;
|
|
834
|
-
readonly strokeLinecap: "round";
|
|
835
|
-
readonly strokeLinejoin: "round";
|
|
836
|
-
};
|
|
837
|
-
/**
|
|
838
|
-
* Path data for host chrome: the buttons around the chart rather than the
|
|
839
|
-
* tools in it. Same rules as the tool tier (one path per glyph, no presentation
|
|
840
|
-
* attributes, integer coordinates) on the 16 grid with a 1..15 live area.
|
|
841
|
-
*
|
|
842
|
-
* The pair `cursor` / `magnet` / `text` also exist in the tool registry, at 24.
|
|
843
|
-
* They are drawn twice on purpose: a rail button and a toolbar button are
|
|
844
|
-
* different sizes, and the whole point of a second grid is not scaling one
|
|
845
|
-
* drawing to both.
|
|
846
|
-
*/
|
|
847
|
-
declare const CHROME_ICONS: Readonly<Record<string, string>>;
|
|
848
|
-
/**
|
|
849
|
-
* Chrome glyphs meant to be painted solid. Paths carry no presentation
|
|
850
|
-
* attributes, so the fill is applied by the wrapper (`chromeIconSvg` does it,
|
|
851
|
-
* a host with its own wrapper reads this set) and the registry stays pure.
|
|
852
|
-
*/
|
|
853
|
-
declare const CHROME_ICON_FILLED: ReadonlySet<string>;
|
|
854
|
-
/** The chrome glyph for an id, or `undefined` when there is none. */
|
|
855
|
-
declare function chromeIcon(id: string): string | undefined;
|
|
856
|
-
/** Every id the chrome tier covers. */
|
|
857
|
-
declare function chromeIconIds(): string[];
|
|
858
|
-
|
|
859
|
-
/** Prefix of every `<symbol id>` in the sprite, and of every `<use href>`. */
|
|
860
|
-
declare const ICON_SYMBOL_PREFIX = "oac-icon-";
|
|
861
|
-
/** Options shared by the inline builders. */
|
|
862
|
-
interface IconSvgOptions {
|
|
863
|
-
/**
|
|
864
|
-
* Width and height. A number is CSS pixels; a string is written verbatim, so
|
|
865
|
-
* `'1em'` sizes the glyph with the surrounding text. Default: the grid's
|
|
866
|
-
* native size (24 for tools, 16 for chrome), where the stroke is crispest.
|
|
867
|
-
*/
|
|
868
|
-
size?: number | string;
|
|
869
|
-
/** Stroke width in viewBox units. Default: the tier's `*_STROKE`. */
|
|
870
|
-
stroke?: number;
|
|
871
|
-
/** A class for the host's own styling. */
|
|
872
|
-
className?: string;
|
|
873
|
-
}
|
|
874
|
-
/** Options for `toolCursor`. */
|
|
875
|
-
interface ToolCursorOptions {
|
|
876
|
-
/** Cursor image size in CSS pixels. Default 20. Browsers reject images over 128. */
|
|
877
|
-
size?: number;
|
|
878
|
-
/** The pointer's active pixel, from the image's top-left. Default: the centre. */
|
|
879
|
-
hotspot?: readonly [number, number];
|
|
880
|
-
/** Glyph colour. Default white. */
|
|
881
|
-
color?: string;
|
|
882
|
-
/**
|
|
883
|
-
* Halo colour. Default: black under a light `color`, white under a dark one,
|
|
884
|
-
* judged from a hex colour. A non-hex `color` gets a black halo unless this
|
|
885
|
-
* is set.
|
|
886
|
-
*/
|
|
887
|
-
halo?: string;
|
|
888
|
-
/** The keyword after the image, for a browser that will not take it. Default `crosshair`. */
|
|
889
|
-
fallback?: string;
|
|
890
|
-
}
|
|
891
|
-
/**
|
|
892
|
-
* A complete inline `<svg>` for one tool glyph, stroked in `currentColor`.
|
|
893
|
-
*
|
|
894
|
-
* ```ts
|
|
895
|
-
* button.innerHTML = iconSvg('trend-line');
|
|
896
|
-
* button.innerHTML = iconSvg('trend-line', { size: '1em' });
|
|
897
|
-
* ```
|
|
898
|
-
*/
|
|
899
|
-
declare function iconSvg(id: string, opts?: IconSvgOptions): string;
|
|
900
|
-
/**
|
|
901
|
-
* A complete inline `<svg>` for one chrome glyph, on the 16 grid. Glyphs in
|
|
902
|
-
* `CHROME_ICON_FILLED` are painted solid as well as stroked.
|
|
903
|
-
*/
|
|
904
|
-
declare function chromeIconSvg(id: string, opts?: IconSvgOptions): string;
|
|
905
|
-
/**
|
|
906
|
-
* One hidden `<svg>` of `<symbol>`s, for a host that shows many glyphs and
|
|
907
|
-
* wants each path in the document once. Inject it once, then place glyphs with
|
|
908
|
-
* `iconUse`. Symbols carry the path and viewBox only; stroke and fill inherit
|
|
909
|
-
* from the `<svg>` around each `<use>`, so one sprite serves every weight.
|
|
910
|
-
*
|
|
911
|
-
* Default: every tool glyph. Repeated ids collapse to one symbol, since a
|
|
912
|
-
* duplicate element id is an invalid document.
|
|
913
|
-
*/
|
|
914
|
-
declare function iconSprite(ids?: readonly string[]): string;
|
|
915
|
-
/** An `<svg>` that references a symbol from `iconSprite`. Same frame as `iconSvg`. */
|
|
916
|
-
declare function iconUse(id: string, opts?: IconSvgOptions): string;
|
|
917
|
-
/**
|
|
918
|
-
* A CSS `cursor` value carrying the tool's glyph, for the canvas while that
|
|
919
|
-
* tool is armed.
|
|
920
|
-
*
|
|
921
|
-
* The glyph is drawn twice: once in `halo`, one pixel wider on each side, and
|
|
922
|
-
* once in `color` on top, so it reads on a light chart and a dark one without
|
|
923
|
-
* the host choosing per theme. The value is `url("data:image/svg+xml,...") x y,
|
|
924
|
-
* fallback`, ready for `canvas.style.cursor`.
|
|
925
|
-
*/
|
|
926
|
-
declare function toolCursor(id: string, opts?: ToolCursorOptions): string;
|
|
927
|
-
|
|
928
|
-
/**
|
|
929
|
-
* A `DrawingLayer` renders the drawings of one pane and answers the chart's
|
|
930
|
-
* hit-test. Anchors live in `{ time, price }`, so the layer maps them through
|
|
931
|
-
* the *fractional* index helpers: the gapless axis means an anchor can sit
|
|
932
|
-
* between bars (inside a collapsed weekend) or past the last one (a forward
|
|
933
|
-
* projection), and whole-index lookups have nothing to return there.
|
|
934
|
-
*
|
|
935
|
-
* Each pane carries **two** layers, one at z-order `bottom` for drawings with a
|
|
936
|
-
* negative `zIndex` (under the series) and one at `top` for the rest. The top
|
|
937
|
-
* one takes over handles and hit-testing for the pair through `setBelow`, so a
|
|
938
|
-
* shape parked under the candles still shows its grab handles above them and
|
|
939
|
-
* a click lands on whatever the eye sees on top.
|
|
940
|
-
*
|
|
941
|
-
* Hit ids are `draw:<id>` for the body and `draw:<id>#<n>` for anchor `n`, so
|
|
942
|
-
* the controller can tell "move the whole shape" from "move this handle".
|
|
943
|
-
*
|
|
944
|
-
* The hover ring, the magnet ring and the hover handles are all overlay
|
|
945
|
-
* state: they change on every pointer move, so they must only ever cost the
|
|
946
|
-
* top canvas. The layer that paints them is the one whose `requestUpdate`
|
|
947
|
-
* the chart maps to the cursor tier, which is why the bottom layer of a pair
|
|
948
|
-
* stores that state and asks for nothing.
|
|
949
|
-
*/
|
|
950
|
-
|
|
951
|
-
/** Which side of the series a layer paints on. */
|
|
952
|
-
type DrawingLayerOrder = 'bottom' | 'top';
|
|
953
|
-
/** The pointer kinds the layer sizes its targets for. */
|
|
954
|
-
type DrawingPointerKind = 'mouse' | 'touch' | 'pen';
|
|
955
|
-
/**
|
|
956
|
-
* Paint order: by `zIndex`, ties by array position. `Array.prototype.sort` is
|
|
957
|
-
* stable, which is what makes the tie rule hold without a second key.
|
|
958
|
-
*/
|
|
959
|
-
declare function sortByZIndex(drawings: readonly Drawing[]): Drawing[];
|
|
960
|
-
declare class DrawingLayer implements IPrimitive {
|
|
961
|
-
private readonly _order;
|
|
962
|
-
/** In paint order. */
|
|
963
|
-
private _drawings;
|
|
964
|
-
private _host;
|
|
965
|
-
private _selected;
|
|
966
|
-
/** The drawing under the pointer, whether or not it is selected. */
|
|
967
|
-
private _hovered;
|
|
968
|
-
/** Where the next click will land while the magnet is pulling it. */
|
|
969
|
-
private _snap;
|
|
970
|
-
/** Anchors of the in-progress drawing, plus the live cursor point. */
|
|
971
|
-
private _preview;
|
|
972
|
-
/** The layer under this one, whose handles and hits this layer answers for. */
|
|
973
|
-
private _below;
|
|
974
|
-
/** The layer that has taken over this one's handles and hit-testing. */
|
|
975
|
-
private _above;
|
|
976
|
-
/** Sizes grab targets for the device last seen. */
|
|
977
|
-
private _touch;
|
|
978
|
-
constructor(order?: DrawingLayerOrder);
|
|
979
|
-
attached(host: PrimitiveHost): void;
|
|
980
|
-
detached(): void;
|
|
981
|
-
zOrder(): ZOrder;
|
|
982
|
-
/** Drawings overlay the price range; they never drive it. */
|
|
983
|
-
autoscaleInfo(): null;
|
|
984
|
-
setDrawings(drawings: readonly Drawing[]): void;
|
|
985
|
-
setSelected(ids: readonly string[]): void;
|
|
986
|
-
/**
|
|
987
|
-
* The drawing under the pointer. Its handles paint at a lighter weight than
|
|
988
|
-
* a selection's, as the hint that it can be grabbed. Repaints only from the
|
|
989
|
-
* layer that paints handles: the adopted bottom layer keeps the id for its
|
|
990
|
-
* own bookkeeping and asks for nothing, since its repaint costs the series.
|
|
991
|
-
*/
|
|
992
|
-
setHovered(id: string | null): void;
|
|
993
|
-
hovered(): string | null;
|
|
994
|
-
/**
|
|
995
|
-
* The point the magnet will snap the next click to, or null when it is not
|
|
996
|
-
* pulling. Painted as a hollow ring so the user sees the anchor land before
|
|
997
|
-
* committing to it.
|
|
998
|
-
*/
|
|
999
|
-
setSnapPoint(point: DrawingPoint | null): void;
|
|
1000
|
-
snapPoint(): DrawingPoint | null;
|
|
1001
|
-
/**
|
|
1002
|
-
* Size the grab targets for the device in use. Touch doubles the radii; a
|
|
1003
|
-
* mouse or a pen keeps the desktop sizes. The render context may carry the
|
|
1004
|
-
* same fact (`pointerType`), and when it does that wins per call, so a
|
|
1005
|
-
* first touch on a fresh chart is already sized right.
|
|
1006
|
-
*/
|
|
1007
|
-
setPointerType(kind: DrawingPointerKind | null | undefined): void;
|
|
1008
|
-
setPreview(drawing: Drawing | null): void;
|
|
1009
|
-
/**
|
|
1010
|
-
* Adopt the layer under this one. From then on this layer paints the handles
|
|
1011
|
-
* of both and answers `hitTest` for both, and the adopted layer paints bodies
|
|
1012
|
-
* only. Handles have to live up here: a selected drawing under the series
|
|
1013
|
-
* would otherwise have its handles buried under the candles, and a handle
|
|
1014
|
-
* you cannot see is a handle you cannot grab. Pass null to release.
|
|
1015
|
-
*/
|
|
1016
|
-
setBelow(layer: DrawingLayer | null): void;
|
|
1017
|
-
/** Repaint for overlay-only state, from the layer that paints it. */
|
|
1018
|
-
private _requestOverlay;
|
|
1019
|
-
/** Whether targets are sized for a fingertip on this call. */
|
|
1020
|
-
private _isTouch;
|
|
1021
|
-
private _grabRadius;
|
|
1022
|
-
private _handleRadius;
|
|
1023
|
-
/** Map an anchor to media px on this pane. */
|
|
1024
|
-
private _project;
|
|
1025
|
-
private _points;
|
|
1026
|
-
/** Selected, unlocked drawings of this layer, in paint order. */
|
|
1027
|
-
private _handled;
|
|
1028
|
-
/**
|
|
1029
|
-
* The hovered drawing of this layer, when it is one that could be grabbed
|
|
1030
|
-
* and is not already showing selection handles.
|
|
1031
|
-
*/
|
|
1032
|
-
private _hoverHandled;
|
|
1033
|
-
draw(ctx: CanvasRenderingContext2D, rc: PrimitiveRenderContext): void;
|
|
1034
|
-
private _drawingContext;
|
|
1035
|
-
private _drawContent;
|
|
1036
|
-
private _drawPlacementGuide;
|
|
1037
|
-
/**
|
|
1038
|
-
* Anchor handles. A hover shows them light (thin, translucent) as a hint
|
|
1039
|
-
* that the shape can be grabbed; a selection shows them at full weight.
|
|
1040
|
-
*/
|
|
1041
|
-
private _drawHandles;
|
|
1042
|
-
/** The magnet ring: hollow, in the axis text colour, at the snap point. */
|
|
1043
|
-
private _drawSnapRing;
|
|
1044
|
-
hitTest(x: number, y: number, rc: PrimitiveRenderContext): PrimitiveHit | null;
|
|
1045
|
-
private _hitHandle;
|
|
1046
|
-
private _hitBody;
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
/**
|
|
1050
|
-
* Clipboard transfer for drawings: the layer between the drawing model and the
|
|
1051
|
-
* OS clipboard.
|
|
1052
|
-
*
|
|
1053
|
-
* Two things make this more than `JSON.stringify`:
|
|
1054
|
-
*
|
|
1055
|
-
* 1. **The OS clipboard is shared with everything else on the machine.** A
|
|
1056
|
-
* paste can arrive from a spreadsheet, another application, or a hand-edited
|
|
1057
|
-
* copy of our own payload. So the payload is written under a namespaced key
|
|
1058
|
-
* and everything read back is validated field by field before it can reach
|
|
1059
|
-
* the model. Foreign text is *not ours* and is ignored, never an exception
|
|
1060
|
-
* the host has to catch on every Ctrl+V.
|
|
1061
|
-
* 2. **Clipboard access is async and permission-gated.** `navigator.clipboard`
|
|
1062
|
-
* rejects when the document is not focused, the page is not secure, or the
|
|
1063
|
-
* user denied the permission. Copy must still work inside the tab, so every
|
|
1064
|
-
* write also lands in a module-level in-memory clipboard which is shared by
|
|
1065
|
-
* every controller in the page. That is what makes chart-to-chart paste work
|
|
1066
|
-
* with the permission denied, and it is why the memory store is a singleton
|
|
1067
|
-
* rather than per-controller state.
|
|
1068
|
-
*
|
|
1069
|
-
* The payload body is a drawings document (`DrawingsDocument`), so a copy made
|
|
1070
|
-
* by a 1.9.x build (a version 1 body carrying the old style-bag text fields)
|
|
1071
|
-
* is upgraded by the same migration a saved layout goes through.
|
|
1072
|
-
*/
|
|
1073
|
-
|
|
1074
|
-
/**
|
|
1075
|
-
* Top-level key of the JSON payload. Namespaced so a paste of arbitrary text,
|
|
1076
|
-
* or of JSON belonging to some other application, is recognisable as not ours
|
|
1077
|
-
* by looking at one property.
|
|
1078
|
-
*/
|
|
1079
|
-
declare const DRAWING_CLIPBOARD_KEY = "openalgo-charts/drawings";
|
|
1080
|
-
/**
|
|
1081
|
-
* Payload format version. Tracks the model version, since the body *is* a
|
|
1082
|
-
* drawings document: version 1 carried 1.9.x drawings, version 2 carries the
|
|
1083
|
-
* split text and levelled fibs.
|
|
1084
|
-
*/
|
|
1085
|
-
declare const DRAWING_CLIPBOARD_VERSION: number;
|
|
1086
|
-
/** The async slice of `navigator.clipboard` this module uses. */
|
|
1087
|
-
interface ClipboardPort {
|
|
1088
|
-
writeText(text: string): Promise<void>;
|
|
1089
|
-
readText(): Promise<string>;
|
|
1090
|
-
}
|
|
1091
|
-
/** Test seam: drop whatever the in-memory clipboard is holding. */
|
|
1092
|
-
declare function clearMemoryClipboard(): void;
|
|
1093
|
-
/** `navigator.clipboard` when the browser exposes it, else null. */
|
|
1094
|
-
declare function systemClipboard(): ClipboardPort | null;
|
|
1095
|
-
/** Deep copy of the persisted fields, so a clone shares nothing with its source. */
|
|
1096
|
-
declare function cloneDrawing(d: Drawing): Drawing;
|
|
1097
|
-
/** Serialise drawings into the namespaced payload written to the clipboard. */
|
|
1098
|
-
declare function encodeClipboardPayload(drawings: readonly Drawing[]): string;
|
|
1099
|
-
/**
|
|
1100
|
-
* Validate one entry into a drawing with no id. Returns null for anything that
|
|
1101
|
-
* cannot be rendered: an unknown tool would throw inside the controller, and a
|
|
1102
|
-
* NaN anchor produces a drawing that can never be drawn or hit-tested again.
|
|
1103
|
-
* Accepts the 1.9.x shape too, lifting its text fields into `text`.
|
|
1104
|
-
*/
|
|
1105
|
-
declare function sanitizeDrawing(value: unknown): Omit<Drawing, 'id'> | null;
|
|
1106
|
-
/**
|
|
1107
|
-
* Parse clipboard text into drawings, or null when the text is not ours or is
|
|
1108
|
-
* not usable. All-or-nothing on purpose: a payload with one corrupt entry is a
|
|
1109
|
-
* corrupt payload, and pasting the other nine silently would be worse than
|
|
1110
|
-
* pasting none.
|
|
1111
|
-
*/
|
|
1112
|
-
declare function decodeClipboardPayload(text: unknown): Omit<Drawing, 'id'>[] | null;
|
|
1113
|
-
interface DrawingClipboardOptions {
|
|
1114
|
-
/** Where to read and write. Defaults to `navigator.clipboard` when present. */
|
|
1115
|
-
port?: ClipboardPort | null;
|
|
1116
|
-
/**
|
|
1117
|
-
* Keep a copy in the shared in-memory clipboard so copy and paste keep
|
|
1118
|
-
* working when the OS clipboard is unavailable or the permission is refused.
|
|
1119
|
-
* Default true. Set false to make a failed system write a failed copy, which
|
|
1120
|
-
* a host that must not silently lose cross-tab transfer may prefer.
|
|
1121
|
-
*/
|
|
1122
|
-
fallbackToMemory?: boolean;
|
|
1123
|
-
}
|
|
1124
|
-
/**
|
|
1125
|
-
* The clipboard as the controller sees it: drawings in, drawings out, no
|
|
1126
|
-
* exceptions escaping. Every failure mode (no clipboard API, refused
|
|
1127
|
-
* permission, foreign text, corrupt payload) reduces to `false` or `null`.
|
|
1128
|
-
*/
|
|
1129
|
-
declare class DrawingClipboard {
|
|
1130
|
-
private _port;
|
|
1131
|
-
private _fallback;
|
|
1132
|
-
/** Why the last operation did not reach the OS clipboard, if it did not. */
|
|
1133
|
-
private _lastError;
|
|
1134
|
-
constructor(options?: DrawingClipboardOptions);
|
|
1135
|
-
/** Swap the port at runtime (a host granting permission later, or a test). */
|
|
1136
|
-
setPort(port: ClipboardPort | null): void;
|
|
1137
|
-
/**
|
|
1138
|
-
* Turn the in-memory backstop off or on. With it off, a refused system write
|
|
1139
|
-
* is a failed copy, which is what a host wants when a cut that cannot reach
|
|
1140
|
-
* the OS clipboard must not delete the drawing.
|
|
1141
|
-
*/
|
|
1142
|
-
setFallbackToMemory(enabled: boolean): void;
|
|
1143
|
-
/**
|
|
1144
|
-
* Why the OS clipboard was not used by the last call, or null when it was.
|
|
1145
|
-
* Set on a successful copy too, when the payload reached memory but not the
|
|
1146
|
-
* system clipboard: that copy works in this tab and will not appear in
|
|
1147
|
-
* another, which is exactly what a host wants to be able to tell the user.
|
|
1148
|
-
*/
|
|
1149
|
-
lastError(): string | null;
|
|
1150
|
-
/**
|
|
1151
|
-
* Write drawings out. Resolves true when the payload is retrievable by a
|
|
1152
|
-
* later `read()` (through the system clipboard, or through memory when the
|
|
1153
|
-
* fallback is on), false when it is not, so a caller doing a cut knows
|
|
1154
|
-
* whether it is safe to delete the original.
|
|
1155
|
-
*/
|
|
1156
|
-
write(drawings: readonly Drawing[]): Promise<boolean>;
|
|
1157
|
-
/**
|
|
1158
|
-
* Read drawings back, or null when there is nothing of ours to paste. The
|
|
1159
|
-
* system clipboard wins when it holds our payload, so a copy made in another
|
|
1160
|
-
* tab beats a stale in-tab one; memory is consulted when the read fails or
|
|
1161
|
-
* returns something that is not ours. That last case can paste an older copy
|
|
1162
|
-
* after the user has copied unrelated text elsewhere, which is the deliberate
|
|
1163
|
-
* trade: losing the copy whenever a browser refuses the read half of the
|
|
1164
|
-
* permission would be the worse surprise.
|
|
1165
|
-
*/
|
|
1166
|
-
read(): Promise<Omit<Drawing, 'id'>[] | null>;
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
/**
|
|
1170
|
-
* Drawing controller: the interaction and persistence layer over
|
|
1171
|
-
* `DrawingLayer`. It is **headless**: no DOM, no toolbar. A host sets the
|
|
1172
|
-
* active tool (from its own button, a shortcut, a command palette) and the
|
|
1173
|
-
* controller runs placement, selection, dragging, undo, and serialisation.
|
|
1174
|
-
*
|
|
1175
|
-
* It listens on the chart's event bus (`click`, `crosshair:move`, `drag`,
|
|
1176
|
-
* `drag:end`) rather than the single-slot `subscribeClick`/`subscribeDrag`
|
|
1177
|
-
* callbacks, so a host keeps using those for its own order lines.
|
|
1178
|
-
*
|
|
1179
|
-
* Selection is a list. Every method that edits takes the whole list into one
|
|
1180
|
-
* undo entry, so a multi-drag, a batch delete or a paste of ten shapes is one
|
|
1181
|
-
* Ctrl+Z, which is what the hand that did it expects.
|
|
1182
|
-
*/
|
|
1183
|
-
|
|
1184
|
-
/**
|
|
1185
|
-
* The slice of the chart this controller needs.
|
|
1186
|
-
*
|
|
1187
|
-
* Declared structurally rather than as `Chart` on purpose. Each tier ships its
|
|
1188
|
-
* own bundled `.d.ts`, so naming the class here made the draw tier re-declare
|
|
1189
|
-
* `Chart`, and because `Chart` has private members, TypeScript treats the two
|
|
1190
|
-
* declarations as *different* types. A TS consumer passing the chart from
|
|
1191
|
-
* `createChart()` got "separate declarations of a private property", which made
|
|
1192
|
-
* the tier unusable from TypeScript at all. An interface with no private
|
|
1193
|
-
* members is structural, so the real `Chart` satisfies it with nothing to cast.
|
|
634
|
+
* Declared structurally rather than as `Chart` on purpose. Each tier ships its
|
|
635
|
+
* own bundled `.d.ts`, so naming the class here made the draw tier re-declare
|
|
636
|
+
* `Chart`, and because `Chart` has private members, TypeScript treats the two
|
|
637
|
+
* declarations as *different* types. A TS consumer passing the chart from
|
|
638
|
+
* `createChart()` got "separate declarations of a private property", which made
|
|
639
|
+
* the tier unusable from TypeScript at all. An interface with no private
|
|
640
|
+
* members is structural, so the real `Chart` satisfies it with nothing to cast.
|
|
1194
641
|
*/
|
|
1195
642
|
interface DrawingChartHost {
|
|
643
|
+
readonly isDestroyed?: boolean;
|
|
1196
644
|
/**
|
|
1197
645
|
* The event bus. The controller listens for `click`, `crosshair:move`,
|
|
1198
646
|
* `drag`, `drag:end` and `dblclick`, and for `hover` (`{ id }`, the hit id
|
|
@@ -1279,13 +727,15 @@ interface DrawingControllerOptions {
|
|
|
1279
727
|
pasteOffsetPixels?: number;
|
|
1280
728
|
}
|
|
1281
729
|
/** What `drawing:change` reports happened to the listed ids. */
|
|
1282
|
-
type DrawingChangeKind = 'add' | 'update' | 'remove' | 'reorder';
|
|
730
|
+
type DrawingChangeKind = 'add' | 'update' | 'remove' | 'reorder' | 'undo' | 'redo';
|
|
1283
731
|
declare class DrawingController {
|
|
1284
732
|
private readonly _chart;
|
|
1285
733
|
private _opts;
|
|
1286
734
|
private readonly _clipboard;
|
|
1287
735
|
private readonly _layers;
|
|
1288
736
|
private _drawings;
|
|
737
|
+
private readonly _linkedPreviews;
|
|
738
|
+
private _destroyed;
|
|
1289
739
|
private _tool;
|
|
1290
740
|
private _pending;
|
|
1291
741
|
private _pendingPane;
|
|
@@ -1307,6 +757,7 @@ declare class DrawingController {
|
|
|
1307
757
|
/** Snapshots for undo/redo; each is a full drawing list (they are small). */
|
|
1308
758
|
private _undo;
|
|
1309
759
|
private _redo;
|
|
760
|
+
private _pendingHistory;
|
|
1310
761
|
/**
|
|
1311
762
|
* One gesture's starting state. `items` are ids rather than objects because
|
|
1312
763
|
* an undo mid-drag replaces every drawing object, and a stale reference
|
|
@@ -1348,6 +799,13 @@ declare class DrawingController {
|
|
|
1348
799
|
*/
|
|
1349
800
|
drawings(): readonly Drawing[];
|
|
1350
801
|
get(id: string): Drawing | undefined;
|
|
802
|
+
get isDestroyed(): boolean;
|
|
803
|
+
/** Apply a linked commit without adding to this chart's local undo history. */
|
|
804
|
+
applyLinkedDrawing(id: string, drawing: Drawing | null): void;
|
|
805
|
+
/** A linked drag paints over its committed drawing without changing saved state. */
|
|
806
|
+
setLinkedPreview(id: string, drawing: Drawing | null): void;
|
|
807
|
+
/** Reorder related drawings inside their existing slots, preserving unrelated local order. */
|
|
808
|
+
reorderLinkedDrawings(ids: readonly string[]): void;
|
|
1351
809
|
/** Supported numeric levels, independent of whether the queried time lies on the shape. */
|
|
1352
810
|
alertInfo(id: string): AlertDrawingInfo;
|
|
1353
811
|
/** Numeric drawing value using the actual pane projection and collapsed time axis. */
|
|
@@ -1457,6 +915,7 @@ declare class DrawingController {
|
|
|
1457
915
|
private _offsetTime;
|
|
1458
916
|
undo(): boolean;
|
|
1459
917
|
redo(): boolean;
|
|
918
|
+
private _applyHistory;
|
|
1460
919
|
/** Drop selected ids the model no longer holds, after a history jump. */
|
|
1461
920
|
private _pruneSelection;
|
|
1462
921
|
canUndo(): boolean;
|
|
@@ -1546,78 +1005,753 @@ declare class DrawingController {
|
|
|
1546
1005
|
private _onClick;
|
|
1547
1006
|
private _placePoint;
|
|
1548
1007
|
/**
|
|
1549
|
-
* Where a click at `point` actually lands for the armed tool: on the 45
|
|
1550
|
-
* degree lock while Shift holds the free end of a line, else on the magnet
|
|
1551
|
-
* when it pulls, else where it was. The lock wins over the magnet because a
|
|
1552
|
-
* snapped price would bend the exact angle the lock exists to give.
|
|
1008
|
+
* Where a click at `point` actually lands for the armed tool: on the 45
|
|
1009
|
+
* degree lock while Shift holds the free end of a line, else on the magnet
|
|
1010
|
+
* when it pulls, else where it was. The lock wins over the magnet because a
|
|
1011
|
+
* snapped price would bend the exact angle the lock exists to give.
|
|
1012
|
+
*/
|
|
1013
|
+
private _aimPoint;
|
|
1014
|
+
/**
|
|
1015
|
+
* The free end of a two-anchor line under angle lock, or null when the lock
|
|
1016
|
+
* does not apply: no Shift, a tool without the flag, no anchor yet to
|
|
1017
|
+
* measure from, or a host that cannot map pixels (the lock is a screen
|
|
1018
|
+
* angle, so there is nothing to lock to in data space).
|
|
1019
|
+
*/
|
|
1020
|
+
private _lockedPoint;
|
|
1021
|
+
/**
|
|
1022
|
+
* The nearest O/H/L/C of the hovered bar, at that bar's time, when the
|
|
1023
|
+
* magnet pulls; null when it does not. `strong` always pulls; `weak` only
|
|
1024
|
+
* within a few pixels, measured on screen so the pull is the same reach at
|
|
1025
|
+
* every zoom. Price panes only: an indicator pane's values are not prices.
|
|
1026
|
+
*/
|
|
1027
|
+
private _snapPoint;
|
|
1028
|
+
private _onDrag;
|
|
1029
|
+
private _emitDragPreview;
|
|
1030
|
+
/** Roll back an interrupted drag and leave the pre-gesture undo/redo stacks intact. */
|
|
1031
|
+
cancelDrag(): boolean;
|
|
1032
|
+
/** Apply one drag frame to the model, from the gesture's snapshot. */
|
|
1033
|
+
private _moveDrag;
|
|
1034
|
+
/** How far down the screen `to` is from `from` on one pane, in media px. */
|
|
1035
|
+
private _pixelDelta;
|
|
1036
|
+
/** An anchor in container media px, or null on a host without the mapping. */
|
|
1037
|
+
private _toPixel;
|
|
1038
|
+
/** The inverse of `_toPixel`. */
|
|
1039
|
+
private _fromPixel;
|
|
1040
|
+
/**
|
|
1041
|
+
* `free` projected onto the nearest 45 degree ray from `anchor`, all in
|
|
1042
|
+
* screen space: the angle the eye reads is the one on the canvas, and a log
|
|
1043
|
+
* scale or a tall pane would make a data-space angle anything but. The
|
|
1044
|
+
* projection rather than a rotation, so a level line still ends under the
|
|
1045
|
+
* pointer's x and a vertical one under its y; only the stray axis is
|
|
1046
|
+
* dropped. Null when the host cannot map pixels, or the two coincide.
|
|
1047
|
+
*/
|
|
1048
|
+
private _lockAngle;
|
|
1049
|
+
private _onDragEnd;
|
|
1050
|
+
/**
|
|
1051
|
+
* The pair of layers for a pane, made on first use. The bottom one is added
|
|
1052
|
+
* first so a host that lists primitives sees them in paint order; the top one
|
|
1053
|
+
* adopts it so handles and hit-tests come from one place.
|
|
1054
|
+
*/
|
|
1055
|
+
private _layerFor;
|
|
1056
|
+
/** Whether a drawing paints on the top layer: over the series, or lifted for a drag. */
|
|
1057
|
+
private _onTop;
|
|
1058
|
+
/** Push the current list into each pane's layers and into the chart state. */
|
|
1059
|
+
private _sync;
|
|
1060
|
+
/**
|
|
1061
|
+
* The per-frame half of a drag: only the top layers of the panes the
|
|
1062
|
+
* gesture touches are re-listed, so the repaint stays on the cursor tier.
|
|
1063
|
+
* Everything moving is on a top layer by then (anything under the series
|
|
1064
|
+
* was lifted when the gesture began), and the bottom layers have not
|
|
1065
|
+
* changed since, so re-listing them would cost a series repaint for
|
|
1066
|
+
* nothing.
|
|
1067
|
+
*/
|
|
1068
|
+
private _syncDrag;
|
|
1069
|
+
/**
|
|
1070
|
+
* Mirror the in-progress anchors (plus the cursor) into the preview slot.
|
|
1071
|
+
* The cursor point goes through the same aim as a click would, so the
|
|
1072
|
+
* preview shows the locked angle or the snapped anchor before it lands.
|
|
1073
|
+
*/
|
|
1074
|
+
private _syncPreview;
|
|
1075
|
+
/**
|
|
1076
|
+
* Show where the magnet will land the next click, or nothing. A ring only
|
|
1077
|
+
* while a click would place an anchor: a tool armed, not a brush (which
|
|
1078
|
+
* inks where the pointer is), and the pull actually applying at the cursor.
|
|
1079
|
+
* Angle lock bypasses the magnet, so it hides the ring too.
|
|
1080
|
+
*/
|
|
1081
|
+
private _syncSnapRing;
|
|
1082
|
+
private _pushUndo;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
/** Both fields must be known. A host may use its feed namespace as the exchange. */
|
|
1086
|
+
interface DrawingLinkContext {
|
|
1087
|
+
symbol?: string;
|
|
1088
|
+
exchange?: string;
|
|
1089
|
+
}
|
|
1090
|
+
/** Resolve a host-owned identity without modifying the chart's data context. */
|
|
1091
|
+
type DrawingLinkContextSource = DrawingLinkContext | (() => DrawingLinkContext | null | undefined);
|
|
1092
|
+
interface DrawingLinkOptions {
|
|
1093
|
+
enabled?: boolean;
|
|
1094
|
+
}
|
|
1095
|
+
interface DrawingLinkChart extends Pick<DrawingChartHost, 'on'> {
|
|
1096
|
+
readonly isDestroyed?: boolean;
|
|
1097
|
+
getDataContext?(): Readonly<DrawingLinkContext> | undefined;
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Existing local drawings stay local until `share` is called. Persisted shared
|
|
1101
|
+
* lineage reconnects across restores. Only price-pane drawings participate; time anchors
|
|
1102
|
+
* cross the boundary unchanged so each interval uses its own coordinate map.
|
|
1103
|
+
*/
|
|
1104
|
+
declare class DrawingLinkGroup {
|
|
1105
|
+
private readonly _members;
|
|
1106
|
+
private _enabled;
|
|
1107
|
+
private _broadcasting;
|
|
1108
|
+
private _destroyed;
|
|
1109
|
+
constructor(options?: DrawingLinkOptions);
|
|
1110
|
+
options(): Required<DrawingLinkOptions>;
|
|
1111
|
+
add(chart: DrawingLinkChart, controller: DrawingController, context?: DrawingLinkContextSource): void;
|
|
1112
|
+
setOptions(options: DrawingLinkOptions): void;
|
|
1113
|
+
/** Report the current instrument. Unknown identity stops sharing immediately. */
|
|
1114
|
+
setContext(chart: DrawingLinkChart, context: DrawingLinkContext | undefined): void;
|
|
1115
|
+
/** Share selected ids, or every existing eligible drawing when ids are omitted. */
|
|
1116
|
+
share(chart: DrawingLinkChart, ids?: readonly string[]): number;
|
|
1117
|
+
has(chart: DrawingLinkChart): boolean;
|
|
1118
|
+
/** Committed drawings remain on peers; transient previews are discarded. */
|
|
1119
|
+
remove(chart: DrawingLinkChart): void;
|
|
1120
|
+
destroy(): void;
|
|
1121
|
+
private _eligible;
|
|
1122
|
+
private _create;
|
|
1123
|
+
private _reconnect;
|
|
1124
|
+
private _change;
|
|
1125
|
+
private _commit;
|
|
1126
|
+
private _preview;
|
|
1127
|
+
private _syncOrder;
|
|
1128
|
+
private _orderFrom;
|
|
1129
|
+
private _clearPreview;
|
|
1130
|
+
private _clearMemberPreviews;
|
|
1131
|
+
private _detachDrawings;
|
|
1132
|
+
}
|
|
1133
|
+
declare function createDrawingLinkGroup(options?: DrawingLinkOptions): DrawingLinkGroup;
|
|
1134
|
+
|
|
1135
|
+
/**
|
|
1136
|
+
* Built-in drawing tools + the tool registry. Same philosophy as the chart-type
|
|
1137
|
+
* and indicator registries: a tool is a descriptor, the layer just runs it, and
|
|
1138
|
+
* `registerDrawingTool` makes a custom one first-class.
|
|
1139
|
+
*
|
|
1140
|
+
* `draw` receives anchors already in device px; `distance` receives them in
|
|
1141
|
+
* media px, the same space as the incoming cursor.
|
|
1142
|
+
*
|
|
1143
|
+
* Text lives in `drawing.text` (a `DrawingText`), never in the style bag: a
|
|
1144
|
+
* shape's outline colour and its label colour are two decisions, and a tool
|
|
1145
|
+
* that prints only a readout (a fib ladder, a measure chip) still reads its
|
|
1146
|
+
* face from there. Ladders read `FibLevel[]` and stroke each level in its own
|
|
1147
|
+
* colour, taken from the shared palette in levels.ts.
|
|
1148
|
+
*
|
|
1149
|
+
* Every tool declares `settings`: the fields a host may show for it. The
|
|
1150
|
+
* schema is a contract, not a wish list. A field is declared only when this
|
|
1151
|
+
* file reads it, because a control with nothing behind it is a defect.
|
|
1152
|
+
*/
|
|
1153
|
+
|
|
1154
|
+
declare function registerDrawingTool(tool: DrawingTool): void;
|
|
1155
|
+
declare function getDrawingTool(id: string): DrawingTool;
|
|
1156
|
+
declare function hasDrawingTool(id: string): boolean;
|
|
1157
|
+
declare function registeredDrawingTools(): DrawingTool[];
|
|
1158
|
+
/** Keyboard event fields a shortcut is matched against. */
|
|
1159
|
+
interface ShortcutEvent {
|
|
1160
|
+
key: string;
|
|
1161
|
+
altKey?: boolean;
|
|
1162
|
+
ctrlKey?: boolean;
|
|
1163
|
+
metaKey?: boolean;
|
|
1164
|
+
shiftKey?: boolean;
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* The id of the tool whose `shortcut` matches this key event, or `null`.
|
|
1168
|
+
*
|
|
1169
|
+
* Pure, so a host can bind one `keydown` listener and decide for itself when
|
|
1170
|
+
* shortcuts apply. The library installs no listener, because only the host
|
|
1171
|
+
* knows whether the chart has focus, a dialog is open, or the user is typing.
|
|
1172
|
+
*
|
|
1173
|
+
* Modifiers must match exactly: `Alt+T` will not fire for `Ctrl+Alt+T`, so a
|
|
1174
|
+
* tool shortcut cannot shadow a browser or host chord. `metaKey` (Cmd) is
|
|
1175
|
+
* treated as Ctrl, which is what a Mac user expects.
|
|
1176
|
+
*/
|
|
1177
|
+
declare function matchDrawingShortcut(e: ShortcutEvent): string | null;
|
|
1178
|
+
/** Every registered tool that has a shortcut, as `id -> shortcut`. */
|
|
1179
|
+
declare function drawingShortcuts(): Record<string, string>;
|
|
1180
|
+
/**
|
|
1181
|
+
* The settings a host may show for a tool: the tool's own declaration, else
|
|
1182
|
+
* the line fields, which every stroked custom tool reads. This is a registry
|
|
1183
|
+
* lookup, which is why it lives here and not in schema.ts: that module stays
|
|
1184
|
+
* free of any import that could loop back into this one.
|
|
1185
|
+
*/
|
|
1186
|
+
declare function drawingSettingsSchema(toolId: string): SettingsSchema;
|
|
1187
|
+
declare const TREND_LINE: DrawingTool;
|
|
1188
|
+
declare const RAY: DrawingTool;
|
|
1189
|
+
declare const EXTENDED_LINE: DrawingTool;
|
|
1190
|
+
declare const ARROW: DrawingTool;
|
|
1191
|
+
declare const HORIZONTAL_LINE: DrawingTool;
|
|
1192
|
+
declare const HORIZONTAL_RAY: DrawingTool;
|
|
1193
|
+
declare const VERTICAL_LINE: DrawingTool;
|
|
1194
|
+
declare const CROSS_LINE: DrawingTool;
|
|
1195
|
+
declare const RECTANGLE: DrawingTool;
|
|
1196
|
+
declare const ELLIPSE: DrawingTool;
|
|
1197
|
+
declare const PARALLEL_CHANNEL: DrawingTool;
|
|
1198
|
+
declare const FIB_RETRACEMENT: DrawingTool;
|
|
1199
|
+
declare const FIB_EXTENSION: DrawingTool;
|
|
1200
|
+
declare const MEASURE: DrawingTool;
|
|
1201
|
+
declare const LONG_POSITION: DrawingTool;
|
|
1202
|
+
declare const SHORT_POSITION: DrawingTool;
|
|
1203
|
+
declare const TEXT: DrawingTool;
|
|
1204
|
+
/**
|
|
1205
|
+
* Path: click each vertex, double-click to finish, arrowhead on the last leg.
|
|
1206
|
+
* The arrow is what separates it from `polyline`: a path points somewhere.
|
|
1207
|
+
*/
|
|
1208
|
+
declare const PATH: DrawingTool;
|
|
1209
|
+
/**
|
|
1210
|
+
* Brush: freehand ink. Press, drag, release. The anchors are the thinned
|
|
1211
|
+
* samples of the gesture and the spline between them is what is stroked, so
|
|
1212
|
+
* the ink stays a curve after the thinning that keeps a stroke small.
|
|
1213
|
+
*/
|
|
1214
|
+
declare const BRUSH: DrawingTool;
|
|
1215
|
+
/**
|
|
1216
|
+
* Rotated rectangle: anchors 0 and 1 lay out one edge (and so the rotation),
|
|
1217
|
+
* and anchor 2 sets the depth perpendicular to it. An axis-aligned `rectangle`
|
|
1218
|
+
* cannot follow a trend channel; this can.
|
|
1219
|
+
*/
|
|
1220
|
+
declare const ROTATED_RECTANGLE: DrawingTool;
|
|
1221
|
+
/**
|
|
1222
|
+
* Double curve: an S through three anchors. `curve` bends one way off a single
|
|
1223
|
+
* control; this mirrors that control about the midpoint so the second half bends
|
|
1224
|
+
* back, which is the shape a rounded top-then-bottom actually needs.
|
|
1225
|
+
*/
|
|
1226
|
+
declare const DOUBLE_CURVE: DrawingTool;
|
|
1227
|
+
/**
|
|
1228
|
+
* Cyclic lines: vertical lines repeating at the interval the two anchors set,
|
|
1229
|
+
* for reading a rhythm forward off a measured swing.
|
|
1230
|
+
*/
|
|
1231
|
+
declare const CYCLIC_LINES: DrawingTool;
|
|
1232
|
+
/**
|
|
1233
|
+
* Time cycles: semicircles of the anchors' width repeating along the axis, the
|
|
1234
|
+
* classic cycle-projection overlay.
|
|
1235
|
+
*/
|
|
1236
|
+
declare const TIME_CYCLES: DrawingTool;
|
|
1237
|
+
/**
|
|
1238
|
+
* Sine line: a full wave between the anchors. The horizontal span is one
|
|
1239
|
+
* period, the vertical offset its amplitude.
|
|
1240
|
+
*/
|
|
1241
|
+
declare const SINE_LINE: DrawingTool;
|
|
1242
|
+
/**
|
|
1243
|
+
* Price label: a pill of the anchored price with a tail pointing at the bar.
|
|
1244
|
+
* Reads its value off the anchor, so dragging it re-reads rather than going
|
|
1245
|
+
* stale the way a typed-in text would. Text, when given, replaces the price.
|
|
1246
|
+
*/
|
|
1247
|
+
declare const PRICE_LABEL: DrawingTool;
|
|
1248
|
+
/**
|
|
1249
|
+
* Callout: a text bubble on its own anchor with a tail back to the point it
|
|
1250
|
+
* annotates, so the note can sit clear of the price action it refers to.
|
|
1251
|
+
*/
|
|
1252
|
+
declare const CALLOUT: DrawingTool;
|
|
1253
|
+
/** Flag mark: a pennant on a pole at one anchor, for tagging a bar. */
|
|
1254
|
+
declare const FLAG_MARK: DrawingTool;
|
|
1255
|
+
/**
|
|
1256
|
+
* Note: a pin at the bar with its text to the upper right.
|
|
1257
|
+
*
|
|
1258
|
+
* The pin is the point being annotated and the plate is the annotation, which
|
|
1259
|
+
* is why the two are drawn as separate marks joined by a stem rather than as
|
|
1260
|
+
* one bubble: the reader needs to see exactly which bar is meant, and a bubble
|
|
1261
|
+
* wide enough to hold a sentence covers several.
|
|
1262
|
+
*/
|
|
1263
|
+
declare const NOTE: DrawingTool;
|
|
1264
|
+
/**
|
|
1265
|
+
* Balloon: a speech bubble sitting above its anchor, tail pointing down.
|
|
1266
|
+
*
|
|
1267
|
+
* One anchor rather than the callout's two: a balloon is for saying something
|
|
1268
|
+
* *about this bar*, so letting the bubble be dragged away from what it labels
|
|
1269
|
+
* would only invite it to drift.
|
|
1270
|
+
*/
|
|
1271
|
+
declare const BALLOON: DrawingTool;
|
|
1272
|
+
/**
|
|
1273
|
+
* Comment: a small square-cornered box with a tail off its bottom left.
|
|
1274
|
+
*
|
|
1275
|
+
* Deliberately plainer than the balloon: a chart that says something at every
|
|
1276
|
+
* other bar needs one of these marks to be quiet, and the shape is the only
|
|
1277
|
+
* thing distinguishing them once both are the user's own colour.
|
|
1278
|
+
*/
|
|
1279
|
+
declare const COMMENT: DrawingTool;
|
|
1280
|
+
/**
|
|
1281
|
+
* Signpost: a post standing on the bar with its plate at the top.
|
|
1282
|
+
*
|
|
1283
|
+
* The one annotation anchored to *time* rather than to a level: the post is
|
|
1284
|
+
* vertical so the plate can clear the price action entirely while the foot
|
|
1285
|
+
* still names an exact bar. Useful for events, which happen at a moment and
|
|
1286
|
+
* not at a price.
|
|
1287
|
+
*/
|
|
1288
|
+
declare const SIGNPOST: DrawingTool;
|
|
1289
|
+
/**
|
|
1290
|
+
* Price note: the anchored price, with the user's text under it.
|
|
1291
|
+
*
|
|
1292
|
+
* The price is read off the anchor rather than typed, so dragging the note
|
|
1293
|
+
* re-reads it. A typed price is a number that was true once, which on a chart
|
|
1294
|
+
* is worse than no number at all.
|
|
1295
|
+
*/
|
|
1296
|
+
declare const PRICE_NOTE: DrawingTool;
|
|
1297
|
+
/**
|
|
1298
|
+
* Table: rows of text in a grid, anchored top-left.
|
|
1299
|
+
*
|
|
1300
|
+
* Cells come from the text: a newline starts a row and a pipe separates
|
|
1301
|
+
* columns, so a whole table is one editable string and survives `getState`
|
|
1302
|
+
* with no new shape in the drawing model. The first row is drawn as a header
|
|
1303
|
+
* because a table on a chart is nearly always labelled.
|
|
1304
|
+
*/
|
|
1305
|
+
declare const TABLE: DrawingTool;
|
|
1306
|
+
/**
|
|
1307
|
+
* Measurers. `measure` reports price *and* time together; these two constrain it
|
|
1308
|
+
* to one axis, which is what you want when the other one is noise: sizing a
|
|
1309
|
+
* retracement without caring how long it took, or counting bars to an event
|
|
1310
|
+
* without caring where price went.
|
|
1311
|
+
*/
|
|
1312
|
+
declare const PRICE_RANGE: DrawingTool;
|
|
1313
|
+
declare const DATE_RANGE: DrawingTool;
|
|
1314
|
+
/**
|
|
1315
|
+
* Position forecast: project a move from an anchor. Two anchors give the
|
|
1316
|
+
* projected leg; the shape extends the same slope past the target as a dashed
|
|
1317
|
+
* cone, so the drawing says "if this continues" rather than just marking a line.
|
|
1318
|
+
*/
|
|
1319
|
+
declare const FORECAST: DrawingTool;
|
|
1320
|
+
/**
|
|
1321
|
+
* Circle from centre + a radius handle. The radius is measured in *pixels*, so
|
|
1322
|
+
* it stays a circle on screen instead of the ellipse the two axes' differing
|
|
1323
|
+
* scales would otherwise produce.
|
|
1324
|
+
*/
|
|
1325
|
+
declare const CIRCLE: DrawingTool;
|
|
1326
|
+
declare const TRIANGLE: DrawingTool;
|
|
1327
|
+
/** Free-form polyline: click each vertex, double-click to finish. */
|
|
1328
|
+
declare const POLYLINE: DrawingTool;
|
|
1329
|
+
/** Arc through three anchors: the middle one is on the curve, not a handle. */
|
|
1330
|
+
declare const ARC: DrawingTool;
|
|
1331
|
+
/** Quadratic curve: the middle anchor is a control handle, off the curve. */
|
|
1332
|
+
declare const CURVE: DrawingTool;
|
|
1333
|
+
declare const ARROW_UP: DrawingTool;
|
|
1334
|
+
declare const ARROW_DOWN: DrawingTool;
|
|
1335
|
+
declare const ARROW_LEFT: DrawingTool;
|
|
1336
|
+
declare const ARROW_RIGHT: DrawingTool;
|
|
1337
|
+
/** Highlighter: the brush with a fat, translucent stroke. */
|
|
1338
|
+
declare const HIGHLIGHTER: DrawingTool;
|
|
1339
|
+
/** Fib channel: fib levels spread across a trend leg, parallel to it. */
|
|
1340
|
+
declare const FIB_CHANNEL: DrawingTool;
|
|
1341
|
+
/**
|
|
1342
|
+
* Fib time zone: vertical lines at Fibonacci multiples of the base leg's width.
|
|
1343
|
+
* Its levels count bars rather than divide a leg, so they carry no convention
|
|
1344
|
+
* colour and fall back to the drawing's own.
|
|
1345
|
+
*/
|
|
1346
|
+
declare const FIB_TIME_ZONE: DrawingTool;
|
|
1347
|
+
/** Rays from the anchor at fib fractions of the leg: the speed resistance fan. */
|
|
1348
|
+
declare const FIB_FAN: DrawingTool;
|
|
1349
|
+
/**
|
|
1350
|
+
* Gann fan: rays from one anchor at the classic price/time angles. A level's
|
|
1351
|
+
* ratio is price per unit of time, so the 1x1 is 1, the 1x2 is 0.5 and the
|
|
1352
|
+
* 2x1 is 2; each angle keeps its own colour from the cycle palette.
|
|
1353
|
+
*/
|
|
1354
|
+
declare const GANN_FAN: DrawingTool;
|
|
1355
|
+
/**
|
|
1356
|
+
* Gann box: the drawn rectangle divided at its levels on both axes, plus the
|
|
1357
|
+
* 1x1 diagonal. Ratio 0 is the first anchor's price and time, ratio 1 the
|
|
1358
|
+
* second's, so the box reads like a retracement laid over a date range.
|
|
1359
|
+
*/
|
|
1360
|
+
declare const GANN_BOX: DrawingTool;
|
|
1361
|
+
declare const BUILTIN_DRAWING_TOOLS: readonly DrawingTool[];
|
|
1362
|
+
/** Register every built-in tool. Idempotent; called on tier import. */
|
|
1363
|
+
declare function registerBuiltinDrawingTools(): void;
|
|
1364
|
+
|
|
1365
|
+
/**
|
|
1366
|
+
* The shared level palette for the Fibonacci and Gann family.
|
|
1367
|
+
*
|
|
1368
|
+
* Every ladder tool (retracement, extension, channel, fan, time zone, the Gann
|
|
1369
|
+
* fan and box) strokes a list of ratios, and each ratio has a colour the eye
|
|
1370
|
+
* expects: 0.618 reads as one thing across every tool, not a different hue per
|
|
1371
|
+
* tool. Before this module each tool would have restated those colours, and
|
|
1372
|
+
* restated colours drift. This is the one statement; tools take their defaults
|
|
1373
|
+
* from it and hosts seed a newly added level from it.
|
|
1374
|
+
*
|
|
1375
|
+
* Pure: no DOM, no registry. Safe to import from a worker or a settings panel.
|
|
1376
|
+
*/
|
|
1377
|
+
|
|
1378
|
+
/**
|
|
1379
|
+
* The colour of a ratio that is an anchor rather than a level (0, 1, 2, 3 are
|
|
1380
|
+
* where the measured leg starts and ends, or whole multiples of it) and of any
|
|
1381
|
+
* ratio the convention does not name. Neutral on purpose: it is the reference
|
|
1382
|
+
* the coloured levels are read against.
|
|
1383
|
+
*/
|
|
1384
|
+
declare const LEVEL_NEUTRAL = "#787b86";
|
|
1385
|
+
/**
|
|
1386
|
+
* The conventional colour for a Fibonacci ratio. Anchors (0, 1, 2, 3) and any
|
|
1387
|
+
* ratio without a convention come back {@link LEVEL_NEUTRAL}, so a host can call
|
|
1388
|
+
* this for every new level and always get a usable colour.
|
|
1389
|
+
*/
|
|
1390
|
+
declare function levelColor(ratio: number): string;
|
|
1391
|
+
/**
|
|
1392
|
+
* A short sequence of colours that stay distinguishable side by side, for
|
|
1393
|
+
* tools whose levels are positions rather than ratios: the angles of a Gann
|
|
1394
|
+
* fan, the repeats of a cycle. Index `i` wraps, so any count is safe.
|
|
1395
|
+
*/
|
|
1396
|
+
declare const CYCLE_PALETTE: readonly string[];
|
|
1397
|
+
/** The `i`th cycle colour. Wraps in both directions; a negative index is fine. */
|
|
1398
|
+
declare function cycleColor(i: number): string;
|
|
1399
|
+
/** `0.618` as `61.8%`: the text a level prints when it carries no label. */
|
|
1400
|
+
declare function formatRatio(ratio: number): string;
|
|
1401
|
+
/**
|
|
1402
|
+
* The label for a Gann angle stored as a price-per-time ratio: `1` is the 1x1,
|
|
1403
|
+
* `0.5` the 1x2, `2` the 2x1. Ratios that are not clean reciprocals fall back
|
|
1404
|
+
* to the ratio itself, which is still true, just less idiomatic.
|
|
1405
|
+
*/
|
|
1406
|
+
declare function gannLabel(ratio: number): string;
|
|
1407
|
+
/** A mutable copy of a default ladder, for a fresh drawing's own `style.levels`. */
|
|
1408
|
+
declare function cloneLevels(levels: readonly FibLevel[]): FibLevel[];
|
|
1409
|
+
/** Retracement and extension: the classic ladder, coloured by convention. */
|
|
1410
|
+
declare const DEFAULT_FIB: readonly FibLevel[];
|
|
1411
|
+
/** Speed fan: rays at the fractions of the leg. No 0 ray, it would be flat. */
|
|
1412
|
+
declare const DEFAULT_FIB_FAN: readonly FibLevel[];
|
|
1413
|
+
/** Gann box: quarters plus the golden pair, applied to both axes of the box. */
|
|
1414
|
+
declare const DEFAULT_GANN_BOX: readonly FibLevel[];
|
|
1415
|
+
/**
|
|
1416
|
+
* Gann fan: the classic angles as price-per-time ratios, 1x8 up to 8x1. These
|
|
1417
|
+
* are positions in a sequence rather than Fibonacci ratios, so they take the
|
|
1418
|
+
* cycle palette.
|
|
1419
|
+
*/
|
|
1420
|
+
declare const DEFAULT_GANN_FAN: readonly FibLevel[];
|
|
1421
|
+
/**
|
|
1422
|
+
* Time zones count bars along the Fibonacci sequence, so `ratio` here is a
|
|
1423
|
+
* multiple of the anchor leg, not a fraction of it. No colour is set: there is
|
|
1424
|
+
* no convention for "the 13 line", so every zone takes the drawing's own colour
|
|
1425
|
+
* until the user gives one its own.
|
|
1426
|
+
*/
|
|
1427
|
+
declare const DEFAULT_FIB_TIME_ZONE: readonly FibLevel[];
|
|
1428
|
+
|
|
1429
|
+
/**
|
|
1430
|
+
* Glyphs for the drawing tools and for host chrome, as path data.
|
|
1431
|
+
*
|
|
1432
|
+
* The engine ships no DOM, and this does not change that: an icon here is a
|
|
1433
|
+
* string of SVG path commands, not an element. The host still builds its own
|
|
1434
|
+
* toolbar, flyouts and rail; what it no longer has to do is draw every glyph
|
|
1435
|
+
* before it can show them. `icon-svg.ts` turns these into markup strings for a
|
|
1436
|
+
* host that wants the convenience; this file is the single source both of them
|
|
1437
|
+
* and every other surface read from.
|
|
1438
|
+
*
|
|
1439
|
+
* That was the real cost of leaving them out. Every adopter drew their own set,
|
|
1440
|
+
* each drifted on stroke weight, grid and visual density independently, and the
|
|
1441
|
+
* result read as sixty icons rather than as one set, however carefully any
|
|
1442
|
+
* single glyph was made. A shipped set is worth more than a better glyph.
|
|
1443
|
+
*
|
|
1444
|
+
* # Two tiers, one weight
|
|
1445
|
+
*
|
|
1446
|
+
* Tool glyphs live on a 24-unit grid and are shown at 24px in the rail. Host
|
|
1447
|
+
* chrome (undo, close, the settings tab rail) is shown at 16px beside them, and
|
|
1448
|
+
* a 24-grid glyph scaled to 16 lands its 2-unit stroke on 1.33 pixels, blurred
|
|
1449
|
+
* across two rows on every edge. So chrome has its own registry drawn on a
|
|
1450
|
+
* 16-unit grid with a 1.5 stroke. The two strokes are deliberately not in exact
|
|
1451
|
+
* proportion: a small glyph needs a slightly heavier relative stroke than a
|
|
1452
|
+
* large one to read as the same weight, and `tests/draw-icons.test.ts` holds
|
|
1453
|
+
* the chrome tier inside that band rather than at parity.
|
|
1454
|
+
*
|
|
1455
|
+
* # The grid
|
|
1456
|
+
*
|
|
1457
|
+
* Every glyph is authored to the same constraints, and `tests/draw-icons.test.ts`
|
|
1458
|
+
* enforces all of them mechanically, because a set of this size cannot be kept
|
|
1459
|
+
* consistent by review:
|
|
1460
|
+
*
|
|
1461
|
+
* - **One viewBox per tier.** 24 by 24 for tools, 16 by 16 for chrome, so a
|
|
1462
|
+
* host sets the size once per surface.
|
|
1463
|
+
* - **A margin all round.** Live area 2 to 22 on the tool grid, 1 to 15 on the
|
|
1464
|
+
* chrome grid. Without it, glyphs that happen to reach the edge look larger
|
|
1465
|
+
* than their neighbours and the rail reads as ragged.
|
|
1466
|
+
* - **Integer coordinates.** With `STROKE` of 2, an orthogonal edge centred on
|
|
1467
|
+
* an integer covers exactly two device pixels at 1:1, which is what makes it
|
|
1468
|
+
* crisp. Half-unit coordinates were the previous set's crispness bug: at a
|
|
1469
|
+
* 1.5 stroke on integers, nothing landed on a pixel boundary at any size.
|
|
1470
|
+
* - **One stroke weight per tier.** Three different weights across identically
|
|
1471
|
+
* sized boxes is the single most visible tell of a set assembled rather than
|
|
1472
|
+
* drawn.
|
|
1473
|
+
*
|
|
1474
|
+
* # Rendering
|
|
1475
|
+
*
|
|
1476
|
+
* Tool glyphs are crispest at 24px, and at any integer multiple of it. At 18px
|
|
1477
|
+
* the 0.75 scale puts a 2-unit stroke on 1.5 device pixels and every edge is
|
|
1478
|
+
* anti-aliased across two rows: that is a host sizing choice, not something the
|
|
1479
|
+
* path data can fix. Prefer 24, or 12 with a heavier weight. Chrome glyphs are
|
|
1480
|
+
* drawn for 16px and its multiples.
|
|
1481
|
+
*/
|
|
1482
|
+
/** The viewBox every glyph is authored in. */
|
|
1483
|
+
declare const ICON_VIEWBOX = "0 0 24 24";
|
|
1484
|
+
/**
|
|
1485
|
+
* Stroke width in viewBox units. Paths carry no presentation attributes, so a
|
|
1486
|
+
* host that wants a lighter set overrides this once rather than editing glyphs.
|
|
1487
|
+
*/
|
|
1488
|
+
declare const ICON_STROKE = 2;
|
|
1489
|
+
/**
|
|
1490
|
+
* The attribute bag a tier hands its host. Structural, so the markup builders
|
|
1491
|
+
* in `icon-svg.ts` take either tier's bag through one signature.
|
|
1492
|
+
*/
|
|
1493
|
+
interface IconAttrs {
|
|
1494
|
+
readonly viewBox: string;
|
|
1495
|
+
readonly fill: 'none';
|
|
1496
|
+
readonly stroke: 'currentColor';
|
|
1497
|
+
readonly strokeWidth: number;
|
|
1498
|
+
readonly strokeLinecap: 'round';
|
|
1499
|
+
readonly strokeLinejoin: 'round';
|
|
1500
|
+
}
|
|
1501
|
+
/** Attributes a host should apply to the `<svg>`, so every set matches. */
|
|
1502
|
+
declare const ICON_ATTRS: {
|
|
1503
|
+
readonly viewBox: "0 0 24 24";
|
|
1504
|
+
readonly fill: "none";
|
|
1505
|
+
readonly stroke: "currentColor";
|
|
1506
|
+
readonly strokeWidth: 2;
|
|
1507
|
+
readonly strokeLinecap: "round";
|
|
1508
|
+
readonly strokeLinejoin: "round";
|
|
1509
|
+
};
|
|
1510
|
+
/**
|
|
1511
|
+
* Path data by tool id, plus a few keys a host toolbar needs that are not
|
|
1512
|
+
* themselves tools (`cursor`, the group headers).
|
|
1513
|
+
*
|
|
1514
|
+
* Values are the `d` attribute of one `<path>`. Multiple subpaths are joined
|
|
1515
|
+
* into the same string rather than split across elements, so a host renders one
|
|
1516
|
+
* node per glyph.
|
|
1517
|
+
*/
|
|
1518
|
+
declare const DRAWING_TOOL_ICONS: Readonly<Record<string, string>>;
|
|
1519
|
+
/**
|
|
1520
|
+
* The glyph for a tool, or `undefined` when it has none.
|
|
1521
|
+
*
|
|
1522
|
+
* Undefined rather than a placeholder: a host that renders an empty box has a
|
|
1523
|
+
* visible gap to fix, while one handed a question mark ships it.
|
|
1524
|
+
*/
|
|
1525
|
+
declare function drawingToolIcon(toolId: string): string | undefined;
|
|
1526
|
+
/** Every id this set covers, for a host building a palette from it. */
|
|
1527
|
+
declare function drawingToolIconIds(): string[];
|
|
1528
|
+
/** The viewBox every chrome glyph is authored in. */
|
|
1529
|
+
declare const CHROME_ICON_VIEWBOX = "0 0 16 16";
|
|
1530
|
+
/**
|
|
1531
|
+
* Chrome stroke width in viewBox units. Not the tool stroke scaled (that would
|
|
1532
|
+
* be 1.33): at 16px a glyph needs a touch more relative weight than at 24px to
|
|
1533
|
+
* read as the same line, and 1.5 is where the two rails match by eye.
|
|
1534
|
+
*/
|
|
1535
|
+
declare const CHROME_ICON_STROKE = 1.5;
|
|
1536
|
+
/** Attributes a host should apply to the `<svg>` around a chrome glyph. */
|
|
1537
|
+
declare const CHROME_ICON_ATTRS: {
|
|
1538
|
+
readonly viewBox: "0 0 16 16";
|
|
1539
|
+
readonly fill: "none";
|
|
1540
|
+
readonly stroke: "currentColor";
|
|
1541
|
+
readonly strokeWidth: 1.5;
|
|
1542
|
+
readonly strokeLinecap: "round";
|
|
1543
|
+
readonly strokeLinejoin: "round";
|
|
1544
|
+
};
|
|
1545
|
+
/**
|
|
1546
|
+
* Path data for host chrome: the buttons around the chart rather than the
|
|
1547
|
+
* tools in it. Same rules as the tool tier (one path per glyph, no presentation
|
|
1548
|
+
* attributes, integer coordinates) on the 16 grid with a 1..15 live area.
|
|
1549
|
+
*
|
|
1550
|
+
* The pair `cursor` / `magnet` / `text` also exist in the tool registry, at 24.
|
|
1551
|
+
* They are drawn twice on purpose: a rail button and a toolbar button are
|
|
1552
|
+
* different sizes, and the whole point of a second grid is not scaling one
|
|
1553
|
+
* drawing to both.
|
|
1554
|
+
*/
|
|
1555
|
+
declare const CHROME_ICONS: Readonly<Record<string, string>>;
|
|
1556
|
+
/**
|
|
1557
|
+
* Chrome glyphs meant to be painted solid. Paths carry no presentation
|
|
1558
|
+
* attributes, so the fill is applied by the wrapper (`chromeIconSvg` does it,
|
|
1559
|
+
* a host with its own wrapper reads this set) and the registry stays pure.
|
|
1560
|
+
*/
|
|
1561
|
+
declare const CHROME_ICON_FILLED: ReadonlySet<string>;
|
|
1562
|
+
/** The chrome glyph for an id, or `undefined` when there is none. */
|
|
1563
|
+
declare function chromeIcon(id: string): string | undefined;
|
|
1564
|
+
/** Every id the chrome tier covers. */
|
|
1565
|
+
declare function chromeIconIds(): string[];
|
|
1566
|
+
|
|
1567
|
+
/** Prefix of every `<symbol id>` in the sprite, and of every `<use href>`. */
|
|
1568
|
+
declare const ICON_SYMBOL_PREFIX = "oac-icon-";
|
|
1569
|
+
/** Options shared by the inline builders. */
|
|
1570
|
+
interface IconSvgOptions {
|
|
1571
|
+
/**
|
|
1572
|
+
* Width and height. A number is CSS pixels; a string is written verbatim, so
|
|
1573
|
+
* `'1em'` sizes the glyph with the surrounding text. Default: the grid's
|
|
1574
|
+
* native size (24 for tools, 16 for chrome), where the stroke is crispest.
|
|
1553
1575
|
*/
|
|
1554
|
-
|
|
1576
|
+
size?: number | string;
|
|
1577
|
+
/** Stroke width in viewBox units. Default: the tier's `*_STROKE`. */
|
|
1578
|
+
stroke?: number;
|
|
1579
|
+
/** A class for the host's own styling. */
|
|
1580
|
+
className?: string;
|
|
1581
|
+
}
|
|
1582
|
+
/** Options for `toolCursor`. */
|
|
1583
|
+
interface ToolCursorOptions {
|
|
1584
|
+
/** Cursor image size in CSS pixels. Default 20. Browsers reject images over 128. */
|
|
1585
|
+
size?: number;
|
|
1586
|
+
/** The pointer's active pixel, from the image's top-left. Default: the centre. */
|
|
1587
|
+
hotspot?: readonly [number, number];
|
|
1588
|
+
/** Glyph colour. Default white. */
|
|
1589
|
+
color?: string;
|
|
1555
1590
|
/**
|
|
1556
|
-
*
|
|
1557
|
-
*
|
|
1558
|
-
*
|
|
1559
|
-
* angle, so there is nothing to lock to in data space).
|
|
1591
|
+
* Halo colour. Default: black under a light `color`, white under a dark one,
|
|
1592
|
+
* judged from a hex colour. A non-hex `color` gets a black halo unless this
|
|
1593
|
+
* is set.
|
|
1560
1594
|
*/
|
|
1561
|
-
|
|
1595
|
+
halo?: string;
|
|
1596
|
+
/** The keyword after the image, for a browser that will not take it. Default `crosshair`. */
|
|
1597
|
+
fallback?: string;
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
* A complete inline `<svg>` for one tool glyph, stroked in `currentColor`.
|
|
1601
|
+
*
|
|
1602
|
+
* ```ts
|
|
1603
|
+
* button.innerHTML = iconSvg('trend-line');
|
|
1604
|
+
* button.innerHTML = iconSvg('trend-line', { size: '1em' });
|
|
1605
|
+
* ```
|
|
1606
|
+
*/
|
|
1607
|
+
declare function iconSvg(id: string, opts?: IconSvgOptions): string;
|
|
1608
|
+
/**
|
|
1609
|
+
* A complete inline `<svg>` for one chrome glyph, on the 16 grid. Glyphs in
|
|
1610
|
+
* `CHROME_ICON_FILLED` are painted solid as well as stroked.
|
|
1611
|
+
*/
|
|
1612
|
+
declare function chromeIconSvg(id: string, opts?: IconSvgOptions): string;
|
|
1613
|
+
/**
|
|
1614
|
+
* One hidden `<svg>` of `<symbol>`s, for a host that shows many glyphs and
|
|
1615
|
+
* wants each path in the document once. Inject it once, then place glyphs with
|
|
1616
|
+
* `iconUse`. Symbols carry the path and viewBox only; stroke and fill inherit
|
|
1617
|
+
* from the `<svg>` around each `<use>`, so one sprite serves every weight.
|
|
1618
|
+
*
|
|
1619
|
+
* Default: every tool glyph. Repeated ids collapse to one symbol, since a
|
|
1620
|
+
* duplicate element id is an invalid document.
|
|
1621
|
+
*/
|
|
1622
|
+
declare function iconSprite(ids?: readonly string[]): string;
|
|
1623
|
+
/** An `<svg>` that references a symbol from `iconSprite`. Same frame as `iconSvg`. */
|
|
1624
|
+
declare function iconUse(id: string, opts?: IconSvgOptions): string;
|
|
1625
|
+
/**
|
|
1626
|
+
* A CSS `cursor` value carrying the tool's glyph, for the canvas while that
|
|
1627
|
+
* tool is armed.
|
|
1628
|
+
*
|
|
1629
|
+
* The glyph is drawn twice: once in `halo`, one pixel wider on each side, and
|
|
1630
|
+
* once in `color` on top, so it reads on a light chart and a dark one without
|
|
1631
|
+
* the host choosing per theme. The value is `url("data:image/svg+xml,...") x y,
|
|
1632
|
+
* fallback`, ready for `canvas.style.cursor`.
|
|
1633
|
+
*/
|
|
1634
|
+
declare function toolCursor(id: string, opts?: ToolCursorOptions): string;
|
|
1635
|
+
|
|
1636
|
+
/**
|
|
1637
|
+
* A `DrawingLayer` renders the drawings of one pane and answers the chart's
|
|
1638
|
+
* hit-test. Anchors live in `{ time, price }`, so the layer maps them through
|
|
1639
|
+
* the *fractional* index helpers: the gapless axis means an anchor can sit
|
|
1640
|
+
* between bars (inside a collapsed weekend) or past the last one (a forward
|
|
1641
|
+
* projection), and whole-index lookups have nothing to return there.
|
|
1642
|
+
*
|
|
1643
|
+
* Each pane carries **two** layers, one at z-order `bottom` for drawings with a
|
|
1644
|
+
* negative `zIndex` (under the series) and one at `top` for the rest. The top
|
|
1645
|
+
* one takes over handles and hit-testing for the pair through `setBelow`, so a
|
|
1646
|
+
* shape parked under the candles still shows its grab handles above them and
|
|
1647
|
+
* a click lands on whatever the eye sees on top.
|
|
1648
|
+
*
|
|
1649
|
+
* Hit ids are `draw:<id>` for the body and `draw:<id>#<n>` for anchor `n`, so
|
|
1650
|
+
* the controller can tell "move the whole shape" from "move this handle".
|
|
1651
|
+
*
|
|
1652
|
+
* The hover ring, the magnet ring and the hover handles are all overlay
|
|
1653
|
+
* state: they change on every pointer move, so they must only ever cost the
|
|
1654
|
+
* top canvas. The layer that paints them is the one whose `requestUpdate`
|
|
1655
|
+
* the chart maps to the cursor tier, which is why the bottom layer of a pair
|
|
1656
|
+
* stores that state and asks for nothing.
|
|
1657
|
+
*/
|
|
1658
|
+
|
|
1659
|
+
/** Which side of the series a layer paints on. */
|
|
1660
|
+
type DrawingLayerOrder = 'bottom' | 'top';
|
|
1661
|
+
/** The pointer kinds the layer sizes its targets for. */
|
|
1662
|
+
type DrawingPointerKind = 'mouse' | 'touch' | 'pen';
|
|
1663
|
+
/**
|
|
1664
|
+
* Paint order: by `zIndex`, ties by array position. `Array.prototype.sort` is
|
|
1665
|
+
* stable, which is what makes the tie rule hold without a second key.
|
|
1666
|
+
*/
|
|
1667
|
+
declare function sortByZIndex(drawings: readonly Drawing[]): Drawing[];
|
|
1668
|
+
declare class DrawingLayer implements IPrimitive {
|
|
1669
|
+
private readonly _order;
|
|
1670
|
+
/** In paint order. */
|
|
1671
|
+
private _drawings;
|
|
1672
|
+
private _host;
|
|
1673
|
+
private _selected;
|
|
1674
|
+
/** The drawing under the pointer, whether or not it is selected. */
|
|
1675
|
+
private _hovered;
|
|
1676
|
+
/** Where the next click will land while the magnet is pulling it. */
|
|
1677
|
+
private _snap;
|
|
1678
|
+
/** Anchors of the in-progress drawing, plus the live cursor point. */
|
|
1679
|
+
private _preview;
|
|
1680
|
+
/** The layer under this one, whose handles and hits this layer answers for. */
|
|
1681
|
+
private _below;
|
|
1682
|
+
/** The layer that has taken over this one's handles and hit-testing. */
|
|
1683
|
+
private _above;
|
|
1684
|
+
/** Sizes grab targets for the device last seen. */
|
|
1685
|
+
private _touch;
|
|
1686
|
+
constructor(order?: DrawingLayerOrder);
|
|
1687
|
+
attached(host: PrimitiveHost): void;
|
|
1688
|
+
detached(): void;
|
|
1689
|
+
zOrder(): ZOrder;
|
|
1690
|
+
/** Drawings overlay the price range; they never drive it. */
|
|
1691
|
+
autoscaleInfo(): null;
|
|
1692
|
+
setDrawings(drawings: readonly Drawing[]): void;
|
|
1693
|
+
setSelected(ids: readonly string[]): void;
|
|
1562
1694
|
/**
|
|
1563
|
-
* The
|
|
1564
|
-
*
|
|
1565
|
-
*
|
|
1566
|
-
*
|
|
1695
|
+
* The drawing under the pointer. Its handles paint at a lighter weight than
|
|
1696
|
+
* a selection's, as the hint that it can be grabbed. Repaints only from the
|
|
1697
|
+
* layer that paints handles: the adopted bottom layer keeps the id for its
|
|
1698
|
+
* own bookkeeping and asks for nothing, since its repaint costs the series.
|
|
1567
1699
|
*/
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
/** Apply one drag frame to the model, from the gesture's snapshot. */
|
|
1571
|
-
private _moveDrag;
|
|
1572
|
-
/** How far down the screen `to` is from `from` on one pane, in media px. */
|
|
1573
|
-
private _pixelDelta;
|
|
1574
|
-
/** An anchor in container media px, or null on a host without the mapping. */
|
|
1575
|
-
private _toPixel;
|
|
1576
|
-
/** The inverse of `_toPixel`. */
|
|
1577
|
-
private _fromPixel;
|
|
1700
|
+
setHovered(id: string | null): void;
|
|
1701
|
+
hovered(): string | null;
|
|
1578
1702
|
/**
|
|
1579
|
-
*
|
|
1580
|
-
*
|
|
1581
|
-
*
|
|
1582
|
-
* projection rather than a rotation, so a level line still ends under the
|
|
1583
|
-
* pointer's x and a vertical one under its y; only the stray axis is
|
|
1584
|
-
* dropped. Null when the host cannot map pixels, or the two coincide.
|
|
1703
|
+
* The point the magnet will snap the next click to, or null when it is not
|
|
1704
|
+
* pulling. Painted as a hollow ring so the user sees the anchor land before
|
|
1705
|
+
* committing to it.
|
|
1585
1706
|
*/
|
|
1586
|
-
|
|
1587
|
-
|
|
1707
|
+
setSnapPoint(point: DrawingPoint | null): void;
|
|
1708
|
+
snapPoint(): DrawingPoint | null;
|
|
1588
1709
|
/**
|
|
1589
|
-
*
|
|
1590
|
-
*
|
|
1591
|
-
*
|
|
1710
|
+
* Size the grab targets for the device in use. Touch doubles the radii; a
|
|
1711
|
+
* mouse or a pen keeps the desktop sizes. The render context may carry the
|
|
1712
|
+
* same fact (`pointerType`), and when it does that wins per call, so a
|
|
1713
|
+
* first touch on a fresh chart is already sized right.
|
|
1592
1714
|
*/
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
private _onTop;
|
|
1596
|
-
/** Push the current list into each pane's layers and into the chart state. */
|
|
1597
|
-
private _sync;
|
|
1715
|
+
setPointerType(kind: DrawingPointerKind | null | undefined): void;
|
|
1716
|
+
setPreview(drawing: Drawing | null): void;
|
|
1598
1717
|
/**
|
|
1599
|
-
*
|
|
1600
|
-
*
|
|
1601
|
-
*
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1604
|
-
* nothing.
|
|
1718
|
+
* Adopt the layer under this one. From then on this layer paints the handles
|
|
1719
|
+
* of both and answers `hitTest` for both, and the adopted layer paints bodies
|
|
1720
|
+
* only. Handles have to live up here: a selected drawing under the series
|
|
1721
|
+
* would otherwise have its handles buried under the candles, and a handle
|
|
1722
|
+
* you cannot see is a handle you cannot grab. Pass null to release.
|
|
1605
1723
|
*/
|
|
1606
|
-
|
|
1724
|
+
setBelow(layer: DrawingLayer | null): void;
|
|
1725
|
+
/** Repaint for overlay-only state, from the layer that paints it. */
|
|
1726
|
+
private _requestOverlay;
|
|
1727
|
+
/** Whether targets are sized for a fingertip on this call. */
|
|
1728
|
+
private _isTouch;
|
|
1729
|
+
private _grabRadius;
|
|
1730
|
+
private _handleRadius;
|
|
1731
|
+
/** Map an anchor to media px on this pane. */
|
|
1732
|
+
private _project;
|
|
1733
|
+
private _points;
|
|
1734
|
+
/** Selected, unlocked drawings of this layer, in paint order. */
|
|
1735
|
+
private _handled;
|
|
1607
1736
|
/**
|
|
1608
|
-
*
|
|
1609
|
-
*
|
|
1610
|
-
* preview shows the locked angle or the snapped anchor before it lands.
|
|
1737
|
+
* The hovered drawing of this layer, when it is one that could be grabbed
|
|
1738
|
+
* and is not already showing selection handles.
|
|
1611
1739
|
*/
|
|
1612
|
-
private
|
|
1740
|
+
private _hoverHandled;
|
|
1741
|
+
draw(ctx: CanvasRenderingContext2D, rc: PrimitiveRenderContext): void;
|
|
1742
|
+
private _drawingContext;
|
|
1743
|
+
private _drawContent;
|
|
1744
|
+
private _drawPlacementGuide;
|
|
1613
1745
|
/**
|
|
1614
|
-
*
|
|
1615
|
-
*
|
|
1616
|
-
* inks where the pointer is), and the pull actually applying at the cursor.
|
|
1617
|
-
* Angle lock bypasses the magnet, so it hides the ring too.
|
|
1746
|
+
* Anchor handles. A hover shows them light (thin, translucent) as a hint
|
|
1747
|
+
* that the shape can be grabbed; a selection shows them at full weight.
|
|
1618
1748
|
*/
|
|
1619
|
-
private
|
|
1620
|
-
|
|
1749
|
+
private _drawHandles;
|
|
1750
|
+
/** The magnet ring: hollow, in the axis text colour, at the snap point. */
|
|
1751
|
+
private _drawSnapRing;
|
|
1752
|
+
hitTest(x: number, y: number, rc: PrimitiveRenderContext): PrimitiveHit | null;
|
|
1753
|
+
private _hitHandle;
|
|
1754
|
+
private _hitBody;
|
|
1621
1755
|
}
|
|
1622
1756
|
|
|
1623
1757
|
/**
|
|
@@ -1825,4 +1959,4 @@ declare const PATTERN_DRAWING_TOOLS: readonly DrawingTool[];
|
|
|
1825
1959
|
|
|
1826
1960
|
declare const DRAW_TIER: "draw";
|
|
1827
1961
|
|
|
1828
|
-
export { ADVANCED_GEOMETRY_TOOLS, ADVANCED_LINE_TOOLS, ALIGN_OPTIONS, ARC, ARROW, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, BALLOON, BRUSH, BUILTIN_DRAWING_TOOLS, CALLOUT, CHROME_ICONS, CHROME_ICON_ATTRS, CHROME_ICON_FILLED, CHROME_ICON_STROKE, CHROME_ICON_VIEWBOX, CIRCLE, COLOR_FIELD, COMMENT, CROSS_LINE, CURVE, CYCLE_PALETTE, CYCLIC_LINES, type ClipboardPort, DATE_RANGE, DEFAULT_FIB, DEFAULT_FIB_FAN, DEFAULT_FIB_TIME_ZONE, DEFAULT_GANN_BOX, DEFAULT_GANN_FAN, DOUBLE_CURVE, DRAWING_CLIPBOARD_KEY, DRAWING_CLIPBOARD_VERSION, DRAWING_STATE_VERSION, DRAWING_TOOL_ICONS, DRAW_TIER, type DrawContext, type Drawing, type DrawingChangeKind, type DrawingChartHost, DrawingClipboard, type DrawingClipboardOptions, DrawingController, type DrawingControllerOptions, type DrawingInput, type DrawingKeyAction, type DrawingKeyContext, type DrawingKeyEvent, DrawingLayer, type DrawingLayerOrder, type DrawingPatch, type DrawingPoint, type DrawingPointerKind, type DrawingStyle, type DrawingText, type DrawingTool, type DrawingValueContext, type DrawingsDocument, ELLIPSE, EXTENDED_LINE, EXTEND_FIELDS, type ExpandContext, FIB_CHANNEL, FIB_EXTENSION, FIB_FAN, FIB_RETRACEMENT, FIB_TIME_ZONE, FILL_FIELDS, FLAG_MARK, FONT_FIELDS, FONT_OPTIONS, FORECAST, type FibLevel, type FieldGroup, type FieldKind, GANN_BOX, GANN_FAN, HIGHLIGHTER, HORIZONTAL_LINE, HORIZONTAL_RAY, type HitContext, ICON_ATTRS, ICON_STROKE, ICON_SYMBOL_PREFIX, ICON_VIEWBOX, type IconAttrs, type IconSvgOptions, LEVEL_FIELDS, LEVEL_NEUTRAL, LINE_FIELDS, LINE_STYLE_FIELD, LINE_STYLE_OPTIONS, LINE_WIDTH_FIELD, LONG_POSITION, MEASURE, type MagnetMode, NOTE, NUDGE_STEP_PX, NUDGE_STEP_SHIFT_PX, PARALLEL_CHANNEL, PATH, PATTERN_DRAWING_TOOLS, PLATE_TEXT_FIELDS, POLYLINE, PRICE_LABEL, PRICE_NOTE, PRICE_RANGE, RAY, RECTANGLE, ROTATED_RECTANGLE, SHAPE_TEXT_FIELDS, SHORT_POSITION, SHOW_LABELS_FIELD, SIGNPOST, SINE_LINE, type ScreenPoint, type SettingsField, type SettingsSchema, type ShortcutEvent, TABLE, TEXT, TEXT_FIELDS, TEXT_POSITION_OPTIONS, TEXT_VALUE_FIELD, TIME_CYCLES, TREND_LINE, TRIANGLE, type ToolCursorOptions, VALIGN_OPTIONS, VERTICAL_LINE, applyDrawingSettings, boundsOf, catmullRom, chromeIcon, chromeIconIds, chromeIconSvg, clearMemoryClipboard, cloneDrawing, cloneLevels, coerceSettingValue, composeSettings, cycleColor, decodeClipboardPayload, distToEllipse, distToLine, distToPolyline, distToRect, distToSegment, drawingSettingsSchema, drawingShortcuts, drawingToolIcon, drawingToolIconIds, encodeClipboardPayload, extendSegment, formatRatio, gannLabel, getDrawingTool, hasDrawingTool, iconSprite, iconSvg, iconUse, keyToDrawingAction, levelColor, matchDrawingShortcut, migrateDrawings, pressureWidth, rdpSimplify, readDrawingSetting, readDrawingSettings, rectOf, registerBuiltinDrawingTools, registerDrawingTool, registeredDrawingTools, sanitizeDrawing, sortByZIndex, systemClipboard, toolCursor };
|
|
1962
|
+
export { ADVANCED_GEOMETRY_TOOLS, ADVANCED_LINE_TOOLS, ALIGN_OPTIONS, ANCHORED_VWAP, ARC, ARROW, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, type AnalysisProfileRow, type AnalysisStatus, type AnchoredVwapOptions, type AnchoredVwapPoint, type AnchoredVwapResult, type AnchoredVwapSource, BALLOON, BRUSH, BUILTIN_DRAWING_TOOLS, CALLOUT, CHROME_ICONS, CHROME_ICON_ATTRS, CHROME_ICON_FILLED, CHROME_ICON_STROKE, CHROME_ICON_VIEWBOX, CIRCLE, COLOR_FIELD, COMMENT, CROSS_LINE, CURVE, CYCLE_PALETTE, CYCLIC_LINES, type ClipboardPort, DATE_RANGE, DEFAULT_FIB, DEFAULT_FIB_FAN, DEFAULT_FIB_TIME_ZONE, DEFAULT_GANN_BOX, DEFAULT_GANN_FAN, DOUBLE_CURVE, DRAWING_CLIPBOARD_KEY, DRAWING_CLIPBOARD_VERSION, DRAWING_STATE_VERSION, DRAWING_TOOL_ICONS, DRAW_TIER, type DrawContext, type Drawing, type DrawingChangeKind, type DrawingChartHost, DrawingClipboard, type DrawingClipboardOptions, DrawingController, type DrawingControllerOptions, type DrawingInput, type DrawingKeyAction, type DrawingKeyContext, type DrawingKeyEvent, DrawingLayer, type DrawingLayerOrder, type DrawingLinkChart, type DrawingLinkContext, type DrawingLinkContextSource, DrawingLinkGroup, type DrawingLinkOptions, type DrawingPatch, type DrawingPoint, type DrawingPointerKind, type DrawingStyle, type DrawingText, type DrawingTool, type DrawingValueContext, type DrawingsDocument, ELLIPSE, EXTENDED_LINE, EXTEND_FIELDS, type ExpandContext, FIB_CHANNEL, FIB_EXTENSION, FIB_FAN, FIB_RETRACEMENT, FIB_TIME_ZONE, FILL_FIELDS, FIXED_RANGE_VOLUME_PROFILE, FLAG_MARK, FONT_FIELDS, FONT_OPTIONS, FORECAST, type FibLevel, type FieldGroup, type FieldKind, type FixedRangeVolumeProfileOptions, type FixedRangeVolumeProfileResult, GANN_BOX, GANN_FAN, HIGHLIGHTER, HORIZONTAL_LINE, HORIZONTAL_RAY, type HitContext, ICON_ATTRS, ICON_STROKE, ICON_SYMBOL_PREFIX, ICON_VIEWBOX, type IconAttrs, type IconSvgOptions, LEVEL_FIELDS, LEVEL_NEUTRAL, LINE_FIELDS, LINE_STYLE_FIELD, LINE_STYLE_OPTIONS, LINE_WIDTH_FIELD, LONG_POSITION, MEASURE, type MagnetMode, NOTE, NUDGE_STEP_PX, NUDGE_STEP_SHIFT_PX, PARALLEL_CHANNEL, PATH, PATTERN_DRAWING_TOOLS, PLATE_TEXT_FIELDS, POLYLINE, PRICE_LABEL, PRICE_NOTE, PRICE_RANGE, RAY, RECTANGLE, ROTATED_RECTANGLE, SHAPE_TEXT_FIELDS, SHORT_POSITION, SHOW_LABELS_FIELD, SIGNPOST, SINE_LINE, type ScreenPoint, type SettingsField, type SettingsSchema, type ShortcutEvent, TABLE, TEXT, TEXT_FIELDS, TEXT_POSITION_OPTIONS, TEXT_VALUE_FIELD, TIME_CYCLES, TREND_LINE, TRIANGLE, type ToolCursorOptions, VALIGN_OPTIONS, VERTICAL_LINE, anchoredVwapAnalysis, applyDrawingSettings, boundsOf, catmullRom, chromeIcon, chromeIconIds, chromeIconSvg, clearMemoryClipboard, cloneDrawing, cloneLevels, coerceSettingValue, composeSettings, createDrawingLinkGroup, cycleColor, decodeClipboardPayload, distToEllipse, distToLine, distToPolyline, distToRect, distToSegment, drawingSettingsSchema, drawingShortcuts, drawingToolIcon, drawingToolIconIds, encodeClipboardPayload, extendSegment, fixedRangeVolumeProfileAnalysis, formatRatio, gannLabel, getDrawingTool, hasDrawingTool, iconSprite, iconSvg, iconUse, keyToDrawingAction, levelColor, matchDrawingShortcut, migrateDrawings, pressureWidth, rdpSimplify, readDrawingSetting, readDrawingSettings, rectOf, registerBuiltinDrawingTools, registerDrawingTool, registeredDrawingTools, sanitizeDrawing, sortByZIndex, systemClipboard, toolCursor };
|