diff --git a/ui/src/dashboards/components/GraphOptionsTimeAxis.js b/ui/src/dashboards/components/GraphOptionsTimeAxis.js
index ac6090b00d..e92e3ac295 100644
--- a/ui/src/dashboards/components/GraphOptionsTimeAxis.js
+++ b/ui/src/dashboards/components/GraphOptionsTimeAxis.js
@@ -1,29 +1,30 @@
import React from 'react'
import PropTypes from 'prop-types'
-const VERTICAL = 'VERTICAL'
-const HORIZONTAL = 'HORIZONTAL'
-const GraphOptionsTimeAxis = ({TimeAxis, onToggleTimeAxis}) =>
+const GraphOptionsTimeAxis = ({verticalTimeAxis, onToggleVerticalTimeAxis}) =>
-const {func, string} = PropTypes
+const {bool, func} = PropTypes
-GraphOptionsTimeAxis.propTypes = {TimeAxis: string, onToggleTimeAxis: func}
+GraphOptionsTimeAxis.propTypes = {
+ verticalTimeAxis: bool,
+ onToggleVerticalTimeAxis: func,
+}
export default GraphOptionsTimeAxis
diff --git a/ui/src/dashboards/components/TableOptions.tsx b/ui/src/dashboards/components/TableOptions.tsx
index c8694e4c3e..1a2da1067e 100644
--- a/ui/src/dashboards/components/TableOptions.tsx
+++ b/ui/src/dashboards/components/TableOptions.tsx
@@ -10,6 +10,7 @@ import GraphOptionsTimeAxis from 'src/dashboards/components/GraphOptionsTimeAxis
import GraphOptionsSortBy from 'src/dashboards/components/GraphOptionsSortBy'
import GraphOptionsTextWrapping from 'src/dashboards/components/GraphOptionsTextWrapping'
import GraphOptionsCustomizeColumns from 'src/dashboards/components/GraphOptionsCustomizeColumns'
+
import ThresholdsList from 'src/shared/components/ThresholdsList'
import ThresholdsListTypeToggle from 'src/shared/components/ThresholdsListTypeToggle'
@@ -51,12 +52,14 @@ export class TableOptions extends PureComponent {
get columnNames() {
const {tableOptions: {columnNames}} = this.props
-
return columnNames || []
}
get timeColumn() {
- return (this.columnNames.find(c => c.internalName === 'time')) || TIME_COLUMN_DEFAULT
+ return (
+ this.columnNames.find(c => c.internalName === 'time') ||
+ TIME_COLUMN_DEFAULT
+ )
}
get computedColumnNames() {
@@ -71,24 +74,20 @@ export class TableOptions extends PureComponent {
)
return existing || {internalName, displayName: ''}
})
- }))
+ })
+ )
return [this.timeColumn, ...queryFields]
}
componentWillMount() {
const {handleUpdateTableOptions, tableOptions} = this.props
- handleUpdateTableOptions({...tableOptions, columnNames: this.computedColumnNames})
+ handleUpdateTableOptions({
+ ...tableOptions,
+ columnNames: this.computedColumnNames
+ })
}
- handleToggleSingleStatType = () => {}
-
- handleAddThreshold = () => {}
-
- handleDeleteThreshold = () => () => {}
-
- handleChooseColor = () => () => {}
-
handleChooseSortBy = option => {
const {tableOptions, handleUpdateTableOptions} = this.props
const sortBy = {displayName: option.text, internalName: option.key}
@@ -101,7 +100,10 @@ export class TableOptions extends PureComponent {
handleUpdateTableOptions({...tableOptions, timeFormat})
}
- handleToggleTimeAxis = () => {}
+ onToggleVerticalTimeAxis = verticalTimeAxis => () => {
+ const {tableOptions, handleUpdateTableOptions} = this.props
+ handleUpdateTableOptions({...tableOptions, verticalTimeAxis})
+ }
handleToggleTextWrapping = () => {}
@@ -116,16 +118,14 @@ export class TableOptions extends PureComponent {
render() {
const {
- tableOptions: {timeFormat, columnNames: columns},
+ tableOptions: {timeFormat, columnNames: columns, verticalTimeAxis},
onResetFocus,
- tableOptions,
+ tableOptions
} = this.props
- const TimeAxis = 'vertical'
-
const tableSortByOptions = this.computedColumnNames.map(col => ({
text: col.displayName || col.internalName,
- key: col.internalName,
+ key: col.internalName
}))
return (
@@ -141,8 +141,8 @@ export class TableOptions extends PureComponent {
onTimeFormatChange={this.handleTimeFormatChange}
/>
{
}
const mapStateToProps = ({cellEditorOverlay: {cell: {tableOptions}}}) => ({
- tableOptions,
+ tableOptions
})
const mapDispatchToProps = dispatch => ({
- handleUpdateTableOptions: bindActionCreators(updateTableOptions, dispatch),
+ handleUpdateTableOptions: bindActionCreators(updateTableOptions, dispatch)
})
export default connect(mapStateToProps, mapDispatchToProps)(TableOptions)
diff --git a/ui/src/dashboards/constants/index.js b/ui/src/dashboards/constants/index.js
index 15ee95eed4..20404f3497 100644
--- a/ui/src/dashboards/constants/index.js
+++ b/ui/src/dashboards/constants/index.js
@@ -1,3 +1,5 @@
+import {DEFAULT_TABLE_OPTIONS} from 'src/shared/constants/tableGraph'
+
export const EMPTY_DASHBOARD = {
id: 0,
name: '',
@@ -20,6 +22,7 @@ export const NEW_DEFAULT_DASHBOARD_CELL = {
name: 'Untitled Cell',
type: 'line',
queries: [],
+ tableOptions: DEFAULT_TABLE_OPTIONS,
}
export const NEW_DASHBOARD = {
diff --git a/ui/src/dashboards/reducers/cellEditorOverlay.js b/ui/src/dashboards/reducers/cellEditorOverlay.js
index 8c4159759d..4629e89750 100644
--- a/ui/src/dashboards/reducers/cellEditorOverlay.js
+++ b/ui/src/dashboards/reducers/cellEditorOverlay.js
@@ -1,3 +1,5 @@
+import _ from 'lodash'
+
import {
THRESHOLD_TYPE_TEXT,
DEFAULT_THRESHOLDS_LIST_COLORS,
@@ -28,7 +30,11 @@ export default function cellEditorOverlay(state = initialState, action) {
)
const gaugeColors = validateGaugeColors(colors)
- const tableOptions = cell.tableOptions || initializeOptions('table')
+ const tableOptions = _.get(
+ cell,
+ 'tableOptions',
+ initializeOptions('table')
+ )
return {
...state,
diff --git a/ui/src/shared/components/TableGraph.js b/ui/src/shared/components/TableGraph.js
index f8856c97fe..130e9b0af1 100644
--- a/ui/src/shared/components/TableGraph.js
+++ b/ui/src/shared/components/TableGraph.js
@@ -22,6 +22,7 @@ class TableGraph extends Component {
super(props)
this.state = {
data: [[]],
+ unzippedData: [[]],
hoveredColumnIndex: NULL_COLUMN_INDEX,
hoveredRowIndex: NULL_ROW_INDEX,
sortByColumnIndex: -1,
@@ -29,31 +30,44 @@ class TableGraph extends Component {
}
componentWillReceiveProps(nextProps) {
- const {data} = timeSeriesToTableGraph(nextProps.data)
+ const {data, unzippedData} = timeSeriesToTableGraph(nextProps.data)
const {tableOptions: {sortBy: {internalName}}} = nextProps
const sortByColumnIndex = _.indexOf(data[0], internalName)
const sortedData = _.sortBy(_.drop(data, 1), sortByColumnIndex)
- this.setState({data: [data[0], ...sortedData], sortByColumnIndex})
+ this.setState({
+ data: [data[0], ...sortedData],
+ unzippedData,
+ sortByColumnIndex,
+ })
}
- calcHoverTimeRow = (data, hoverTime) =>
- !isEmpty(data) && hoverTime !== NULL_HOVER_TIME
- ? data.findIndex(
- row => row[0] && _.isNumber(row[0]) && row[0] >= hoverTime
- )
- : undefined
+ calcHoverTimeIndex = (data, hoverTime, verticalTimeAxis) => {
+ if (isEmpty(data) || hoverTime === NULL_HOVER_TIME) {
+ return undefined
+ }
+ if (verticalTimeAxis) {
+ return data.findIndex(
+ row => row[0] && _.isNumber(row[0]) && row[0] >= hoverTime
+ )
+ }
+ return data[0].findIndex(d => _.isNumber(d) && d >= hoverTime)
+ }
handleHover = (columnIndex, rowIndex) => () => {
- if (this.props.onSetHoverTime) {
- const {data} = this.state
- this.props.onSetHoverTime(data[rowIndex][0].toString())
- this.setState({
- hoveredColumnIndex: columnIndex,
- hoveredRowIndex: rowIndex,
- })
+ const {onSetHoverTime, tableOptions} = this.props
+ const {data} = this.state
+ if (onSetHoverTime) {
+ const hoverTime = tableOptions.verticalTimeAxis
+ ? data[rowIndex][0]
+ : data[0][columnIndex]
+ onSetHoverTime(hoverTime.toString())
}
+ this.setState({
+ hoveredColumnIndex: columnIndex,
+ hoveredRowIndex: rowIndex,
+ })
}
handleMouseOut = () => {
@@ -66,10 +80,12 @@ class TableGraph extends Component {
}
}
- cellRenderer = ({columnIndex, rowIndex, key, style, parent}) => {
- const {hoveredColumnIndex, hoveredRowIndex, data} = this.state
+ cellRenderer = ({columnIndex, rowIndex, key, parent, style}) => {
+ const data = _.get(this.props, ['tableOptions', 'verticalTimeAxis'], true)
+ ? this.state.data
+ : this.state.unzippedData
+ const {hoveredColumnIndex, hoveredRowIndex} = this.state
const {colors} = this.props
-
const columnCount = _.get(data, ['0', 'length'], 0)
const rowCount = data.length
const {tableOptions} = this.props
@@ -80,12 +96,15 @@ class TableGraph extends Component {
const isFixedRow = rowIndex === 0 && columnIndex > 0
const isFixedColumn = rowIndex > 0 && columnIndex === 0
- const isTimeData = isFixedColumn
+ const isTimeData = tableOptions.verticalTimeAxis
+ ? isFixedColumn
+ : isFixedRow
const isFixedCorner = rowIndex === 0 && columnIndex === 0
const isLastRow = rowIndex === rowCount - 1
const isLastColumn = columnIndex === columnCount - 1
const isHighlighted =
rowIndex === parent.props.scrollToRow ||
+ columnIndex === parent.props.scrollToColumn ||
(rowIndex === hoveredRowIndex && hoveredRowIndex !== 0) ||
(columnIndex === hoveredColumnIndex && hoveredColumnIndex !== 0)
const dataIsNumerical = _.isNumber(data[rowIndex][columnIndex])
@@ -139,16 +158,20 @@ class TableGraph extends Component {
render() {
const {sortByColumnIndex, hoveredColumnIndex, hoveredRowIndex} = this.state
const {hoverTime, tableOptions, colors} = this.props
- const {data} = this.state
+
+ const verticalTimeAxis = _.get(tableOptions, 'verticalTimeAxis', true)
+
+ const data = verticalTimeAxis ? this.state.data : this.state.unzippedData
+
const columnCount = _.get(data, ['0', 'length'], 0)
const rowCount = data.length
const COLUMN_WIDTH = 300
const ROW_HEIGHT = 30
const tableWidth = this.gridContainer ? this.gridContainer.clientWidth : 0
const tableHeight = this.gridContainer ? this.gridContainer.clientHeight : 0
- const hoverTimeRow =
+ const hoverTimeIndex =
hoveredRowIndex === NULL_ROW_INDEX
- ? this.calcHoverTimeRow(data, hoverTime)
+ ? this.calcHoverTimeIndex(data, hoverTime, verticalTimeAxis)
: hoveredRowIndex
return (
@@ -175,8 +198,10 @@ class TableGraph extends Component {
columnNames={
tableOptions ? tableOptions.columnNames : [TIME_COLUMN_DEFAULT]
}
+ scrollToRow={verticalTimeAxis ? hoverTimeIndex : undefined}
+ scrollToColumn={verticalTimeAxis ? undefined : hoverTimeIndex}
+ verticalTimeAxis={verticalTimeAxis}
sortByColumnIndex={sortByColumnIndex}
- scrollToRow={hoverTimeRow}
cellRenderer={this.cellRenderer}
hoveredColumnIndex={hoveredColumnIndex}
hoveredRowIndex={hoveredRowIndex}
diff --git a/ui/src/shared/constants/tableGraph.js b/ui/src/shared/constants/tableGraph.js
index ffa2694f82..e0949b6e0d 100644
--- a/ui/src/shared/constants/tableGraph.js
+++ b/ui/src/shared/constants/tableGraph.js
@@ -21,8 +21,8 @@ export const FORMAT_OPTIONS = [
]
export const DEFAULT_TABLE_OPTIONS = {
- timeFormat: 'MM/DD/YYYY HH:mm:ss.ss',
verticalTimeAxis: true,
+ timeFormat: TIME_FORMAT_DEFAULT,
sortBy: TIME_COLUMN_DEFAULT,
wrapping: 'truncate',
columnNames: [TIME_COLUMN_DEFAULT],
diff --git a/ui/src/shared/constants/thresholds.js b/ui/src/shared/constants/thresholds.js
index 0d366ebcb5..9941bef092 100644
--- a/ui/src/shared/constants/thresholds.js
+++ b/ui/src/shared/constants/thresholds.js
@@ -187,3 +187,7 @@ export const validateGaugeColors = colors => {
return formattedColors
}
+
+export const stringifyColorValues = colors => {
+ return colors.map(color => ({...color, value: `${color.value}`}))
+}
diff --git a/ui/src/utils/timeSeriesToDygraph.js b/ui/src/utils/timeSeriesToDygraph.js
index a3a8b0f80a..b5d18c3cc9 100644
--- a/ui/src/utils/timeSeriesToDygraph.js
+++ b/ui/src/utils/timeSeriesToDygraph.js
@@ -177,9 +177,11 @@ export const timeSeriesToTableGraph = raw => {
const labels = ['time', ...map(sortedLabels, ({label}) => label)]
const tableData = map(sortedTimeSeries, ({time, values}) => [time, ...values])
-
+ const data = tableData.length ? [labels, ...tableData] : [[]]
+ const unzippedData = _.unzip(data)
return {
- data: tableData.length ? [labels, ...tableData] : [[]],
+ data,
+ unzippedData,
}
}