Formula1 Race Result by Bar-Chart-Race

Web Development




Project Overview


You can see this project at http://f1raceresult.xyz

f1_race_result is my first web front-end project that summarizes Formula1 race results by bar-chart-race. For now, you can see all race results after 2022.

The above site is optimized for laptop or desktop screens.

Please send all bug reports or questions by email below.

doryeon514@gm.gist.ac.kr / doryeon514@gmail.com


Algorithm


Data Processing

I use Fast-F1 python package to access race session data.

I configure below class to process f1 telemetry data.

import fastf1
class RaceDataProcessor:
    def __init__(self,year:int,circuit:str):
        self.year = year
        self.circuit = circuit
        self.race = fastf1.get_session(self.year, self.circuit, 'R')

I got three sets of data per lap.

    def getGaptoAnother(self, driver_name):
        gap_result = []
        driver_laps = self.race.laps.pick_driver(driver_name).reset_index()
        for i in range(self.race.total_laps):
            for sector in ["Sector1SessionTime", "Sector2SessionTime", "Sector3SessionTime"]:
                target_laps = min(self.race.laps.pick_lap(i+1)[sector])

The storage method for each data varies depending on its state.

  • For normal(racing without special situation) state, save gap time from race leader.
  • For Retire, save -1.
  • For missing value, save pandas.NA. pandas.fillna(method=’ffill’) function can fill in missing values.
  • For backmarkers, Because the race ends early, the remaining laps are recorded as the last gap time.

And saving each data as json form to use in react.

Bar-Chart-Race

I use react for web page, and published by giuhub-page. I modified ChartRace.js and styleChart.css to suit my needs. All code comes from react-chart-race.

I changed two things.

  • Sorting order to reverse.
constructor(props){
    super(props);
    this.state = {
        data: this.props.data.sort((a,b) => a.value - b.value),
        // previous: data: this.props.data.sort((a,b) => b.value - a.value)
        temp: this.props.data,
        maxValue: Math.max.apply(Math, this.props.data.map(item => item.value))
    };
}
  • The bar size(width, height) changed from px to %.
  • Add parameter paddingY, paddingbar to cinfig bar size.

To express bar-chart-race like a video, I use useEffect hook. handleChange() function changes index and data. And when index changes, handleChange() operated repeatly until the end of the race.

function handleChange() {
    setIndex(index + 1);
    const data = getData(index-1);
    const lap = getLap(index-1);
    setData([...data]);
    setLap(lap)
}

useEffect(() => {
    let id;
    if (isActive && absoluteActive){
    id = setInterval(() => {
      handleChange();
    }, 300);
    }
    else{
      clearInterval(index);
    }

    if(index === jsondata[year][circuit].end) {
      setAbsoluteActive(false);
    }
    return () => clearInterval(id);
    }, [isActive, index]);
Other Designs

I use react-select for select box. And I refer CSS Scan page for button.