Prettify and not error when no values returned from influxdb

pull/10616/head
Andrew Watkins 2017-04-25 13:32:04 -07:00
parent 12c70bf923
commit c7e957ee36
1 changed files with 96 additions and 52 deletions

View File

@ -16,67 +16,102 @@ const cells = {
} }
// activeQueryIndex is an optional argument that indicated which query's series we want highlighted. // activeQueryIndex is an optional argument that indicated which query's series we want highlighted.
export default function timeSeriesToDygraph(raw = [], activeQueryIndex, isInDataExplorer) { export default function timeSeriesToDygraph(
raw = [],
activeQueryIndex,
isInDataExplorer
) {
// collect results from each influx response // collect results from each influx response
const results = reduce(raw, (acc, rawResponse, responseIndex) => { const results = reduce(
const responses = _.get(rawResponse, 'response.results', []) raw,
const indexedResponses = map(responses, (response) => ({...response, responseIndex})) (acc, rawResponse, responseIndex) => {
return [...acc, ...indexedResponses] const responses = _.get(rawResponse, 'response.results', [])
}, []) const indexedResponses = map(responses, response => ({
...response,
responseIndex,
}))
return [...acc, ...indexedResponses]
},
[]
)
// collect each series // collect each series
const serieses = reduce(results, (acc, {series = [], responseIndex}, index) => { const serieses = reduce(
return [...acc, ...map(series, (item) => ({...item, responseIndex, index}))] results,
}, []) (acc, {series = [], responseIndex}, index) => {
return [...acc, ...map(series, item => ({...item, responseIndex, index}))]
},
[]
)
const size = reduce(serieses, (acc, {columns, values}) => { const size = reduce(
if (columns.length && values.length) { serieses,
return acc + (columns.length - 1) * values.length (acc, {columns, values}) => {
} if (columns.length && (values && values.length)) {
return acc return acc + (columns.length - 1) * values.length
}, 0) }
return acc
},
0
)
// convert series into cells with rows and columns // convert series into cells with rows and columns
let cellIndex = 0 let cellIndex = 0
let labels = [] let labels = []
forEach(serieses, ({name: measurement, columns, values, index: seriesIndex, responseIndex, tags = {}}) => { forEach(
const rows = map(values, (vals) => ({ serieses,
vals, ({
})) name: measurement,
columns,
// tagSet is each tag key and value for a series values,
const tagSet = map(Object.keys(tags), (tag) => `[${tag}=${tags[tag]}]`).sort().join('') index: seriesIndex,
const unsortedLabels = map(columns.slice(1), (field) => ({
label: `${measurement}.${field}${tagSet}`,
responseIndex, responseIndex,
seriesIndex, tags = {},
})) }) => {
labels = concat(labels, unsortedLabels) const rows = map(values || [], vals => ({
vals,
}))
forEach(rows, ({vals}) => { // tagSet is each tag key and value for a series
const [time, ...rowValues] = vals 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(rowValues, (value, i) => { forEach(rows, ({vals}) => {
cells.label[cellIndex] = unsortedLabels[i].label const [time, ...rowValues] = vals
cells.value[cellIndex] = value
cells.time[cellIndex] = time forEach(rowValues, (value, i) => {
cells.seriesIndex[cellIndex] = seriesIndex cells.label[cellIndex] = unsortedLabels[i].label
cells.responseIndex[cellIndex] = responseIndex cells.value[cellIndex] = value
cellIndex++ // eslint-disable-line no-plusplus cells.time[cellIndex] = time
cells.seriesIndex[cellIndex] = seriesIndex
cells.responseIndex[cellIndex] = responseIndex
cellIndex++ // eslint-disable-line no-plusplus
})
}) })
}) }
}) )
const sortedLabels = _.sortBy(labels, 'label') const sortedLabels = _.sortBy(labels, 'label')
const tsMemo = {} const tsMemo = {}
const nullArray = Array(sortedLabels.length).fill(null) const nullArray = Array(sortedLabels.length).fill(null)
const labelsToValueIndex = reduce(sortedLabels, (acc, {label, seriesIndex}, i) => { const labelsToValueIndex = reduce(
// adding series index prevents overwriting of two distinct labels that have the same field and measurements sortedLabels,
acc[label + seriesIndex] = i (acc, {label, seriesIndex}, i) => {
return acc // adding series index prevents overwriting of two distinct labels that have the same field and measurements
}, {}) acc[label + seriesIndex] = i
return acc
},
{}
)
const timeSeries = [] const timeSeries = []
for (let i = 0; i < size; i++) { for (let i = 0; i < size; i++) {
@ -97,23 +132,32 @@ export default function timeSeriesToDygraph(raw = [], activeQueryIndex, isInData
tsMemo[time] = existingRowIndex tsMemo[time] = existingRowIndex
} }
timeSeries[existingRowIndex].values[labelsToValueIndex[label + seriesIndex]] = value timeSeries[existingRowIndex].values[
labelsToValueIndex[label + seriesIndex]
] = value
} }
const sortedTimeSeries = _.sortBy(timeSeries, 'time') const sortedTimeSeries = _.sortBy(timeSeries, 'time')
const dygraphSeries = reduce(sortedLabels, (acc, {label, responseIndex}) => { const dygraphSeries = reduce(
if (!isInDataExplorer) { sortedLabels,
acc[label] = { (acc, {label, responseIndex}) => {
axis: responseIndex === 0 ? 'y' : 'y2', if (!isInDataExplorer) {
acc[label] = {
axis: responseIndex === 0 ? 'y' : 'y2',
}
} }
}
return acc return acc
}, {}) },
{}
)
return { return {
labels: ['time', ...map(sortedLabels, ({label}) => label)], labels: ['time', ...map(sortedLabels, ({label}) => label)],
timeSeries: map(sortedTimeSeries, ({time, values}) => ([new Date(time), ...values])), timeSeries: map(sortedTimeSeries, ({time, values}) => [
new Date(time),
...values,
]),
dygraphSeries, dygraphSeries,
} }
} }