import './lib/d3.v7.min.js'; let POINTS = []; const x = d3.scaleLinear([0, 120]).nice(30); const y = d3.scaleLinear([0, 350]); const line = d3.line(d => x(d[0]), d => y(d[1])); const margin = 2 * parseFloat(getComputedStyle(document.documentElement).fontSize); const svg = d3.select('#plot'); // Add the x-axis. const xa = svg.append('g'); // Add the y-axis. const ya = svg.append('g'); const PLOTS = {}; const sec = d3.format('02'); const min = d3.format(' '); const minsec = v => `${min(Math.floor(v / 60))}:${sec(v % 60)}`; export const addPlot = (name) => { const path = svg.append('path') .attr('fill', 'none') .attr('stroke', 'black') .attr('stroke-width', '2'); PLOTS[name] = { data: [], path, }; return PLOTS[name]; }; export const update = () => { const times = d3.merge(Object.values(PLOTS).map(p => p.data.map(d => d[0]))); const temps = d3.merge(Object.values(PLOTS).map(p => p.data.map(d => d[1]))); x.domain([0, d3.max([...times, 120])]).nice(30); y.domain([0, d3.max([...temps, 200])]).nice(25); xa.transition().call(d3.axisBottom(x).tickFormat(minsec)) ya.transition().call(d3.axisLeft(y)) for (const { path, data } of Object.values(PLOTS)) { path.transition().attr('d', line(data)); } }; const onresize = () => { const width = svg.node().clientWidth; const height = svg.node().clientHeight; svg .attr('width', width) .attr('height', height); x.range([margin, width - margin]); y.range([height - margin, margin]); xa.transition().call(d3.axisBottom(x).tickFormat(minsec)) ya.transition().call(d3.axisLeft(y)) for (const { path, data } of Object.values(PLOTS)) { path.transition().attr('d', line(data)); } xa.attr('transform', `translate(0, ${height - margin})`); ya.attr('transform', `translate(${margin}, 0)`); }; window.addEventListener('resize', onresize); onresize(); update();