diff --git a/scripts/graph.ts b/scripts/graph.ts index f5b44f6..2b64b6a 100644 --- a/scripts/graph.ts +++ b/scripts/graph.ts @@ -1,43 +1,102 @@ import uPlot from "./uPlot.js"; +// https://sashamaps.net/docs/resources/20-colors/ +// Related: https://en.wikipedia.org/wiki/Help:Distinguishable_colors +const COLORS = [ + "#e6194B", // Red + "#3cb44b", // Green + "#ffe119", // Yellow + "#4363d8", // Blue + "#f58231", // Orange + // "#911eb4", // Purple + "#42d4f4", // Cyan + "#f032e6", // Magenta + // "#bfef45", // Lime + "#fabed4", // Pink + "#469990", // Teal + "#dcbeff", // Lavender + "#9A6324", // Brown + "#fffac8", // Beige + "#800000", // Maroon + "#aaffc3", // Mint + // "#808000", // Olive + "#ffd8b1", // Apricot + "#000075", // Navy + "#a9a9a9", // Grey + // "#ffffff", // White + "#000000", // Black +]; + interface GraphData { hashes: string[]; times: number[]; measurements: { [key: string]: (number | null)[]; }; } -let opts = { - title: "HEHE", - width: 600, - height: 400, - series: [ - {}, - { - label: "wall-clock/build", +function update_plot_with_data(data: GraphData) { + let series: uPlot.Series[] = [{}]; + let values: uPlot.AlignedData = [data.times]; + + for (const [i, metric] of Object.keys(data.measurements).sort().entries()) { + series.push({ + label: metric, spanGaps: true, - stroke: "blue", - width: 1, + stroke: COLORS[i % COLORS.length], + }); + values.push(data.measurements[metric]!); + } + + const opts: uPlot.Options = { + title: "Measurements", + width: 600, + height: 400, + series, + }; + + plot?.destroy(); + plot = new uPlot(opts, values, plot_div); +} + +async function update_plot_with_metrics(metrics: string[]) { + const url = "data?" + new URLSearchParams(metrics.map(m => ["metric", m])); + const response = await fetch(url); + const data: GraphData = await response.json(); + update_plot_with_data(data); +} + +function find_selected_metrics(): string[] { + const inputs = metrics_div.querySelectorAll('input[type="checkbox"]'); + + let metrics: string[] = []; + for (const input of inputs) { + if (input.checked) { + metrics.push(input.name); } - ], + } + return metrics; }; -let plot = new uPlot(opts, [], document.body); +async function update_plot() { + const metrics = find_selected_metrics(); + if (metrics.length > 0) { + await update_plot_with_metrics(metrics); + } else { + update_plot_with_data({ + hashes: [], + times: [], + measurements: {}, + }); + } +} -fetch("data?metric=wall-clock/build") - .then(r => r.json() as Promise) - .then(data => { - console.log(data); - plot.setData([ - data.times, - data.measurements["wall-clock/build"]!, - ]); - }); +// Initialization -// function display(metrics: string[]) { -// let url = "data" + new URLSearchParams(metrics.map(m => ["metric", m])); -// fetch(url) -// .then(r => r.json() as Promise) -// .then(data => { +const plot_div = document.getElementById("plot")!; +const metrics_div = document.getElementById("metrics")!; +let plot: uPlot | null = null; -// }) -// } +for (const input of metrics_div.querySelectorAll('input[type="checkbox"]')) { + input.addEventListener("change", update_plot); +} + +update_plot(); diff --git a/templates/pages/graph.html b/templates/pages/graph.html index b1e68a3..633673f 100644 --- a/templates/pages/graph.html +++ b/templates/pages/graph.html @@ -33,6 +33,8 @@
-{{ metrics|safe }} +
+ {{ metrics|safe }} +
{% endblock %}