Constant glassbench::VIEWER_JS[][src]

pub const VIEWER_JS: &str = "\nasync function main(sql_conf){\n\tlet db_bytes = base64ToArrayBuffer(db64)\n\tconst SQL = await initSqlJs(sql_conf)\n\tconst db = new SQL.Database(new Uint8Array(db_bytes))\n\tlet benches = db.exec(\"SELECT * FROM bench\")\n\twindow.gb = wrap(db)\n\tcreate_gui()\n\tmake_selector(gb_conf.bench_name, gb_conf.task_name)\n}\n\nfunction create_gui() {\n\t$(\"body\",\n\t\t$(\"<#infos\",\n\t\t\t$(`<a>Glassbench ${gb_conf.gb_version}`, {\n\t\t\t\thref: \"https://github.com/Canop/glassbench\",\n\t\t\t\ttarget: \"_blank\",\n\t\t\t}),\n\t\t),\n\t\t$(\"<#selectors\"),\n\t\t$(\"<#view\",\n\t\t\t$(\"<.tabs\"),\n\t\t\t$(\"<.pages\"),\n\t\t)\n\t)\n\tfunction unselect() {\n\t\tfor (e of $(\"#view .tabs .tab, #view .pages .page\")) {\n\t\t\te.classList.remove(\"selected\")\n\t\t}\n\t}\n\t;[\"Table\", \"Graph\"].forEach(name => {\n\t\tunselect()\n\t\tlet page = $(\"<.page.selected\", { id: name })\n\t\tlet tab = $(\"<span.tab.selected\", {\n\t\t\ttextContent: name,\n\t\t\tclick: () => {\n\t\t\t\tunselect()\n\t\t\t\ttab.classList.add(\"selected\")\n\t\t\t\tpage.classList.add(\"selected\")\n\t\t\t}\n\t\t})\n\t\t$(\"#view .tabs\", tab)\n\t\t$(\"#view .pages\", page)\n\t})\n\t$(\"#Table\",\n\t\t$(\"<.table-wrapper\",\n\t\t\t$(\"<table\",\n\t\t\t\t$(\"<thead\", $(\"<tr\",\n\t\t\t\t\t$(\"<th.group>dataset\"),\n\t\t\t\t\t$(\"<th.bench_id>bench id\"),\n\t\t\t\t\t$(\"<th.commit_id>commit id\"),\n\t\t\t\t\t$(\"<th.date>date\"),\n\t\t\t\t\t$(\"<th.task_name>task name\"),\n\t\t\t\t\t$(\"<th.duration_str>mean dur.\"),\n\t\t\t\t\t$(\"<th.duration_ns>mean (ns)\"),\n\t\t\t\t\t$(\"<th.tag>tag\"),\n\t\t\t\t)),\n\t\t\t\t$(\"<tbody#tbody\")\n\t\t\t)\n\t\t)\n\t)\n\t$(\"#Graph\",\n\t\t$(\"<div\", { id: \"vis\" })\n\t)\n}\n\nfunction update_view() {\n\tlet view_data = make_view_data()\n\tupdate_graph(view_data)\n\tupdate_table(view_data)\n}\n\n// return [{\n// \tgroup_id, group_name, bench_name, task_name, include_tag, tag,\n// \trows:[{date,duration_ns,tag,duration_str}]\n// }]\nfunction make_view_data() {\n\tlet groups = []\n\tfor (let [group_id, selector] of $$(\".selector\").entries()) {\n\t\tlet bench_name = $(selector, \"select.bench\").value\n\t\tlet task_name = $(selector, \"select.task\").value\n\t\tlet include_tag = !$(selector, \"select.tag-toggle\").selectedIndex\n\t\tlet tag = $(selector, \".tag\").value\n\t\tlet rows = get_rows(bench_name, task_name, include_tag, tag)\n\t\tlet group_name = task_name\n\t\tgroups.push({\n\t\t\tgroup_id,\n\t\t\tgroup_name,\n\t\t\tbench_name,\n\t\t\tinclude_tag,\n\t\t\ttag,\n\t\t\ttask_name,\n\t\t\trows,\n\t\t})\n\t}\n\treturn groups\n}\n\n// return [{date,tag,duration_ns,duration_str}]\nfunction get_rows(bench_name, task_name, include_tag, tag) {\n\tlet sql = `SELECT\n\t\t\tbench.id, bench.time, bench.tag, bench.commit_id,\n\t\t\ttask.iterations, task.mean_duration_ns\n\t\tFROM task JOIN bench ON task.bench=bench.id\n\t\tWHERE bench.name=? AND task.name=?`\n\tlet args = [bench_name, task_name]\n\tif (tag) {\n\t\tif (include_tag) {\n\t\t\tsql += \" AND tag LIKE ?\"\n\t\t} else {\n\t\t\tsql += \" AND (tag IS NULL OR tag NOT LIKE ?)\"\n\t\t}\n\t\targs.push(`%${tag}%`)\n\t}\n\treturn gb.lists(sql, args).map(row => ({\n\t\tbench_id: row[0],\n\t\tcommit_id: row[3],\n\t\tdate: row[1] * 1000,\n\t\tduration_ns: row[5],\n\t\ttag: row[2],\n\t\tduration_str: fmt_nanos(row[5])\n\t}))\n}\n\nfunction update_table(view_data) {\n\tlet tbody = $(\"#tbody\")\n\twhile (tbody.firstChild) tbody.removeChild(tbody.lastChild)\n\tfor (let g of view_data) {\n\t\tfor (let row of g.rows) {\n\t\t\t$(tbody, $(`<tr.group_${g.group_id}`,\n\t\t\t\t$(`<td.group_id>${g.group_id + 1}`), // counting from 1\n\t\t\t\t$(\"<td.bench_id\", { textContent: row.bench_id }),\n\t\t\t\t$(\"<td.commit_id\", { textContent: row.commit_id.slice(0, 10) }),\n\t\t\t\t$(\"<td.date\", { textContent: new Date(row.date) }),\n\t\t\t\t$(\"<td.task_name\", { textContent: g.task_name }),\n\t\t\t\t$(\"<td.duration_str\", { textContent: row.duration_str }),\n\t\t\t\t$(\"<td.duration_ns\", { textContent: row.duration_ns }),\n\t\t\t\t$(\"<td.tag\", { textContent: row.tag }),\n\t\t\t))\n\t\t}\n\t}\n}\n\nfunction update_graph(view_data) {\n\tif (window.graph) window.graph.destroy()\n\tlet groups = new vis.DataSet()\n\tlet items = []\n\tlet min_date\n\tlet max_date\n\tfor (let g of view_data) {\n\t\tlet group = {\n\t\t\tid: g.group_id,\n\t\t\tcontent: g.group_name,\n\t\t}\n\t\tfor (let row of g.rows) {\n\t\t\tif (!(min_date<row.date)) min_date = row.date\n\t\t\tif (!(max_date>row.date)) max_date = row.date\n\t\t\titems.push({\n\t\t\t\tx: row.date,\n\t\t\t\ty: row.duration_ns,\n\t\t\t\tgroup: g.group_id,\n\t\t\t\tlabel: { content: row.duration_str }\n\t\t\t})\n\t\t}\n\t}\n\tvar options = {\n\t\tstart: min_date - (max_date-min_date)/10,\n\t\tend: max_date + (max_date-min_date)/10,\n\t\tshaded: true,\n\t}\n\twindow.graph = new vis.Graph2d($(\"#vis\"), items, groups, options)\n\tgraph.on(\'click\', function (properties) {\n\t\tconsole.log(\"click\", properties)\n\t})\n}\n\nfunction make_selector(bench_name, task_name) {\n\tlet bench_name_select = $(\"<select.bench\",\n\t\t{ change: update_task_name_select },\n\t\tgb.bench_names.map(bn => $(`<option>${bn}`))\n\t)\n\tif (bench_name) {\n\t\tlet idx = gb.bench_names.indexOf(bench_name)\n\t\tif (idx >= 0) bench_name_select.selectedIndex = idx\n\t}\n\tlet task_name_select = $(\"<select.task\", { change: update_view })\n\tfunction update_task_name_select(){\n\t\tlet bench_name = bench_name_select.value\n\t\tconsole.log(\'bench_name:\', bench_name);\n\t\tlet bench_id = gb.val(\"SELECT id FROM bench WHERE name=$name\", { $name: bench_name })\n\t\tlet task_names = gb\n\t\t\t.list(\n\t\t\t\t\"SELECT name FROM task where bench=$bench_id\",\n\t\t\t\t{ $bench_id: bench_id }\n\t\t\t)\n\t\ttask_name_select.innerHTML = \"\"\n\t\t$(task_name_select, task_names.map(name => $(`<option>${name}`)))\n\t\treturn task_names\n\t}\n\tlet tag_input = $(\"<input.tag\", {\n\t\tchange: update_view,\n\t\tkeyup: update_view,\n\t})\n\tlet task_names = update_task_name_select()\n\tif (task_name) {\n\t\tlet idx = task_names.indexOf(task_name)\n\t\tif (idx >= 0) task_name_select.selectedIndex = idx\n\t}\n\tlet wrapper = $(\"<.selector-wrapper\",\n\t\t$(\"<.selector\",\n\t\t\t$(\"<label>bench:\", bench_name_select),\n\t\t\t$(\"<label>task:\", task_name_select),\n\t\t\t$(\"<select.tag-toggle\", { change: update_view },\n\t\t\t\t$(\"<option>with tag\"),\n\t\t\t\t$(\"<option>without tag\"),\n\t\t\t),\n\t\t\ttag_input,\n\t\t\t$(\"<.legend-icon\"),\n\t\t\t$(\"<button.remover>-\", {\n\t\t\t\tclick: () => {\n\t\t\t\t\twrapper.remove()\n\t\t\t\t\tupdate_view()\n\t\t\t\t}\n\t\t\t})\n\t\t),\n\t\t$(\"<.adder\",\n\t\t\t$(\"<button>+\", { click: make_selector })\n\t\t)\n\t)\n\t$(\"#selectors\", wrapper)\n\tupdate_view()\n}\n\nfunction wrap(db) {\n\tlet gb = {}\n\tgb.val = (sql, args) => gb.list(sql, args)[0]\n\tgb.list = (sql, args) => {\n\t\tlet res = db.exec(sql, args)[0]\n\t\treturn res ? res.values.map(r => r[0]) : []\n\t}\n\tgb.lists = (sql, args) => {\n\t\tlet res = db.exec(sql, args)[0]\n\t\treturn res ? res.values : []\n\t}\n\tgb.bench_names = gb.list(\"SELECT DISTINCT(name) FROM bench\")\n\treturn gb\n}\n\nfunction base64ToArrayBuffer(base64) {\n\tvar binary_string = window.atob(base64)\n\tvar len = binary_string.length\n\tvar bytes = new Uint8Array(len)\n\tfor (var i = 0; i < len; i++) {\n\t\tbytes[i] = binary_string.charCodeAt(i)\n\t}\n\treturn bytes.buffer\n}\n\nfunction fmt_nanos(nanos) {\n\tif (nanos < 1000) {\n\t\treturn nanos + \"ns\"\n\t}\n\tconst num = n => n > 999 ? Math.round(n) : n.toFixed(2)\n\tlet micros = nanos / 1000\n\tif (micros < 1000) {\n\t\treturn num(micros) + \"\u{b5}s\"\n\t}\n\tlet millis = micros / 1000\n\tif (millis < 1000) {\n\t\treturn num(millis) + \"ms\"\n\t}\n\tlet seconds = millis / 1000\n\treturn num(seconds) + \"s\"\n}\n";