@@ -28,12 +28,6 @@ ChartJS.register(
2828 TimeScale ,
2929) ;
3030
31- interface TideDataPoint {
32- time : Date ;
33- level : number ;
34- label ?: string ;
35- }
36-
3731interface Props {
3832 station : Station ;
3933 extremesData : ExtremesResponse | null ;
@@ -42,31 +36,35 @@ interface Props {
4236
4337export function TideGraph ( { station, extremesData, timelineData } : Props ) {
4438 const units = timelineData ?. units || extremesData ?. units || "meters" ;
45- const isReference = station . type === "reference" ;
4639
47- const data : TideDataPoint [ ] = useMemo ( ( ) => {
48- if ( isReference && timelineData ) {
49- return timelineData . timeline . map ( ( p ) => ( {
50- time : new Date ( p . time ) ,
51- level : p . level ,
52- } ) ) ;
53- }
54- if ( ! isReference && extremesData ) {
55- return extremesData . extremes . map ( ( p ) => ( {
56- time : new Date ( p . time ) ,
57- level : p . level ,
58- label : p . label ,
59- } ) ) ;
60- }
61- return [ ] ;
62- } , [ isReference , timelineData , extremesData ] ) ;
40+ const timelinePoints = useMemo ( ( ) => {
41+ if ( ! timelineData ) return [ ] ;
42+ return timelineData . timeline . map ( ( p ) => ( {
43+ time : new Date ( p . time ) ,
44+ level : p . level ,
45+ } ) ) ;
46+ } , [ timelineData ] ) ;
47+
48+ const extremePoints = useMemo ( ( ) => {
49+ if ( ! extremesData ) return [ ] ;
50+ return extremesData . extremes . map ( ( p ) => ( {
51+ time : new Date ( p . time ) ,
52+ level : p . level ,
53+ label : p . label ,
54+ } ) ) ;
55+ } , [ extremesData ] ) ;
6356
6457 const datum =
65- ( isReference ? timelineData ?. datum : extremesData ?. datum ) ||
66- station . chart_datum ;
58+ timelineData ?. datum || extremesData ?. datum || station . chart_datum ;
6759
68- const minLevel = data . length > 0 ? Math . min ( ...data . map ( ( d ) => d . level ) ) : 0 ;
69- const maxLevel = data . length > 0 ? Math . max ( ...data . map ( ( d ) => d . level ) ) : 2 ;
60+ const minLevel =
61+ timelinePoints . length > 0
62+ ? Math . min ( ...timelinePoints . map ( ( d ) => d . level ) )
63+ : 0 ;
64+ const maxLevel =
65+ timelinePoints . length > 0
66+ ? Math . max ( ...timelinePoints . map ( ( d ) => d . level ) )
67+ : 2 ;
7068 const padding = ( maxLevel - minLevel ) * 0.1 || 0.5 ;
7169
7270 const pointDateStyle = Intl . DateTimeFormat ( undefined , {
@@ -84,9 +82,21 @@ export function TideGraph({ station, extremesData, timelineData }: Props) {
8482 const currentTime = new Date ( ) ;
8583 const chartData = {
8684 datasets : [
85+ {
86+ label : "High/Low" ,
87+ data : extremePoints . map ( ( d ) => ( { x : d . time , y : d . level } ) ) ,
88+ borderColor : "transparent" ,
89+ backgroundColor : "#0284c7" ,
90+ borderWidth : 0 ,
91+ fill : false ,
92+ pointRadius : 5 ,
93+ pointHoverRadius : 7 ,
94+ pointStyle : "circle" as const ,
95+ showLine : false ,
96+ } ,
8797 {
8898 label : "Water Level" ,
89- data : data . map ( ( d ) => ( { x : d . time , y : d . level } ) ) ,
99+ data : timelinePoints . map ( ( d ) => ( { x : d . time , y : d . level } ) ) ,
90100 borderColor : "#0ea5e9" ,
91101 backgroundColor : "rgba(14, 165, 233, 0.1)" ,
92102 borderWidth : 2 ,
@@ -124,13 +134,19 @@ export function TideGraph({ station, extremesData, timelineData }: Props) {
124134 } ,
125135 tooltip : {
126136 displayColors : false ,
137+ filter : ( item : any ) => item . dataset . label !== "Current Time" ,
127138 callbacks : {
128139 title : ( context : any ) => {
129140 if ( context . length === 0 ) return "" ;
130141 return pointDateStyle . format ( new Date ( context [ 0 ] . parsed . x ) ) ;
131142 } ,
132143 label : ( context : any ) => {
133- return `${ ( context . parsed . y ?? 0 ) . toFixed ( 2 ) } ${ unitsLabel } ` ;
144+ const value = `${ ( context . parsed . y ?? 0 ) . toFixed ( 2 ) } ${ unitsLabel } ` ;
145+ if ( context . dataset . label === "High/Low" ) {
146+ const extreme = extremePoints [ context . dataIndex ] ;
147+ return extreme ?. label ? `${ extreme . label } : ${ value } ` : value ;
148+ }
149+ return value ;
134150 } ,
135151 } ,
136152 } ,
@@ -165,7 +181,7 @@ export function TideGraph({ station, extremesData, timelineData }: Props) {
165181 return (
166182 < div className = "space-y-4" >
167183 < div className = "" >
168- { data . length > 0 ? (
184+ { timelinePoints . length > 0 ? (
169185 < div >
170186 < Line data = { chartData } options = { chartOptions } />
171187 </ div >
0 commit comments