<!--
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>
				Go branch:
				<select id="branch-select" name="branch">
					<option>master</option>
					<option>release-branch.go1.19</option>
					<option>release-branch.go1.20</option>
					<option>release-branch.go1.21</option>
					<option>release-branch.go1.22</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>gotip-linux-amd64-perf_vs_release</code> column on the
		<a href="https://ci.chromium.org/p/golang/g/go-gotip/console">build dashboard</a>
		for tested ("ok") / untested (empty) commits.
	</p>
	<p>
		The 'Go branch' selection above is the Go branch that benchmarking
		ran against on
		<a href="https://ci.chromium.org/ui/p/golang">the build dashboard</a>.
	</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>
	<p>
		Further documentation is available on the
		<a href=https://go.dev/wiki/PerformanceMonitoring>wiki</a>.
	</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 +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;

// HTML to inject when there's no data found.
const noDataHTML = `
<grid class="Dashboard-section Dashboard-section-expand">
	<h2 class="Dashboard-title">No data</h2>
	<p class="Dashboard-documentation">
		Found no data. Consider trying a different time range. Note also that subrepositories like tools have
		no data against the Go master branch, in which case, try picking a release branch.
	</p>
</grid>
`

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;
	let addedChart = false;
	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");
		if (bench.Regression) {
			const p = document.createElement("p");
			p.classList.add("Dashboard-regression-description");
			const r = bench.Regression;
			if (r.DeltaIndex >= 0) {
				// Generate some text indicating the regression.
				const rd = bench.Values[r.DeltaIndex];
				const regression = (Math.abs(r.Change)*100).toFixed(2);
				const shortCommit = rd.CommitHash.slice(0, 7);
				let diffText = "regression";
				let isRegression = true;
				if (r.Change < 0) {
					// Note: r.Change already has its sign flipped for HigherIsBetter.
					// Positive always means regression, negative always means improvement.
					diffText = "improvement";
					isRegression = false;
				}
				p.innerHTML = `${regression}% ${diffText}, ${(r.Delta*100).toFixed(2)}%-point change at <a href="?benchmark=${bench.Name}&unit=${bench.Unit}#${commitToId(rd.CommitHash)}">${shortCommit}</a>.`;

				// Add a link to file a bug.
				if (isRegression) {
					const title = `affected/package: ${regression}% regression in ${bench.Name} ${bench.Unit} at ${shortCommit}`;
					const body = `Discovered a regression in ${bench.Unit} of ${regression}% for benchmark ${bench.Name} at ${shortCommit}.\n\n<ADD MORE DETAILS>.`
					let query = `?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}&labels=Performance`;
					p.innerHTML += ` <a href="https://github.com/golang/go/issues/new${query}">File an issue</a>.`;
				} else {
					// Include a grinning emoji if it's an improvement.
					p.innerHTML += ` <span style="font-style: normal;">&#128513;</span>`;
				}
			} else {
				p.textContext = `Not ranked because ${r.IgnoredBecause}.`;
			}
			item.appendChild(p);
		}
		item.appendChild(BandChart(bench.Values, {
			benchmark: bench.Name,
			unit: bench.Unit,
			repository: repository,
			minViewDeltaPercent: minViewDeltaPercent,
			higherIsBetter: bench.HigherIsBetter,
		}));
		grid.appendChild(item);
		addedChart = true;
	}
	if (!addedChart) {
		dashboard.innerHTML = noDataHTML;
	}
}

function commitToId(commitHash) {
	return "commit" + commitHash;
}

function idToCommit(id) {
	if (id && id.startsWith("commit")) {
		return id.slice(6);
	}
	return null;
}

function addTable(bench, unit, repository) {
	let commitSelected = idToCommit(window.location.hash.slice(1));
	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;
	}

	const createCommitCell = function(commit, repository) {
		const commitHash = createCell("", false);
		const commitLink = document.createElement("a");
		commitLink.href = "https://go.googlesource.com/" + repository + "/+show/" + commit;
		commitLink.textContent = commit.slice(0, 7);
		commitHash.appendChild(commitLink);
		commitHash.classList.add("Dashboard-table-commit");
		return commitHash;
	}

	// Create the header.
	const header = document.createElement("tr");
	header.appendChild(createCell("Date", true));
	header.appendChild(createCell("Experiment commit", true));
	header.appendChild(createCell("Delta", true));
	header.appendChild(createCell("Baseline commit", true));
	header.appendChild(createCell("x/benchmarks commit", 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");
		if (commitSelected && commitSelected === v.CommitHash) {
			row.classList.add("selected");
		}

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

		// Commit hash.
		const commitCell = createCommitCell(v.CommitHash, repository);
		commitCell.id = commitToId(v.CommitHash);
		row.appendChild(commitCell);

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

		// Baseline commit hash.
		row.appendChild(createCommitCell(v.BaselineCommitHash, repository));

		// Benchmarks commit hash.
		row.appendChild(createCommitCell(v.BenchmarksCommitHash, "benchmarks"));

		table.appendChild(row);
	}

	if (commitSelected) {
		// Now that we've generated anchors for every commit, let's scroll to the
		// right one. The browser won't do this automatically because the anchors
		// don't exist when the page is loaded.
		const anchor = document.querySelector("#" + commitToId(commitSelected));
		window.scrollTo({
			top: anchor.getBoundingClientRect().top + window.pageYOffset - 20,
		})
	}
}

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>
