WIP Create groupby time series trunction

Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com>
pull/10616/head
Iris Scholten 2018-04-10 17:05:16 -07:00
parent 424ef25d13
commit fc5e16ce56
3 changed files with 177 additions and 5 deletions

View File

@ -56,6 +56,10 @@ interface QueryAST {
limits: {limit: number}
sources: Sources[]
condition?: any
groupBy?: {
tags?: string[]
time: {interval: string}
}
}
interface Props {

View File

@ -50,7 +50,7 @@ class TableGraph extends Component {
}
componentWillReceiveProps(nextProps) {
const {data} = timeSeriesToTableGraph(nextProps.data)
const {data} = timeSeriesToTableGraph(nextProps.data, nextProps.queryASTs)
if (_.isEmpty(data[0])) {
return
}
@ -158,7 +158,7 @@ class TableGraph extends Component {
}
handleClickFieldName = fieldName => () => {
const {tableOptions} = this.props
const {tableOptions, queryASTs} = this.props
const {data, sortField, sortDirection} = this.state
const verticalTimeAxis = _.get(tableOptions, 'verticalTimeAxis', true)
const fieldNames = _.get(tableOptions, 'fieldNames', [TIME_FIELD_DEFAULT])
@ -175,7 +175,8 @@ class TableGraph extends Component {
fieldName,
direction,
verticalTimeAxis,
fieldNames
fieldNames,
timeFormat
)
this.setState({

View File

@ -2,6 +2,7 @@ import _ from 'lodash'
import {shiftDate} from 'shared/query/helpers'
import {map, reduce, filter, forEach, concat, clone} from 'fast.js'
import {calculateColumnWidths} from 'src/dashboards/utils/tableGraph'
import {groupByTag} from 'src/kapacitor/actions/queryConfigs'
/**
* Accepts an array of raw influxdb responses and returns a format
@ -172,8 +173,174 @@ export const timeSeriesToDygraph = (raw = [], isInDataExplorer) => {
}
}
export const timeSeriesToTableGraph = raw => {
const {sortedLabels, sortedTimeSeries} = timeSeriesTransform(raw)
const hasGroupBy = queryASTs => {
return queryASTs.some(queryAST => {
return _.get(queryAST, ['groupBy', 'tags'], false)
})
}
const groupByTimeSeriesTransform = (raw = [], queryASTs = []) => {
const groupBys = queryASTs.map(queryAST => {
return _.get(queryAST, ['groupBy', 'tags'], false)
})
raw.forEach((r, i) => {
if (groupBys[i]) {
// treat it like a groupBy
} else {
// don't treat it like a groupby..
}
})
console.log('queryASTs', queryASTs)
// foreachqueryAST in queryASTs
// determine if hasGroupBy
// if hasGroupBy time// tag/ select
// if nothasGroupBy append
console.log('raw', raw)
// collect results from each influx response
const results = reduce(
raw,
(acc, rawResponse, responseIndex) => {
const responses = _.get(rawResponse, 'response.results', [])
const indexedResponses = map(responses, response => ({
...response,
responseIndex,
}))
return [...acc, ...indexedResponses]
},
[]
)
// collect each series
const serieses = reduce(
results,
(acc, {series = [], responseIndex}, index) => {
return [...acc, ...map(series, item => ({...item, responseIndex, index}))]
},
[]
)
console.log('serieses', serieses)
const tags = queryASTs.reduce((acc, queryAST) => {
return [...acc, ..._.get(queryAST, ['groupBy', 'tags'], [])]
}, [])
tags.forEach(tag => {
const filtered = serieses.filter(s => {
const t = _.get(s, '')
})
})
const size = reduce(
serieses,
(acc, {columns, values}) => {
if (columns.length && (values && values.length)) {
return acc + (columns.length - 1) * values.length
}
return acc
},
0
)
// convert series into cells with rows and columns
let cellIndex = 0
let labels = []
forEach(
serieses,
({
name: measurement,
columns,
values,
index: seriesIndex,
responseIndex,
tags = {},
}) => {
const rows = map(values || [], vals => ({
vals,
}))
// tagSet is each tag key and value for a series
const tagSet = map(Object.keys(tags), tag => `[${tag}=${tags[tag]}]`)
.sort()
.join('')
const unsortedLabels = map(columns.slice(1), field => ({
label: `${measurement}.${field}${tagSet}`,
responseIndex,
seriesIndex,
}))
labels = concat(labels, unsortedLabels)
forEach(rows, ({vals}) => {
const [time, ...rowValues] = vals
forEach(rowValues, (value, i) => {
cells.label[cellIndex] = unsortedLabels[i].label
cells.value[cellIndex] = value
cells.time[cellIndex] = time
cells.seriesIndex[cellIndex] = seriesIndex
cells.responseIndex[cellIndex] = responseIndex
cellIndex++ // eslint-disable-line no-plusplus
})
})
}
)
const sortedLabels = _.sortBy(labels, 'label')
const tsMemo = {}
const nullArray = Array(sortedLabels.length).fill(null)
const labelsToValueIndex = reduce(
sortedLabels,
(acc, {label, seriesIndex}, i) => {
// adding series index prevents overwriting of two distinct labels that have the same field and measurements
acc[label + seriesIndex] = i
return acc
},
{}
)
const timeSeries = []
for (let i = 0; i < size; i++) {
let 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')
}
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 {
sortedLabels,
sortedTimeSeries,
}
}
export const timeSeriesToTableGraph = (raw, queryASTs) => {
const {sortedLabels, sortedTimeSeries} = hasGroupBy(queryASTs)
? groupByTimeSeriesTransform(raw, queryASTs)
: timeSeriesTransform(raw)
const labels = ['time', ...map(sortedLabels, ({label}) => label)]