@funnest/charts 0.6.9 → 0.6.12
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/dist/chart.d.ts +10 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +80 -14
- package/dist/objects/drawings.d.ts +50 -1
- package/dist/objects/types.d.ts +8 -0
- package/dist/render/renderer.d.ts +2 -1
- package/package.json +1 -1
package/dist/chart.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { type Drawing, type DrawingDefinition, type DrawingType } from './object
|
|
|
6
6
|
import { type AlertLineOptions, type ExecutionMarker, type LineHandle, type OrderLineOptions, type PositionLineOptions, type TradingLabelOptions } from './objects/trading';
|
|
7
7
|
import { type ChartSettings, type ChartState } from './settings';
|
|
8
8
|
import { type TradingAdapter } from './objects/trading-sync';
|
|
9
|
+
import type { ChartOverlay } from './objects/types';
|
|
9
10
|
import { type ChartType, type CrosshairInfo, type PaneId } from './render/renderer';
|
|
10
11
|
import { type ThemeTokens } from './theme';
|
|
11
12
|
import type { Bar, ConnectionState, Datafeed, Quote, Resolution, SymbolInfo, TickSize } from './types';
|
|
@@ -166,6 +167,7 @@ export declare class Chart {
|
|
|
166
167
|
private readonly interaction;
|
|
167
168
|
private readonly cleanups;
|
|
168
169
|
private readonly drawings;
|
|
170
|
+
private readonly overlays;
|
|
169
171
|
private readonly trading;
|
|
170
172
|
private readonly tradingSync;
|
|
171
173
|
private tooltipKey;
|
|
@@ -411,6 +413,14 @@ export declare class Chart {
|
|
|
411
413
|
addOrderLine(options: OrderLineOptions): LineHandle<OrderLineOptions>;
|
|
412
414
|
/** Price alert line (dotted, gray, "알림" label). Pass `onMove` to make it draggable and `onCancel` for an ×. */
|
|
413
415
|
addAlertLine(options: AlertLineOptions): LineHandle<AlertLineOptions>;
|
|
416
|
+
/**
|
|
417
|
+
* Paints `overlay` on the price pane every frame (see ChartOverlay). `redraw()` asks for a
|
|
418
|
+
* new frame after its data changed; `remove()` takes it off.
|
|
419
|
+
*/
|
|
420
|
+
addOverlay(overlay: ChartOverlay): {
|
|
421
|
+
redraw(): void;
|
|
422
|
+
remove(): void;
|
|
423
|
+
};
|
|
414
424
|
/** Fill markers (▲ buy under the bar, ▼ sell above; ⚡ at the price for liquidations). Replaces the previous set. */
|
|
415
425
|
setExecutions(markers: readonly ExecutionMarker[]): void;
|
|
416
426
|
/** What position/order/alert line labels show and where (direction, price, size, P&L, ×, alignment, line width). */
|
package/dist/index.d.ts
CHANGED
|
@@ -13,9 +13,9 @@ export type { FormatPriceOptions } from './price';
|
|
|
13
13
|
export { decimalsOf, formatCompact, formatPrice, krxTickSize, resolveTickSize, roundToTick } from './price';
|
|
14
14
|
export { isIntradayResolution, resolutionToMs } from './resolution';
|
|
15
15
|
export type { ChartType } from './render/renderer';
|
|
16
|
-
export type { BuiltinDrawingType, Drawing, DrawingDefinition, DrawingGeometry, DrawingPoint, DrawingRenderContext, DrawingType, } from './objects/drawings';
|
|
16
|
+
export type { BuiltinDrawingType, Drawing, DrawingDefinition, DrawingGeometry, DrawingPoint, DrawingRenderContext, DrawingStyle, DrawingColorSlot, DrawingType, } from './objects/drawings';
|
|
17
17
|
export { BUILTIN_DRAWINGS, distToSegment, FIB_LEVELS } from './objects/drawings';
|
|
18
|
-
export type { PaneCoords } from './objects/types';
|
|
18
|
+
export type { ChartOverlay, ObjectRenderContext, PaneCoords } from './objects/types';
|
|
19
19
|
export type { Painter } from './render/painter';
|
|
20
20
|
export type { Palette } from './render/renderer';
|
|
21
21
|
export { snapToOhlc } from './objects/magnet';
|
package/dist/index.js
CHANGED
|
@@ -1221,6 +1221,7 @@ var IndicatorManager = class {
|
|
|
1221
1221
|
};
|
|
1222
1222
|
|
|
1223
1223
|
// src/objects/drawings.ts
|
|
1224
|
+
var DASHES = { solid: [], dashed: [6, 4], dotted: [1.5, 3] };
|
|
1224
1225
|
var FIB_LEVELS = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1];
|
|
1225
1226
|
var FIB_COLORS = ["#8B95A1", "#F04452", "#FF9F0A", "#12B886", "#3182F6", "#7048E8", "#8B95A1"];
|
|
1226
1227
|
var HANDLE_RADIUS = 5;
|
|
@@ -1240,7 +1241,7 @@ var BUILTIN_DRAWINGS = [
|
|
|
1240
1241
|
group: "line",
|
|
1241
1242
|
clicks: 2,
|
|
1242
1243
|
distance: (g, x, y) => distToSegment(x, y, ...p0(g), ...p1(g)),
|
|
1243
|
-
render: (_d, { painter, color, ...g }) => painter.line(...p0(g), ...p1(g), color, 2)
|
|
1244
|
+
render: (_d, { painter, color, ...g }) => painter.line(...p0(g), ...p1(g), color, g.width(2), g.dash())
|
|
1244
1245
|
},
|
|
1245
1246
|
{
|
|
1246
1247
|
type: "horizontal",
|
|
@@ -1252,7 +1253,9 @@ var BUILTIN_DRAWINGS = [
|
|
|
1252
1253
|
distance: (g, _x, y) => Math.abs(y - p0(g)[1]),
|
|
1253
1254
|
render: (d, { painter, color, coords, badge, ...g }) => {
|
|
1254
1255
|
const y = p0(g)[1];
|
|
1255
|
-
|
|
1256
|
+
const dash = g.dash();
|
|
1257
|
+
if (g.width(1) === 1 && !dash.length) painter.hLine(y, 0, coords.plotWidth, color);
|
|
1258
|
+
else painter.line(0, y, coords.plotWidth, y, color, g.width(1), dash);
|
|
1256
1259
|
badge(y, coords.formatPrice(d.points[0].price), color);
|
|
1257
1260
|
}
|
|
1258
1261
|
},
|
|
@@ -1262,6 +1265,7 @@ var BUILTIN_DRAWINGS = [
|
|
|
1262
1265
|
group: "fib",
|
|
1263
1266
|
section: { ko: "\uD53C\uBCF4\uB098\uCE58", en: "Fibonacci" },
|
|
1264
1267
|
clicks: 2,
|
|
1268
|
+
colors: FIB_LEVELS.map((level, i) => ({ key: String(level), name: { ko: String(level), en: String(level) }, color: FIB_COLORS[i] })),
|
|
1265
1269
|
distance: (g, x, y) => {
|
|
1266
1270
|
const [x1, y1] = p0(g);
|
|
1267
1271
|
const [x2, y2] = p1(g);
|
|
@@ -1282,7 +1286,7 @@ var BUILTIN_DRAWINGS = [
|
|
|
1282
1286
|
FIB_LEVELS.forEach((level, i) => {
|
|
1283
1287
|
const price = b + (a - b) * level;
|
|
1284
1288
|
const y = c.priceToY(price);
|
|
1285
|
-
const levelColor = d.color ?? FIB_COLORS[i];
|
|
1289
|
+
const levelColor = d.style?.colors?.[String(level)] ?? d.color ?? FIB_COLORS[i];
|
|
1286
1290
|
if (i > 0) {
|
|
1287
1291
|
const prevY = c.priceToY(b + (a - b) * FIB_LEVELS[i - 1]);
|
|
1288
1292
|
ctx.save();
|
|
@@ -1314,6 +1318,7 @@ var DrawingManager = class {
|
|
|
1314
1318
|
tool = null;
|
|
1315
1319
|
selectedId = null;
|
|
1316
1320
|
draft = null;
|
|
1321
|
+
freehandLast = null;
|
|
1317
1322
|
drag = null;
|
|
1318
1323
|
get selected() {
|
|
1319
1324
|
return this.drawings.find((d) => d.id === this.selectedId) ?? null;
|
|
@@ -1368,6 +1373,13 @@ var DrawingManager = class {
|
|
|
1368
1373
|
const def = this.tool ? this.registry.get(this.tool) : void 0;
|
|
1369
1374
|
if (!def) return;
|
|
1370
1375
|
const point = c.pointAt(x, y);
|
|
1376
|
+
if (def.freehand) {
|
|
1377
|
+
if (this.draft) return this.finish();
|
|
1378
|
+
this.draft = { drawing: { id: newId("d"), type: def.type, points: [point] }, placed: [point] };
|
|
1379
|
+
this.freehandLast = [x, y];
|
|
1380
|
+
this.onChange("preview");
|
|
1381
|
+
return;
|
|
1382
|
+
}
|
|
1371
1383
|
if (!this.draft) {
|
|
1372
1384
|
const placed = [point];
|
|
1373
1385
|
this.draft = { drawing: { id: newId("d"), type: def.type, points: this.expand(def, placed, c) }, placed };
|
|
@@ -1384,11 +1396,25 @@ var DrawingManager = class {
|
|
|
1384
1396
|
const draft = this.draft;
|
|
1385
1397
|
const def = draft && this.registry.get(draft.drawing.type);
|
|
1386
1398
|
if (!draft || !def) return;
|
|
1399
|
+
if (def.freehand) {
|
|
1400
|
+
const last = this.freehandLast;
|
|
1401
|
+
if (last && Math.hypot(x - last[0], y - last[1]) < 3) return;
|
|
1402
|
+
if (draft.drawing.points.length >= 4e3) return;
|
|
1403
|
+
this.freehandLast = [x, y];
|
|
1404
|
+
draft.drawing.points.push(c.pointAt(x, y));
|
|
1405
|
+
this.onChange("preview");
|
|
1406
|
+
return;
|
|
1407
|
+
}
|
|
1387
1408
|
draft.drawing.points = this.expand(def, [...draft.placed, c.pointAt(x, y)], c);
|
|
1388
1409
|
this.onChange("preview");
|
|
1389
1410
|
}
|
|
1390
1411
|
/** Pointer released: a drag since the first point places the next one (drag-to-draw). */
|
|
1391
1412
|
releaseAt(c, x, y, moved) {
|
|
1413
|
+
const def = this.draft && this.registry.get(this.draft.drawing.type);
|
|
1414
|
+
if (def?.freehand) {
|
|
1415
|
+
if (moved && this.draft.drawing.points.length > 1) this.finish();
|
|
1416
|
+
return;
|
|
1417
|
+
}
|
|
1392
1418
|
if (this.draft && moved) this.createAt(c, x, y);
|
|
1393
1419
|
}
|
|
1394
1420
|
finish() {
|
|
@@ -1407,7 +1433,7 @@ var DrawingManager = class {
|
|
|
1407
1433
|
handles(c, d) {
|
|
1408
1434
|
const def = this.registry.get(d.type);
|
|
1409
1435
|
const g = this.geometry(c, d);
|
|
1410
|
-
return def?.handles ? def.handles(g) : g.points;
|
|
1436
|
+
return def?.handles ? def.handles(g) : def?.freehand ? [] : g.points;
|
|
1411
1437
|
}
|
|
1412
1438
|
hitTest(c, x, y, tolerance) {
|
|
1413
1439
|
const selected = this.selected;
|
|
@@ -1426,6 +1452,7 @@ var DrawingManager = class {
|
|
|
1426
1452
|
const d = this.drawings.find((x2) => x2.id === id);
|
|
1427
1453
|
if (!d) return;
|
|
1428
1454
|
this.select(id);
|
|
1455
|
+
if (d.style?.locked) return;
|
|
1429
1456
|
this.drag = { id, part, x, y, origin: this.geometry(c, d).points };
|
|
1430
1457
|
}
|
|
1431
1458
|
dragTo(c, x, y) {
|
|
@@ -1448,21 +1475,33 @@ var DrawingManager = class {
|
|
|
1448
1475
|
this.drag = null;
|
|
1449
1476
|
}
|
|
1450
1477
|
// ── Rendering ─────────────────────────────────────────────────────
|
|
1451
|
-
render(rc, badges) {
|
|
1478
|
+
render(rc, badges, bars = [], barIndexAt = () => -1) {
|
|
1452
1479
|
const all = this.draft ? [...this.drawings, this.draft.drawing] : this.drawings;
|
|
1453
1480
|
const c = rc.coords;
|
|
1454
1481
|
for (const d of all) {
|
|
1455
1482
|
const def = this.registry.get(d.type);
|
|
1456
1483
|
if (!def) continue;
|
|
1457
1484
|
const color = d.color ?? rc.palette.accent;
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1485
|
+
const style = d.style ?? {};
|
|
1486
|
+
rc.painter.ctx.save();
|
|
1487
|
+
try {
|
|
1488
|
+
def.render(d, {
|
|
1489
|
+
...this.geometry(c, d),
|
|
1490
|
+
painter: rc.painter,
|
|
1491
|
+
palette: rc.palette,
|
|
1492
|
+
color,
|
|
1493
|
+
style,
|
|
1494
|
+
colorOf: (key) => style.colors?.[key] ?? d.color ?? def.colors?.find((c2) => c2.key === key)?.color ?? color,
|
|
1495
|
+
width: (fallback) => Math.min(8, Math.max(0.5, style.width ?? fallback)),
|
|
1496
|
+
dash: (fallback = []) => style.dash ? DASHES[style.dash] : [...fallback],
|
|
1497
|
+
bars,
|
|
1498
|
+
barIndexAt,
|
|
1499
|
+
badge: (y, text, bg, fg = "#FFFFFF") => badges.push({ y, text, bg, fg })
|
|
1500
|
+
});
|
|
1501
|
+
} finally {
|
|
1502
|
+
rc.painter.ctx.restore();
|
|
1503
|
+
}
|
|
1504
|
+
if (d.id === this.selectedId && !style.locked || d === this.draft?.drawing) {
|
|
1466
1505
|
for (const [px, py] of this.handles(c, d)) rc.painter.circle(px, py, HANDLE_RADIUS, rc.palette.background, color);
|
|
1467
1506
|
}
|
|
1468
1507
|
}
|
|
@@ -2409,8 +2448,17 @@ function drawMain(layer, m) {
|
|
|
2409
2448
|
ctx.clip();
|
|
2410
2449
|
const o = m.objects;
|
|
2411
2450
|
const rc = { painter: p, coords: o.coords, palette: pal };
|
|
2451
|
+
for (const overlay of o.overlays) {
|
|
2452
|
+
ctx.save();
|
|
2453
|
+
try {
|
|
2454
|
+
overlay.render(rc);
|
|
2455
|
+
} catch (error) {
|
|
2456
|
+
console.error("[fnc] overlay", error);
|
|
2457
|
+
}
|
|
2458
|
+
ctx.restore();
|
|
2459
|
+
}
|
|
2412
2460
|
o.trading.render(rc, m.bars, o.barIndexAt, (i) => m.timeScale.indexToX(i), o.tradingLabels, badges);
|
|
2413
|
-
o.drawings.render(rc, badges);
|
|
2461
|
+
o.drawings.render(rc, badges, m.bars, o.barIndexAt);
|
|
2414
2462
|
ctx.restore();
|
|
2415
2463
|
const last = f.settings.lastPriceLine ? m.bars[m.bars.length - 1] : void 0;
|
|
2416
2464
|
const lastColor = last && last.close >= last.open ? pal.up : pal.down;
|
|
@@ -2747,6 +2795,7 @@ var Chart = class {
|
|
|
2747
2795
|
interaction;
|
|
2748
2796
|
cleanups = [];
|
|
2749
2797
|
drawings;
|
|
2798
|
+
overlays = [];
|
|
2750
2799
|
trading;
|
|
2751
2800
|
tradingSync;
|
|
2752
2801
|
tooltipKey = null;
|
|
@@ -3723,6 +3772,22 @@ var Chart = class {
|
|
|
3723
3772
|
addAlertLine(options) {
|
|
3724
3773
|
return this.trading.addAlert(options);
|
|
3725
3774
|
}
|
|
3775
|
+
/**
|
|
3776
|
+
* Paints `overlay` on the price pane every frame (see ChartOverlay). `redraw()` asks for a
|
|
3777
|
+
* new frame after its data changed; `remove()` takes it off.
|
|
3778
|
+
*/
|
|
3779
|
+
addOverlay(overlay) {
|
|
3780
|
+
this.overlays.push(overlay);
|
|
3781
|
+
this.invalidate();
|
|
3782
|
+
return {
|
|
3783
|
+
redraw: () => this.invalidate(),
|
|
3784
|
+
remove: () => {
|
|
3785
|
+
const i = this.overlays.indexOf(overlay);
|
|
3786
|
+
if (i >= 0) this.overlays.splice(i, 1);
|
|
3787
|
+
this.invalidate();
|
|
3788
|
+
}
|
|
3789
|
+
};
|
|
3790
|
+
}
|
|
3726
3791
|
/** Fill markers (▲ buy under the bar, ▼ sell above; ⚡ at the price for liquidations). Replaces the previous set. */
|
|
3727
3792
|
setExecutions(markers) {
|
|
3728
3793
|
this.trading.setExecutions(markers);
|
|
@@ -3829,6 +3894,7 @@ var Chart = class {
|
|
|
3829
3894
|
replaySelecting: this.replaySelecting,
|
|
3830
3895
|
objects: {
|
|
3831
3896
|
coords: this.paneCoords(),
|
|
3897
|
+
overlays: this.overlays,
|
|
3832
3898
|
drawings: this.drawings,
|
|
3833
3899
|
trading: this.trading,
|
|
3834
3900
|
tradingLabels: TRADING_LABELS[this.locale],
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Bar } from '../types';
|
|
1
2
|
import type { Locale } from '../model/time-format';
|
|
2
3
|
import type { Painter } from '../render/painter';
|
|
3
4
|
import type { Palette } from '../render/renderer';
|
|
@@ -11,11 +12,37 @@ export interface DrawingPoint {
|
|
|
11
12
|
time: number;
|
|
12
13
|
price: number;
|
|
13
14
|
}
|
|
15
|
+
/** How a drawing looks beyond its color (all optional; tools read them through the render context). */
|
|
16
|
+
export interface DrawingStyle {
|
|
17
|
+
/** Main line width in CSS px (1–4). */
|
|
18
|
+
width?: number;
|
|
19
|
+
/** Main line pattern. */
|
|
20
|
+
dash?: 'solid' | 'dashed' | 'dotted';
|
|
21
|
+
/** Text tools (and notes on others): what it says. */
|
|
22
|
+
text?: string;
|
|
23
|
+
/** Text size in CSS px. */
|
|
24
|
+
fontSize?: number;
|
|
25
|
+
/** Can't be dragged or edited until unlocked (still selectable). */
|
|
26
|
+
locked?: boolean;
|
|
27
|
+
/** Colors of the tool's parts (`DrawingDefinition.colors` keys), where set apart from the rest. */
|
|
28
|
+
colors?: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A part of a tool with its own color (a Fibonacci level, a position's target zone…). Its color
|
|
32
|
+
* is `style.colors[key]`, else the drawing's color (picking one recolors every part), else `color`.
|
|
33
|
+
*/
|
|
34
|
+
export interface DrawingColorSlot {
|
|
35
|
+
key: string;
|
|
36
|
+
name: Record<Locale, string>;
|
|
37
|
+
/** Default color. */
|
|
38
|
+
color: string;
|
|
39
|
+
}
|
|
14
40
|
export interface Drawing {
|
|
15
41
|
id: string;
|
|
16
42
|
type: DrawingType;
|
|
17
43
|
points: DrawingPoint[];
|
|
18
44
|
color?: string;
|
|
45
|
+
style?: DrawingStyle;
|
|
19
46
|
}
|
|
20
47
|
/** What a drawing definition gets to measure and paint itself. Pixels are relative to the price pane. */
|
|
21
48
|
export interface DrawingGeometry {
|
|
@@ -28,6 +55,18 @@ export interface DrawingRenderContext extends DrawingGeometry {
|
|
|
28
55
|
palette: Palette;
|
|
29
56
|
/** `drawing.color`, or the theme accent. */
|
|
30
57
|
color: string;
|
|
58
|
+
/** `drawing.style` (empty object when none). */
|
|
59
|
+
style: DrawingStyle;
|
|
60
|
+
/** A part's color (see `DrawingDefinition.colors`): its own, else the drawing's, else the default. */
|
|
61
|
+
colorOf(key: string): string;
|
|
62
|
+
/** The main line width: the drawing's style, else the tool's default. */
|
|
63
|
+
width(fallback: number): number;
|
|
64
|
+
/** The main line dash pattern for canvas: the drawing's style, else the tool's default. */
|
|
65
|
+
dash(fallback?: readonly number[]): number[];
|
|
66
|
+
/** The chart's bars (oldest first), for tools that measure them (VWAP, volume profile…). */
|
|
67
|
+
bars: readonly Bar[];
|
|
68
|
+
/** Index of the last bar at or before `time` (-1 before the first). */
|
|
69
|
+
barIndexAt(time: number): number;
|
|
31
70
|
/** Adds a price-axis badge (drawn above the axis labels, clamped to the pane). */
|
|
32
71
|
badge(y: number, text: string, bg: string, fg?: string): void;
|
|
33
72
|
}
|
|
@@ -61,6 +100,15 @@ export interface DrawingDefinition {
|
|
|
61
100
|
constrain?(points: DrawingPoint[], index: number): DrawingPoint[];
|
|
62
101
|
/** Drag handle positions; dragging handle i moves point i. Default: the points. */
|
|
63
102
|
handles?(geometry: DrawingGeometry): [number, number][];
|
|
103
|
+
/**
|
|
104
|
+
* Drawn by dragging: every pointer move adds a point (a brush); releasing (or clicking again)
|
|
105
|
+
* finishes it. `clicks` is ignored.
|
|
106
|
+
*/
|
|
107
|
+
freehand?: boolean;
|
|
108
|
+
/** Has text (`style.text`): the widget offers a text field for it when selected. */
|
|
109
|
+
text?: boolean;
|
|
110
|
+
/** Parts with their own colors: the widget lets each be recolored (read them with `rc.colorOf`). */
|
|
111
|
+
colors?: DrawingColorSlot[];
|
|
64
112
|
/** Distance in px from (x, y) to the shape, for hit testing. */
|
|
65
113
|
distance(geometry: DrawingGeometry, x: number, y: number): number;
|
|
66
114
|
render(drawing: Drawing, rc: DrawingRenderContext): void;
|
|
@@ -84,6 +132,7 @@ export declare class DrawingManager {
|
|
|
84
132
|
tool: DrawingType | null;
|
|
85
133
|
selectedId: string | null;
|
|
86
134
|
private draft;
|
|
135
|
+
private freehandLast;
|
|
87
136
|
private drag;
|
|
88
137
|
constructor(onChange: (change: DrawingsChange) => void, registry?: Map<string, DrawingDefinition>);
|
|
89
138
|
get selected(): Drawing | null;
|
|
@@ -109,5 +158,5 @@ export declare class DrawingManager {
|
|
|
109
158
|
beginDrag(c: PaneCoords, id: string, part: 'body' | number, x: number, y: number): void;
|
|
110
159
|
dragTo(c: PaneCoords, x: number, y: number): void;
|
|
111
160
|
endDrag(moved: boolean): void;
|
|
112
|
-
render(rc: ObjectRenderContext, badges: AxisBadge[]): void;
|
|
161
|
+
render(rc: ObjectRenderContext, badges: AxisBadge[], bars?: readonly Bar[], barIndexAt?: (time: number) => number): void;
|
|
113
162
|
}
|
package/dist/objects/types.d.ts
CHANGED
|
@@ -22,6 +22,14 @@ export interface ObjectRenderContext {
|
|
|
22
22
|
coords: PaneCoords;
|
|
23
23
|
palette: Palette;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Something an app paints on the price pane every frame (a liquidation map, volume profile…),
|
|
27
|
+
* clipped to the pane, above the candles and indicators, under trading lines and drawings.
|
|
28
|
+
* Added with chart.addOverlay(); it reads its own data and the pane's coordinates.
|
|
29
|
+
*/
|
|
30
|
+
export interface ChartOverlay {
|
|
31
|
+
render(rc: ObjectRenderContext): void;
|
|
32
|
+
}
|
|
25
33
|
export type ObjectHit = {
|
|
26
34
|
kind: 'drawing';
|
|
27
35
|
id: string;
|
|
@@ -5,7 +5,7 @@ import type { Bar } from '../types';
|
|
|
5
5
|
import type { CanvasLayer } from './canvas-layer';
|
|
6
6
|
import type { DrawingManager } from '../objects/drawings';
|
|
7
7
|
import type { TradingLabels, TradingLayer } from '../objects/trading';
|
|
8
|
-
import type { PaneCoords } from '../objects/types';
|
|
8
|
+
import type { ChartOverlay, PaneCoords } from '../objects/types';
|
|
9
9
|
import type { IndicatorOutput } from '../indicators/definitions';
|
|
10
10
|
import type { ChartSettings } from '../settings';
|
|
11
11
|
export type ChartType = 'candles' | 'line' | 'area';
|
|
@@ -95,6 +95,7 @@ export interface RenderModel {
|
|
|
95
95
|
replaySelecting?: boolean;
|
|
96
96
|
objects: {
|
|
97
97
|
coords: PaneCoords;
|
|
98
|
+
overlays: readonly ChartOverlay[];
|
|
98
99
|
drawings: DrawingManager;
|
|
99
100
|
trading: TradingLayer;
|
|
100
101
|
tradingLabels: TradingLabels;
|