@@ -13,7 +13,6 @@ import type {
13
13
ISeriesApi ,
14
14
LineData ,
15
15
UTCTimestamp ,
16
- WhitespaceData ,
17
16
} from "lightweight-charts" ;
18
17
import {
19
18
AreaSeries ,
@@ -28,8 +27,8 @@ import { z } from "zod";
28
27
29
28
import styles from "./chart.module.scss" ;
30
29
import {
31
- lookbackToMilliseconds ,
32
- useChartLookback ,
30
+ quickSelectWindowToMilliseconds ,
31
+ useChartQuickSelectWindow ,
33
32
useChartResolution ,
34
33
} from "./use-chart-toolbar" ;
35
34
import { useLivePriceData } from "../../../hooks/use-live-price-data" ;
@@ -62,19 +61,14 @@ const useChart = (symbol: string, feedId: string) => {
62
61
63
62
const useChartElem = ( symbol : string , feedId : string ) => {
64
63
const logger = useLogger ( ) ;
65
- const [ lookback ] = useChartLookback ( ) ;
64
+ const [ quickSelectWindow ] = useChartQuickSelectWindow ( ) ;
66
65
const [ resolution ] = useChartResolution ( ) ;
67
66
const chartContainerRef = useRef < HTMLDivElement | null > ( null ) ;
68
67
const chartRef = useRef < ChartRefContents | undefined > ( undefined ) ;
69
68
const isBackfilling = useRef ( false ) ;
70
69
const priceFormatter = usePriceFormatter ( ) ;
71
- const resolutionRef = useRef ( resolution ) ;
72
70
const abortControllerRef = useRef < AbortController | undefined > ( undefined ) ;
73
71
74
- useEffect ( ( ) => {
75
- resolutionRef . current = resolution ;
76
- } , [ resolution ] ) ;
77
-
78
72
const { current : livePriceData } = useLivePriceData ( Cluster . Pythnet , feedId ) ;
79
73
80
74
const didResetVisibleRange = useRef ( false ) ;
@@ -154,31 +148,33 @@ const useChartElem = (symbol: string, feedId: string) => {
154
148
} ) ;
155
149
156
150
fetch ( url , { signal : abortControllerRef . current . signal } )
157
- . then ( async ( data ) => historicalDataSchema . parse ( await data . json ( ) ) )
158
- . then ( ( data ) => {
151
+ . then ( ( rawData ) => rawData . json ( ) )
152
+ . then ( ( jsonData ) => {
159
153
if ( ! chartRef . current ) {
160
154
return ;
161
155
}
162
156
157
+ const data = historicalDataSchema . parse ( jsonData ) ;
158
+
163
159
// Get the current historical price data
164
- const currentHistoricalPriceData = chartRef . current . price
165
- . data ( )
166
- . filter ( ( d ) => isLineData ( d ) ) ;
160
+ // Note that .data() returns (WhitespaceData | LineData)[], hence the type cast
161
+ const currentHistoricalPriceData =
162
+ chartRef . current . price . data ( ) as LineData [ ] ;
167
163
const currentHistoricalConfidenceHighData =
168
- chartRef . current . confidenceHigh . data ( ) . filter ( ( d ) => isLineData ( d ) ) ;
164
+ chartRef . current . confidenceHigh . data ( ) as LineData [ ] ;
169
165
const currentHistoricalConfidenceLowData =
170
- chartRef . current . confidenceLow . data ( ) . filter ( ( d ) => isLineData ( d ) ) ;
166
+ chartRef . current . confidenceLow . data ( ) as LineData [ ] ;
171
167
172
168
const newHistoricalPriceData = data . map ( ( d ) => ( {
173
- time : Number ( d . timestamp ) as UTCTimestamp ,
169
+ time : d . time ,
174
170
value : d . price ,
175
171
} ) ) ;
176
172
const newHistoricalConfidenceHighData = data . map ( ( d ) => ( {
177
- time : Number ( d . timestamp ) as UTCTimestamp ,
173
+ time : d . time ,
178
174
value : d . price + d . confidence ,
179
175
} ) ) ;
180
176
const newHistoricalConfidenceLowData = data . map ( ( d ) => ( {
181
- time : Number ( d . timestamp ) as UTCTimestamp ,
177
+ time : d . time ,
182
178
value : d . price - d . confidence ,
183
179
} ) ) ;
184
180
@@ -273,15 +269,15 @@ const useChartElem = (symbol: string, feedId: string) => {
273
269
const newToMs = firstMs ;
274
270
const newFromMs = startOfResolution (
275
271
new Date ( newToMs - visibleRangeMs ) ,
276
- resolutionRef . current ,
272
+ resolution ,
277
273
) ;
278
274
279
275
// When we're getting close to the earliest data, we need to backfill more
280
276
if ( remainingDataMs <= threshold ) {
281
277
fetchHistoricalData ( {
282
278
from : newFromMs / 1000 ,
283
279
to : newToMs / 1000 ,
284
- resolution : resolutionRef . current ,
280
+ resolution,
285
281
} ) ;
286
282
}
287
283
} ) ;
@@ -306,7 +302,9 @@ const useChartElem = (symbol: string, feedId: string) => {
306
302
const now = new Date ( ) ;
307
303
const to = startOfResolution ( now , resolution ) ;
308
304
const from = startOfResolution (
309
- new Date ( now . getTime ( ) - lookbackToMilliseconds ( lookback ) ) ,
305
+ new Date (
306
+ now . getTime ( ) - quickSelectWindowToMilliseconds ( quickSelectWindow ) ,
307
+ ) ,
310
308
resolution ,
311
309
) ;
312
310
@@ -326,7 +324,7 @@ const useChartElem = (symbol: string, feedId: string) => {
326
324
to : to / 1000 ,
327
325
resolution,
328
326
} ) ;
329
- } , [ lookback , resolution , fetchHistoricalData ] ) ;
327
+ } , [ quickSelectWindow , resolution , fetchHistoricalData ] ) ;
330
328
331
329
return { chartRef, chartContainerRef } ;
332
330
} ;
@@ -340,11 +338,17 @@ type ChartRefContents = {
340
338
} ;
341
339
342
340
const historicalDataSchema = z . array (
343
- z . strictObject ( {
344
- timestamp : z . number ( ) . transform ( BigInt ) ,
345
- price : z . number ( ) ,
346
- confidence : z . number ( ) ,
347
- } ) ,
341
+ z
342
+ . strictObject ( {
343
+ timestamp : z . number ( ) ,
344
+ price : z . number ( ) ,
345
+ confidence : z . number ( ) ,
346
+ } )
347
+ . transform ( ( d ) => ( {
348
+ time : Number ( d . timestamp ) as UTCTimestamp ,
349
+ price : d . price ,
350
+ confidence : d . confidence ,
351
+ } ) ) ,
348
352
) ;
349
353
const priceFormat = {
350
354
type : "price" ,
@@ -443,17 +447,12 @@ const getColors = (container: HTMLDivElement, resolvedTheme: string) => {
443
447
} ;
444
448
} ;
445
449
446
- function isLineData ( data : LineData | WhitespaceData ) : data is LineData {
447
- return "time" in data && "value" in data ;
448
- }
449
-
450
450
/**
451
451
* Merge (and sort) two arrays of line data, deduplicating by time
452
452
*/
453
453
export function mergeData ( as : LineData [ ] , bs : LineData [ ] ) {
454
454
const unique = new Map < number , LineData > ( ) ;
455
455
456
- // TODO fhqvst Can optimize with while's
457
456
for ( const a of as ) {
458
457
unique . set ( a . time as number , a ) ;
459
458
}
0 commit comments