From ca9e4b797b08ddcae9cdc6bc76fad284d0659fb5 Mon Sep 17 00:00:00 2001 From: ebb-tide Date: Fri, 4 May 2018 14:35:08 -0700 Subject: [PATCH] Flatten groupbys when parsing data for csv download in dashboard --- ui/src/shared/components/AutoRefresh.tsx | 4 ++- ui/src/shared/components/Layout.js | 6 ++-- ui/src/shared/components/LayoutCell.js | 8 ++--- ui/src/shared/parsing/resultsToCSV.js | 37 ++++++++++++------------ 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/ui/src/shared/components/AutoRefresh.tsx b/ui/src/shared/components/AutoRefresh.tsx index cfbb2f5a5..53ee8381a 100644 --- a/ui/src/shared/components/AutoRefresh.tsx +++ b/ui/src/shared/components/AutoRefresh.tsx @@ -4,6 +4,7 @@ import _ from 'lodash' import {fetchTimeSeries} from 'src/shared/apis/query' import {DEFAULT_TIME_SERIES} from 'src/shared/constants/series' import {TimeSeriesServerResponse, TimeSeriesResponse} from 'src/types/series' +import {timeSeriesToTableGraph} from 'src/utils/timeSeriesTransformers' interface Axes { bounds: { @@ -129,8 +130,9 @@ const AutoRefresh = ( isFetching: false, }) + const {data} = timeSeriesToTableGraph(newSeries) if (grabDataForDownload) { - grabDataForDownload(newSeries) + grabDataForDownload(data) } } catch (err) { console.error(err) diff --git a/ui/src/shared/components/Layout.js b/ui/src/shared/components/Layout.js index b38adbdef..aa441602b 100644 --- a/ui/src/shared/components/Layout.js +++ b/ui/src/shared/components/Layout.js @@ -23,7 +23,7 @@ const getSource = (cell, source, sources, defaultSource) => { @ErrorHandling class LayoutState extends Component { state = { - celldata: [], + celldata: [[]], } grabDataForDownload = celldata => { @@ -122,7 +122,7 @@ const Layout = ( ) -const {arrayOf, bool, func, number, shape, string} = PropTypes +const {array, arrayOf, bool, func, number, shape, string} = PropTypes Layout.contextTypes = { source: shape(), @@ -200,7 +200,7 @@ LayoutState.propTypes = {...propTypes} Layout.propTypes = { ...propTypes, grabDataForDownload: func, - celldata: arrayOf(shape()), + celldata: arrayOf(array), } export default LayoutState diff --git a/ui/src/shared/components/LayoutCell.js b/ui/src/shared/components/LayoutCell.js index 7bbb05cba..6f66844b6 100644 --- a/ui/src/shared/components/LayoutCell.js +++ b/ui/src/shared/components/LayoutCell.js @@ -8,9 +8,9 @@ import LayoutCellMenu from 'shared/components/LayoutCellMenu' import LayoutCellHeader from 'shared/components/LayoutCellHeader' import {notify} from 'src/shared/actions/notifications' import {notifyCSVDownloadFailed} from 'src/shared/copy/notifications' -import {dashboardtoCSV} from 'shared/parsing/resultsToCSV' import download from 'src/external/download.js' import {ErrorHandling} from 'src/shared/decorators/errors' +import {dataToCSV} from 'src/shared/parsing/resultsToCSV' @ErrorHandling class LayoutCell extends Component { @@ -26,7 +26,7 @@ class LayoutCell extends Component { const joinedName = cell.name.split(' ').join('_') const {celldata} = this.props try { - download(dashboardtoCSV(celldata), `${joinedName}.csv`, 'text/plain') + download(dataToCSV(celldata), `${joinedName}.csv`, 'text/plain') } catch (error) { notify(notifyCSVDownloadFailed()) console.error(error) @@ -79,7 +79,7 @@ class LayoutCell extends Component { } } -const {arrayOf, bool, func, node, number, shape, string} = PropTypes +const {array, arrayOf, bool, func, node, number, shape, string} = PropTypes LayoutCell.propTypes = { cell: shape({ @@ -96,7 +96,7 @@ LayoutCell.propTypes = { onSummonOverlayTechnologies: func, isEditable: bool, onCancelEditCell: func, - celldata: arrayOf(shape()), + celldata: arrayOf(array), } export default LayoutCell diff --git a/ui/src/shared/parsing/resultsToCSV.js b/ui/src/shared/parsing/resultsToCSV.js index c3d3fdd02..c73698fd1 100644 --- a/ui/src/shared/parsing/resultsToCSV.js +++ b/ui/src/shared/parsing/resultsToCSV.js @@ -1,5 +1,6 @@ import _ from 'lodash' import moment from 'moment' +import {map} from 'fast.js' export const formatDate = timestamp => moment(timestamp).format('M/D/YYYY h:mm:ss.SSSSSSSSS A') @@ -30,24 +31,22 @@ export const resultsToCSV = results => { return {flag: 'ok', name, CSVString} } -export const dashboardtoCSV = data => { - const columnNames = _.flatten( - data.map(r => _.get(r, 'results[0].series[0].columns', [])) - ) - const timeIndices = columnNames - .map((e, i) => (e === 'time' ? i : -1)) - .filter(e => e >= 0) - - let values = data.map(r => _.get(r, 'results[0].series[0].values', [])) - values = _.unzip(values).map(v => _.flatten(v)) - if (timeIndices) { - values.map(v => { - timeIndices.forEach(i => (v[i] = formatDate(v[i]))) - return v - }) +export const dataToCSV = ([titleRow, ...valueRows]) => { + if (_.isEmpty(titleRow)) { + return '' } - const CSVString = [columnNames.join(',')] - .concat(values.map(v => v.join(','))) - .join('\n') - return CSVString + if (_.isEmpty(valueRows)) { + return ['date', titleRow.slice(1)].join(',') + } + if (titleRow[0] === 'time') { + const titlesString = ['date', titleRow.slice(1)].join(',') + + const valuesString = map(valueRows, ([timestamp, ...values]) => [ + [formatDate(timestamp), ...values].join(','), + ]).join('\n') + return `${titlesString}\n${valuesString}` + } + const allRows = [titleRow, ...valueRows] + const allRowsStringArray = map(allRows, r => r.join(',')) + return allRowsStringArray.join('\n') }