Convert TableGraph to TS
parent
eb73b090cd
commit
30164a1e9b
|
@ -119,6 +119,8 @@
|
|||
"webpack-dev-server": "^2.11.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/chroma-js": "^1.3.4",
|
||||
"@types/react-virtualized": "^9.18.3",
|
||||
"axios": "^0.13.1",
|
||||
"bignumber.js": "^4.0.2",
|
||||
"calculate-size": "^1.1.1",
|
||||
|
|
|
@ -4,8 +4,11 @@ import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
|||
import {Grid} from 'react-virtualized'
|
||||
|
||||
const SCROLLBAR_SIZE_BUFFER = 20
|
||||
type HeightWidthFunction = (arg: {index: number}) => {} | number
|
||||
|
||||
interface Props {
|
||||
width: number
|
||||
height: number
|
||||
columnCount?: number
|
||||
classNameBottomLeftGrid?: string
|
||||
classNameBottomRightGrid?: string
|
||||
|
@ -23,15 +26,12 @@ interface Props {
|
|||
scrollTop?: number
|
||||
scrollLeft?: number
|
||||
rowCount?: number
|
||||
rowHeight?: (arg: {index: number}) => {} | number
|
||||
columnWidth?: (arg: object) => {} | number
|
||||
rowHeight?: number | HeightWidthFunction
|
||||
columnWidth?: number | HeightWidthFunction
|
||||
onScroll?: (arg: object) => {}
|
||||
width: number
|
||||
height: number
|
||||
scrollToRow?: () => {}
|
||||
onSectionRendered?: () => {}
|
||||
scrollToColumn?: () => {}
|
||||
cellRenderer?: (arg: object) => JSX.Element
|
||||
[key: string]: any // MultiGrid can accept any prop, and will rerender if they change
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -99,10 +99,10 @@ class MultiGrid extends React.PureComponent<Props, State> {
|
|||
private deferredMeasurementCacheTopRightGrid: CellMeasurerCacheDecorator
|
||||
private leftGridWidth: number | null = 0
|
||||
private topGridHeight: number | null = 0
|
||||
private lastRenderedColumnWidth: (arg: object) => {} | number
|
||||
private lastRenderedColumnWidth: number | HeightWidthFunction
|
||||
private lastRenderedFixedColumnCount: number = 0
|
||||
private lastRenderedFixedRowCount: number = 0
|
||||
private lastRenderedRowHeight: (arg: {index: number}) => {} | number
|
||||
private lastRenderedRowHeight: number | HeightWidthFunction
|
||||
private bottomRightGridStyle: object | null
|
||||
private topRightGridStyle: object | null
|
||||
private lastRenderedStyle: object | null
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import React, {Component} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import React, {PureComponent} from 'react'
|
||||
import _ from 'lodash'
|
||||
import classnames from 'classnames'
|
||||
import {connect} from 'react-redux'
|
||||
|
@ -26,12 +25,68 @@ import {
|
|||
DEFAULT_VERTICAL_TIME_AXIS,
|
||||
DEFAULT_SORT_DIRECTION,
|
||||
} from 'src/shared/constants/tableGraph'
|
||||
import {generateThresholdsListHexs} from 'shared/constants/colorOperations'
|
||||
import {colorsStringSchema} from 'shared/schemas'
|
||||
import {generateThresholdsListHexs} from 'src/shared/constants/colorOperations'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
import {TimeSeriesServerResponse} from 'src/types/series'
|
||||
import {ColorString} from 'src/types/colors'
|
||||
type dbData = string | number | null
|
||||
|
||||
interface TableOptions {
|
||||
verticalTimeAxis: boolean
|
||||
sortBy: FieldOption
|
||||
wrapping?: string
|
||||
fixFirstColumn: boolean
|
||||
}
|
||||
|
||||
interface DecimalPlaces {
|
||||
isEnforced: boolean
|
||||
digits: number
|
||||
}
|
||||
|
||||
interface FieldOption {
|
||||
internalName: string
|
||||
displayName: string
|
||||
visible: boolean
|
||||
}
|
||||
|
||||
interface Sort {
|
||||
field: string
|
||||
direction: string
|
||||
}
|
||||
|
||||
interface Props {
|
||||
data: TimeSeriesServerResponse
|
||||
tableOptions: TableOptions
|
||||
timeFormat: string
|
||||
decimalPlaces: DecimalPlaces
|
||||
fieldOptions: FieldOption[]
|
||||
hoverTime: string
|
||||
handleUpdateFieldOptions: (fieldOptions: FieldOption[]) => void
|
||||
handleSetHoverTime: (hovertime: string) => void
|
||||
colors: ColorString
|
||||
isInCEO: boolean
|
||||
}
|
||||
|
||||
interface State {
|
||||
data: dbData[][]
|
||||
transformedData: dbData[][]
|
||||
sortedTimeVals: number[]
|
||||
sortedLabels: string[]
|
||||
hoveredColumnIndex: number
|
||||
hoveredRowIndex: number
|
||||
timeColumnWidth: number
|
||||
sort: Sort
|
||||
columnWidths: {}
|
||||
totalColumnWidths: number
|
||||
isTimeVisible: boolean
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
class TableGraph extends Component {
|
||||
class TableGraph extends PureComponent<Props, State> {
|
||||
private multiGridRef: React.RefObject<MultiGrid>
|
||||
private gridContainer: React.Ref<HTMLDivElement>
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
|
@ -40,6 +95,7 @@ class TableGraph extends Component {
|
|||
['tableOptions', 'sortBy', 'internalName'],
|
||||
DEFAULT_TIME_FIELD.internalName
|
||||
)
|
||||
this.multiGridRef = React.createRef<MultiGrid>()
|
||||
|
||||
this.state = {
|
||||
data: [[]],
|
||||
|
@ -51,11 +107,11 @@ class TableGraph extends Component {
|
|||
sort: {field: sortField, direction: DEFAULT_SORT_DIRECTION},
|
||||
columnWidths: {},
|
||||
totalColumnWidths: 0,
|
||||
timeColumnWidth: 0,
|
||||
isTimeVisible: true,
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
public componentDidMount() {
|
||||
const sortField = _.get(
|
||||
this.props,
|
||||
['tableOptions', 'sortBy', 'internalName'],
|
||||
|
@ -112,7 +168,7 @@ class TableGraph extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
handleUpdateFieldOptions = fieldOptions => {
|
||||
public handleUpdateFieldOptions = fieldOptions => {
|
||||
const {isInCEO} = this.props
|
||||
if (!isInCEO) {
|
||||
return
|
||||
|
@ -120,7 +176,7 @@ class TableGraph extends Component {
|
|||
this.props.handleUpdateFieldOptions(fieldOptions)
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
public componentWillReceiveProps(nextProps) {
|
||||
const updatedProps = _.keys(nextProps).filter(
|
||||
k => !_.isEqual(this.props[k], nextProps[k])
|
||||
)
|
||||
|
@ -201,7 +257,7 @@ class TableGraph extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
calcScrollToColRow = () => {
|
||||
public calcScrollToColRow = () => {
|
||||
const {data, sortedTimeVals, hoveredColumnIndex, isTimeVisible} = this.state
|
||||
const {hoverTime, tableOptions} = this.props
|
||||
const hoveringThisTable = hoveredColumnIndex !== NULL_ARRAY_INDEX
|
||||
|
@ -215,11 +271,11 @@ class TableGraph extends Component {
|
|||
return {scrollToColumn: undefined, scrollToRow: undefined}
|
||||
}
|
||||
|
||||
const firstDiff = Math.abs(hoverTime - sortedTimeVals[1]) // sortedTimeVals[0] is "time"
|
||||
const firstDiff = Math.abs(Number(hoverTime) - sortedTimeVals[1]) // sortedTimeVals[0] is "time"
|
||||
const hoverTimeFound = reduce(
|
||||
sortedTimeVals,
|
||||
(acc, currentTime, index) => {
|
||||
const thisDiff = Math.abs(hoverTime - currentTime)
|
||||
const thisDiff = Math.abs(Number(hoverTime) - currentTime)
|
||||
if (thisDiff < acc.diff) {
|
||||
return {index, diff: thisDiff}
|
||||
}
|
||||
|
@ -234,7 +290,7 @@ class TableGraph extends Component {
|
|||
return {scrollToRow, scrollToColumn}
|
||||
}
|
||||
|
||||
handleHover = (columnIndex, rowIndex) => () => {
|
||||
public handleHover = (columnIndex, rowIndex) => () => {
|
||||
const {
|
||||
handleSetHoverTime,
|
||||
tableOptions: {verticalTimeAxis},
|
||||
|
@ -255,7 +311,7 @@ class TableGraph extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
handleMouseLeave = () => {
|
||||
public handleMouseLeave = () => {
|
||||
if (this.props.handleSetHoverTime) {
|
||||
this.props.handleSetHoverTime(NULL_HOVER_TIME)
|
||||
this.setState({
|
||||
|
@ -265,7 +321,7 @@ class TableGraph extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
handleClickFieldName = clickedFieldName => () => {
|
||||
public handleClickFieldName = clickedFieldName => () => {
|
||||
const {tableOptions, fieldOptions, timeFormat, decimalPlaces} = this.props
|
||||
const {data, sort} = this.state
|
||||
|
||||
|
@ -292,7 +348,7 @@ class TableGraph extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
calculateColumnWidth = columnSizerWidth => column => {
|
||||
public calculateColumnWidth = columnSizerWidth => column => {
|
||||
const {index} = column
|
||||
const {
|
||||
tableOptions: {fixFirstColumn},
|
||||
|
@ -321,7 +377,7 @@ class TableGraph extends Component {
|
|||
return adjustedColumnSizerWidth
|
||||
}
|
||||
|
||||
createCellContents = (
|
||||
public createCellContents = (
|
||||
cellData,
|
||||
fieldName,
|
||||
isTimeData,
|
||||
|
@ -341,7 +397,7 @@ class TableGraph extends Component {
|
|||
return `${cellData}`
|
||||
}
|
||||
|
||||
cellRenderer = ({columnIndex, rowIndex, key, parent, style}) => {
|
||||
public cellRenderer = ({columnIndex, rowIndex, key, parent, style}) => {
|
||||
const {
|
||||
hoveredColumnIndex,
|
||||
hoveredRowIndex,
|
||||
|
@ -448,12 +504,7 @@ class TableGraph extends Component {
|
|||
)
|
||||
}
|
||||
|
||||
getMultiGridRef = (r, registerChild) => {
|
||||
this.multiGridRef = r
|
||||
return registerChild(r)
|
||||
}
|
||||
|
||||
render() {
|
||||
public render() {
|
||||
const {
|
||||
hoveredColumnIndex,
|
||||
hoveredRowIndex,
|
||||
|
@ -484,7 +535,7 @@ class TableGraph extends Component {
|
|||
return (
|
||||
<div
|
||||
className="table-graph-container"
|
||||
ref={gridContainer => (this.gridContainer = gridContainer)}
|
||||
ref={this.gridContainer}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
>
|
||||
{rowCount > 0 && (
|
||||
|
@ -494,73 +545,44 @@ class TableGraph extends Component {
|
|||
columnMinWidth={COLUMN_MIN_WIDTH}
|
||||
width={tableWidth}
|
||||
>
|
||||
{({columnWidth, registerChild}) => (
|
||||
<MultiGrid
|
||||
ref={r => this.getMultiGridRef(r, registerChild)}
|
||||
columnCount={columnCount}
|
||||
columnWidth={this.calculateColumnWidth(columnWidth)}
|
||||
rowCount={rowCount}
|
||||
rowHeight={ROW_HEIGHT}
|
||||
height={tableHeight}
|
||||
width={tableWidth}
|
||||
fixedColumnCount={fixedColumnCount}
|
||||
fixedRowCount={1}
|
||||
enableFixedColumnScroll={true}
|
||||
enableFixedRowScroll={true}
|
||||
scrollToRow={scrollToRow}
|
||||
scrollToColumn={scrollToColumn}
|
||||
sort={sort}
|
||||
cellRenderer={this.cellRenderer}
|
||||
hoveredColumnIndex={hoveredColumnIndex}
|
||||
hoveredRowIndex={hoveredRowIndex}
|
||||
hoverTime={hoverTime}
|
||||
colors={colors}
|
||||
fieldOptions={fieldOptions}
|
||||
tableOptions={tableOptions}
|
||||
timeFormat={timeFormat}
|
||||
decimalPlaces={decimalPlaces}
|
||||
timeColumnWidth={timeColumnWidth}
|
||||
classNameBottomRightGrid="table-graph--scroll-window"
|
||||
/>
|
||||
)}
|
||||
{({columnWidth, registerChild}) => {
|
||||
registerChild(this.multiGridRef)
|
||||
return (
|
||||
<MultiGrid
|
||||
ref={this.multiGridRef}
|
||||
columnCount={columnCount}
|
||||
columnWidth={this.calculateColumnWidth(columnWidth)}
|
||||
rowCount={rowCount}
|
||||
rowHeight={ROW_HEIGHT}
|
||||
height={tableHeight}
|
||||
width={tableWidth}
|
||||
fixedColumnCount={fixedColumnCount}
|
||||
fixedRowCount={1}
|
||||
enableFixedColumnScroll={true}
|
||||
enableFixedRowScroll={true}
|
||||
scrollToRow={scrollToRow}
|
||||
scrollToColumn={scrollToColumn}
|
||||
cellRenderer={this.cellRenderer}
|
||||
sort={sort}
|
||||
hoveredColumnIndex={hoveredColumnIndex}
|
||||
hoveredRowIndex={hoveredRowIndex}
|
||||
hoverTime={hoverTime}
|
||||
colors={colors}
|
||||
fieldOptions={fieldOptions}
|
||||
tableOptions={tableOptions}
|
||||
timeFormat={timeFormat}
|
||||
decimalPlaces={decimalPlaces}
|
||||
timeColumnWidth={timeColumnWidth}
|
||||
classNameBottomRightGrid="table-graph--scroll-window"
|
||||
/>
|
||||
)
|
||||
}}
|
||||
</ColumnSizer>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
const {arrayOf, bool, number, shape, string, func} = PropTypes
|
||||
|
||||
TableGraph.propTypes = {
|
||||
data: arrayOf(shape()),
|
||||
tableOptions: shape({
|
||||
verticalTimeAxis: bool.isRequired,
|
||||
sortBy: shape({
|
||||
internalName: string.isRequired,
|
||||
displayName: string.isRequired,
|
||||
visible: bool.isRequired,
|
||||
}).isRequired,
|
||||
wrapping: string.isRequired,
|
||||
fixFirstColumn: bool.isRequired,
|
||||
}),
|
||||
timeFormat: string.isRequired,
|
||||
decimalPlaces: shape({
|
||||
isEnforced: bool.isRequired,
|
||||
digits: number.isRequired,
|
||||
}).isRequired,
|
||||
fieldOptions: arrayOf(
|
||||
shape({
|
||||
internalName: string.isRequired,
|
||||
displayName: string.isRequired,
|
||||
visible: bool.isRequired,
|
||||
})
|
||||
).isRequired,
|
||||
hoverTime: string,
|
||||
handleUpdateFieldOptions: func,
|
||||
handleSetHoverTime: func,
|
||||
colors: colorsStringSchema,
|
||||
isInCEO: bool,
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
handleUpdateFieldOptions: bindActionCreators(updateFieldOptions, dispatch),
|
|
@ -5,7 +5,7 @@ import {
|
|||
THRESHOLD_COLORS,
|
||||
THRESHOLD_TYPE_BASE,
|
||||
THRESHOLD_TYPE_TEXT,
|
||||
} from 'shared/constants/thresholds'
|
||||
} from 'src/shared/constants/thresholds'
|
||||
|
||||
import {
|
||||
CELL_TYPE_LINE,
|
||||
|
@ -48,6 +48,8 @@ export const generateThresholdsListHexs = ({
|
|||
cellType === CELL_TYPE_TABLE ? '#BEC2CC' : THRESHOLD_COLORS[11].hex,
|
||||
}
|
||||
const lastValueNumber = Number(lastValue) || 0
|
||||
let bgColor
|
||||
let textColor
|
||||
|
||||
if (!colors.length) {
|
||||
return defaultColoring
|
||||
|
@ -85,16 +87,14 @@ export const generateThresholdsListHexs = ({
|
|||
colors,
|
||||
lastValueNumber
|
||||
)
|
||||
const bgColor = null
|
||||
const textColor = nearestCrossedThreshold.hex
|
||||
|
||||
return {bgColor, textColor}
|
||||
return {bgColor: null, textColor: nearestCrossedThreshold.hex}
|
||||
}
|
||||
|
||||
// When there is only a base color and it's applued to the background
|
||||
if (colors.length === 1) {
|
||||
const bgColor = baseColor.hex
|
||||
const textColor = getLegibleTextColor(bgColor)
|
||||
bgColor = baseColor.hex
|
||||
textColor = getLegibleTextColor(bgColor)
|
||||
|
||||
return {bgColor, textColor}
|
||||
}
|
||||
|
@ -106,16 +106,16 @@ export const generateThresholdsListHexs = ({
|
|||
lastValueNumber
|
||||
)
|
||||
|
||||
const bgColor = nearestCrossedThreshold
|
||||
bgColor = nearestCrossedThreshold
|
||||
? nearestCrossedThreshold.hex
|
||||
: baseColor.hex
|
||||
const textColor = getLegibleTextColor(bgColor)
|
||||
textColor = getLegibleTextColor(bgColor)
|
||||
|
||||
return {bgColor, textColor}
|
||||
}
|
||||
|
||||
// If all else fails, use safe default
|
||||
const bgColor = null
|
||||
const textColor = baseColor.hex
|
||||
bgColor = null
|
||||
textColor = baseColor.hex
|
||||
return {bgColor, textColor}
|
||||
}
|
|
@ -1,7 +1,12 @@
|
|||
import {map, reduce} from 'fast.js'
|
||||
import {groupByTimeSeriesTransform} from 'src/utils/groupByTimeSeriesTransform'
|
||||
|
||||
export const timeSeriesToDygraph = (raw = [], isInDataExplorer) => {
|
||||
import {TimeSeriesServerResponse} from 'src/types/series'
|
||||
|
||||
export const timeSeriesToDygraph = (
|
||||
raw: TimeSeriesServerResponse,
|
||||
isInDataExplorer: boolean
|
||||
) => {
|
||||
const isTable = false
|
||||
const {sortedLabels, sortedTimeSeries} = groupByTimeSeriesTransform(
|
||||
raw,
|
||||
|
@ -31,7 +36,7 @@ export const timeSeriesToDygraph = (raw = [], isInDataExplorer) => {
|
|||
}
|
||||
}
|
||||
|
||||
export const timeSeriesToTableGraph = raw => {
|
||||
export const timeSeriesToTableGraph = (raw: TimeSeriesServerResponse) => {
|
||||
const isTable = true
|
||||
const {sortedLabels, sortedTimeSeries} = groupByTimeSeriesTransform(
|
||||
raw,
|
13
ui/yarn.lock
13
ui/yarn.lock
|
@ -24,6 +24,10 @@
|
|||
version "0.22.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.7.tgz#4a92eafedfb2b9f4437d3a4410006d81114c66ce"
|
||||
|
||||
"@types/chroma-js@^1.3.4":
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/chroma-js/-/chroma-js-1.3.4.tgz#ef6d73041992544f492c5baad96468791ec45af5"
|
||||
|
||||
"@types/codemirror@^0.0.56":
|
||||
version "0.0.56"
|
||||
resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-0.0.56.tgz#1fcf68df0d0a49791d843dadda7d94891ac88669"
|
||||
|
@ -61,7 +65,7 @@
|
|||
version "9.6.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.6.tgz#439b91f9caf3983cad2eef1e11f6bedcbf9431d2"
|
||||
|
||||
"@types/prop-types@^15.5.2":
|
||||
"@types/prop-types@*", "@types/prop-types@^15.5.2":
|
||||
version "15.5.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.5.2.tgz#3c6b8dceb2906cc87fe4358e809f9d20c8d59be1"
|
||||
|
||||
|
@ -84,6 +88,13 @@
|
|||
"@types/history" "^3"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-virtualized@^9.18.3":
|
||||
version "9.18.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.18.3.tgz#777b3c28bd2b972d0a402f2f9d11bacef550be1c"
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^16.0.38":
|
||||
version "16.3.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.3.12.tgz#68d9146f3e9797e38ffbf22f7ed1dde91a2cfd2e"
|
||||
|
|
Loading…
Reference in New Issue