From cb265aeb8ce5280874db02776c287ab1a3e6ac4c Mon Sep 17 00:00:00 2001 From: ebb-tide Date: Wed, 18 Apr 2018 16:48:44 -0700 Subject: [PATCH] Add groupby responses without unnnecessary padding --- ui/src/dashboards/utils/tableGraph.ts | 19 ++-- ui/src/shared/components/TableGraph.js | 21 ++-- ui/src/utils/groupBy.js | 128 +++++++++++-------------- ui/src/utils/timeSeriesTransformers.js | 1 + 4 files changed, 76 insertions(+), 93 deletions(-) diff --git a/ui/src/dashboards/utils/tableGraph.ts b/ui/src/dashboards/utils/tableGraph.ts index c872a071eb..4380ca2ec4 100644 --- a/ui/src/dashboards/utils/tableGraph.ts +++ b/ui/src/dashboards/utils/tableGraph.ts @@ -77,28 +77,25 @@ const updateMaxWidths = ( ) } -export const computeFieldNames = (existingFieldNames, queryASTs) => { +export const computeFieldNames = (existingFieldNames, sortedLabels) => { const timeField = existingFieldNames.find(f => f.internalName === 'time') || TIME_FIELD_DEFAULT let astNames = [timeField] - queryASTs.forEach(q => { - const {fields, sources} = q - const sourceName = _.get(sources, ['0', 'name']) - fields.forEach(f => { - const {alias, column: {val}} = f - const value = val || alias - const internalName = `${sourceName}.${value}` - const field = {internalName, displayName: '', visible: true} - astNames = [...astNames, field] - }) + + sortedLabels.forEach(({label}) => { + const field = {internalName: label, displayName: '', visible: true} + astNames = [...astNames, field] }) + const intersection = existingFieldNames.filter(f => { return astNames.find(a => a.internalName === f.internalName) }) + const newFields = astNames.filter(a => { return !existingFieldNames.find(f => f.internalName === a.internalName) }) + return [...intersection, ...newFields] } diff --git a/ui/src/shared/components/TableGraph.js b/ui/src/shared/components/TableGraph.js index bdadfc50b4..d7959ee87d 100644 --- a/ui/src/shared/components/TableGraph.js +++ b/ui/src/shared/components/TableGraph.js @@ -41,6 +41,7 @@ class TableGraph extends Component { data: [[]], processedData: [[]], sortedTimeVals: [], + sortedLabels: [], hoveredColumnIndex: NULL_ARRAY_INDEX, hoveredRowIndex: NULL_ARRAY_INDEX, sortField, @@ -50,16 +51,16 @@ class TableGraph extends Component { } } - shouldComponentUpdate(nextProps) { + componentWillReceiveProps(nextProps) { const updatedProps = _.keys(nextProps).filter( k => !_.isEqual(this.props[k], nextProps[k]) ) - return !!_.intersection(updatedProps, ['data', 'queryASTs', 'tableOptions']) - .length - } - componentWillReceiveProps(nextProps) { - const {data} = timeSeriesToTableGraph(nextProps.data, nextProps.queryASTs) + const {data, sortedLabels} = + _.includes(updatedProps, 'data') || _.includes(updatedProps, 'queryASTs') + ? timeSeriesToTableGraph(nextProps.data, nextProps.queryASTs) + : this.state + if (_.isEmpty(data[0])) { return } @@ -72,11 +73,8 @@ class TableGraph extends Component { timeFormat, }, } = nextProps - const computedFieldNames = computeFieldNames( - fieldNames, - nextProps.queryASTs - ) - + const computedFieldNames = computeFieldNames(fieldNames, sortedLabels) + // MUST UPDATE FIELD NAMES HERE. let direction, sortFieldName if ( _.get(this.props, ['tableOptions', 'sortBy', 'internalName'], '') === @@ -104,6 +102,7 @@ class TableGraph extends Component { ) this.setState({ data, + sortedLabels, processedData, sortedTimeVals, sortField: sortFieldName, diff --git a/ui/src/utils/groupBy.js b/ui/src/utils/groupBy.js index 8fbf1e7b4d..d173c02b1b 100644 --- a/ui/src/utils/groupBy.js +++ b/ui/src/utils/groupBy.js @@ -2,7 +2,7 @@ import _ from 'lodash' import {shiftDate} from 'shared/query/helpers' import {map, reduce, forEach, concat, clone} from 'fast.js' -const groupIt = (responses, responseIndex, groupBys) => { +const groupByTransform = (responses, responseIndex, groupBys) => { const firstColumns = _.get(responses, [0, 'series', 0, 'columns']) const accum = [ { @@ -37,7 +37,7 @@ export const groupByTimeSeriesTransform = (raw = [], queryASTs = []) => { const responses = _.get(rawResponse, 'response.results', []) const indexedResponses = groupBys[responseIndex] - ? groupIt(responses, responseIndex, groupBys[responseIndex]) + ? groupByTransform(responses, responseIndex, groupBys[responseIndex]) : map(responses, response => ({ ...response, responseIndex, @@ -71,6 +71,7 @@ export const groupByTimeSeriesTransform = (raw = [], queryASTs = []) => { }, 0 ) + // console.log('size', size) // convert series into cells with rows and columns let cellIndex = 0 let labels = [] @@ -84,16 +85,20 @@ export const groupByTimeSeriesTransform = (raw = [], queryASTs = []) => { seriesIndex: new Array(DEFAULT_SIZE), responseIndex: new Array(DEFAULT_SIZE), } + forEach( serieses, - ({ - name: measurement, - columns, - values, - seriesIndex, - responseIndex, - tags = {}, - }) => { + ( + { + name: measurement, + columns, + values, + seriesIndex, + responseIndex, + tags = {}, + }, + ind + ) => { const rows = map(values || [], vals => ({ vals, })) @@ -103,6 +108,7 @@ export const groupByTimeSeriesTransform = (raw = [], queryASTs = []) => { responseIndex, seriesIndex, })) + serieses[ind].unsortedLabels = unsortedLabels labels = concat(labels, unsortedLabels) const groupByTags = groupBys[responseIndex] cells.groupByLabels = groupByTags @@ -126,7 +132,8 @@ export const groupByTimeSeriesTransform = (raw = [], queryASTs = []) => { const sortedLabels = _.sortBy(labels, 'label') const tsMemo = {} - const nullArray = Array(sortedLabels.length).fill(null) + const nullArray = Array(sortedLabels.length).fill('null') + const slashArray = Array(sortedLabels.length).fill('-') const labelsToValueIndex = reduce( sortedLabels, @@ -139,33 +146,52 @@ export const groupByTimeSeriesTransform = (raw = [], queryASTs = []) => { ) const timeSeries = [] + let existingRowIndex + forEach(serieses, s => { + if (groupBys[s.responseIndex]) { + forEach(s.values, vs => { + timeSeries.push({time: vs[0], values: clone(slashArray)}) + existingRowIndex = timeSeries.length - 1 + forEach(vs.slice(1), (v, i) => { + const label = s.unsortedLabels[i].label + timeSeries[existingRowIndex].values[ + labelsToValueIndex[label + s.seriesIndex] + ] = v + }) + }) + } + }) for (let i = 0; i < size; i++) { - let time = cells.time[i] + let time + time = cells.time[i] const value = cells.value[i] const label = cells.label[i] const seriesIndex = cells.seriesIndex[i] - if (label.includes('_shifted__')) { - const [, quantity, duration] = label.split('__') - time = +shiftDate(time, quantity, duration).format('x') + if (!groupBys[cells.responseIndex[i]]) { + if (label.includes('_shifted__')) { + const [, quantity, duration] = label.split('__') + time = +shiftDate(time, quantity, duration).format('x') + } + + existingRowIndex = tsMemo[time] + + if (existingRowIndex === undefined) { + timeSeries.push({ + time, + values: clone(slashArray), + }) + + existingRowIndex = timeSeries.length - 1 + tsMemo[time] = existingRowIndex + } + + timeSeries[existingRowIndex].values[ + labelsToValueIndex[label + seriesIndex] + ] = value } - - let existingRowIndex = tsMemo[time] - - if (existingRowIndex === undefined) { - timeSeries.push({ - time, - values: clone(nullArray), - }) - - existingRowIndex = timeSeries.length - 1 - tsMemo[time] = existingRowIndex - } - - timeSeries[existingRowIndex].values[ - labelsToValueIndex[label + seriesIndex] - ] = value } + const sortedTimeSeries = _.sortBy(timeSeries, 'time') return { @@ -173,43 +199,3 @@ export const groupByTimeSeriesTransform = (raw = [], queryASTs = []) => { sortedTimeSeries, } } - -// export const groupByTimeSeriesTransform = (raw = [], queryASTs = []) => { -// -// raw.forEach((r, i) => { -// const columnsInRaw = _.get( -// r, -// ['response', 'results', '0', 'series', '0', 'columns'], -// [] -// ) -// const unselectedGroupBys = groupBys[i].filter( -// gb => !_.includes(columnsInRaw, gb) -// ) -// const series = _.get(r, ['response', 'results', '0', 'series'], []) -// const result = reduce( -// series, -// (acc, s) => { -// const seriesValues = s.values -// const unselectedGroupBysTags = unselectedGroupBys.map(gb => s.tags[gb]) -// -// const seriesRows = map(seriesValues, v => [ -// v[0], -// ...unselectedGroupBysTags, -// ...v.slice(1), -// ]) -// return _.concat(acc, seriesRows) -// }, -// [] -// ) -// labels = [ -// series[0].columns[0], -// ...unselectedGroupBys, -// ...series[0].columns.slice(1), -// ] -// finalResult = _.concat(finalResult, result) -// }) -// return { -// sortedLabels: finalResult[0], -// sortedTimeSeries: finalResult.slice(1), -// } -// } diff --git a/ui/src/utils/timeSeriesTransformers.js b/ui/src/utils/timeSeriesTransformers.js index 0a88577985..a961938cd2 100644 --- a/ui/src/utils/timeSeriesTransformers.js +++ b/ui/src/utils/timeSeriesTransformers.js @@ -190,6 +190,7 @@ export const timeSeriesToTableGraph = (raw, queryASTs) => { const data = tableData.length ? [labels, ...tableData] : [[]] return { data, + sortedLabels, } }