in frontend/app/components/chart/table_utils.ts [201:287]
function mergeSortTables(
diffTable: google.visualization.DataTable,
oldTable: google.visualization.DataTable,
newTable: google.visualization.DataTable, referenceCol: number,
comparisonCol: number, formatDiffInfo: FormatDiffInfo[],
formatValueInfo: FormatValueInfo[]): number {
oldTable.sort({column: referenceCol, desc: false}); // Ascending order.
newTable.sort({column: referenceCol, desc: false}); // Ascending order.
const oldSize = oldTable.getNumberOfRows();
const newSize = newTable.getNumberOfRows();
// colsCount is number of columns in the original tables. In diffTable
// there is one additional column at the end which is the difference
// in self time between two stats. The column is used solely for
// sorting the diffTable and gets hidden before function returns.
const colsCount = oldTable.getNumberOfColumns();
const largeCharInASCII = '~~~~';
let rowIndex = 0;
for (let oldRow = 0, newRow = 0; oldRow < oldSize || newRow < newSize;
rowIndex++) {
// Assign the largest character in ASCII table for comparison.
const oldReferenceValue = (oldRow < oldSize) ?
oldTable.getValue(oldRow, referenceCol) :
largeCharInASCII;
const newReferenceValue = (newRow < newSize) ?
newTable.getValue(newRow, referenceCol) :
largeCharInASCII;
if (oldRow < oldSize && newRow < newSize &&
oldReferenceValue === newReferenceValue) {
// If reference value is the same, then diff the two stats.
for (let colIndex = 0; colIndex < colsCount; colIndex++) {
if (colIndex !== 0 && oldTable.getColumnType(colIndex) === 'number') {
const baseVal = oldTable.getValue(oldRow, colIndex);
const diffVal = newTable.getValue(newRow, colIndex) -
oldTable.getValue(oldRow, colIndex);
diffTable.setCell(
rowIndex, colIndex,
formatValue(baseVal, colIndex, formatValueInfo) +
formatDiff(diffVal, baseVal, colIndex, formatDiffInfo));
} else { // Use oldTable's string values, or rank.
diffTable.setCell(
rowIndex, colIndex, oldTable.getValue(oldRow, colIndex));
}
}
const diffValue = newTable.getValue(newRow, comparisonCol) -
oldTable.getValue(oldRow, comparisonCol);
diffTable.setCell(rowIndex, colsCount, diffValue);
oldRow++, newRow++;
} else if (newRow === newSize || oldReferenceValue < newReferenceValue) {
// If only old stats, then assign the diff as negative old stats.
for (let colIndex = 0; colIndex < colsCount; colIndex++) {
if (colIndex !== 0 && oldTable.getColumnType(colIndex) === 'number') {
const baseVal = oldTable.getValue(oldRow, colIndex);
const diffVal = -oldTable.getValue(oldRow, colIndex);
diffTable.setCell(
rowIndex, colIndex,
formatValue(baseVal, colIndex, formatValueInfo) +
formatDiff(diffVal, baseVal, colIndex, formatDiffInfo));
} else { // Use oldTable's string values, or rank.
diffTable.setCell(
rowIndex, colIndex, oldTable.getValue(oldRow, colIndex));
}
}
const diffValue = -oldTable.getValue(oldRow, comparisonCol);
diffTable.setCell(rowIndex, colsCount, diffValue);
oldRow++;
} else { // if (oldRow == oldSize || oldReferenceValue > newReferenceValue)
// If only new stats, then assign the diff as new stats.
for (let colIndex = 0; colIndex < colsCount; colIndex++) {
if (colIndex !== 0 && newTable.getColumnType(colIndex) === 'number') {
const baseVal = 0;
const diffVal = newTable.getValue(newRow, colIndex);
diffTable.setCell(
rowIndex, colIndex,
formatValue(baseVal, colIndex, formatValueInfo) +
formatDiff(diffVal, baseVal, colIndex, formatDiffInfo));
} else { // Use newTable's string values, or rank.
diffTable.setCell(
rowIndex, colIndex, newTable.getValue(newRow, colIndex));
}
}
const diffValue = newTable.getValue(newRow, comparisonCol);
diffTable.setCell(rowIndex, colsCount, diffValue);
newRow++;
} // End of if condition comparing opName.
} // End of for loop over all rows.
return rowIndex;
}