1- import { Box , RangeSlider , RangeSliderValue } from "@mantine/core" ;
2- import { ArrowFatLinesRight , Pause , Play } from "@phosphor-icons/react" ;
1+ import { Box , Button , RangeSlider , RangeSliderValue } from "@mantine/core" ;
2+ import { ArrowFatLinesRight , CaretDoubleRight , Pause , Play } from "@phosphor-icons/react" ;
33import { useCallback , useEffect , useMemo , useRef , useState } from "react" ;
44import { useDataMethods } from "../data-processing/DataMethodsProvider" ;
55import DataSourceType from "@/models/DataSourceType" ;
66import useDebounceCallbackGreedy from "../utils/useGreedyDebounce" ;
7+ import { timeColumnName } from "../data-processing/datatypes" ;
78
89export default function TimelineBar ( ) {
910 const [ paused , setPaused ] = useState ( true ) ;
11+ const { switchToRecording } = useDataMethods ( ) ;
1012
1113 return (
1214 < >
@@ -23,61 +25,73 @@ export default function TimelineBar() {
2325 < MainSlider />
2426 </ div >
2527 < SyncButton />
28+ < Button
29+ onClick = { ( ) =>
30+ switchToRecording ( "fs-data/FS-2/2025-03-06-BrakingTests1.parquet" )
31+ }
32+ />
2633 </ div >
2734 </ >
2835 ) ;
2936}
3037
3138function SyncButton ( ) {
32- const [ isTimelineSynced , setIsTimelineSynced ] = useState ( false ) ;
33- const { subscribeIsTimelineSynced } = useDataMethods ( ) ;
39+ const [ enabled , setEnabled ] = useState ( false ) ;
40+ const [ visible , setVisible ] = useState ( false ) ;
41+ const { subscribeIsTimelineSynced, setIsTimelineSynced, subscribeDataSource } =
42+ useDataMethods ( ) ;
3443 useEffect ( ( ) => {
35- return subscribeIsTimelineSynced ( ( isTimelineSynced : boolean ) => {
36- setIsTimelineSynced ( isTimelineSynced ) ;
44+ const unsub1 = subscribeIsTimelineSynced ( ( isTimelineSynced : boolean ) => {
45+ setEnabled ( isTimelineSynced ) ;
3746 } ) ;
47+ const unsub2 = subscribeDataSource ( ( dataSourceType ) => {
48+ setVisible ( dataSourceType == DataSourceType . LIVE ) ;
49+ } ) ;
50+ return ( ) => {
51+ unsub1 ( ) ;
52+ unsub2 ( ) ;
53+ }
54+ } , [ ] ) ;
55+ const setTimelineSynced = useCallback ( ( ) => {
56+ setEnabled ( true ) ;
57+ setIsTimelineSynced ( true , "timelineBar" ) ;
3858 } , [ ] ) ;
39- const toggleIsTimelineSynced = useCallback ( ( ) => setIsTimelineSynced ( ! isTimelineSynced ) , [ ] ) ;
4059
41- return (
42- < Box c = { isTimelineSynced ? "neutral.8" : "neutral.5" } >
43- < ArrowFatLinesRight color = "currentColor" weight = "fill" onClick = { toggleIsTimelineSynced } />
60+ return visible ? (
61+ < Box c = { enabled ? "neutral.9" : "neutral.4" } >
62+ < CaretDoubleRight
63+ color = "currentColor"
64+ weight = "fill"
65+ size = { 24 }
66+ onClick = { enabled ? undefined : setTimelineSynced }
67+ />
4468 </ Box >
45- ) ;
69+ ) : null ;
4670}
4771
4872function MainSlider ( ) {
4973 const [ disabled , setDisabled ] = useState < boolean > ( false ) ;
50- const [ minMax , setMinMax ] = useState < RangeSliderValue > ( [ 0 , 10 ] ) ; // timestamp (seconds)
74+ const [ minMax , setMinMax ] = useState < RangeSliderValue > ( [ 0 , 10 ] ) ;
5175 const [ value , setValue ] = useState < RangeSliderValue > ( [ 0 , 10 ] ) ;
5276 const debouncedSetValue = useDebounceCallbackGreedy ( ( value ) => setValue ( value ) , 10 ) ;
5377 const ref = useRef < HTMLDivElement > ( null ) ;
54- // id is only used to differentiate between who set viewEdges (avoid infinite recursion)
78+ // id is only used to differentiate between who set viewInterval (avoid infinite recursion)
5579 const id = "timelineBar" ;
5680
81+ useEffect ( ( ) => console . log ( "value:" , value ) , [ value ] ) ;
82+
5783 const {
5884 setViewInterval,
5985 subscribeDataSource,
6086 subscribeNumRows,
6187 subscribeViewInterval,
6288 subscribeDataInterval,
6389 viewIntervalRef,
90+ dataArraysRef,
6491 // setCursorPosition, // eventually?
6592 } = useDataMethods ( ) ;
6693
67- // useEffect(() => {
68- // console.log("Updated minMax:", minMax);
69- // }, [minMax]); // Runs whenever minMax updates
70-
7194 useEffect ( ( ) => {
72- // const unsub1 = subscribeFullArrays((fullArrays) => {
73- // const timeCol = fullArrays[timeColumnName];
74- // // Need at least one point to set min/max!
75- // if (timeCol && timeCol.length > 0) {
76- // // Give 0.5s padding on either side
77- // setMinMax([timeCol[0] - 0.5, timeCol[timeCol.length - 1] + 0.5]);
78- // // console.log([timeCol[0] - 0.5, timeCol[timeCol.length - 1] + 0.5]);
79- // }
80- // });
8195 const unsub1 = subscribeDataInterval ( ( [ left , right ] ) => {
8296 setMinMax ( [ left , right ] ) ;
8397 } ) ;
@@ -105,12 +119,22 @@ function MainSlider() {
105119
106120 const onChange = useCallback ( ( range : RangeSliderValue ) => {
107121 if ( range [ 1 ] == viewIntervalRef . current [ 1 ] ) {
108- console . log ( "range[1] ==" , range [ 1 ] , "== value[1] ==" , viewIntervalRef . current [ 1 ] ) ;
122+ // console.log("range[1] ==", range[1], "== value[1] ==", viewIntervalRef.current[1]);
109123 } else {
110- console . log ( "range[1] ==" , range [ 1 ] , "=/= value[1] ==" , viewIntervalRef . current [ 1 ] ) ;
124+ // console.log(
125+ // "range[1] ==",
126+ // range[1],
127+ // "=/= value[1] ==",
128+ // viewIntervalRef.current[1],
129+ // );
111130 }
112131 setValue ( range ) ;
113- setViewInterval ( range , id ) ;
132+ // setViewInterval(range, id);
133+
134+ const val = dataArraysRef . current [ timeColumnName ] ! [ range [ 0 ] ] ;
135+ console . log ( "idx:" , range [ 0 ] , val , dataArraysRef . current [ ":Time" ] ) ;
136+ console . log ( "timeline setting range:" , range ) ;
137+
114138 } , [ ] ) ;
115139
116140 const sliderStyles = useMemo (
@@ -122,20 +146,29 @@ function MainSlider() {
122146 [ ] ,
123147 ) ;
124148
149+ const formatLabel = ( idx : number ) => {
150+ const val = dataArraysRef . current [ timeColumnName ] ! [ idx ] ;
151+
152+ // console.log("idx:", idx, val, dataArraysRef.current[":Time"]);
153+ return val !== undefined ? val . toFixed ( 2 ) : "???" ;
154+
155+ } ;
156+
125157 return (
126158 < >
127159 < RangeSlider
128160 ref = { ref }
129- step = { 0.01 } // 100Hz == 0.01s per point
161+ step = { 1 } // timeline _only_ refers to indexes into data arrays, so must be integers only
130162 disabled = { disabled }
131163 onChange = { onChange }
132164 // it's right around the corner I can feel it...
133- min = { 55000 } // min={ minMax[0]}
134- max = { 58000 } // max={ minMax[1]}
135- minRange = { 10 }
136- // maxRange ??
165+ min = { minMax [ 0 ] }
166+ max = { minMax [ 1 ] }
167+ minRange = { 1 }
168+ maxRange = { minMax [ 1 ] - minMax [ 0 ] }
137169 value = { value }
138170 styles = { sliderStyles }
171+ label = { formatLabel }
139172 />
140173 { /* <DraggableRangeSlider */ }
141174 { /* value={sliderRange} */ }
0 commit comments