<!--
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" style="background: antiquewhite;">
	<div>
		A banner isn't actively displayed at this time. This serves as a placeholder
		that can be used if a banner does need to be displayed.
	</div>
</header -->
<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>
			<span class="left-separator"></span>
			<li><a class="alt-nav-button" href="?repository=tools&benchmark=all&branch=latest-release">x/tools Dashboard</a>
			<li><a class="alt-nav-button" href="?benchmark=regressions&platform=linux/amd64">linux/amd64 Regressions</a>
			<li><a class="alt-nav-button" href="?benchmark=regressions&platform=linux/arm64">linux/arm64 Regressions</a>
			<li><a class="alt-nav-button" href="?repository=tools&benchmark=regressions&branch=latest-release">x/tools Regressions</a>
		</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="button" class="alt-nav-button" onclick="setBenchmarkInput('all')" value="All">
				<input type="button" class="alt-nav-button" onclick="setBenchmarkInput('regressions')" value="Regressions first">
			</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"></select>
				Platform:
				<select id="platform-select" name="platform">
					<option>all</option>
					<option>linux/amd64</option>
					<option>linux/arm64</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_debian12-perf_vs_release</code>
		column on the
		<a href="https://ci.chromium.org/p/golang/g/go-gotip/console">build dashboard</a>.
		Individually tested commits have their own green box. A single
		box that covers multiple commits indicates that only the latest
		commit in the range was tested.
	</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 setBenchmarkInput(benchmark) {
	let input = document.getElementById('benchmark-input');
	input.value = benchmark;
}

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

	removeLoadingMessage();

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

		if (bench.Name != prevName || bench.Platform != prevPlatform) {
			prevName = bench.Name;
			prevPlatform = bench.Platform;

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

			let link = document.createElement("a");
			link.href = "?benchmark=" + bench.Name + "&platform=" + bench.Platform + "&repository=" + repository + "&branch=" + goBranch;
			link.textContent = bench.Name + " (" + bench.Platform + ")";

			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}&platform=${bench.Platform}#${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} on ${bench.Platform} 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,
			platform: bench.Platform,
			repository: repository,
			minViewDeltaPercent: minViewDeltaPercent,
			higherIsBetter: bench.HigherIsBetter,
			history: commits,
		}));
		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, platform, repository, goBranch, commits) {
	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 + "&platform=" + platform + "&repository=" + repository + "&branch=" + goBranch;
	link.textContent = bench.Name + " (" + unit + ", " + platform + ")";

	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;
	}

	// Create a map of hashes to values.
	let valuesByCommit = new Map();
	for (let i = 0; i < bench.Values.length; i++) {
		valuesByCommit.set(bench.Values[i].CommitHash, bench.Values[i])
	}

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

		// Create a row per value.
		const row = document.createElement("tr");
		if (commitSelected && commitSelected === c.Hash) {
			row.classList.add("selected");
		}

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

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

		if (valuesByCommit.has(c.Hash)) {
			const v = valuesByCommit.get(c.Hash);

			// 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"));
		} else {
			// Row without info.
			const range = createCell("", false);
			range.appendChild(NoDataRange(min, max, 640, 48));
			range.classList.add("Dashboard-table-range");
			row.appendChild(range);

			const baselineNA = createCell("N/A", false);
			baselineNA.classList.add("Dashboard-table-commit");
			row.appendChild(baselineNA);

			const benchmarksNA = createCell("N/A", false);
			benchmarksNA.classList.add("Dashboard-table-commit");
			row.appendChild(benchmarksNA);
		}

		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);
}

let now = new Date();

// Fill search boxes from query params.
function prefillSearch(formFields) {
	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 platform = params.get('platform');
	if (platform) {
		let select = document.getElementById('platform-select');
		select.value = platform;
	}

	let branch = params.get('branch');
	if (branch) {
		let select = document.getElementById('branch-select');
		if (branch === "latest-release") {
			select.value = formFields.LatestReleaseBranch;
		} else {
			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 {
		// 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);
	}
}
fetch('./formfields.json')
	.then(response => {
		if (!response.ok) {
			throw new Error("Form fields fetch failed");
		}
		return response.json();
	})
	.then(function(formFields) {
		let select = document.getElementById('branch-select');
		for (const i in formFields.Branches) {
			var opt = document.createElement('option');
			opt.value = formFields.Branches[i];
			opt.innerText = formFields.Branches[i];
			select.appendChild(opt);
		}
		var opt = document.createElement('option');
		opt.value = "latest-release";
		opt.innerText = "Latest release branch";
		select.appendChild(opt);
		prefillSearch(formFields);
	});


// Grab the repository so we can plumb it into UI elements.
let repository = (new URLSearchParams(window.location.search)).get('repository');
if (!repository) {
	repository = "go";
}

// Fetch content.
let benchmark = (new URLSearchParams(window.location.search)).get('benchmark');
let unit = (new URLSearchParams(window.location.search)).get('unit');
let platform = (new URLSearchParams(window.location.search)).get('platform');
let goBranch = (new URLSearchParams(window.location.search)).get('branch');
if (!goBranch) {
	// Assume the same thing the server does when no branch is specified.
	goBranch = "master";
}
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(data) {
		let benchmarks = data.Benchmarks;
		let commits = data.Commits;

		// Convert CommitDate and Date to a proper dates.
		benchmarks.forEach(function(b) {
			b.Values.forEach(function(v) {
				v.CommitDate = new Date(v.CommitDate);
			});
		});
		commits.forEach(function(c) {
			c.Date = new Date(c.Date);
		})

		// Figure out the date range we care about.

		// If we have an explicit unit, then there should be just one result.
		if (unit && platform && platform != "all") {
			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, platform, repository, goBranch, commits);
		} else {
			addCharts(benchmarks, repository, goBranch, commits);
		}
	});
</script>

</body>
</html>
