<!--
Copyright 2022 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->

<!DOCTYPE html>
<html lang="en">
<head>
	<title>Go Performance Dashboard</title>
	<link rel="icon" href="https://go.dev/favicon.ico"/>
	<link rel="stylesheet" href="./static/style.css"/>
	<script src="https://ajax.googleapis.com/ajax/libs/d3js/7.4.2/d3.min.js"></script>
	<script src="./third_party/bandchart/bandchart.js"></script>
	<script src="./static/range.js"></script>
</head>

<body class="Dashboard">
<header class="Dashboard-topbar">
	<h1>
		<a href="https://farmer.golang.org/">Go Build Coordinator</a>
	</h1>
	<nav>
		<ul>
			<li><a href="https://build.golang.org/">Build Dashboard</a></li>
			<li><a href="/dashboard">Performance Dashboard</a></li>
			<li><a href="https://farmer.golang.org/builders">Builders</a></li>
		</ul>
	</nav>
</header>

<nav class="Dashboard-controls">
	<form autocomplete="off" action="./">
		<ul>
			<li>
				<div class="Dashboard-search-benchmark">
					<input id="benchmark-input" type="text" name="benchmark" placeholder="Type benchmark name..." />
				</div>
				<div class="Dashboard-search-unit">
					<input id="unit-input" type="text" name="unit" placeholder="Unit (optional)" />
				</div>
				<input type="submit" />
			</li>
			<li><a href="?benchmark=all">All benchmarks</a></li>
			<li><a href="?benchmark=regressions">Regressions first</a></li>
			<span class="left-separator"></span>
			<li>
				Repository:
				<select id="repository-select" name="repository">
					<option>go</option>
					<option>tools</option>
				</select>
				Branch:
				<select id="branch-select" name="branch">
					<option>master</option>
					<option>release-branch.go1.17</option>
					<option>release-branch.go1.18</option>
					<option>release-branch.go1.19</option>
					<option>release-branch.go1.20</option>
				</select>
				Duration (days):
				<div class="Dashboard-duration">
					<input id="days-input" type="number" name="days" value="30" />
				</div>
				End (UTC): <input id="end-input" type="datetime-local" name="end" />
				<input type="submit">
			</li>
		</ul>
	</form>
</nav>

<div class="Dashboard-documentation">
	<p>
		Each graph displays benchmark results relative to its baseline
		commit, which is the latest stable release (e.g., 1.18.3) at
		the time of testing. The 95% confidence interval is displayed
		in light gray. On hover, the graph displays the benchmarked
		commit at that point (click to view full commit).
	</p>
	<p>
		Note that some commits are not tested, so there could be
		multiple commits (not shown) between two points on the graph.
		See the <code>linux-amd64-perf</code> column on the
		<a href="https://build.golang.org/?repo=golang.org%2fx%2fbenchmarks">x/benchmarks build dashboard</a>
		for tested ("ok") / untested (empty) commits.
	</p>
	<p>
		The 'branch' selection above is the Go branch that benchmarking
		ran against on <a href=https://build.golang.org>the build dashboard</a>,
		not the subrepo branch.
	</p>
	<p>
		Using the 'unit' search box above leads to a page that shows much
		more detail about each individual point in the selected time range.
		Another way of reaching this page is to click the unit name that acts
		as each graph's title, i.e. "sec/op".
	</p>
</div>

<grid id="dashboard">
	<grid id="loading" class="Dashboard-section Dashboard-section-expand">
		<h2 class="Dashboard-title" id="loading">Loading...</h2>
	</grid>
</grid>

<script>
// minViewPercentDelta represents the minimum range we're willing to
// let the Y axis have for charts and X axis for ranges in the per-unit
// view. In both cases the unit of this value is a delta percent, hence
// the name.
//
// This constant exists because allowing the axis' range to be arbitrarily
// small produces results that are really noisy visually, even though they
// represent virtually no change. For instance, a relatively low-noise
// series of benchmark results, with a min delta of -0.05% and and +0.05%
// might appear really noisy if we "zoom" in too far, when in actuality
// the amount of noise is incredibly low.
const minViewDeltaPercent = 0.025;

function removeLoadingMessage() {
	let loading = document.getElementById("loading");
	loading.parentNode.removeChild(loading);
}

function addCharts(benchmarks, repository) {
	let dashboard = document.getElementById("dashboard");

	removeLoadingMessage();

	let prevName = "";
	let grid = null;
	for (const b in benchmarks) {
		const bench = benchmarks[b];

		if (bench.Name != prevName) {
			prevName = bench.Name;

			let section = document.createElement("grid");
			section.classList.add("Dashboard-section");
			dashboard.appendChild(section);

			let link = document.createElement("a");
			link.href = "?benchmark=" + bench.Name;
			link.textContent = bench.Name;

			let title = document.createElement("h2");
			title.classList.add("Dashboard-title");
			title.appendChild(link);
			section.appendChild(title);

			grid = document.createElement("grid");
			grid.classList.add("Dashboard-grid");
			section.appendChild(grid);
		}

		let item = document.createElement("div");
		item.classList.add("Dashboard-grid-item");
		item.appendChild(BandChart(bench.Values, {
			benchmark: bench.Name,
			unit: bench.Unit,
			repository: repository,
			minViewDeltaPercent: minViewDeltaPercent,
		}));
		grid.appendChild(item);
	}
}

