@pradeepjadhav/trading-reload-chart 1.0.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/LICENSE +87 -0
- package/README.md +256 -0
- package/dist/canvas/layers/AxisLayerX/AxisLayerX.d.ts +27 -0
- package/dist/canvas/layers/AxisLayerX/AxisLayerX.helpers.d.ts +32 -0
- package/dist/canvas/layers/AxisLayerX/AxisLayerX.types.d.ts +10 -0
- package/dist/canvas/layers/AxisLayerY/AxisLayerY.d.ts +23 -0
- package/dist/canvas/layers/AxisLayerY/AxisLayerY.helpers.d.ts +4 -0
- package/dist/canvas/layers/AxisLayerY/AxisLayerY.types.d.ts +8 -0
- package/dist/canvas/layers/CrosshairLayer.d.ts +23 -0
- package/dist/canvas/layers/CrosshairLayer.types.d.ts +10 -0
- package/dist/canvas/layers/ExistingCandlesLayer.d.ts +107 -0
- package/dist/canvas/layers/ExistingCandlesLayer.types.d.ts +56 -0
- package/dist/canvas/layers/PdhPdlLayer.d.ts +24 -0
- package/dist/canvas/layers/ShapesLayer/FibRetracementShape.d.ts +28 -0
- package/dist/canvas/layers/ShapesLayer/LineShape.d.ts +27 -0
- package/dist/canvas/layers/ShapesLayer/PathShape.d.ts +29 -0
- package/dist/canvas/layers/ShapesLayer/RectangleShape.d.ts +28 -0
- package/dist/canvas/layers/ShapesLayer/ShapesLayer.d.ts +70 -0
- package/dist/canvas/layers/ShapesLayer/ShapesLayer.helpers.d.ts +47 -0
- package/dist/canvas/layers/ShapesLayer/ShapesLayer.types.d.ts +470 -0
- package/dist/canvas/layers/ShapesLayer/ShortLongPosition.d.ts +40 -0
- package/dist/canvas/layers/ShapesLayer/ShortLongPosition.types.d.ts +11 -0
- package/dist/canvas/layers/TradeLayer/TradeLayer.d.ts +152 -0
- package/dist/canvas/layers/TradeLayer/TradeLayer.helpers.d.ts +3 -0
- package/dist/canvas/layers/TradeLayer/TradeLayer.types.d.ts +261 -0
- package/dist/canvas/layers/TradeLayer/TradeLayerEvents.d.ts +68 -0
- package/dist/canvas/layers/TradeLayer/TradeLayerEvents.types.d.ts +12 -0
- package/dist/canvas/layers/VolumeLayer/VolumeLayer.d.ts +28 -0
- package/dist/canvas/layers/VolumeLayer/VolumeLayer.types.d.ts +25 -0
- package/dist/canvas/layers/helpers/LayerHelpers.d.ts +29 -0
- package/dist/chart/ChartController.d.ts +8 -0
- package/dist/chart/ChartController.types.d.ts +224 -0
- package/dist/chart/createChartDom.d.ts +2 -0
- package/dist/chart/createChartDom.types.d.ts +13 -0
- package/dist/chart/utils/deepPartial.types.d.ts +14 -0
- package/dist/chart/utils/getCanvasPoint.d.ts +2 -0
- package/dist/chart/utils/getCanvasPoint.types.d.ts +10 -0
- package/dist/chart/utils/mergeChartConfig.d.ts +3 -0
- package/dist/chart/utils/normalizeCandleTime.d.ts +2 -0
- package/dist/chart/utils/updateTradeTPSL.d.ts +8 -0
- package/dist/config/ChartShapeConfig/chartShapeConfig.d.ts +2 -0
- package/dist/config/chartConfig.d.ts +20 -0
- package/dist/config/chartConfig.types.d.ts +642 -0
- package/dist/config/colors.d.ts +19 -0
- package/dist/config/pairs.d.ts +3 -0
- package/dist/core/CoordinateSystem.d.ts +10 -0
- package/dist/favicon.svg +1 -0
- package/dist/helpers/math.d.ts +1 -0
- package/dist/icons.svg +24 -0
- package/dist/index.d.ts +14 -0
- package/dist/models/Candle.types.d.ts +67 -0
- package/dist/models/ChartViewport.types.d.ts +30 -0
- package/dist/models/Point.types.d.ts +12 -0
- package/dist/models/Trade.types.d.ts +151 -0
- package/dist/models/VisibleRange.types.d.ts +15 -0
- package/dist/react/TradingReload.d.ts +28 -0
- package/dist/react/TradingReload.types.d.ts +74 -0
- package/dist/trading-reload-chart.css +2 -0
- package/dist/trading-reload-chart.js +3503 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Trading Reload Chart Commercial License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pradeep Jadhav. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software, including all source code, compiled code, assets, documentation,
|
|
6
|
+
and related materials (collectively, the "Software"), is proprietary and is
|
|
7
|
+
owned exclusively by Pradeep Jadhav.
|
|
8
|
+
|
|
9
|
+
1. No open source grant
|
|
10
|
+
|
|
11
|
+
No rights are granted under any open source license. Access to, download of,
|
|
12
|
+
installation of, or possession of the Software does not grant any right to use,
|
|
13
|
+
copy, modify, create derivative works of, distribute, sublicense, resell,
|
|
14
|
+
lease, rent, assign, transfer, disclose, or make the Software available to any
|
|
15
|
+
third party, except as expressly authorized in a separate written commercial
|
|
16
|
+
agreement issued by Pradeep Jadhav.
|
|
17
|
+
|
|
18
|
+
2. Commercial use only with a paid license
|
|
19
|
+
|
|
20
|
+
Any use of the Software requires a valid paid commercial license, subscription,
|
|
21
|
+
or other written authorization from Pradeep Jadhav. License scope, permitted
|
|
22
|
+
features, deployment limits, seat limits, environments, and subscription plan
|
|
23
|
+
restrictions may vary by purchased plan or written agreement.
|
|
24
|
+
|
|
25
|
+
3. Feature tiers and restrictions
|
|
26
|
+
|
|
27
|
+
Pradeep Jadhav may offer the Software under different commercial plans, tiers,
|
|
28
|
+
or feature sets. Your rights are limited to the plan you purchased. Use of
|
|
29
|
+
features outside your purchased plan is prohibited unless separately authorized
|
|
30
|
+
in writing.
|
|
31
|
+
|
|
32
|
+
4. Ownership
|
|
33
|
+
|
|
34
|
+
Pradeep Jadhav retains all worldwide right, title, and interest, including all
|
|
35
|
+
copyrights, trade secrets, trademarks, and all other intellectual property
|
|
36
|
+
rights, in and to the Software and all modifications, updates, enhancements,
|
|
37
|
+
and derivative works, to the maximum extent permitted by law. No ownership is
|
|
38
|
+
transferred to you.
|
|
39
|
+
|
|
40
|
+
5. Restrictions
|
|
41
|
+
|
|
42
|
+
Unless expressly authorized in a separate written agreement, you may not:
|
|
43
|
+
|
|
44
|
+
- use the Software in production or for internal business purposes;
|
|
45
|
+
- copy or redistribute the Software;
|
|
46
|
+
- modify, adapt, translate, or create derivative works;
|
|
47
|
+
- reverse engineer, decompile, disassemble, or attempt to extract non-public
|
|
48
|
+
logic, except to the limited extent such restriction is prohibited by
|
|
49
|
+
applicable law;
|
|
50
|
+
- remove or alter proprietary notices;
|
|
51
|
+
- use the Software to build a competing product or service;
|
|
52
|
+
- publish benchmarks or security analysis without prior written permission.
|
|
53
|
+
|
|
54
|
+
6. Termination
|
|
55
|
+
|
|
56
|
+
Any unauthorized use automatically terminates any rights you may have to the
|
|
57
|
+
Software. Upon termination, you must immediately cease use of the Software and
|
|
58
|
+
delete all copies in your possession or control, unless a separate written
|
|
59
|
+
agreement states otherwise.
|
|
60
|
+
|
|
61
|
+
7. Warranty disclaimer
|
|
62
|
+
|
|
63
|
+
TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" AND
|
|
64
|
+
"AS AVAILABLE", WITHOUT WARRANTIES OF ANY KIND, WHETHER EXPRESS, IMPLIED,
|
|
65
|
+
STATUTORY, OR OTHERWISE, INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
66
|
+
FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT.
|
|
67
|
+
|
|
68
|
+
8. Limitation of liability
|
|
69
|
+
|
|
70
|
+
TO THE MAXIMUM EXTENT PERMITTED BY LAW, PRADEEP JADHAV SHALL NOT BE LIABLE FOR
|
|
71
|
+
ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE
|
|
72
|
+
DAMAGES, OR FOR ANY LOSS OF DATA, PROFITS, REVENUE, BUSINESS, GOODWILL, OR
|
|
73
|
+
BUSINESS INTERRUPTION, ARISING OUT OF OR RELATED TO THE SOFTWARE OR THIS
|
|
74
|
+
LICENSE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. TO THE MAXIMUM
|
|
75
|
+
EXTENT PERMITTED BY LAW, THE TOTAL LIABILITY OF PRADEEP JADHAV FOR ANY CLAIM
|
|
76
|
+
RELATING TO THE SOFTWARE SHALL NOT EXCEED THE AMOUNT PAID BY YOU FOR THE
|
|
77
|
+
APPLICABLE LICENSE DURING THE TWELVE (12) MONTHS PRECEDING THE CLAIM.
|
|
78
|
+
|
|
79
|
+
9. Reservation of rights
|
|
80
|
+
|
|
81
|
+
All rights not expressly granted in a separate written commercial agreement are
|
|
82
|
+
reserved by Pradeep Jadhav.
|
|
83
|
+
|
|
84
|
+
10. Contact
|
|
85
|
+
|
|
86
|
+
For commercial licensing, subscriptions, or enterprise terms, contact Pradeep
|
|
87
|
+
Jadhav through the project repository or your negotiated business channel.
|
package/README.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# Trading Chart Library by Pradeep
|
|
2
|
+
|
|
3
|
+
A **React chart library** (HTML Canvas) for trading UIs: candlesticks, volume, axes, crosshair, drawing tools, and open/past trade overlays. Data and state are **controlled by the parent** via props and callbacks.
|
|
4
|
+
|
|
5
|
+
The repo includes a **demo app** under `demo/` (Vite dev server) that loads live/historical data from an API. That harness is not published in the npm package.
|
|
6
|
+
|
|
7
|
+
For architecture, conventions, and agent guidelines, see [AGENTS.md](./AGENTS.md).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- Node.js 18+
|
|
14
|
+
- npm (or compatible package manager)
|
|
15
|
+
- React **18.3+** or **19** (peer dependency when consuming the library)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Quick start (local development)
|
|
20
|
+
|
|
21
|
+
1. **Clone and install**
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
git clone <repository-url>
|
|
25
|
+
cd trading-reload-chart
|
|
26
|
+
npm install
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
2. **Run the demo** (hot reload, port **8999** by default)
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm run dev
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Open the URL Vite prints (typically `http://localhost:8999`). The demo mounts `TradingReload` with sample API/WebSocket wiring in `demo/`.
|
|
36
|
+
|
|
37
|
+
3. **Optional checks**
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm run typecheck # TypeScript
|
|
41
|
+
npm run lint # Biome
|
|
42
|
+
npm run format # Biome format
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Build commands
|
|
48
|
+
|
|
49
|
+
| Script | Purpose |
|
|
50
|
+
| -------------------- | ------------------------------------------- |
|
|
51
|
+
| `npm run dev` | Demo app from source (`demo/main.tsx`) |
|
|
52
|
+
| `npm run build` | **Library** build → `dist/` (ESM + `.d.ts`) |
|
|
53
|
+
| `npm run build:demo` | Static **demo** site build |
|
|
54
|
+
| `npm run preview` | Preview last Vite build |
|
|
55
|
+
|
|
56
|
+
### Production library build
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm run build
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Output (gitignored):
|
|
63
|
+
|
|
64
|
+
- `dist/trading-reload-chart.js` — ESM bundle (React externalized)
|
|
65
|
+
- `dist/index.d.ts` — public TypeScript declarations
|
|
66
|
+
|
|
67
|
+
`package.json` exposes the library via `"exports"`, `"main"`, `"module"`, and `"types"`. Only `dist/` is included in `"files"` for publishing.
|
|
68
|
+
|
|
69
|
+
### Demo production build
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm run build:demo
|
|
73
|
+
npm run preview
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Using the library in React / Next.js
|
|
79
|
+
|
|
80
|
+
The chart is **client-only** (canvas + DOM). It does **not** support SSR.
|
|
81
|
+
|
|
82
|
+
### 1. Install the package
|
|
83
|
+
|
|
84
|
+
**From npm** (after publish):
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm install trading-reload-chart react react-dom
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Directly from GitHub**:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npm install git+https://github.com/Pradeep17Jadhav/trading-reload-chart.git#main
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**From this repo** (local path or `npm pack`):
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# In trading-reload-chart repo
|
|
100
|
+
npm run build
|
|
101
|
+
npm pack
|
|
102
|
+
# In your app
|
|
103
|
+
npm install /path/to/trading-reload-chart/trading-reload-chart-1.0.0.tgz
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Or link during development:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
cd trading-reload-chart && npm run build && npm link
|
|
110
|
+
cd your-app && npm link trading-reload-chart
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 2. Next.js App Router
|
|
114
|
+
|
|
115
|
+
Use a client boundary. The component already includes `"use client"`.
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
"use client";
|
|
119
|
+
|
|
120
|
+
import { useState } from "react";
|
|
121
|
+
import {
|
|
122
|
+
TradingReload,
|
|
123
|
+
type Candle,
|
|
124
|
+
type Shape,
|
|
125
|
+
type ShapeToolType,
|
|
126
|
+
type OpenTrade,
|
|
127
|
+
} from "trading-reload-chart";
|
|
128
|
+
|
|
129
|
+
export function ChartPanel() {
|
|
130
|
+
const [candles, setCandles] = useState<Candle[]>([]);
|
|
131
|
+
const [shapes, setShapes] = useState<Shape[]>([]);
|
|
132
|
+
const [activeShapeTool, setActiveShapeTool] = useState<ShapeToolType | null>(
|
|
133
|
+
null,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<div className="h-full w-full min-h-[400px]">
|
|
138
|
+
<TradingReload
|
|
139
|
+
activeSymbol="EURUSD"
|
|
140
|
+
candles={candles}
|
|
141
|
+
shapes={shapes}
|
|
142
|
+
activeShapeTool={activeShapeTool}
|
|
143
|
+
onShapeAdded={(payload) => {
|
|
144
|
+
setShapes((prev) => [...prev, payload.shape]);
|
|
145
|
+
setActiveShapeTool(null);
|
|
146
|
+
}}
|
|
147
|
+
onActiveShapeToolChange={setActiveShapeTool}
|
|
148
|
+
/>
|
|
149
|
+
</div>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
- Give the parent a **defined height** (flex child, `h-full`, or fixed `min-height`). `TradingReload` fills **100%** of that container.
|
|
155
|
+
- Do **not** import chart CSS manually; styles ship with the component (`src/styles/chart.css`).
|
|
156
|
+
|
|
157
|
+
### 3. Vite / Create React App
|
|
158
|
+
|
|
159
|
+
Same import; wrap the chart in a sized container:
|
|
160
|
+
|
|
161
|
+
```tsx
|
|
162
|
+
import { TradingReload, type Candle } from "trading-reload-chart";
|
|
163
|
+
|
|
164
|
+
export function App() {
|
|
165
|
+
return (
|
|
166
|
+
<div style={{ width: "100%", height: "100vh" }}>
|
|
167
|
+
<TradingReload
|
|
168
|
+
activeSymbol="EURUSD"
|
|
169
|
+
candles={candles}
|
|
170
|
+
shapes={[]}
|
|
171
|
+
activeShapeTool={null}
|
|
172
|
+
/>
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 4. Public API surface
|
|
179
|
+
|
|
180
|
+
Import from the package root:
|
|
181
|
+
|
|
182
|
+
| Export | Description |
|
|
183
|
+
| -------------------------------------------- | -------------------- |
|
|
184
|
+
| `TradingReload` | Main React component |
|
|
185
|
+
| `TradingReloadProps` | Component props |
|
|
186
|
+
| `Candle`, `OpenTrade`, `ClosedTrade`, … | Domain types |
|
|
187
|
+
| `Shape`, `ShapeToolType`, shape payloads | Drawing types |
|
|
188
|
+
| `ChartConfig`, `CHART_CONFIG`, `DeepPartial` | Configuration |
|
|
189
|
+
| `PastTradeIndicator`, trade handle types | Trade overlay types |
|
|
190
|
+
|
|
191
|
+
Controlled props (parent owns state): `candles`, `liveCandle`, `openTrades`, `pastTrades`, `shapes`, `activeShapeTool`, `config`, `activeSymbol`.
|
|
192
|
+
|
|
193
|
+
Callbacks: `onShapeAdded`, `onShapeModified`, `onActiveShapeToolChange`, `onTradeModify`.
|
|
194
|
+
|
|
195
|
+
See [AGENTS.md](./AGENTS.md) for the full props contract.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Project layout
|
|
200
|
+
|
|
201
|
+
```txt
|
|
202
|
+
trading-reload-chart/
|
|
203
|
+
├── demo/ # Dev harness (API/WebSocket); not published
|
|
204
|
+
├── src/
|
|
205
|
+
│ ├── index.ts # Public exports
|
|
206
|
+
│ ├── react/ # TradingReload component
|
|
207
|
+
│ ├── chart/ # ChartController, DOM, utils
|
|
208
|
+
│ ├── canvas/layers/ # Canvas layers (candles, shapes, trades, …)
|
|
209
|
+
│ ├── config/ # CHART_CONFIG and types
|
|
210
|
+
│ ├── models/ # Candle, Trade, ChartViewport, … (*.types.ts)
|
|
211
|
+
│ ├── helpers/ # Shared pure utilities
|
|
212
|
+
│ ├── core/ # Coordinate math
|
|
213
|
+
│ └── styles/ # chart.css
|
|
214
|
+
├── dist/ # Library build output
|
|
215
|
+
├── AGENTS.md
|
|
216
|
+
└── vite.config.ts # `dev` = demo; `build --mode library` = package
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Type declarations live in **`*.types.ts`** files next to implementation code (see AGENTS.md).
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Features
|
|
224
|
+
|
|
225
|
+
- Layered canvas rendering (volume, candles, shapes, trades, axes, crosshair)
|
|
226
|
+
- Pan, horizontal wheel zoom, Ctrl+wheel vertical zoom
|
|
227
|
+
- Drawing tools (trendline, rectangle, path, fib, long/short position)
|
|
228
|
+
- Open trade SL/TP drag with `onTradeModify` on release
|
|
229
|
+
- Past trade markers
|
|
230
|
+
- Deep-merge chart `config` over defaults
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Interaction
|
|
235
|
+
|
|
236
|
+
| Action | Result |
|
|
237
|
+
| ---------------------- | --------------------------------------------- |
|
|
238
|
+
| Drag | Pan chart |
|
|
239
|
+
| Mouse wheel | Horizontal zoom |
|
|
240
|
+
| Ctrl + wheel | Vertical zoom |
|
|
241
|
+
| Move pointer | Crosshair + axis labels |
|
|
242
|
+
| Escape (while drawing) | Cancel tool (`onActiveShapeToolChange(null)`) |
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Browser support
|
|
247
|
+
|
|
248
|
+
Modern evergreen browsers with Canvas 2D (Chrome, Edge, Firefox, Safari).
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## License
|
|
253
|
+
|
|
254
|
+
Commercial, proprietary license. Use of this library requires a paid license,
|
|
255
|
+
subscription, or other written authorization from Pradeep Jadhav. See
|
|
256
|
+
[LICENSE](./LICENSE).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Candle } from '../../../models/Candle.types';
|
|
2
|
+
import { ChartViewport } from '../../../models/ChartViewport.types';
|
|
3
|
+
import { AxisLayerXCrosshair, AxisLayerXOptions } from './AxisLayerX.types';
|
|
4
|
+
export declare class AxisLayerX {
|
|
5
|
+
#private;
|
|
6
|
+
candles: Candle[];
|
|
7
|
+
viewport: ChartViewport | null;
|
|
8
|
+
crosshair: AxisLayerXCrosshair;
|
|
9
|
+
constructor(options: AxisLayerXOptions);
|
|
10
|
+
setCandles(candles: Candle[]): void;
|
|
11
|
+
setViewport(viewport: ChartViewport): void;
|
|
12
|
+
setCrosshair(crosshair: AxisLayerXCrosshair): void;
|
|
13
|
+
hideCrosshair(): void;
|
|
14
|
+
render(): void;
|
|
15
|
+
drawCrosshairTimeLabel(): void;
|
|
16
|
+
private clearCanvas;
|
|
17
|
+
private drawBackground;
|
|
18
|
+
private drawTopBorder;
|
|
19
|
+
private drawAxisLabels;
|
|
20
|
+
private getVisibleCandleIndexRange;
|
|
21
|
+
private getSlotTime;
|
|
22
|
+
private getCandleCenterX;
|
|
23
|
+
private isLabelOutsideCanvas;
|
|
24
|
+
private drawTick;
|
|
25
|
+
private drawLabel;
|
|
26
|
+
private getCrosshairLabelX;
|
|
27
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Candle } from '../../../models/Candle.types';
|
|
2
|
+
/**
|
|
3
|
+
* Detect candle timeframe from the data.
|
|
4
|
+
* Uses median of the first few inter-candle gaps to be robust against gaps.
|
|
5
|
+
*/
|
|
6
|
+
export declare const detectCandleTimeframeMs: (candles: Candle[]) => number;
|
|
7
|
+
/**
|
|
8
|
+
* Pick the smallest nice interval (in ms) that keeps labels from overlapping.
|
|
9
|
+
*/
|
|
10
|
+
export declare const getXAxisNiceIntervalMs: ({ candleSpacing, candleTimeframeMs, labelWidth, minLabelGap, }: {
|
|
11
|
+
candleSpacing: number;
|
|
12
|
+
candleTimeframeMs: number;
|
|
13
|
+
labelWidth: number;
|
|
14
|
+
minLabelGap: number;
|
|
15
|
+
}) => number;
|
|
16
|
+
/**
|
|
17
|
+
* Returns true when a timestamp is aligned to the given interval boundary
|
|
18
|
+
* using local (browser) time values, so labels display at round local times.
|
|
19
|
+
*/
|
|
20
|
+
export declare const isAlignedToInterval: (timestamp: number, intervalMs: number) => boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Format a timestamp for the X axis.
|
|
23
|
+
* At midnight (00:00 local) shows the day-of-month number (e.g. "15")
|
|
24
|
+
* so the viewer knows a new day started.
|
|
25
|
+
* All other times show HH:MM.
|
|
26
|
+
*/
|
|
27
|
+
export declare const formatXAxisLabel: (timestamp: number) => string;
|
|
28
|
+
/**
|
|
29
|
+
* Full date + time format for the crosshair tooltip.
|
|
30
|
+
* Example: "Wed 15 May 10.35"
|
|
31
|
+
*/
|
|
32
|
+
export declare const formatTimeDayDateHHMM: (timestamp: number) => string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ChartViewport } from '../../../models/ChartViewport.types';
|
|
2
|
+
import { AxisLayerYCrosshair, AxisLayerYOptions } from './AxisLayerY.types';
|
|
3
|
+
export declare class AxisLayerY {
|
|
4
|
+
#private;
|
|
5
|
+
viewport: ChartViewport | null;
|
|
6
|
+
crosshair: AxisLayerYCrosshair;
|
|
7
|
+
constructor(options: AxisLayerYOptions);
|
|
8
|
+
setViewport(viewport: ChartViewport): void;
|
|
9
|
+
setCrosshair(crosshair: AxisLayerYCrosshair): void;
|
|
10
|
+
hideCrosshair(): void;
|
|
11
|
+
render(): void;
|
|
12
|
+
drawCrosshairPriceLabel(): void;
|
|
13
|
+
private clearCanvas;
|
|
14
|
+
private drawBackground;
|
|
15
|
+
private drawLeftBorder;
|
|
16
|
+
private drawPriceLabels;
|
|
17
|
+
private getVisiblePriceRange;
|
|
18
|
+
private getPriceY;
|
|
19
|
+
private isPriceOutsideCanvas;
|
|
20
|
+
private drawTick;
|
|
21
|
+
private drawPriceLabel;
|
|
22
|
+
private getCrosshairLabelY;
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CrosshairLayerOptions, CrosshairStyle, UpdateMousePositionOptions } from './CrosshairLayer.types';
|
|
2
|
+
export declare class CrosshairLayer {
|
|
3
|
+
#private;
|
|
4
|
+
mouseX: number;
|
|
5
|
+
mouseY: number;
|
|
6
|
+
visible: boolean;
|
|
7
|
+
crosshairColor: string;
|
|
8
|
+
crosshairThickness: number;
|
|
9
|
+
crosshairStyle: CrosshairStyle;
|
|
10
|
+
constructor(options: CrosshairLayerOptions);
|
|
11
|
+
updateMousePosition(x: number, y: number, options?: UpdateMousePositionOptions): void;
|
|
12
|
+
hide(): void;
|
|
13
|
+
applyCrosshairStyle(): void;
|
|
14
|
+
drawVerticalCrosshairLine(ctx: CanvasRenderingContext2D, height: number): void;
|
|
15
|
+
drawHorizontalCrosshairLine(ctx: CanvasRenderingContext2D, width: number): void;
|
|
16
|
+
render(): void;
|
|
17
|
+
private getLocalCanvasPoint;
|
|
18
|
+
private clampX;
|
|
19
|
+
private clampY;
|
|
20
|
+
private clamp;
|
|
21
|
+
private getLineDash;
|
|
22
|
+
private drawLine;
|
|
23
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type CrosshairStyle = "solid" | "dashed" | "dotted";
|
|
2
|
+
export type CrosshairLayerOptions = {
|
|
3
|
+
canvas: HTMLCanvasElement;
|
|
4
|
+
crosshairColor?: string;
|
|
5
|
+
crosshairThickness?: number;
|
|
6
|
+
crosshairStyle?: CrosshairStyle;
|
|
7
|
+
};
|
|
8
|
+
export type UpdateMousePositionOptions = {
|
|
9
|
+
snapX?: number;
|
|
10
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Candle } from '../../models/Candle.types';
|
|
2
|
+
import { ChartViewport } from '../../models/ChartViewport.types';
|
|
3
|
+
import { VisibleRange } from '../../models/VisibleRange.types';
|
|
4
|
+
import { DrawCandlesOptions, DrawPriceLineOptions, DrawSingleCandleOptions, ExistingCandlesLayerOptions } from './ExistingCandlesLayer.types';
|
|
5
|
+
export declare class ExistingCandlesLayer {
|
|
6
|
+
#private;
|
|
7
|
+
candles: Candle[];
|
|
8
|
+
baseCandleWidth: number;
|
|
9
|
+
baseCandleGap: number;
|
|
10
|
+
bullishColor: string;
|
|
11
|
+
bearishColor: string;
|
|
12
|
+
/**
|
|
13
|
+
* Camera horizontal offset
|
|
14
|
+
*/
|
|
15
|
+
offsetX: number;
|
|
16
|
+
/**
|
|
17
|
+
* Horizontal zoom level
|
|
18
|
+
*/
|
|
19
|
+
zoomX: number;
|
|
20
|
+
/**
|
|
21
|
+
* Camera vertical range
|
|
22
|
+
*/
|
|
23
|
+
priceRange: number;
|
|
24
|
+
/**
|
|
25
|
+
* Camera vertical center
|
|
26
|
+
*/
|
|
27
|
+
priceCenter: number;
|
|
28
|
+
/**
|
|
29
|
+
* Baseline range used to calculate
|
|
30
|
+
* percentage-based vertical zoom limits.
|
|
31
|
+
*/
|
|
32
|
+
initialPriceRange: number;
|
|
33
|
+
/**
|
|
34
|
+
* Auto-follow feature enabled
|
|
35
|
+
*/
|
|
36
|
+
autoFollowLatestCandle: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Runtime follow state
|
|
39
|
+
*/
|
|
40
|
+
isFollowingLatest: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Threshold from right edge
|
|
43
|
+
* where auto-follow activates
|
|
44
|
+
*/
|
|
45
|
+
autoFollowThresholdCandles: number;
|
|
46
|
+
/**
|
|
47
|
+
* Empty candle spacing
|
|
48
|
+
* on right side
|
|
49
|
+
*/
|
|
50
|
+
rightOffsetCandles: number;
|
|
51
|
+
constructor(options: ExistingCandlesLayerOptions);
|
|
52
|
+
initializeViewport(): void;
|
|
53
|
+
isWithinAutoFollowThreshold(): boolean;
|
|
54
|
+
updateLiveCandle(candle: Candle): void;
|
|
55
|
+
get candleWidth(): number;
|
|
56
|
+
get candleGap(): number;
|
|
57
|
+
get candleSpacing(): number;
|
|
58
|
+
get minPrice(): number;
|
|
59
|
+
get maxPrice(): number;
|
|
60
|
+
get liveCandle(): Candle;
|
|
61
|
+
get viewport(): ChartViewport;
|
|
62
|
+
getVisibleRange(chartWidth: number): VisibleRange;
|
|
63
|
+
getCandleX(candleIndex: number): number;
|
|
64
|
+
getCandleCenterX(candleIndex: number): number;
|
|
65
|
+
getNearestCandleIndexByX(x: number): number | null;
|
|
66
|
+
/**
|
|
67
|
+
* Returns the grid-snapped canvas X for any position,
|
|
68
|
+
* including positions beyond the last candle (unclamped).
|
|
69
|
+
*/
|
|
70
|
+
getRawCandleSnapX(x: number): number;
|
|
71
|
+
getPriceAtY(y: number): number;
|
|
72
|
+
panHorizontally(deltaX: number): void;
|
|
73
|
+
panVertically(deltaY: number): void;
|
|
74
|
+
zoomHorizontally(delta: number): void;
|
|
75
|
+
zoomVertically(delta: number): void;
|
|
76
|
+
resetView(): void;
|
|
77
|
+
render(): void;
|
|
78
|
+
drawCandles({ ctx, candles, startIndex, chartHeight }: DrawCandlesOptions): void;
|
|
79
|
+
drawSingleCandle({ ctx, candleX, openY, closeY, highY, lowY, candleColor }: DrawSingleCandleOptions): void;
|
|
80
|
+
private drawPriceLine;
|
|
81
|
+
drawBidPriceLine({ ctx, chartWidth, chartHeight }: DrawPriceLineOptions): void;
|
|
82
|
+
drawAskPriceLine({ ctx, chartWidth, chartHeight }: DrawPriceLineOptions): void;
|
|
83
|
+
private getDefaultOffsetX;
|
|
84
|
+
private getTotalChartWidth;
|
|
85
|
+
private getRightOffsetPixels;
|
|
86
|
+
private getRightGap;
|
|
87
|
+
private setFallbackViewport;
|
|
88
|
+
private getInitialVisibleCandles;
|
|
89
|
+
private getCandlesPriceBounds;
|
|
90
|
+
private getInitialPriceRange;
|
|
91
|
+
private getInitialFallbackPercent;
|
|
92
|
+
private detectCandleTimeframeMs;
|
|
93
|
+
private applyManualViewportOverrides;
|
|
94
|
+
private closeLastCandle;
|
|
95
|
+
private appendLiveCandle;
|
|
96
|
+
private updateAutoFollowAfterAppend;
|
|
97
|
+
private clampCandleIndex;
|
|
98
|
+
private getRightEdgeCandleIndex;
|
|
99
|
+
private getNextHorizontalZoom;
|
|
100
|
+
private getNextVerticalPriceRange;
|
|
101
|
+
private clearCanvas;
|
|
102
|
+
private getCandleColor;
|
|
103
|
+
private getCandleYCoordinates;
|
|
104
|
+
private getPriceY;
|
|
105
|
+
private getBidPriceLineColor;
|
|
106
|
+
private getAskPriceLineColor;
|
|
107
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Candle } from '../../models/Candle.types';
|
|
2
|
+
export type ExistingCandlesLayerOptions = {
|
|
3
|
+
canvas: HTMLCanvasElement;
|
|
4
|
+
candles: Candle[];
|
|
5
|
+
baseCandleWidth?: number;
|
|
6
|
+
baseCandleGap?: number;
|
|
7
|
+
bullishColor?: string;
|
|
8
|
+
bearishColor?: string;
|
|
9
|
+
offsetX?: number;
|
|
10
|
+
zoomX?: number;
|
|
11
|
+
priceRange?: number;
|
|
12
|
+
priceCenter?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Enable automatic scrolling
|
|
15
|
+
* when latest candle moves
|
|
16
|
+
*/
|
|
17
|
+
autoFollowLatestCandle?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Number of candles from right edge
|
|
20
|
+
* where auto-follow becomes active.
|
|
21
|
+
*
|
|
22
|
+
* 0 = only when latest candle reaches right edge
|
|
23
|
+
*
|
|
24
|
+
* Example:
|
|
25
|
+
* 10 = auto-follow activates when
|
|
26
|
+
* latest candle reaches 10th position
|
|
27
|
+
* from right edge
|
|
28
|
+
*/
|
|
29
|
+
autoFollowThresholdCandles?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Empty candle space on right side
|
|
32
|
+
*/
|
|
33
|
+
rightOffsetCandles?: number;
|
|
34
|
+
};
|
|
35
|
+
export type CandleYCoordinates = {
|
|
36
|
+
openY: number;
|
|
37
|
+
closeY: number;
|
|
38
|
+
highY: number;
|
|
39
|
+
lowY: number;
|
|
40
|
+
};
|
|
41
|
+
export type DrawCandlesOptions = {
|
|
42
|
+
ctx: CanvasRenderingContext2D;
|
|
43
|
+
candles: Candle[];
|
|
44
|
+
startIndex: number;
|
|
45
|
+
chartHeight: number;
|
|
46
|
+
};
|
|
47
|
+
export type DrawSingleCandleOptions = CandleYCoordinates & {
|
|
48
|
+
ctx: CanvasRenderingContext2D;
|
|
49
|
+
candleX: number;
|
|
50
|
+
candleColor: string;
|
|
51
|
+
};
|
|
52
|
+
export type DrawPriceLineOptions = {
|
|
53
|
+
ctx: CanvasRenderingContext2D;
|
|
54
|
+
chartWidth: number;
|
|
55
|
+
chartHeight: number;
|
|
56
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { PreviousDayHighLowConfig } from '../../config/chartConfig.types';
|
|
2
|
+
import { ChartViewport } from '../../models/ChartViewport.types';
|
|
3
|
+
export type PreviousDay = {
|
|
4
|
+
high: number;
|
|
5
|
+
low: number;
|
|
6
|
+
};
|
|
7
|
+
type PdhPdlLayerOptions = {
|
|
8
|
+
ctx: CanvasRenderingContext2D;
|
|
9
|
+
config: PreviousDayHighLowConfig | null;
|
|
10
|
+
};
|
|
11
|
+
export declare class PdhPdlLayer {
|
|
12
|
+
#private;
|
|
13
|
+
constructor({ ctx, config }: PdhPdlLayerOptions);
|
|
14
|
+
setViewport(viewport: ChartViewport): void;
|
|
15
|
+
setConfig(config: PreviousDayHighLowConfig | null): void;
|
|
16
|
+
setPreviousDay(data: PreviousDay | null | undefined): void;
|
|
17
|
+
/**
|
|
18
|
+
* Draws PDH/PDL lines onto the shared canvas.
|
|
19
|
+
* The caller is responsible for clearing the canvas before rendering;
|
|
20
|
+
* this layer only appends on top of whatever is already drawn.
|
|
21
|
+
*/
|
|
22
|
+
render(): void;
|
|
23
|
+
}
|
|
24
|
+
export {};
|