@dwlf/charting 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +184 -19
- package/dist/charting/__tests__/chartSpec.test.d.ts +1 -0
- package/dist/charting/scales.d.ts +14 -0
- package/dist/charting/types.d.ts +454 -0
- package/dist/charting.css +1 -1
- package/dist/components/DWLFChart.d.ts +119 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/overlays/AlertLineAnnotationView.d.ts +14 -0
- package/dist/components/overlays/AnnotationLayer.d.ts +55 -0
- package/dist/components/overlays/ArrowAnnotationView.d.ts +24 -0
- package/dist/components/overlays/BosLineAnnotationView.d.ts +22 -0
- package/dist/components/overlays/BrushAnnotationView.d.ts +20 -0
- package/dist/components/overlays/ChannelAnnotationView.d.ts +23 -0
- package/dist/components/overlays/CrossLineAnnotationView.d.ts +29 -0
- package/dist/components/overlays/DiagonalLineOverlay.d.ts +31 -0
- package/dist/components/overlays/EmojiAnnotationView.d.ts +22 -0
- package/dist/components/overlays/FairValueGapAnnotationView.d.ts +23 -0
- package/dist/components/overlays/FibExtensionAnnotationView.d.ts +19 -0
- package/dist/components/overlays/FibRetracementAnnotationView.d.ts +19 -0
- package/dist/components/overlays/HLineAnnotationView.d.ts +15 -0
- package/dist/components/overlays/HorizontalLineOverlay.d.ts +23 -0
- package/dist/components/overlays/MarkerOverlay.d.ts +66 -0
- package/dist/components/overlays/MeasureAnnotationView.d.ts +25 -0
- package/dist/components/overlays/MessageBubbleOverlay.d.ts +55 -0
- package/dist/components/overlays/OrderBlockAnnotationView.d.ts +23 -0
- package/dist/components/overlays/PitchforkAnnotationView.d.ts +19 -0
- package/dist/components/overlays/PositionOverlay.d.ts +52 -0
- package/dist/components/overlays/RayAnnotationView.d.ts +30 -0
- package/dist/components/overlays/RectangleAnnotationView.d.ts +23 -0
- package/dist/components/overlays/SMAOverlay.d.ts +20 -0
- package/dist/components/overlays/TextAnnotationView.d.ts +24 -0
- package/dist/components/overlays/TimeRangeAnnotationView.d.ts +22 -0
- package/dist/components/overlays/TrendLineAnnotationView.d.ts +23 -0
- package/dist/components/overlays/VLineAnnotationView.d.ts +26 -0
- package/dist/components/overlays/annotationConstants.d.ts +21 -0
- package/dist/components/overlays/annotationUtils.d.ts +13 -0
- package/dist/components/overlays/useAnnotationDrag.d.ts +18 -0
- package/dist/components/overlays/usePointAnnotationDrag.d.ts +23 -0
- package/dist/hooks/useCandlestickChart.d.ts +18 -0
- package/dist/hooks/useChartAnimations.d.ts +49 -0
- package/dist/hooks/useChartLayout.d.ts +12 -0
- package/dist/hooks/useChartPanZoom.d.ts +7 -0
- package/dist/hooks/useChartPanZoomVirtual.d.ts +24 -0
- package/dist/hooks/useContainerSize.d.ts +4 -0
- package/dist/hooks/useOverlayToggles.d.ts +19 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +56 -0
- package/dist/index.js +13 -13
- package/dist/utils/indicators.d.ts +40 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -22,17 +22,14 @@ import type { ChartSpec } from '@dwlf/charting';
|
|
|
22
22
|
const spec: ChartSpec = {
|
|
23
23
|
panes: [
|
|
24
24
|
{
|
|
25
|
-
|
|
25
|
+
id: 'price',
|
|
26
|
+
heightRatio: 3,
|
|
27
|
+
yScale: { mode: 'auto' },
|
|
26
28
|
series: [
|
|
27
29
|
{
|
|
30
|
+
key: 'candles',
|
|
28
31
|
type: 'ohlc',
|
|
29
|
-
data: candles
|
|
30
|
-
x: new Date(c.t * 1000).toISOString(),
|
|
31
|
-
open: c.o,
|
|
32
|
-
high: c.h,
|
|
33
|
-
low: c.l,
|
|
34
|
-
close: c.c,
|
|
35
|
-
})),
|
|
32
|
+
data: candles, // array of { t, o, h, l, c }
|
|
36
33
|
},
|
|
37
34
|
],
|
|
38
35
|
},
|
|
@@ -40,22 +37,160 @@ const spec: ChartSpec = {
|
|
|
40
37
|
};
|
|
41
38
|
|
|
42
39
|
function MyChart() {
|
|
43
|
-
return <DWLFChart spec={spec} />;
|
|
40
|
+
return <DWLFChart spec={spec} darkMode={true} enablePanZoom={true} />;
|
|
44
41
|
}
|
|
45
42
|
```
|
|
46
43
|
|
|
44
|
+
## Dark Mode
|
|
45
|
+
|
|
46
|
+
Dark mode is supported via the `darkMode` prop (defaults to `true`):
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<DWLFChart spec={spec} darkMode={true} />
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This controls the background, text, grid, crosshair, tooltip, and candle colors automatically.
|
|
53
|
+
|
|
54
|
+
For further customisation, use `axisColors`:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
<DWLFChart
|
|
58
|
+
spec={spec}
|
|
59
|
+
darkMode={true}
|
|
60
|
+
axisColors={{ dark: '#8b949e', light: '#57606a' }}
|
|
61
|
+
/>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Timestamps
|
|
65
|
+
|
|
66
|
+
**Important:** The charting library expects timestamps in **milliseconds** (Unix epoch in ms). If your data uses seconds (common in crypto APIs), multiply by 1000:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
const chartData = candles.map(c => ({
|
|
70
|
+
t: c.t * 1000, // seconds → milliseconds
|
|
71
|
+
o: c.o,
|
|
72
|
+
h: c.h,
|
|
73
|
+
l: c.l,
|
|
74
|
+
c: c.c,
|
|
75
|
+
}));
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
When pairing with `@dwlf/indicators`, note that indicator output uses the same timestamp format as input. If your source data uses seconds, the indicator output will too — convert when passing to the chart.
|
|
79
|
+
|
|
80
|
+
## Series Configuration
|
|
81
|
+
|
|
82
|
+
Each pane contains an array of series. Every series needs a `key` (unique identifier), `type`, and `data`.
|
|
83
|
+
|
|
84
|
+
### Series Types
|
|
85
|
+
|
|
86
|
+
| Type | Description | Data format |
|
|
87
|
+
|------|-------------|-------------|
|
|
88
|
+
| `ohlc` | Candlestick chart | `{ t, o, h, l, c }[]` |
|
|
89
|
+
| `line` | Line chart | `{ t, v }[]` |
|
|
90
|
+
| `hist` | Histogram bars | `{ t, v }[]` |
|
|
91
|
+
| `area` | Filled area | `{ t, v }[]` |
|
|
92
|
+
| `marker` | Point markers | `{ t, price, text?, tooltip?, shape? }[]` |
|
|
93
|
+
| `position` | Trade positions | `{ t, price, type, stopLoss?, takeProfit? }[]` |
|
|
94
|
+
|
|
95
|
+
### Series Colors
|
|
96
|
+
|
|
97
|
+
Set colors with the `color` shorthand or `style.color` (both work):
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
// Shorthand
|
|
101
|
+
{ key: 'ema8', type: 'line', data: ema8, color: '#58a6ff' }
|
|
102
|
+
|
|
103
|
+
// Full style object (takes precedence)
|
|
104
|
+
{ key: 'ema8', type: 'line', data: ema8, style: { color: '#58a6ff', lineWidth: 2, dashed: true } }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Style Options
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
interface SeriesStyle {
|
|
111
|
+
color?: string; // Series color
|
|
112
|
+
lineWidth?: number; // Line thickness (default: 1.5)
|
|
113
|
+
dashed?: boolean; // Dashed line
|
|
114
|
+
opacity?: number; // Opacity (0-1)
|
|
115
|
+
markerShape?: 'arrow-up' | 'arrow-down' | 'circle';
|
|
116
|
+
markerSize?: number;
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Multi-Pane Layout
|
|
121
|
+
|
|
122
|
+
Use `heightRatio` to control pane proportions:
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
const spec: ChartSpec = {
|
|
126
|
+
panes: [
|
|
127
|
+
{
|
|
128
|
+
id: 'price',
|
|
129
|
+
heightRatio: 3, // 75% of height
|
|
130
|
+
yScale: { mode: 'auto' },
|
|
131
|
+
series: [{ key: 'candles', type: 'ohlc', data: candles }],
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'dss',
|
|
135
|
+
heightRatio: 1, // 25% of height
|
|
136
|
+
yScale: { mode: 'fixed', min: 0, max: 100 },
|
|
137
|
+
series: [
|
|
138
|
+
{ key: 'dss', type: 'line', data: dssData, color: '#22c55e' },
|
|
139
|
+
{ key: 'signal', type: 'line', data: signalData, color: '#ef4444' },
|
|
140
|
+
],
|
|
141
|
+
guides: [
|
|
142
|
+
{ y: 80, dashed: true, label: 'OB', color: '#ef4444' },
|
|
143
|
+
{ y: 20, dashed: true, label: 'OS', color: '#22c55e' },
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## DWLFChart Props
|
|
151
|
+
|
|
152
|
+
| Prop | Type | Default | Description |
|
|
153
|
+
|------|------|---------|-------------|
|
|
154
|
+
| `spec` | `ChartSpec` | — | Chart specification (panes, series, guides) |
|
|
155
|
+
| `darkMode` | `boolean` | `true` | Dark/light theme |
|
|
156
|
+
| `enablePanZoom` | `boolean` | `false` | Enable scroll-to-zoom and drag-to-pan |
|
|
157
|
+
| `timeframe` | `string` | `'daily'` | Affects X-axis date formatting (`'daily'`, `'weekly'`, `'4h'`, `'1h'`) |
|
|
158
|
+
| `initialVisibleCount` | `number` | — | Number of candles visible initially (controls default zoom) |
|
|
159
|
+
| `extraRightSlots` | `number` | — | Extra padding on the right edge |
|
|
160
|
+
| `compressGaps` | `boolean` | `false` | Remove weekend/holiday gaps |
|
|
161
|
+
| `crosshairSnapMode` | `'series' \| 'pointer'` | `'series'` | `'pointer'` follows mouse freely, `'series'` snaps to nearest candle |
|
|
162
|
+
| `showCrosshairPriceLabel` | `boolean` | — | Show price label on crosshair |
|
|
163
|
+
| `axisColors` | `{ light?: string; dark?: string }` | — | Custom axis/crosshair colors |
|
|
164
|
+
| `annotations` | `Annotation[]` | — | Chart annotations (lines, text, fib, etc.) |
|
|
165
|
+
| `className` | `string` | — | CSS class on container |
|
|
166
|
+
| `style` | `CSSProperties` | — | Inline styles on container |
|
|
167
|
+
| `animationState` | `ChartAnimationState` | — | Control entry animations |
|
|
168
|
+
|
|
47
169
|
## Annotations
|
|
48
170
|
|
|
49
|
-
20+ built-in annotation types with
|
|
171
|
+
20+ built-in annotation types with creation helpers:
|
|
50
172
|
|
|
51
173
|
```tsx
|
|
52
|
-
import {
|
|
174
|
+
import {
|
|
175
|
+
DWLFChart,
|
|
176
|
+
AnnotationLayer,
|
|
177
|
+
createHLineAnnotation,
|
|
178
|
+
createTrendLineAnnotation,
|
|
179
|
+
createFibRetracementAnnotation,
|
|
180
|
+
} from '@dwlf/charting';
|
|
53
181
|
|
|
54
182
|
const annotations = [
|
|
55
|
-
createHLineAnnotation({ price:
|
|
56
|
-
createTrendLineAnnotation({ time1, price1, time2, price2 }),
|
|
183
|
+
createHLineAnnotation({ price: 42000, label: 'Support', color: '#22c55e' }),
|
|
184
|
+
createTrendLineAnnotation({ time1, price1, time2, price2, color: '#3b82f6' }),
|
|
57
185
|
createFibRetracementAnnotation({ time1, price1, time2, price2 }),
|
|
58
186
|
];
|
|
187
|
+
|
|
188
|
+
<DWLFChart
|
|
189
|
+
spec={spec}
|
|
190
|
+
annotations={annotations}
|
|
191
|
+
onAnnotationSelect={(id) => console.log('selected', id)}
|
|
192
|
+
onAnnotationMove={(id, update) => console.log('moved', id, update)}
|
|
193
|
+
/>
|
|
59
194
|
```
|
|
60
195
|
|
|
61
196
|
**Available annotations:** Horizontal Line, Vertical Line, Text, Trend Line, Ray, Cross Line, Rectangle, Channel, Fibonacci Retracement, Fibonacci Extension, Measure, Pitchfork, Arrow, Time Range, Alert Line, Brush, Emoji, Order Block, Fair Value Gap, BOS Line.
|
|
@@ -64,17 +199,47 @@ const annotations = [
|
|
|
64
199
|
|
|
65
200
|
```tsx
|
|
66
201
|
import {
|
|
67
|
-
useCandlestickChart,
|
|
68
|
-
useChartPanZoom,
|
|
69
|
-
useChartLayout,
|
|
70
|
-
useContainerSize,
|
|
71
|
-
useChartAnimations,
|
|
202
|
+
useCandlestickChart, // D3 scales and layout for candlestick data
|
|
203
|
+
useChartPanZoom, // Pan and zoom state management
|
|
204
|
+
useChartLayout, // Chart dimension calculations
|
|
205
|
+
useContainerSize, // Responsive container sizing
|
|
206
|
+
useChartAnimations, // Entry animation orchestration
|
|
207
|
+
useOverlayToggles, // Overlay visibility management
|
|
72
208
|
} from '@dwlf/charting';
|
|
73
209
|
```
|
|
74
210
|
|
|
211
|
+
## Using with @dwlf/indicators
|
|
212
|
+
|
|
213
|
+
Fetch candles from your data source, compute indicators, render:
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
import { EMA, Bollinger, DSS } from '@dwlf/indicators';
|
|
217
|
+
import { DWLFChart } from '@dwlf/charting';
|
|
218
|
+
import '@dwlf/charting/styles';
|
|
219
|
+
|
|
220
|
+
// Compute indicators (timestamps must match your candle timestamps)
|
|
221
|
+
const ema8 = EMA.computeEMA(candles, 8);
|
|
222
|
+
const bb = Bollinger.computeBollingerBands(candles, { length: 20 });
|
|
223
|
+
|
|
224
|
+
// Build chart spec — remember to convert timestamps to milliseconds
|
|
225
|
+
const spec = {
|
|
226
|
+
panes: [{
|
|
227
|
+
id: 'price',
|
|
228
|
+
heightRatio: 1,
|
|
229
|
+
yScale: { mode: 'auto' },
|
|
230
|
+
series: [
|
|
231
|
+
{ key: 'candles', type: 'ohlc', data: candles.map(c => ({ ...c, t: c.t * 1000 })) },
|
|
232
|
+
{ key: 'ema8', type: 'line', data: ema8.ema.map(p => ({ t: p.t * 1000, v: p.v })), color: '#58a6ff' },
|
|
233
|
+
{ key: 'bb-upper', type: 'line', data: bb.upper.map(p => ({ t: p.t * 1000, v: p.v })), color: '#8b949e', style: { dashed: true } },
|
|
234
|
+
{ key: 'bb-lower', type: 'line', data: bb.lower.map(p => ({ t: p.t * 1000, v: p.v })), color: '#8b949e', style: { dashed: true } },
|
|
235
|
+
],
|
|
236
|
+
}],
|
|
237
|
+
};
|
|
238
|
+
```
|
|
239
|
+
|
|
75
240
|
## Used By
|
|
76
241
|
|
|
77
|
-
This is the same charting engine that powers [DWLF](https://dwlf.co.uk) — a market intelligence platform for
|
|
242
|
+
This is the same charting engine that powers [DWLF](https://dwlf.co.uk) — a market intelligence platform for AI agents and traders.
|
|
78
243
|
|
|
79
244
|
## License
|
|
80
245
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ChartSpec, LinePoint, OhlcPoint, PaneComputedScale, PaneSpec, SeriesSpec } from './types';
|
|
2
|
+
export type ResolvePaneDomainOptions = {
|
|
3
|
+
includeOverlaysInAutoScale?: boolean;
|
|
4
|
+
};
|
|
5
|
+
export declare const resolvePaneDomain: (pane: PaneSpec, options?: ResolvePaneDomainOptions) => [number, number];
|
|
6
|
+
export declare const createPaneScale: (domain: [number, number], height: number) => PaneComputedScale;
|
|
7
|
+
export type BuildPaneScalesOptions = {
|
|
8
|
+
includeOverlaysInAutoScale?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare const buildPaneScales: (spec: ChartSpec, paneHeights: Record<string, number>, options?: BuildPaneScalesOptions) => Record<string, PaneComputedScale>;
|
|
11
|
+
export declare const collectPaneTimes: (pane: PaneSpec) => number[];
|
|
12
|
+
export declare const collectSpecTimes: (spec: ChartSpec) => number[];
|
|
13
|
+
export declare const findClosestTime: (times: number[], value: number) => number;
|
|
14
|
+
export type { LinePoint, OhlcPoint, PaneSpec, SeriesSpec };
|