function addTable(bench, unit, repository) {
	let dashboard = document.getElementById("dashboard");

	removeLoadingMessage();

	let section = document.createElement("grid");
	section.classList.add("Dashboard-section");
	section.classList.add("Dashboard-section-expand");
	dashboard.appendChild(section);

	let link = document.createElement("a");
	link.href = "?benchmark=" + bench.Name + "&unit=" + unit;
	link.textContent = bench.Name + " (" + unit + ")";

	let title = document.createElement("h2");
	title.classList.add("Dashboard-title");
	title.appendChild(link);
	section.appendChild(title);

	const table = document.createElement("table");
	table.classList.add("Dashboard-table");
	section.appendChild(table);

	const createCell = function(text, header) {
		let elemType = "td";
		if (header) {
			elemType = "th";
		}
		const elem = document.createElement(elemType);
		elem.textContent = text;
		return elem;
	}

	// Create the header.
	const header = document.createElement("tr");
	header.appendChild(createCell("Date", true));
	header.appendChild(createCell("Commit", true));
	header.appendChild(createCell("Delta", true));
	table.appendChild(header);

	// Find the min and max.
	let min = bench.Values[0].Low;
	let max = bench.Values[0].High;
	for (let i = 1; i < bench.Values.length; i++) {
		if (bench.Values[i].Low < min) {
			min = bench.Values[i].Low;
		}
		if (bench.Values[i].High > max) {
			max = bench.Values[i].High;
		}
	}

	// Clamp for presentation.
	if (min < 0 && min > -minViewDeltaPercent) {
		min = -minViewDeltaPercent
	}
	if (max > 0 && max < minViewDeltaPercent) {
		max = minViewDeltaPercent
	}
	if (max-min < 2*minViewDeltaPercent) {
		const amt = (2*minViewDeltaPercent-(max-min))/2;
		max += amt;
		min -= amt;
	}

	// Iterate backwards, showing the most recent first.
	for (let i = bench.Values.length-1; i >= 0; i--) {
		const v = bench.Values[i];

		// Create a row per value.
		const row = document.createElement("tr");

		// Commit date.
		row.appendChild(createCell(Intl.DateTimeFormat([], {
			dateStyle: "long",
			timeStyle: "short",
		}).format(v.CommitDate), false));

		// Commit hash.
		const commitHash = createCell("", false);
		const commitLink = document.createElement("a");
		commitLink.href = "https://go.googlesource.com/" + repository + "/+show/" + v.CommitHash;
		commitLink.textContent = v.CommitHash.slice(0, 7);
		commitHash.appendChild(commitLink);
		commitHash.classList.add("Dashboard-table-commit")
		row.appendChild(commitHash);

		// Range visualization.
		const range = createCell("", false);
		range.appendChild(Range(v.Low, v.Center, v.High, min, max, 640, 32, bench.Unit));
		range.classList.add("Dashboard-table-range")
		row.appendChild(range);

		table.appendChild(row);
	}
}

function failure(name, response) {
	let dashboard = document.getElementById("dashboard");

	removeLoadingMessage();

	let title = document.createElement("h2");
	title.classList.add("Dashboard-title");
	title.textContent = "Benchmark \"" + name + "\" not found.";
	dashboard.appendChild(title);

	let message = document.createElement("p");
	message.classList.add("Dashboard-documentation");
	response.text().then(function(error) {
		message.textContent = error;
	});
	dashboard.appendChild(message);
}

// Fill search boxes from query params.
function prefillSearch() {
	let params = new URLSearchParams(window.location.search);

	let benchmark = params.get('benchmark');
	if (benchmark) {
		let input = document.getElementById('benchmark-input');
		input.value = benchmark;
	}

	let unit = params.get('unit');
	if (unit) {
		let input = document.getElementById('unit-input');
		input.value = unit;
	}

	let repository = params.get('repository');
	if (repository) {
		let select = document.getElementById('repository-select');
		select.value = repository;
	}

	let branch = params.get('branch');
	if (branch) {
		let select = document.getElementById('branch-select');
		select.value = branch;
	}

	let days = params.get('days');
	if (days) {
		let input = document.getElementById('days-input');
		input.value = days;
	}

	let end = params.get('end');
	let input = document.getElementById('end-input');
	if (end) {
		input.value = end;
	} else {
		// Default to now.
		let now = new Date();

		// toISOString always uses UTC, then we just chop off the end
		// of string to get the datetime-local format of
		// 2000-12-31T15:00.
		//
		// Yes, this is really the suggested approach...
		input.value = now.toISOString().slice(0, 16);
	}
}
prefillSearch()

// Grab the repository so we can plumb it into UI elements.
// prefillSearch set this up for us just now.
const repository = document.getElementById('repository-select').value;

// Fetch content.
let benchmark = (new URLSearchParams(window.location.search)).get('benchmark');
let unit = (new URLSearchParams(window.location.search)).get('unit');
let dataURL = './data.json' + window.location.search;  // Pass through all URL params.
fetch(dataURL)
	.then(response => {
		if (!response.ok) {
			failure(benchmark, response);
			throw new Error("Data fetch failed");
		}
		return response.json();
	})
	.then(function(benchmarks) {
		// Convert CommitDate to a proper date.
		benchmarks.forEach(function(b) {
			b.Values.forEach(function(v) {
				v.CommitDate = new Date(v.CommitDate);
			});
		});

		// If we have an explicit unit, then there should be just one result.
		if (unit) {
			if (benchmarks.length !== 1) {
				failure(benchmark, "got more that one benchmark when a unit was specified");
				throw new Error("Data fetch failed");
			}
			addTable(benchmarks[0], unit, repository);
		} else {
			addCharts(benchmarks, repository);
		}
	});
</script>

</body>
</html>
