@@ -16,6 +16,7 @@ const BarChartRace = ({ title, barRaceData }) => {
1616 const svgRef = useRef ( null ) ; // Reference to the SVG element
1717 const currentKeyframeRef = useRef ( 0 ) ; // Tracks the current keyframe
1818 const [ isPlaying , setIsPlaying ] = useState ( false ) ; // Play/pause state
19+ const [ playSpeed , setPlaySpeed ] = useState ( 5 ) ;
1920 const [ startYear , setStartYear ] = useState ( 0 ) ; // Minimum year in data
2021 const [ endYear , setEndYear ] = useState ( 0 ) ; // Maximum year in data
2122 const [ year , setYear ] = useState ( startYear ) ; // Current selected year
@@ -24,6 +25,8 @@ const BarChartRace = ({ title, barRaceData }) => {
2425 const keyframesRef = useRef ( [ ] ) ; // Stores all keyframes
2526 const timeoutRef = useRef ( null ) ; // Handles animation timing
2627 const inputRef = useRef ( null ) ; // Reference to range input
28+ const inputSpeedRef = useRef ( null ) ; // Reference to speed input
29+ const DEFAULT_TRANSITION_DELAY = 250 ;
2730
2831 useEffect ( ( ) => {
2932 const fetchDataAsync = ( ) => {
@@ -71,7 +74,10 @@ const BarChartRace = ({ title, barRaceData }) => {
7174
7275 const startAnimation = ( ) => {
7376 if ( currentKeyframeRef . current < keyframesRef . current . length ) {
74- const transition = svgRef . current . transition ( ) . duration ( 250 ) . ease ( d3 . easeLinear ) ;
77+ const animationDelay = 1000 / playSpeed ;
78+
79+ const transition = svgRef . current . transition ( ) . duration ( animationDelay ) . ease ( d3 . easeLinear ) ;
80+
7581 const keyframe = keyframesRef . current [ currentKeyframeRef . current ] ;
7682
7783 updateChart ( keyframe , transition , inputRef , null ) ;
@@ -83,7 +89,7 @@ const BarChartRace = ({ title, barRaceData }) => {
8389 setYear ( keyframe [ 0 ] . getFullYear ( ) ) ;
8490
8591 // Continue animation after delay
86- timeoutRef . current = setTimeout ( startAnimation , 250 ) ;
92+ timeoutRef . current = setTimeout ( startAnimation , animationDelay ) ;
8793 } else {
8894 setIsPlaying ( false ) ;
8995 }
@@ -92,7 +98,7 @@ const BarChartRace = ({ title, barRaceData }) => {
9298 const playPause = ( ) => {
9399 if ( isPlaying ) {
94100 clearTimeout ( timeoutRef . current ) ;
95- const transition = svgRef . current . transition ( ) . duration ( 250 ) . ease ( d3 . easeLinear ) ;
101+ const transition = svgRef . current . transition ( ) . duration ( DEFAULT_TRANSITION_DELAY ) . ease ( d3 . easeLinear ) ;
96102 updateChart ( currentKeyframeState , transition , inputRef , null ) ;
97103 } else {
98104 startAnimation ( ) ;
@@ -110,12 +116,19 @@ const BarChartRace = ({ title, barRaceData }) => {
110116 const frameIndex = keyframesRef . current . findIndex ( frame => frame [ 0 ] . getFullYear ( ) === selectedYear ) ;
111117
112118 if ( frameIndex !== - 1 ) {
113- const transition = svgRef . current . transition ( ) . duration ( 250 ) . ease ( d3 . easeLinear ) ;
119+ const transition = svgRef . current . transition ( ) . duration ( DEFAULT_TRANSITION_DELAY ) . ease ( d3 . easeLinear ) ;
114120 currentKeyframeRef . current = frameIndex ; // Set current keyframe
115121 updateChart ( keyframesRef . current [ frameIndex ] , transition , inputRef , null ) ;
116122 }
117123 } ;
118124
125+ const onPlaySpeedChange = ( event ) => {
126+ const selectedSpeed = parseInt ( event . target . value , 10 ) ;
127+ setPlaySpeed ( selectedSpeed ) ;
128+ clearTimeout ( timeoutRef . current ) ;
129+ setIsPlaying ( false ) ;
130+ } ;
131+
119132 return (
120133 < div id = "parent-container" className = "relative p-4" >
121134 < div id = "play-controls" className = "flex items-center mb-4" >
@@ -135,6 +148,16 @@ const BarChartRace = ({ title, barRaceData }) => {
135148 onChange = { onRangeChange }
136149 ref = { inputRef }
137150 />
151+ < input
152+ id = "play-speed"
153+ type = "number"
154+ value = { playSpeed }
155+ min = "1"
156+ max = "10"
157+ className = "ml-2"
158+ onChange = { onPlaySpeedChange }
159+ ref = { inputSpeedRef }
160+ />
138161 </ div >
139162 < div id = "container" > </ div >
140163 </ div >
0 commit comments