From a8bc05788acf224c1c91aa614a2ca7d4527d62f5 Mon Sep 17 00:00:00 2001 From: Yue Gan Date: Tue, 7 Feb 2017 12:52:42 +0000 Subject: Benchmark part 4: draw line charts -- PiperOrigin-RevId: 146773562 MOS_MIGRATED_REVID=146773562 --- src/tools/benchmark/webapp/draw_chart.js | 174 +++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 src/tools/benchmark/webapp/draw_chart.js (limited to 'src/tools/benchmark/webapp/draw_chart.js') diff --git a/src/tools/benchmark/webapp/draw_chart.js b/src/tools/benchmark/webapp/draw_chart.js new file mode 100644 index 0000000000..62feb2e8ab --- /dev/null +++ b/src/tools/benchmark/webapp/draw_chart.js @@ -0,0 +1,174 @@ +google.charts.load('current', {packages: ['corechart']}); +google.charts.setOnLoadCallback(drawAllChart); + +/** + * Get data from /data.json and draw charts from it. + */ +function drawAllChart() { + $.getJSON('data.json', function(data) { + /** @type {!Array} */ + const chart = []; + const options = []; + /** @type {!Array} */ + const tableData = []; + /** @type {!Array} */ + const columns = []; + const buildTargetResultsLen = data.buildTargetResults.length; + + // add divs to #content + for (let i = 0; i < buildTargetResultsLen; ++i) { + $('
') + .appendTo('#content'); + } + + // draw chart for every BuildTargetResult + for (let i = 0; i < buildTargetResultsLen; ++i) { + const buildEnvResults = data.buildTargetResults[i].buildEnvResults; + + // Add columns and rows for chart + tableData[i] = new google.visualization.DataTable(); + addColumnsFromBuildEnv(tableData[i], buildEnvResults); + addRowsFromData(tableData[i], buildEnvResults); + + options[i] = { + title: data.buildTargetResults[i].buildTargetConfig.description, + tooltip: { isHtml: true, trigger: 'both'}, + intervals: { style: 'bars' }, + chartArea: { width: '70%' } + }; + + chart[i] = new google.visualization.LineChart( + document.getElementById('target' + i)); + chart[i].draw(tableData[i], options[i]); + + // ---------------------------------- event + + columns[i] = []; + for (let j = 0; j < tableData[i].getNumberOfColumns(); j++) { + columns[i].push(j); + } + + google.visualization.events.addListener( + chart[i], 'select', (function (x) { + return function () { + hideOrShow(chart[x], columns[x], tableData[x], options[x]); + }; + })(i)); + } + }); +} + +/** + * Add columns for each buildEnvResults/line. + * @param {!LineChart} lineChart + * @param {!Array} buildEnvResults build results + */ +function addColumnsFromBuildEnv (lineChart, buildEnvResults) { + lineChart.addColumn('string', 'version'); + for (let buildEnvResult of buildEnvResults) { + lineChart.addColumn( + 'number', buildEnvResult.config.description); + lineChart.addColumn({type:'number', role:'interval'}); + lineChart.addColumn({type:'number', role:'interval'}); + lineChart.addColumn( + {'type': 'string', 'role': 'tooltip', 'p': {'html': true}}); + } +} + +/** + * Add rows for each code version. + * @param {!LineChart} lineChart + * @param {!Array} buildEnvResults build results + */ +function addRowsFromData (lineChart, buildEnvResults) { + for (let j = 0; j < buildEnvResults[0].results.length; ++j) { + const row = [buildEnvResults[0].results[j].codeVersion.substr(0, 10)]; + for (let buildEnvResult of buildEnvResults) { + const singleBuildResult = buildEnvResult.results[j]; + + const ave = getAverage(singleBuildResult.results); + const sd = getStandardDeviation(singleBuildResult.results, ave); + row.push(ave); + row.push(ave - sd); + row.push(ave + sd); + row.push( + createCustomHTMLContent( + singleBuildResult.results, singleBuildResult.codeVersion)); + } + lineChart.addRow(row); + } +} + +/** + * Get average of an array. + * @param {!Array} arr + * @return {!number} the average + */ +function getAverage(arr) { + let ave = arr.reduce(function(a, b) { return a + b; }); + ave /= arr.length; + return ave; +} + +/** + * Get standard deviation of an array. + * @param {!Array} arr + * @param {!number} ave average of the array + * @return {!number} the standard deviation + */ +function getStandardDeviation(arr, ave) { + let sd = 0; + for (let item of arr) { + const diff = ave - item; + sd += diff * diff; + } + sd = Math.sqrt(sd); + return sd; +} + +/** + * Create html content as tooltip. + * @param {!Array} arr array of build results + * @return {!string} the html content + */ +function createCustomHTMLContent(arr) { + let str = '
'; + for (let i = 0; i < arr.length; ++i) { + str += (i+1) + '-th run: ' + arr[i] + '
'; + } + str += '
'; + return str; +} + +/** + * Hide or show one column/line in a chart. + * @param {!LineChart} chart the chart to operate + * @param {!Column} columns columns of current chart + * @param {!DataTable} tableData data for current chart + * @param {!Object} options options for current chart + */ +function hideOrShow(chart, columns, tableData, options) { + const sel = chart.getSelection(); + // If selection length is 0, we deselected an element + if (sel.length <= 0 || sel[0].row !== null) { + return; + } + + const col = sel[0].column; + if (columns[col] == col) { + // Hide the data series + columns[col] = { + label: tableData.getColumnLabel(col), + type: tableData.getColumnType(col), + calc: function () { + return null; + } + }; + } else { + // Show the data series + columns[col] = col; + } + const view = new google.visualization.DataView(tableData); + view.setColumns(columns); + chart.draw(view, options); +} \ No newline at end of file -- cgit v1.2.3