wick-charts 0.9.0 → 0.10.1
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 +80 -2
- package/dist/crosshairRenderer.d.ts +2 -2
- package/dist/crosshairRenderer.js +9 -4
- package/dist/index.d.ts +4 -4
- package/dist/renderer.js +35 -26
- package/dist/series/candlestick.d.ts +6 -1
- package/dist/series/candlestick.js +7 -0
- package/dist/series/types.d.ts +2 -2
- package/dist/types.d.ts +25 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -208,6 +208,8 @@ const chart = createCandlestickChart(canvas, {
|
|
|
208
208
|
},
|
|
209
209
|
crosshair: {
|
|
210
210
|
lineColor: '#9090904d',
|
|
211
|
+
lineWidth: 1,
|
|
212
|
+
lineDash: [4, 4], // [] for a solid line — same convention as ctx.setLineDash
|
|
211
213
|
labelBackground: '#3a3a3a',
|
|
212
214
|
labelTextColor: '#f0f0f0',
|
|
213
215
|
labelPaddingX: 4,
|
|
@@ -249,12 +251,18 @@ it per chart instance via `formatLegend`:
|
|
|
249
251
|
const chart = createCandlestickChart(canvas, {
|
|
250
252
|
formatLegend(candle, style, { index, allPoints }) {
|
|
251
253
|
const prev = allPoints[index - 1];
|
|
252
|
-
const change = prev ? ((
|
|
254
|
+
const change = prev ? ((candle.close - prev.close) / prev.close) * 100 : null;
|
|
253
255
|
return [
|
|
254
256
|
`시가 ${candle.open.toLocaleString()}`,
|
|
255
257
|
`고가 ${candle.high.toLocaleString()}`,
|
|
256
258
|
`저가 ${candle.low.toLocaleString()}`,
|
|
257
|
-
`종가 ${candle.close.toLocaleString()}
|
|
259
|
+
`종가 ${candle.close.toLocaleString()}`,
|
|
260
|
+
// A line can be a plain string (drawn in legend.textColor, like the
|
|
261
|
+
// four above) or { text, color } for one that needs its own color —
|
|
262
|
+
// see "Coloring individual legend lines" just below.
|
|
263
|
+
change === null
|
|
264
|
+
? '등락 —'
|
|
265
|
+
: { text: `등락 ${change >= 0 ? '+' : ''}${change.toFixed(2)}%`, color: change >= 0 ? '#22c55e' : '#ef4444' },
|
|
258
266
|
];
|
|
259
267
|
},
|
|
260
268
|
});
|
|
@@ -266,6 +274,20 @@ point currently loaded (not just visible), the same array a `ChartPlugin` reads
|
|
|
266
274
|
`PluginRenderApi.allPoints`; `index` is `candle`'s position in it, so `allPoints[index - 1]` is
|
|
267
275
|
the previous point regardless of where the user has panned/zoomed to.
|
|
268
276
|
|
|
277
|
+
#### Coloring individual legend lines
|
|
278
|
+
|
|
279
|
+
Every line returned by `formatLegend` is a `LegendLine` — either a plain `string`, drawn in
|
|
280
|
+
`legend.textColor` like every line before this existed, or `{ text, color }` for one line that
|
|
281
|
+
needs its own color independent of the rest (the `change` line above: green when positive, red
|
|
282
|
+
when negative, regardless of `legend.textColor`). Mixing both shapes in one returned array, as
|
|
283
|
+
above, is the normal case — only the lines that actually need a distinct color use the object
|
|
284
|
+
form. There's no chart-wide "green means up" setting for this: which color means "up" is a
|
|
285
|
+
convention that varies by market (green-up in most markets, red-up in South Korea and a few
|
|
286
|
+
others) and isn't something the library should hardcode, so `formatLegend` decides it per line
|
|
287
|
+
the same way it decides everything else about the legend's text. This is separate from
|
|
288
|
+
`CandlestickStyle.upColor`/`downColor`, which is the *candle's own* body/wick color, a
|
|
289
|
+
chart-wide setting rather than something recomputed per hovered point.
|
|
290
|
+
|
|
269
291
|
`SeriesDefinition.formatLegend` (what candlestick/line ship with) is a shared default for every
|
|
270
292
|
chart of that *type*; `WickChartOptions.formatLegend` is the per-*instance* override above it —
|
|
271
293
|
reach for the latter for anything that varies by app, session, or locale rather than by chart
|
|
@@ -592,6 +614,62 @@ the price pane — an indicator pane's own hover readout, if you want one, is so
|
|
|
592
614
|
plugin draws (it has the same `xForIndex`/`yForValue` a price-pane plugin does, just mapped
|
|
593
615
|
against that pane's own value domain and pixel rect).
|
|
594
616
|
|
|
617
|
+
### Splitting volume into its own pane
|
|
618
|
+
|
|
619
|
+
The candlestick series' default volume bars are a translucent backdrop *inside* the price
|
|
620
|
+
pane (`CandlestickStyle.volumeAreaHeightRatio`, `0.2` of the chart height by default) — fine
|
|
621
|
+
for a compact chart, but on a tall one, or whenever a candle's own range dips into that bottom
|
|
622
|
+
margin, the bars visually collide with the candles drawn over them. The same `addPane` +
|
|
623
|
+
`ChartPlugin.paneId` mechanism the previous section uses for RSI/MACD works just as well for
|
|
624
|
+
volume — it just reads `Candle.volume` instead of computing an indicator:
|
|
625
|
+
|
|
626
|
+
```ts
|
|
627
|
+
// PaneOptions.getValueRange takes no arguments, so — same as the MACD pane above needing its
|
|
628
|
+
// own auto-fit range — it closes over the chart's current data itself rather than reading it
|
|
629
|
+
// from an argument. `allData` is whatever you last passed to `chart.setData()`.
|
|
630
|
+
let allData: Candle[] = [];
|
|
631
|
+
|
|
632
|
+
const chart = createCandlestickChart(canvas, {
|
|
633
|
+
style: { volumeAreaHeightRatio: 0 }, // suppress the in-pane backdrop — see below for why
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
chart.addPane({
|
|
637
|
+
id: 'volume',
|
|
638
|
+
heightRatio: 0.15,
|
|
639
|
+
getValueRange: () => {
|
|
640
|
+
const { startIndex, endIndex } = chart.getVisibleRange();
|
|
641
|
+
let max = 0;
|
|
642
|
+
for (let i = startIndex; i < endIndex; i++) max = Math.max(max, allData[i]?.volume ?? 0);
|
|
643
|
+
return { min: 0, max: max || 1 };
|
|
644
|
+
},
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
chart.addPlugin({
|
|
648
|
+
paneId: 'volume',
|
|
649
|
+
draw({ ctx, allPoints, visibleStartIndex, visibleEndIndex, xForIndex, yForValue }) {
|
|
650
|
+
const zeroY = yForValue(0);
|
|
651
|
+
const barWidth = (xForIndex(visibleStartIndex + 1) - xForIndex(visibleStartIndex)) * 0.6;
|
|
652
|
+
for (let i = visibleStartIndex; i < visibleEndIndex; i++) {
|
|
653
|
+
const c = allPoints[i];
|
|
654
|
+
if (c.volume === undefined) continue;
|
|
655
|
+
ctx.fillStyle = c.close >= c.open ? '#26a69a' : '#ef5350';
|
|
656
|
+
const y = yForValue(c.volume);
|
|
657
|
+
ctx.fillRect(xForIndex(i) - barWidth / 2, y, barWidth, zeroY - y);
|
|
658
|
+
}
|
|
659
|
+
},
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
chart.setData(candles);
|
|
663
|
+
allData = candles; // keep in sync on every later setData() call too
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
Setting `volumeAreaHeightRatio: 0` on the style matters — leaving the default `0.2` active
|
|
667
|
+
alongside a dedicated volume pane double-draws the bars (once as the in-pane backdrop, once in
|
|
668
|
+
the new pane). Unlike an indicator pane's `getValueRange`, volume's domain is naturally
|
|
669
|
+
`[0, max]` rather than something auto-fit around a signed value the way MACD's is — the
|
|
670
|
+
example above recomputes `max` from the currently visible candles each frame, the same way
|
|
671
|
+
`computeMacdValueRange` does in the "Multi-pane indicators" example above.
|
|
672
|
+
|
|
595
673
|
### Cleanup
|
|
596
674
|
|
|
597
675
|
Call `chart.destroy()` when you're done with a chart (component unmount, etc.) — it removes a
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChartCrosshairOptions, ChartFontOptions, ChartLegendOptions } from './types.js';
|
|
1
|
+
import type { ChartCrosshairOptions, ChartFontOptions, ChartLegendOptions, LegendLine } from './types.js';
|
|
2
2
|
/** Everything one frame's hover crosshair/legend needs — computed by
|
|
3
3
|
* `ChartRenderer.render()` (which owns the hovered point, the active
|
|
4
4
|
* series, and its style) and handed in as plain data so this class stays
|
|
@@ -19,7 +19,7 @@ export interface CrosshairRenderInput {
|
|
|
19
19
|
* across every indicator pane below it. */
|
|
20
20
|
stackHeight: number;
|
|
21
21
|
invertValueAxis: boolean;
|
|
22
|
-
legendParts:
|
|
22
|
+
legendParts: LegendLine[];
|
|
23
23
|
/** The canvas's own backing-store width — needed only to clamp the
|
|
24
24
|
* time-axis label chip so it never runs off the right edge. */
|
|
25
25
|
canvasWidth: number;
|
|
@@ -27,7 +27,8 @@ export class CrosshairRenderer {
|
|
|
27
27
|
const { ctx, crosshair } = this;
|
|
28
28
|
ctx.save();
|
|
29
29
|
ctx.strokeStyle = crosshair.lineColor;
|
|
30
|
-
ctx.
|
|
30
|
+
ctx.lineWidth = crosshair.lineWidth;
|
|
31
|
+
ctx.setLineDash(crosshair.lineDash);
|
|
31
32
|
// Spans the whole pane stack (not just the main pane's own
|
|
32
33
|
// chartHeight) so hovering a candle lines up with the same column
|
|
33
34
|
// across every indicator pane below it — see `stackHeight`'s own doc
|
|
@@ -74,8 +75,12 @@ export class CrosshairRenderer {
|
|
|
74
75
|
ctx.font = this.legendFont();
|
|
75
76
|
ctx.textAlign = 'left';
|
|
76
77
|
ctx.textBaseline = 'top';
|
|
78
|
+
// Each line is either a plain string or { text, color } — normalize to
|
|
79
|
+
// its text once up front for sizing, and read its own color (falling
|
|
80
|
+
// back to legend.textColor) only when actually drawing it below.
|
|
81
|
+
const texts = lines.map((line) => (typeof line === 'string' ? line : line.text));
|
|
77
82
|
const lineHeight = font.legendSize + 4;
|
|
78
|
-
const textWidth = Math.max(...
|
|
83
|
+
const textWidth = Math.max(...texts.map((text) => ctx.measureText(text).width));
|
|
79
84
|
const boxWidth = textWidth + legend.paddingX * 2;
|
|
80
85
|
const boxHeight = lines.length * lineHeight + legend.paddingY * 2;
|
|
81
86
|
const anchorY = hoverY ?? 0;
|
|
@@ -83,9 +88,9 @@ export class CrosshairRenderer {
|
|
|
83
88
|
const top = Math.min(Math.max(anchorY - boxHeight - legend.cursorGap, 0), Math.max(0, chartHeight - boxHeight));
|
|
84
89
|
ctx.fillStyle = legend.background;
|
|
85
90
|
ctx.fillRect(left, top, boxWidth, boxHeight);
|
|
86
|
-
ctx.fillStyle = legend.textColor;
|
|
87
91
|
lines.forEach((line, i) => {
|
|
88
|
-
ctx.
|
|
92
|
+
ctx.fillStyle = typeof line === 'string' ? legend.textColor : (line.color ?? legend.textColor);
|
|
93
|
+
ctx.fillText(texts[i], left + legend.paddingX, top + legend.paddingY + i * lineHeight);
|
|
89
94
|
});
|
|
90
95
|
}
|
|
91
96
|
/** The highlighted price-axis label that follows the crosshair's
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import type { DataLoader } from './dataSource.js';
|
|
|
2
2
|
import type { ChartPlugin } from './plugins/types.js';
|
|
3
3
|
import type { CandlestickStyle } from './series/candlestick.js';
|
|
4
4
|
import type { LineStyle } from './series/line.js';
|
|
5
|
-
import type { Candle, LegendFormatContext, LinePoint, PaneOptions, WickChartOptions, SeriesPoint, ValueRange, WickTime } from './types.js';
|
|
6
|
-
export type { BusinessDay, Candle, LegendFormatContext, LinePoint, PaneOptions, WickChartOptions, WickTime, SeriesPoint, UnixMillis, ValueRange, } from './types.js';
|
|
5
|
+
import type { Candle, LegendFormatContext, LegendLine, LinePoint, PaneOptions, WickChartOptions, SeriesPoint, ValueRange, WickTime } from './types.js';
|
|
6
|
+
export type { BusinessDay, Candle, LegendFormatContext, LegendLine, LinePoint, PaneOptions, WickChartOptions, WickTime, SeriesPoint, UnixMillis, ValueRange, } from './types.js';
|
|
7
7
|
export type { DataLoader, DataRequest } from './dataSource.js';
|
|
8
8
|
export type { ChartPlugin, ChartPointerEvent, PluginRenderApi } from './plugins/types.js';
|
|
9
9
|
export { distanceToSegment, hitTestPoint, hitTestSegment } from './hitTest.js';
|
|
@@ -332,7 +332,7 @@ export declare function createCandlestickChart(canvas: HTMLCanvasElement, option
|
|
|
332
332
|
* `context` narrowed to this series's own types instead of the general
|
|
333
333
|
* (unchecked) `SeriesPoint`/`unknown` shape `WickChartOptions` itself
|
|
334
334
|
* allows — see its doc comment for what this is for. */
|
|
335
|
-
formatLegend?(point: Candle, style: CandlestickStyle, context: LegendFormatContext<Candle>):
|
|
335
|
+
formatLegend?(point: Candle, style: CandlestickStyle, context: LegendFormatContext<Candle>): LegendLine[];
|
|
336
336
|
}): WickChart<Candle>;
|
|
337
337
|
/**
|
|
338
338
|
* The second series type's equivalent of `createCandlestickChart` above —
|
|
@@ -345,5 +345,5 @@ export declare function createLineChart(canvas: HTMLCanvasElement, options?: Omi
|
|
|
345
345
|
style?: Partial<LineStyle>;
|
|
346
346
|
/** Same override as `WickChartOptions.formatLegend`, narrowed to this
|
|
347
347
|
* series's own types — see `createCandlestickChart`'s equivalent. */
|
|
348
|
-
formatLegend?(point: LinePoint, style: LineStyle, context: LegendFormatContext<LinePoint>):
|
|
348
|
+
formatLegend?(point: LinePoint, style: LineStyle, context: LegendFormatContext<LinePoint>): LegendLine[];
|
|
349
349
|
}): WickChart<LinePoint>;
|
package/dist/renderer.js
CHANGED
|
@@ -21,6 +21,8 @@ const DEFAULT_AXIS = {
|
|
|
21
21
|
};
|
|
22
22
|
const DEFAULT_CROSSHAIR = {
|
|
23
23
|
lineColor: '#9090904d',
|
|
24
|
+
lineWidth: 1,
|
|
25
|
+
lineDash: [4, 4],
|
|
24
26
|
labelBackground: '#3a3a3a',
|
|
25
27
|
labelTextColor: '#f0f0f0',
|
|
26
28
|
labelPaddingX: 4,
|
|
@@ -128,6 +130,8 @@ export class ChartRenderer {
|
|
|
128
130
|
};
|
|
129
131
|
const scaledCrosshair = {
|
|
130
132
|
...this.crosshair,
|
|
133
|
+
lineWidth: this.crosshair.lineWidth * ratio,
|
|
134
|
+
lineDash: this.crosshair.lineDash.map((segment) => segment * ratio),
|
|
131
135
|
labelPaddingX: this.crosshair.labelPaddingX * ratio,
|
|
132
136
|
labelPaddingY: this.crosshair.labelPaddingY * ratio,
|
|
133
137
|
};
|
|
@@ -230,32 +234,6 @@ export class ChartRenderer {
|
|
|
230
234
|
axisRenderer.renderPriceAxis(min, max, step, scale, chartWidth, rect.height, rect.top);
|
|
231
235
|
}
|
|
232
236
|
axisRenderer.renderTimeAxis(times, startIdx, visible.length, stackHeight, chartWidth, xForIndex);
|
|
233
|
-
if (hoverIndex !== null && hoverIndex >= startIdx && hoverIndex < endIdx) {
|
|
234
|
-
// The dashed vertical line spans the whole stack (every pane); the
|
|
235
|
-
// horizontal line, price-label chip, and OHLC legend stay scoped
|
|
236
|
-
// to the main pane only — an indicator pane's own hover readout,
|
|
237
|
-
// if it wants one, is the job of whatever plugin draws into it.
|
|
238
|
-
// `formatLegendOverride`, when set, replaces the series's own
|
|
239
|
-
// formatLegend entirely for this chart instance rather than
|
|
240
|
-
// merging with it — see `WickChartOptions.formatLegend`.
|
|
241
|
-
const formatLegend = this.formatLegendOverride ?? seriesDefinition.formatLegend;
|
|
242
|
-
const legendContext = { index: hoverIndex, allPoints: sorted };
|
|
243
|
-
const legendParts = formatLegend?.(sorted[hoverIndex], style, legendContext) ?? [];
|
|
244
|
-
crosshairRenderer.render({
|
|
245
|
-
x: xForIndex(hoverIndex),
|
|
246
|
-
timeSeconds: times[hoverIndex],
|
|
247
|
-
hoverY,
|
|
248
|
-
valueMin,
|
|
249
|
-
valueMax,
|
|
250
|
-
priceStep,
|
|
251
|
-
chartWidth,
|
|
252
|
-
chartHeight,
|
|
253
|
-
stackHeight,
|
|
254
|
-
invertValueAxis: this.invertValueAxis,
|
|
255
|
-
legendParts,
|
|
256
|
-
canvasWidth: canvas.width,
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
237
|
if (plugins.length > 0) {
|
|
260
238
|
// Everything every pane's PluginRenderApi shares — only the pane's
|
|
261
239
|
// own rect/value-domain/scale differ between `buildPluginApi`
|
|
@@ -300,6 +278,37 @@ export class ChartRenderer {
|
|
|
300
278
|
}
|
|
301
279
|
}
|
|
302
280
|
}
|
|
281
|
+
// Drawn last, after every plugin (including paneId'd ones and main-pane
|
|
282
|
+
// overlays like trade markers) rather than right after the axes, so the
|
|
283
|
+
// hover legend/crosshair always sits on top of everything else instead
|
|
284
|
+
// of being covered by a plugin's own output — the crosshair is the most
|
|
285
|
+
// "active"/topmost thing on the chart at the moment it's shown.
|
|
286
|
+
if (hoverIndex !== null && hoverIndex >= startIdx && hoverIndex < endIdx) {
|
|
287
|
+
// The dashed vertical line spans the whole stack (every pane); the
|
|
288
|
+
// horizontal line, price-label chip, and OHLC legend stay scoped
|
|
289
|
+
// to the main pane only — an indicator pane's own hover readout,
|
|
290
|
+
// if it wants one, is the job of whatever plugin draws into it.
|
|
291
|
+
// `formatLegendOverride`, when set, replaces the series's own
|
|
292
|
+
// formatLegend entirely for this chart instance rather than
|
|
293
|
+
// merging with it — see `WickChartOptions.formatLegend`.
|
|
294
|
+
const formatLegend = this.formatLegendOverride ?? seriesDefinition.formatLegend;
|
|
295
|
+
const legendContext = { index: hoverIndex, allPoints: sorted };
|
|
296
|
+
const legendParts = formatLegend?.(sorted[hoverIndex], style, legendContext) ?? [];
|
|
297
|
+
crosshairRenderer.render({
|
|
298
|
+
x: xForIndex(hoverIndex),
|
|
299
|
+
timeSeconds: times[hoverIndex],
|
|
300
|
+
hoverY,
|
|
301
|
+
valueMin,
|
|
302
|
+
valueMax,
|
|
303
|
+
priceStep,
|
|
304
|
+
chartWidth,
|
|
305
|
+
chartHeight,
|
|
306
|
+
stackHeight,
|
|
307
|
+
invertValueAxis: this.invertValueAxis,
|
|
308
|
+
legendParts,
|
|
309
|
+
canvasWidth: canvas.width,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
303
312
|
}
|
|
304
313
|
finally {
|
|
305
314
|
frameState.ended = true;
|
|
@@ -11,7 +11,12 @@ export interface CandlestickStyle {
|
|
|
11
11
|
/** Fraction of the chart's full height that volume bars occupy, measured
|
|
12
12
|
* up from the bottom. Candles still use the full height for their own
|
|
13
13
|
* price scale regardless of this value — the bars sit in this bottom
|
|
14
|
-
* margin, layered underneath
|
|
14
|
+
* margin, layered underneath (and can visually collide with a candle
|
|
15
|
+
* whose range dips into that margin). Defaults to 0.2. Set to 0 to
|
|
16
|
+
* suppress this in-pane backdrop entirely — do this when drawing volume
|
|
17
|
+
* in its own pane instead via `WickChart.addPane` + a `ChartPlugin`
|
|
18
|
+
* reading `Candle.volume` off `allPoints` (see "Splitting volume into
|
|
19
|
+
* its own pane" in the README), so the two don't double-draw. */
|
|
15
20
|
volumeAreaHeightRatio: number;
|
|
16
21
|
/** Opacity (0-1) of the volume bars, so they read as a backdrop rather
|
|
17
22
|
* than competing with the candles drawn over them. Defaults to 0.5. */
|
|
@@ -18,6 +18,13 @@ function getValueRange(visible, scaleFactor) {
|
|
|
18
18
|
* OHLC-only data look exactly as they did before this existed. */
|
|
19
19
|
function drawVolumeBars(context, style) {
|
|
20
20
|
const { ctx, visible, startIndex, xForIndex, slotWidth, chartHeight } = context;
|
|
21
|
+
// A caller drawing volume in its own pane via WickChart.addPane (see
|
|
22
|
+
// "Splitting volume into its own pane" in the README) sets this to 0 to
|
|
23
|
+
// fully suppress this in-pane backdrop — without this guard, the
|
|
24
|
+
// Math.max(1, ...) floor below still drew a 1px sliver per candle even
|
|
25
|
+
// at ratio 0.
|
|
26
|
+
if (style.volumeAreaHeightRatio <= 0)
|
|
27
|
+
return;
|
|
21
28
|
const maxVolume = visible.reduce((max, c) => (c.volume !== undefined ? Math.max(max, c.volume) : max), 0);
|
|
22
29
|
if (maxVolume <= 0)
|
|
23
30
|
return;
|
package/dist/series/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Scale } from '../hybridScale.js';
|
|
2
|
-
import type { LegendFormatContext, SeriesPoint, ValueRange } from '../types.js';
|
|
2
|
+
import type { LegendFormatContext, LegendLine, SeriesPoint, ValueRange } from '../types.js';
|
|
3
3
|
export type { ValueRange } from '../types.js';
|
|
4
4
|
/**
|
|
5
5
|
* Everything a series's `draw` needs to turn its visible points into
|
|
@@ -68,5 +68,5 @@ export interface SeriesDefinition<TPoint extends SeriesPoint, TStyle> {
|
|
|
68
68
|
* previous point — this built-in series doesn't need it, but a custom
|
|
69
69
|
* one can. `WickChartOptions.formatLegend`, when set, overrides this per
|
|
70
70
|
* chart instance rather than per series type — see its own doc comment. */
|
|
71
|
-
formatLegend?(point: TPoint, style: TStyle, context: LegendFormatContext<TPoint>):
|
|
71
|
+
formatLegend?(point: TPoint, style: TStyle, context: LegendFormatContext<TPoint>): LegendLine[];
|
|
72
72
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -103,8 +103,16 @@ export interface ChartAxisOptions {
|
|
|
103
103
|
/** Coloring and padding for the hover crosshair's lines and its two
|
|
104
104
|
* highlighted axis-label chips. */
|
|
105
105
|
export interface ChartCrosshairOptions {
|
|
106
|
-
/**
|
|
106
|
+
/** Crosshair line color. Defaults to `'#9090904d'`. */
|
|
107
107
|
lineColor?: string;
|
|
108
|
+
/** Crosshair line thickness, in CSS px (scaled by `devicePixelRatio`
|
|
109
|
+
* like every other size field here). Defaults to `1`. */
|
|
110
|
+
lineWidth?: number;
|
|
111
|
+
/** `CanvasRenderingContext2D.setLineDash` pattern, in CSS px (scaled by
|
|
112
|
+
* `devicePixelRatio` like every other size field here). Defaults to
|
|
113
|
+
* `[4, 4]`. Pass `[]` for a solid line — the same canvas convention
|
|
114
|
+
* `setLineDash` itself uses, so this needs no separate on/off flag. */
|
|
115
|
+
lineDash?: number[];
|
|
108
116
|
/** Background fill of the price/time label chips. Defaults to `'#3a3a3a'`. */
|
|
109
117
|
labelBackground?: string;
|
|
110
118
|
/** Text color inside the label chips. Defaults to `'#f0f0f0'`. */
|
|
@@ -185,6 +193,18 @@ export interface LegendFormatContext<TPoint extends SeriesPoint = SeriesPoint> {
|
|
|
185
193
|
* time — the same array `SeriesDrawContext.allPoints` is. */
|
|
186
194
|
allPoints: readonly TPoint[];
|
|
187
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* One line of the hover legend — a plain `string` (drawn in the legend's
|
|
198
|
+
* configured `textColor`, same as every version of this library before
|
|
199
|
+
* per-line color existed) or `{ text, color }` for a line that needs its
|
|
200
|
+
* own color independent of the rest — a percent-change line that should
|
|
201
|
+
* read green/red by sign, say. Mixing both in the same `formatLegend`
|
|
202
|
+
* return array is fine: each line is colored independently.
|
|
203
|
+
*/
|
|
204
|
+
export type LegendLine = string | {
|
|
205
|
+
text: string;
|
|
206
|
+
color?: string;
|
|
207
|
+
};
|
|
188
208
|
export interface WickChartOptions {
|
|
189
209
|
/**
|
|
190
210
|
* Which registered series type to render this chart as (see
|
|
@@ -218,7 +238,9 @@ export interface WickChartOptions {
|
|
|
218
238
|
/**
|
|
219
239
|
* Overrides the active series's own `formatLegend` (see
|
|
220
240
|
* `SeriesDefinition.formatLegend`) for this chart instance specifically —
|
|
221
|
-
* the hover legend's text, one
|
|
241
|
+
* the hover legend's text, one `LegendLine` per line (a plain string, or
|
|
242
|
+
* `{ text, color }` for a line that needs its own color — see
|
|
243
|
+
* `LegendLine`). `SeriesDefinition.formatLegend`
|
|
222
244
|
* is a shared default for every chart of that series *type* (registered
|
|
223
245
|
* once via `registerSeries`); this is a per-*instance* override for
|
|
224
246
|
* whatever varies by app/session instead of by chart type — localized
|
|
@@ -238,7 +260,7 @@ export interface WickChartOptions {
|
|
|
238
260
|
* both to the concrete series's own types, the same way they narrow
|
|
239
261
|
* `style` — see their own doc comments.
|
|
240
262
|
*/
|
|
241
|
-
formatLegend?(point: SeriesPoint, style: unknown, context: LegendFormatContext<SeriesPoint>):
|
|
263
|
+
formatLegend?(point: SeriesPoint, style: unknown, context: LegendFormatContext<SeriesPoint>): LegendLine[];
|
|
242
264
|
/**
|
|
243
265
|
* Mirrors the value axis top-to-bottom — every pane's higher values
|
|
244
266
|
* render lower on screen instead of higher, with no change to the
|