blob: b274ab9752514fac8967e05c7c48d86f93b3e0ee [file] [log] [blame]
<!--
The common.js file must be included before this file.
This in an HTML Import-able file that contains the CSS, JS and HTML
Templates for the sk.Compare components.
To use this file import it:
<link href="/res/imp/compare.html" rel="import" />
-->
<template id=compTableTemplate>
<div class=tblPadding></div>
<table class=compTable></table>
</template>
<template id=compTrTemplate>
<tr class=compTr data-weight="0"></tr>
</template>
<template id=compThTemplate>
<th><div class=compTh></div></th>
</template>
<template id=compTdTemplate>
<td class=compTd></td>
</template>
<style type="text/css" media="screen">
.compTable,
.compTd {
border: none;
}
.compHeatHeader {
transform: rotate(-45deg) translate(10px, 0px);
width: 25px;
border: none;
text-decoration: underline;
}
.tblPadding {
height: 200px;
}
</style>
<script type="text/javascript" charset="utf-8">
(function(){
"use strict";
// Keep track of this file so we can grab HTML Templates from it.
var importer__ = new sk.Importer();
/**
* Compare is a container for the compare results.
*/
sk.Compare = function() {
};
/**
* attach, call after construction to hook up elements to their callbacks.
*/
sk.Compare.prototype.attach = function(e) {
// resultsContainer_ is the DOM node containing compare results.
this.resultsContainer_ = $$$('#skCompare');
};
/**
* display tries to construct a table from data and displays it in container.
*
* Parameters cols, cells are defined differently in different contexts.
* Please refer to the calling function for details. In general,
*
* cols contains the column names for the resulting table.
*
* cells is an object keyed by table row name. Within each row, keys are the
* corresponding column indices in the cols above, and values are the pair of
* bench values corresponding to the pair of data to compare. Example:
* {
* "Deque_Push_640_480": {
* 0: [0.9, 1.3],
* 2: [1.1, 0.8],
* ...
* },
* "Another_Test": {
* 1: [0, 0.7],
* ...
* },
* ...
* }
*
*/
sk.Compare.prototype.display = function(cols, cells) {
/**
* Keep reservoir sampling of positive and negative table cell values, used
* for calculating heatmap opaque values.
*/
var MAX_SAMPLES = 9;
var posSamples = [];
var posCounts = 0;
var negSamples = [];
var negCounts = 0;
sk.clearChildren(this.resultsContainer_);
var node = importer__.import('#compTableTemplate');
this.resultsContainer_.appendChild(node);
var header = $$$('.compTr', importer__.import('#compTrTemplate'));
for (var i = 0; i < cols.length; i++) {
var colHeader = importer__.import('#compThTemplate');
$$$('.compTh', colHeader).innerText = cols[i];
$$$('.compTh', colHeader).classList.add('compHeatHeader');
header.appendChild(colHeader);
};
var colHeader = importer__.import('#compThTemplate');
$$$('.compTh', colHeader).innerText = 'test';
header.appendChild(colHeader);
var tableRows = Object.keys(cells).map(function(row) {
var tr = $$$('.compTr', importer__.import('#compTrTemplate'));
var rowData = cells[row];
var weight = 0.0;
for (var i = 0; i < cols.length; i++) {
var val = 0; // Ratio of two benches for the criterion; default to 0.
if (i in rowData) {
var l = rowData[i][0];
var r = rowData[i][1];
if (l > r) {
if (r > 0) {
val = l / r; // Range is (1, Inf).
posCounts++;
if (posSamples.length < MAX_SAMPLES) {
posSamples.push(val);
} else if (Math.random() < MAX_SAMPLES / posCounts) {
posSamples[Math.floor(Math.random() * MAX_SAMPLES)] = val;
}
}
} else if (l > 0) {
// Invert and make negative, mapping (0, 1] to (-Inf, -1].
val = -r / l;
negCounts++;
if (negSamples.length < MAX_SAMPLES) {
negSamples.push(val);
} else if (Math.random() < MAX_SAMPLES / negCounts) {
negSamples[Math.floor(Math.random() * MAX_SAMPLES)] = val;
}
}
weight += val;
}
var td = $$$('.compTd', importer__.import('#compTdTemplate'));
td.innerHTML= val.toFixed(2);
if (val > 0) {
td.style.background = '#AA4499';
} else {
td.style.background = '#999933';
}
tr.appendChild(td);
}
var testTd = $$$('.compTd', importer__.import('#compTdTemplate'));
testTd.innerText = row;
tr.appendChild(testTd);
tr.dataset.weight = weight;
return tr;
});
// Sort rows by weight, descending.
tableRows.sort(function(a, b) {
return b.dataset.weight - a.dataset.weight
});
var table = $$$('.compTable', this.resultsContainer_);
table.appendChild(header);
tableRows.forEach(function(r) {
table.appendChild(r);
});
// Set cell opaqueness from reservoir samples.
posSamples.sort();
negSamples.sort().reverse();
$$('.compTd').forEach(function(td) {
var val = parseFloat(td.innerText);
var arr = posSamples;
if (val < 0) {
arr = negSamples;
}
var i = 0;
for (; i < arr.length; i++) {
if (val < arr[i]) {
break;
}
}
if (val < 0) { // Count from tail.
i = arr.length - i;
}
td.style.opacity = i / 10;
});
}
})();
</script>