Use timeSeriesTransform for dygraphs.
parent
70b7d73040
commit
bb277189b1
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
|||
import Dygraph from 'shared/components/Dygraph'
|
||||
|
||||
import SingleStat from 'src/shared/components/SingleStat'
|
||||
import timeSeriesToDygraph from 'utils/timeSeriesTransformers'
|
||||
import {timeSeriesToDygraph} from 'utils/timeSeriesTransformers'
|
||||
|
||||
import {colorsStringSchema} from 'shared/schemas'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
|
|
@ -125,8 +125,9 @@ const insertGroupByValues = (
|
|||
groupBys,
|
||||
seriesLabels,
|
||||
labelsToValueIndex,
|
||||
dashArray
|
||||
sortedLabels
|
||||
) => {
|
||||
const dashArray = Array(sortedLabels.length).fill('-')
|
||||
const timeSeries = []
|
||||
let existingRowIndex
|
||||
forEach(serieses, (s, sind) => {
|
||||
|
@ -137,7 +138,7 @@ const insertGroupByValues = (
|
|||
forEach(vs.slice(1), (v, i) => {
|
||||
const label = seriesLabels[sind][i].label
|
||||
timeSeries[existingRowIndex].values[
|
||||
labelsToValueIndex[label + s.seriesIndex]
|
||||
labelsToValueIndex[label + s.responseIndex + s.seriesIndex]
|
||||
] = v
|
||||
})
|
||||
})
|
||||
|
@ -154,13 +155,13 @@ const constructTimeSeries = (
|
|||
groupBys,
|
||||
seriesLabels
|
||||
) => {
|
||||
const dashArray = Array(sortedLabels.length).fill('-')
|
||||
const nullArray = Array(sortedLabels.length).fill(null)
|
||||
|
||||
const labelsToValueIndex = reduce(
|
||||
sortedLabels,
|
||||
(acc, {label, seriesIndex}, i) => {
|
||||
(acc, {label, responseIndex, seriesIndex}, i) => {
|
||||
// adding series index prevents overwriting of two distinct labels that have the same field and measurements
|
||||
acc[label + seriesIndex] = i
|
||||
acc[label + responseIndex + seriesIndex] = i
|
||||
return acc
|
||||
},
|
||||
{}
|
||||
|
@ -173,7 +174,7 @@ const constructTimeSeries = (
|
|||
groupBys,
|
||||
seriesLabels,
|
||||
labelsToValueIndex,
|
||||
dashArray
|
||||
sortedLabels
|
||||
)
|
||||
|
||||
let existingRowIndex
|
||||
|
@ -184,6 +185,7 @@ const constructTimeSeries = (
|
|||
const value = cells.value[i]
|
||||
const label = cells.label[i]
|
||||
const seriesIndex = cells.seriesIndex[i]
|
||||
const responseIndex = cells.responseIndex[i]
|
||||
|
||||
if (groupBys[cells.responseIndex[i]]) {
|
||||
// we've already inserted GroupByValues
|
||||
|
@ -200,7 +202,7 @@ const constructTimeSeries = (
|
|||
if (existingRowIndex === undefined) {
|
||||
timeSeries.push({
|
||||
time,
|
||||
values: clone(dashArray),
|
||||
values: clone(nullArray),
|
||||
})
|
||||
|
||||
existingRowIndex = timeSeries.length - 1
|
||||
|
@ -208,14 +210,17 @@ const constructTimeSeries = (
|
|||
}
|
||||
|
||||
timeSeries[existingRowIndex].values[
|
||||
labelsToValueIndex[label + seriesIndex]
|
||||
labelsToValueIndex[label + responseIndex + seriesIndex]
|
||||
] = value
|
||||
}
|
||||
|
||||
return _.sortBy(timeSeries, 'time')
|
||||
}
|
||||
|
||||
export const groupByTimeSeriesTransform = (raw, groupBys = []) => {
|
||||
export const groupByTimeSeriesTransform = (raw, groupBys) => {
|
||||
if (!groupBys) {
|
||||
groupBys = Array(raw.length).fill(false)
|
||||
}
|
||||
const results = constructResults(raw, groupBys)
|
||||
|
||||
const serieses = constructSerieses(results)
|
||||
|
|
|
@ -1,153 +1,9 @@
|
|||
import _ from 'lodash'
|
||||
import {shiftDate} from 'shared/query/helpers'
|
||||
import {map, reduce, forEach, concat, clone} from 'fast.js'
|
||||
import {map, reduce} from 'fast.js'
|
||||
import {groupByTimeSeriesTransform} from 'src/utils/groupBy.js'
|
||||
|
||||
/**
|
||||
* Accepts an array of raw influxdb responses and returns a format
|
||||
* that Dygraph understands.
|
||||
**/
|
||||
|
||||
const DEFAULT_SIZE = 0
|
||||
const cells = {
|
||||
label: new Array(DEFAULT_SIZE),
|
||||
value: new Array(DEFAULT_SIZE),
|
||||
time: new Array(DEFAULT_SIZE),
|
||||
seriesIndex: new Array(DEFAULT_SIZE),
|
||||
responseIndex: new Array(DEFAULT_SIZE),
|
||||
}
|
||||
|
||||
const timeSeriesTransform = (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}))]
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
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 timeSeriesToDygraph = (raw = [], isInDataExplorer) => {
|
||||
const {sortedLabels, sortedTimeSeries} = timeSeriesTransform(raw)
|
||||
const {sortedLabels, sortedTimeSeries} = groupByTimeSeriesTransform(raw)
|
||||
|
||||
const dygraphSeries = reduce(
|
||||
sortedLabels,
|
||||
|
@ -193,5 +49,3 @@ export const timeSeriesToTableGraph = (raw, queryASTs) => {
|
|||
sortedLabels,
|
||||
}
|
||||
}
|
||||
|
||||
export default timeSeriesToDygraph
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import timeSeriesToDygraph, {
|
||||
import {
|
||||
timeSeriesToDygraph,
|
||||
timeSeriesToTableGraph,
|
||||
} from 'src/utils/timeSeriesTransformers'
|
||||
|
||||
|
@ -185,7 +186,6 @@ describe('timeSeriesToDygraph', () => {
|
|||
},
|
||||
},
|
||||
]
|
||||
|
||||
const actual = timeSeriesToDygraph(influxResponse)
|
||||
|
||||
const expected = {
|
||||
|
@ -382,9 +382,9 @@ describe('timeSeriesToTableGraph', () => {
|
|||
const actual = timeSeriesToTableGraph(influxResponse, qASTs)
|
||||
const expected = [
|
||||
['time', 'ma.f1', 'mb.f1', 'mc.f1', 'mc.f2'],
|
||||
[1000, 1, 1, '-', '-'],
|
||||
[1000, 1, 1, null, null],
|
||||
[2000, 2, 2, 3, 3],
|
||||
[4000, '-', '-', 4, 4],
|
||||
[4000, null, null, 4, 4],
|
||||
]
|
||||
|
||||
expect(actual.data).toEqual(expected)
|
||||
|
|
Loading…
Reference in New Issue