mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Extracted row matching function and added comments
This commit is contained in:
parent
8d70f13393
commit
edb2dcf1b0
@ -145,8 +145,8 @@ transformers['table'] = {
|
|||||||
const columnNames = {};
|
const columnNames = {};
|
||||||
|
|
||||||
// Union of all columns
|
// Union of all columns
|
||||||
const columns = data.reduce((acc, d, i) => {
|
const columns = data.reduce((acc, series) => {
|
||||||
d.columns.forEach((col, j) => {
|
series.columns.forEach(col => {
|
||||||
const { text } = col;
|
const { text } = col;
|
||||||
if (columnNames[text] === undefined) {
|
if (columnNames[text] === undefined) {
|
||||||
columnNames[text] = acc.length;
|
columnNames[text] = acc.length;
|
||||||
@ -175,76 +175,84 @@ transformers['table'] = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track column indexes: name -> index
|
// Track column indexes of union: name -> index
|
||||||
const columnNames = {};
|
const columnNames = {};
|
||||||
const columnIndexes = [];
|
|
||||||
|
|
||||||
// Union of all non-value columns
|
// Union of all non-value columns
|
||||||
const columns = data.reduce((acc, d, i) => {
|
const columnsUnion = data.reduce((acc, series) => {
|
||||||
const indexes = [];
|
series.columns.forEach(col => {
|
||||||
d.columns.forEach((col, j) => {
|
|
||||||
const { text } = col;
|
const { text } = col;
|
||||||
if (columnNames[text] === undefined) {
|
if (columnNames[text] === undefined) {
|
||||||
columnNames[text] = acc.length;
|
columnNames[text] = acc.length;
|
||||||
acc.push(col);
|
acc.push(col);
|
||||||
}
|
}
|
||||||
indexes[j] = columnNames[text];
|
|
||||||
});
|
});
|
||||||
columnIndexes.push(indexes);
|
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
model.columns = columns;
|
// Map old column index to union index per series, e.g.,
|
||||||
|
// given columnNames {A: 0, B: 1} and
|
||||||
|
// data [{columns: [{ text: 'A' }]}, {columns: [{ text: 'B' }]}] => [[0], [1]]
|
||||||
|
const columnIndexMapper = data.map(series =>
|
||||||
|
series.columns.map(col => columnNames[col.text])
|
||||||
|
);
|
||||||
|
|
||||||
// Adjust rows to new column indexes
|
// Flatten rows of all series and adjust new column indexes
|
||||||
let rows = data.reduce((acc, d, i) => {
|
const flattenedRows = data.reduce((acc, series, seriesIndex) => {
|
||||||
const indexes = columnIndexes[i];
|
const mapper = columnIndexMapper[seriesIndex];
|
||||||
d.rows.forEach((r, j) => {
|
series.rows.forEach(row => {
|
||||||
const alteredRow = [];
|
const alteredRow = [];
|
||||||
indexes.forEach((to, from) => {
|
// Shifting entries according to index mapper
|
||||||
alteredRow[to] = r[from];
|
mapper.forEach((to, from) => {
|
||||||
|
alteredRow[to] = row[from];
|
||||||
});
|
});
|
||||||
acc.push(alteredRow);
|
acc.push(alteredRow);
|
||||||
});
|
});
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Returns true if both rows have matching non-empty fields as well as matching
|
||||||
|
// indexes where one field is empty and the other is not
|
||||||
|
function areRowsMatching(columns, row, otherRow) {
|
||||||
|
let foundFieldToMatch = false;
|
||||||
|
for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {
|
||||||
|
if (row[columnIndex] !== undefined && otherRow[columnIndex] !== undefined) {
|
||||||
|
if (row[columnIndex] !== otherRow[columnIndex]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (row[columnIndex] === undefined || otherRow[columnIndex] === undefined) {
|
||||||
|
foundFieldToMatch = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return foundFieldToMatch;
|
||||||
|
}
|
||||||
|
|
||||||
// Merge rows that have same values for columns
|
// Merge rows that have same values for columns
|
||||||
const mergedRows = {};
|
const mergedRows = {};
|
||||||
rows = rows.reduce((acc, row, rowIndex) => {
|
const compactedRows = flattenedRows.reduce((acc, row, rowIndex) => {
|
||||||
if (!mergedRows[rowIndex]) {
|
if (!mergedRows[rowIndex]) {
|
||||||
|
// Look from current row onwards
|
||||||
let offset = rowIndex + 1;
|
let offset = rowIndex + 1;
|
||||||
while (offset < rows.length) {
|
// More than one row can be merged into current row
|
||||||
// Find next row that has the same field values unless the respective field is undefined
|
while (offset < flattenedRows.length) {
|
||||||
const match = _.findIndex(rows, (otherRow) => {
|
// Find next row that could be merged
|
||||||
let fieldsAreTheSame = true;
|
const match = _.findIndex(flattenedRows,
|
||||||
let foundFieldToMatch = false;
|
otherRow => areRowsMatching(columnsUnion, row, otherRow),
|
||||||
for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {
|
offset);
|
||||||
if (row[columnIndex] !== undefined && otherRow[columnIndex] !== undefined) {
|
|
||||||
if (row[columnIndex] !== otherRow[columnIndex]) {
|
|
||||||
fieldsAreTheSame = false;
|
|
||||||
}
|
|
||||||
} else if (row[columnIndex] === undefined || otherRow[columnIndex] === undefined) {
|
|
||||||
foundFieldToMatch = true;
|
|
||||||
}
|
|
||||||
if (!fieldsAreTheSame) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fieldsAreTheSame && foundFieldToMatch;
|
|
||||||
}, offset);
|
|
||||||
if (match > -1) {
|
if (match > -1) {
|
||||||
const matchedRow = rows[match];
|
const matchedRow = flattenedRows[match];
|
||||||
// Merge values into current row
|
// Merge values from match into current row if there is a gap in the current row
|
||||||
for (let columnIndex = 0; columnIndex < columns.length; columnIndex++) {
|
for (let columnIndex = 0; columnIndex < columnsUnion.length; columnIndex++) {
|
||||||
if (row[columnIndex] === undefined && matchedRow[columnIndex] !== undefined) {
|
if (row[columnIndex] === undefined && matchedRow[columnIndex] !== undefined) {
|
||||||
row[columnIndex] = matchedRow[columnIndex];
|
row[columnIndex] = matchedRow[columnIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Dont visit this row again
|
||||||
mergedRows[match] = matchedRow;
|
mergedRows[match] = matchedRow;
|
||||||
// Keep looking for more rows to merge
|
// Keep looking for more rows to merge
|
||||||
offset = match + 1;
|
offset = match + 1;
|
||||||
} else {
|
} else {
|
||||||
|
// No match found, stop looking
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,7 +261,8 @@ transformers['table'] = {
|
|||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
model.rows = rows;
|
model.columns = columnsUnion;
|
||||||
|
model.rows = compactedRows;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user