@@ -13,7 +13,6 @@ import type {
1313 ISeriesApi ,
1414 LineData ,
1515 UTCTimestamp ,
16- WhitespaceData ,
1716} from "lightweight-charts" ;
1817import {
1918 AreaSeries ,
@@ -28,8 +27,8 @@ import { z } from "zod";
2827
2928import styles from "./chart.module.scss" ;
3029import {
31- lookbackToMilliseconds ,
32- useChartLookback ,
30+ quickSelectWindowToMilliseconds ,
31+ useChartQuickSelectWindow ,
3332 useChartResolution ,
3433} from "./use-chart-toolbar" ;
3534import { useLivePriceData } from "../../../hooks/use-live-price-data" ;
@@ -62,19 +61,14 @@ const useChart = (symbol: string, feedId: string) => {
6261
6362const useChartElem = ( symbol : string , feedId : string ) => {
6463 const logger = useLogger ( ) ;
65- const [ lookback ] = useChartLookback ( ) ;
64+ const [ quickSelectWindow ] = useChartQuickSelectWindow ( ) ;
6665 const [ resolution ] = useChartResolution ( ) ;
6766 const chartContainerRef = useRef < HTMLDivElement | null > ( null ) ;
6867 const chartRef = useRef < ChartRefContents | undefined > ( undefined ) ;
6968 const isBackfilling = useRef ( false ) ;
7069 const priceFormatter = usePriceFormatter ( ) ;
71- const resolutionRef = useRef ( resolution ) ;
7270 const abortControllerRef = useRef < AbortController | undefined > ( undefined ) ;
7371
74- useEffect ( ( ) => {
75- resolutionRef . current = resolution ;
76- } , [ resolution ] ) ;
77-
7872 const { current : livePriceData } = useLivePriceData ( Cluster . Pythnet , feedId ) ;
7973
8074 const didResetVisibleRange = useRef ( false ) ;
@@ -154,31 +148,33 @@ const useChartElem = (symbol: string, feedId: string) => {
154148 } ) ;
155149
156150 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 ) => {
159153 if ( ! chartRef . current ) {
160154 return ;
161155 }
162156
157+ const data = historicalDataSchema . parse ( jsonData ) ;
158+
163159 // 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 [ ] ;
167163 const currentHistoricalConfidenceHighData =
168- chartRef . current . confidenceHigh . data ( ) . filter ( ( d ) => isLineData ( d ) ) ;
164+ chartRef . current . confidenceHigh . data ( ) as LineData [ ] ;
169165 const currentHistoricalConfidenceLowData =
170- chartRef . current . confidenceLow . data ( ) . filter ( ( d ) => isLineData ( d ) ) ;
166+ chartRef . current . confidenceLow . data ( ) as LineData [ ] ;
171167
172168 const newHistoricalPriceData = data . map ( ( d ) => ( {
173- time : Number ( d . timestamp ) as UTCTimestamp ,
169+ time : d . time ,
174170 value : d . price ,
175171 } ) ) ;
176172 const newHistoricalConfidenceHighData = data . map ( ( d ) => ( {
177- time : Number ( d . timestamp ) as UTCTimestamp ,
173+ time : d . time ,
178174 value : d . price + d . confidence ,
179175 } ) ) ;
180176 const newHistoricalConfidenceLowData = data . map ( ( d ) => ( {
181- time : Number ( d . timestamp ) as UTCTimestamp ,
177+ time : d . time ,
182178 value : d . price - d . confidence ,
183179 } ) ) ;
184180
@@ -273,15 +269,15 @@ const useChartElem = (symbol: string, feedId: string) => {
273269 const newToMs = firstMs ;
274270 const newFromMs = startOfResolution (
275271 new Date ( newToMs - visibleRangeMs ) ,
276- resolutionRef . current ,
272+ resolution ,
277273 ) ;
278274
279275 // When we're getting close to the earliest data, we need to backfill more
280276 if ( remainingDataMs <= threshold ) {
281277 fetchHistoricalData ( {
282278 from : newFromMs / 1000 ,
283279 to : newToMs / 1000 ,
284- resolution : resolutionRef . current ,
280+ resolution,
285281 } ) ;
286282 }
287283 } ) ;
@@ -306,7 +302,9 @@ const useChartElem = (symbol: string, feedId: string) => {
306302 const now = new Date ( ) ;
307303 const to = startOfResolution ( now , resolution ) ;
308304 const from = startOfResolution (
309- new Date ( now . getTime ( ) - lookbackToMilliseconds ( lookback ) ) ,
305+ new Date (
306+ now . getTime ( ) - quickSelectWindowToMilliseconds ( quickSelectWindow ) ,
307+ ) ,
310308 resolution ,
311309 ) ;
312310
@@ -326,7 +324,7 @@ const useChartElem = (symbol: string, feedId: string) => {
326324 to : to / 1000 ,
327325 resolution,
328326 } ) ;
329- } , [ lookback , resolution , fetchHistoricalData ] ) ;
327+ } , [ quickSelectWindow , resolution , fetchHistoricalData ] ) ;
330328
331329 return { chartRef, chartContainerRef } ;
332330} ;
@@ -340,11 +338,17 @@ type ChartRefContents = {
340338} ;
341339
342340const 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+ } ) ) ,
348352) ;
349353const priceFormat = {
350354 type : "price" ,
@@ -443,17 +447,12 @@ const getColors = (container: HTMLDivElement, resolvedTheme: string) => {
443447 } ;
444448} ;
445449
446- function isLineData ( data : LineData | WhitespaceData ) : data is LineData {
447- return "time" in data && "value" in data ;
448- }
449-
450450/**
451451 * Merge (and sort) two arrays of line data, deduplicating by time
452452 */
453453export function mergeData ( as : LineData [ ] , bs : LineData [ ] ) {
454454 const unique = new Map < number , LineData > ( ) ;
455455
456- // TODO fhqvst Can optimize with while's
457456 for ( const a of as ) {
458457 unique . set ( a . time as number , a ) ;
459458 }
0 commit comments