1+ import bytes from 'bytes'
2+ import dayjs from 'dayjs'
3+ import type { DurationUnitType } from 'dayjs/plugin/duration'
14import { Dispatch , ReactNode , SetStateAction , useEffect , useState } from 'react'
25import { useParams } from 'react-router-dom'
36
@@ -7,25 +10,62 @@ import { pastDateRange } from '@/date-utils'
710import RequestsChart from './RequestsChart'
811import BandwidthChart from './BandwidthChart'
912import EarningsChart from './EarningsChart'
10- import bytes from 'bytes'
1113
1214interface OverviewProps {
1315 metricsRes : MetricsResponse
1416 address : string
1517 children ?: ReactNode
1618}
1719
18- function periodToDateRange ( period : TimePeriod ) {
20+ function periodToDateOptions ( period : TimePeriod ) {
21+ let dateRange
22+ let step : DurationUnitType
23+
1924 switch ( period ) {
25+ case TimePeriod . HOUR :
26+ dateRange = pastDateRange ( 'hour' )
27+ step = 'minute'
28+ break
2029 case TimePeriod . WEEK :
21- return pastDateRange ( 'week' )
30+ dateRange = pastDateRange ( 'week' )
31+ step = 'day'
32+ break
2233 case TimePeriod . TWO_WEEK :
23- return pastDateRange ( 'week' , 2 )
24- case TimePeriod . MONTH :
25- return pastDateRange ( 'month' )
26- // case TimePeriod.SIX_MONTH:
27- // return pastDateRange('month', 6)
34+ dateRange = pastDateRange ( 'week' , 2 )
35+ step = 'day'
36+ break
37+ case TimePeriod . DAY :
38+ default :
39+ dateRange = pastDateRange ( 'day' )
40+ step = 'hour'
41+ break
42+ // case TimePeriod.MONTH:
43+ // dateRange = pastDateRange('month')
44+ // break
45+ }
46+
47+ return { dateRange, step }
48+ }
49+
50+ function createChartProps (
51+ dateRange : { startDate : Date , endDate : Date } ,
52+ unit : DurationUnitType ,
53+ isLoading : boolean
54+ ) {
55+ const xScale = {
56+ type : 'time' ,
57+ time : {
58+ unit
59+ } ,
60+ min : dateRange . startDate . getTime ( ) ,
61+ max : dateRange . endDate . getTime ( )
2862 }
63+
64+ // https://github.com/chartjs/Chart.js/pull/6993
65+ // Break the line chart when missing a data point.
66+ const spanGaps = dayjs . duration ( 1 , unit ) . asMilliseconds ( )
67+
68+ return { dateRange, xScale, spanGaps, isLoading }
2969}
3070
3171function SelectTimePeriod (
@@ -87,12 +127,12 @@ function Dashboard () {
87127 ] = useState < MetricsResponse > ( { earnings : [ ] , nodes : [ ] , metrics : [ ] } )
88128
89129 const [ period , setPeriod ] = useState < TimePeriod > ( TimePeriod . WEEK )
90- const dateRange = periodToDateRange ( period )
130+ const { dateRange, step } = periodToDateOptions ( period )
91131 const { startDate, endDate } = dateRange
92132
93- // Don't update chart axes until data is fetched.
94- // It looks weird if axes update immediately.
95- const [ chartDateRange , setChartDateRange ] = useState ( dateRange )
133+ // Don't update charts until data is fetched.
134+ // It looks weird if charts update immediately.
135+ const [ chartOpts , setChartOpts ] = useState ( { dateRange, step } )
96136
97137 const fetchData = async ( ) => {
98138 if ( ! address ) { return }
@@ -102,9 +142,9 @@ function Dashboard () {
102142 setError ( null )
103143
104144 const metricsRes = await api . fetchMetrics (
105- address , startDate , endDate )
145+ address , startDate , endDate , step )
106146 setMetricsRes ( metricsRes )
107- setChartDateRange ( dateRange )
147+ setChartOpts ( { dateRange, step } )
108148 } catch ( err ) {
109149 if ( err instanceof Error ) {
110150 setError ( err ?. message ?? 'Error retrieving metrics.' )
@@ -114,12 +154,10 @@ function Dashboard () {
114154 }
115155 }
116156
117- useEffect ( ( ) => {
118- fetchData ( )
119- } , [ address , startDate . getTime ( ) , endDate . getTime ( ) ] )
157+ useEffect ( ( ) => { fetchData ( ) } , [ address , period ] )
120158
121159 const { earnings, metrics } = metricsRes
122- const chartProps = { dateRange : chartDateRange , isLoading }
160+ const chartProps = createChartProps ( chartOpts . dateRange , chartOpts . step , isLoading )
123161
124162 return (
125163 < div className = "flex-1 flex flex-col gap-4 mt-8" >
0 commit comments