Skip to content

Commit

Permalink
wip: get some lines goin
Browse files Browse the repository at this point in the history
  • Loading branch information
davidharrigan committed Aug 12, 2022
1 parent 55c17a5 commit b0fd8b7
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 24 deletions.
99 changes: 99 additions & 0 deletions src/components/_experimental/CornerAnalysis.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import * as d3 from "d3";
import React, { useRef, useEffect, useMemo } from "react";
import { useRefDimensions } from "libs/react/dimensions";
import type { DriverData, Telemetry } from "libs/types";

interface CornerAnalysisProps {
turnNumber: number;
driverData: DriverData[];
distanceFrom: number;
distanceTo: number;
}

export const CornerAnalysis = (props: CornerAnalysisProps) => {
const ref = useRef(null);
const dimensions = useRefDimensions(ref);
const svgRef = useRef(null);
const allDriverData: DriverTelemetry[] = props.driverData
.map((d) => {
return d.data.map((tel) => {
return {
...tel,
Code: d.driverCode,
Color: d.driverColor,
};
});
})
.flat();

const [mx, my] = [14, 14];

// x scale bounds
const distanceScale = useMemo(() => {
const [xMin, xMax] = [props.distanceFrom, props.distanceTo];
return d3
.scaleLinear()
.domain([xMin ?? 0, xMax ?? 0])
.range([mx, dimensions.width - mx]);
}, [allDriverData, dimensions.width]);

// y scale bounds
const speedScale = useMemo(() => {
const [yMin, yMax] = d3.extent(allDriverData, (d) => d.Speed);
return d3
.scaleLinear()
.domain([yMin ?? 0, yMax ?? 0])
.range([dimensions.height - my, my]);
}, [allDriverData, dimensions.height]);

// draw
useEffect(() => {
if (!distanceScale || !speedScale) {
return;
}

d3.select(svgRef.current).selectAll("*").remove();
drawSpeedGraph(allDriverData);
}, [props, distanceScale, speedScale]);

const drawSpeedGraph = () => {
const color = d3
.scaleOrdinal()
.domain(props.driverData.map((d) => d.driverCode))
.range(props.driverData.map((d) => d.driverColor));

const g = d3
.select(svgRef.current)
.selectAll(`.speed-graph`)
.data<DriverData>(props.driverData)
.enter()
.append("g")
.attr("class", "speed-graph");

g.append("path")
.attr("d", (d) => {
return d3
.line<Telemetry>()
.x((d) => {
return distanceScale(d.Distance);
})
.y((d) => speedScale(d.Speed))(d.data);
})
.attr("fill", "none")
.attr("stroke-width", 2)
.attr("stroke", (d) => color(d.driverCode));
};

return (
<div className="w-full h-full">
<div className="bg-oldLavender">
<p className="text-3xl px-5 py-2 mb-5 tracking-wider">
Corner Analysis - Turn {props.turnNumber} 🏎️ 🏎️ 🏎️
</p>
</div>
<div ref={ref} className="h-full w-full">
<svg width="100%" height="100%" ref={svgRef}></svg>
</div>
</div>
);
};
30 changes: 7 additions & 23 deletions src/components/_experimental/TrackMap.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
import * as d3 from "d3";
import React, { useRef, useEffect, useState, useMemo } from "react";
import { Dimensions, useRefDimensions } from "libs/react/dimensions";
import { svg } from "d3";
import { useRefDimensions } from "libs/react/dimensions";
import type { TrackData, DriverData, Telemetry } from "libs/types";

interface DriverData {
driverCode: string;
driverColor: string;
data: Telemetry[];
}

type DriverTelemetry = Partial<Telemetry> &
TrackMap & {
Code?: string;
};

type Telemetry = TrackMap & {
Speed: number;
Distance: number;
};

type TrackMap = {
type DriverTelemetry = Partial<Telemetry> & {
Code?: string;
X: number;
Y: number;
};
Expand Down Expand Up @@ -109,7 +94,6 @@ export const TrackMap = (props: TrackMapProps) => {
if (!xScale || !yScale) {
return;
}
console.log("draw!");

d3.select(svgRef.current).selectAll("*").remove();
drawMap(map);
Expand All @@ -120,11 +104,11 @@ export const TrackMap = (props: TrackMapProps) => {
}, [props, xScale, yScale]);

// draw track map
const drawMap = (map: TrackMap[]) => {
const drawMap = (map: TrackData[]) => {
const g = d3
.select(svgRef.current)
.selectAll(".track-map")
.data<TrackMap[]>([map])
.data<TrackData[]>([map])
.enter()
.append("g")
.attr("class", "track-map");
Expand All @@ -133,7 +117,7 @@ export const TrackMap = (props: TrackMapProps) => {
.attr(
"d",
d3
.line<TrackMap>()
.line<TrackData>()
.x((d) => xScale(d.X))
.y((d) => yScale(d.Y))
)
Expand Down
17 changes: 17 additions & 0 deletions src/libs/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export interface DriverData {
driverCode: string;
driverColor: string;
data: Telemetry[];
}

export type Telemetry = TrackData & {
Speed: number;
Distance: number;
Brake: boolean;
Throttle: number;
};

export type TrackData = {
X: number;
Y: number;
};
14 changes: 13 additions & 1 deletion src/pages/experiments/trackmap.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { TrackMap } from "components/_experimental/TrackMap";
import { CornerAnalysis } from "components/_experimental/CornerAnalysis";
import { NorrisData, RicciardoData } from "libs/data/mclaren";

export default function TrackMapExperiment() {
return (
<div className="bg-oxfordBlue w-screen h-screen text-eggshell p-10">
<div className="bg-oxfordBlue w-screen h-full text-eggshell p-10">
<div className="w-[600px] h-[600px]">
<TrackMap
driverData={[
Expand All @@ -14,6 +15,17 @@ export default function TrackMapExperiment() {
telemetryOverlay="fastest"
/>
</div>
<div className="pt-10">
<CornerAnalysis
turnNumber={1}
driverData={[
{ driverCode: "NOR", driverColor: "#1E88E5", data: NorrisData },
{ driverCode: "RIC", driverColor: "#ffc107", data: RicciardoData },
]}
distanceFrom={400}
distanceTo={800}
/>
</div>
</div>
);
}

0 comments on commit b0fd8b7

Please sign in to comment.