2024-03-04 13:28:42 +01:00
|
|
|
import * as d3 from "d3";
|
2023-10-01 15:39:30 +02:00
|
|
|
|
2023-10-01 18:41:20 +02:00
|
|
|
export interface Data {
|
|
|
|
date: Date;
|
|
|
|
km: number;
|
|
|
|
}
|
2023-10-01 15:39:30 +02:00
|
|
|
|
2024-03-04 13:28:42 +01:00
|
|
|
if (sessionStorage.getItem("userStats")) {
|
|
|
|
const data = JSON.parse(
|
|
|
|
sessionStorage.getItem("userStats") || "{}",
|
|
|
|
) as Data[];
|
2023-10-01 15:39:30 +02:00
|
|
|
|
2024-03-04 13:28:42 +01:00
|
|
|
if (data.length >= 2) {
|
2023-10-01 18:53:52 +02:00
|
|
|
const margin = { top: 20, right: 20, bottom: 50, left: 50 };
|
|
|
|
const width: number = 960 - margin.left - margin.right;
|
|
|
|
const height: number = 500 - margin.top - margin.bottom;
|
2024-03-04 13:28:42 +01:00
|
|
|
|
2023-10-01 18:53:52 +02:00
|
|
|
data.forEach((d: Data) => {
|
2024-03-04 13:28:42 +01:00
|
|
|
d.date = <Date>new Date(d.date);
|
2023-10-01 18:53:52 +02:00
|
|
|
d.km = +d.km;
|
|
|
|
});
|
2024-03-04 13:28:42 +01:00
|
|
|
|
|
|
|
const x = d3
|
|
|
|
.scaleTime()
|
2023-10-01 18:53:52 +02:00
|
|
|
.domain(<[Date, Date]>d3.extent(data, (d: Data) => d.date))
|
|
|
|
.range([0, width]);
|
2024-03-04 13:28:42 +01:00
|
|
|
|
|
|
|
const y = d3
|
|
|
|
.scaleLinear()
|
2023-10-01 18:53:52 +02:00
|
|
|
.domain([0, Number(d3.max(data, (d: Data) => d.km))])
|
|
|
|
.range([height, 0]);
|
2024-03-04 13:28:42 +01:00
|
|
|
|
|
|
|
const line = d3
|
|
|
|
.line<Data>()
|
2023-10-01 18:53:52 +02:00
|
|
|
.x((d: Data) => x(d.date))
|
|
|
|
.y((d: Data) => y(d.km));
|
2024-03-04 13:28:42 +01:00
|
|
|
|
|
|
|
const svg = d3
|
|
|
|
.select("#container")
|
|
|
|
.append("svg")
|
|
|
|
.attr("width", width + margin.left + margin.right)
|
|
|
|
.attr("height", height + margin.top + margin.bottom)
|
2023-10-01 18:53:52 +02:00
|
|
|
.call(responsivefy)
|
2024-03-04 13:28:42 +01:00
|
|
|
.append("g")
|
|
|
|
.attr("transform", `translate(${margin.left},${margin.top})`);
|
|
|
|
|
|
|
|
svg.append("path").data([data]).attr("class", "line").attr("d", line);
|
|
|
|
|
|
|
|
svg
|
|
|
|
.append("g")
|
|
|
|
.attr("transform", `translate(0,${height})`)
|
2023-10-01 18:53:52 +02:00
|
|
|
.call(d3.axisBottom(x));
|
2024-03-04 13:28:42 +01:00
|
|
|
|
|
|
|
svg.append("g").call(d3.axisLeft(y));
|
2023-10-01 18:53:52 +02:00
|
|
|
}
|
2023-10-01 18:41:20 +02:00
|
|
|
}
|
2023-10-01 15:39:30 +02:00
|
|
|
|
|
|
|
function responsivefy(svg: any) {
|
2023-10-01 18:41:20 +02:00
|
|
|
const container = d3.select(svg.node().parentNode);
|
2024-03-04 13:28:42 +01:00
|
|
|
const width = parseInt(svg.style("width"), 10);
|
|
|
|
const height = parseInt(svg.style("height"), 10);
|
2023-10-01 18:41:20 +02:00
|
|
|
const aspect = width / height;
|
|
|
|
|
2024-03-04 13:28:42 +01:00
|
|
|
svg
|
|
|
|
.attr("viewBox", `0 0 ${width} ${height}`)
|
|
|
|
.attr("preserveAspectRatio", "xMinYMid")
|
2023-10-01 18:41:20 +02:00
|
|
|
.call(resize);
|
|
|
|
|
2024-03-04 13:28:42 +01:00
|
|
|
d3.select(window).on("resize." + container.attr("id"), resize);
|
2023-10-01 18:41:20 +02:00
|
|
|
|
2023-10-01 15:39:30 +02:00
|
|
|
function resize() {
|
2024-03-04 13:28:42 +01:00
|
|
|
const w = parseInt(container.style("width"));
|
|
|
|
svg.attr("width", w);
|
|
|
|
svg.attr("height", Math.round(w / aspect));
|
2023-09-05 23:03:18 +02:00
|
|
|
}
|
2024-03-04 13:28:42 +01:00
|
|
|
}
|