@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.
Files changed (50) hide show
  1. package/README.md +184 -19
  2. package/dist/charting/__tests__/chartSpec.test.d.ts +1 -0
  3. package/dist/charting/scales.d.ts +14 -0
  4. package/dist/charting/types.d.ts +454 -0
  5. package/dist/charting.css +1 -1
  6. package/dist/components/DWLFChart.d.ts +119 -0
  7. package/dist/components/index.d.ts +2 -0
  8. package/dist/components/overlays/AlertLineAnnotationView.d.ts +14 -0
  9. package/dist/components/overlays/AnnotationLayer.d.ts +55 -0
  10. package/dist/components/overlays/ArrowAnnotationView.d.ts +24 -0
  11. package/dist/components/overlays/BosLineAnnotationView.d.ts +22 -0
  12. package/dist/components/overlays/BrushAnnotationView.d.ts +20 -0
  13. package/dist/components/overlays/ChannelAnnotationView.d.ts +23 -0
  14. package/dist/components/overlays/CrossLineAnnotationView.d.ts +29 -0
  15. package/dist/components/overlays/DiagonalLineOverlay.d.ts +31 -0
  16. package/dist/components/overlays/EmojiAnnotationView.d.ts +22 -0
  17. package/dist/components/overlays/FairValueGapAnnotationView.d.ts +23 -0
  18. package/dist/components/overlays/FibExtensionAnnotationView.d.ts +19 -0
  19. package/dist/components/overlays/FibRetracementAnnotationView.d.ts +19 -0
  20. package/dist/components/overlays/HLineAnnotationView.d.ts +15 -0
  21. package/dist/components/overlays/HorizontalLineOverlay.d.ts +23 -0
  22. package/dist/components/overlays/MarkerOverlay.d.ts +66 -0
  23. package/dist/components/overlays/MeasureAnnotationView.d.ts +25 -0
  24. package/dist/components/overlays/MessageBubbleOverlay.d.ts +55 -0
  25. package/dist/components/overlays/OrderBlockAnnotationView.d.ts +23 -0
  26. package/dist/components/overlays/PitchforkAnnotationView.d.ts +19 -0
  27. package/dist/components/overlays/PositionOverlay.d.ts +52 -0
  28. package/dist/components/overlays/RayAnnotationView.d.ts +30 -0
  29. package/dist/components/overlays/RectangleAnnotationView.d.ts +23 -0
  30. package/dist/components/overlays/SMAOverlay.d.ts +20 -0
  31. package/dist/components/overlays/TextAnnotationView.d.ts +24 -0
  32. package/dist/components/overlays/TimeRangeAnnotationView.d.ts +22 -0
  33. package/dist/components/overlays/TrendLineAnnotationView.d.ts +23 -0
  34. package/dist/components/overlays/VLineAnnotationView.d.ts +26 -0
  35. package/dist/components/overlays/annotationConstants.d.ts +21 -0
  36. package/dist/components/overlays/annotationUtils.d.ts +13 -0
  37. package/dist/components/overlays/useAnnotationDrag.d.ts +18 -0
  38. package/dist/components/overlays/usePointAnnotationDrag.d.ts +23 -0
  39. package/dist/hooks/useCandlestickChart.d.ts +18 -0
  40. package/dist/hooks/useChartAnimations.d.ts +49 -0
  41. package/dist/hooks/useChartLayout.d.ts +12 -0
  42. package/dist/hooks/useChartPanZoom.d.ts +7 -0
  43. package/dist/hooks/useChartPanZoomVirtual.d.ts +24 -0
  44. package/dist/hooks/useContainerSize.d.ts +4 -0
  45. package/dist/hooks/useOverlayToggles.d.ts +19 -0
  46. package/dist/index.cjs +1 -1
  47. package/dist/index.d.ts +56 -0
  48. package/dist/index.js +13 -13
  49. package/dist/utils/indicators.d.ts +40 -0
  50. 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
- height: 300,
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.map(c => ({
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 drag-to-create and interactive editing:
171
+ 20+ built-in annotation types with creation helpers:
50
172
 
51
173
  ```tsx
52
- import { DWLFChart, AnnotationLayer, createHLineAnnotation } from '@dwlf/charting';
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: 150, label: 'Support' }),
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 traders. The strategy builders, backtesting UI, and analytics dashboards that sit on top of this library are available via the DWLF platform.
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 };