Add ability to show a line graph and change to other line graph type in veo
parent
b109015749
commit
ede25ecdce
|
@ -78,7 +78,7 @@ class VEO extends PureComponent<Props, State> {
|
|||
onCancel={onHide}
|
||||
onSave={this.handleSave}
|
||||
/>
|
||||
<TimeMachine />
|
||||
<TimeMachine activeTab={activeTab} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ import React, {PureComponent} from 'react'
|
|||
|
||||
// Components
|
||||
import VEOHeaderName from 'src/dashboards/components/VEOHeaderName'
|
||||
import TimeMachineTabs from 'src/shared/components/TimeMachineTabs'
|
||||
import {
|
||||
Radio,
|
||||
ButtonShape,
|
||||
Button,
|
||||
ComponentColor,
|
||||
|
@ -43,26 +43,10 @@ class VEOHeader extends PureComponent<Props> {
|
|||
<VEOHeaderName name={name} onRename={onSetName} />
|
||||
</Page.Header.Left>
|
||||
<Page.Header.Center>
|
||||
<Radio shape={ButtonShape.StretchToFit}>
|
||||
<Radio.Button
|
||||
id="deceo-tab-queries"
|
||||
titleText="Queries"
|
||||
value={TimeMachineTab.Queries}
|
||||
active={activeTab === TimeMachineTab.Queries}
|
||||
onClick={onSetActiveTab}
|
||||
>
|
||||
Queries
|
||||
</Radio.Button>
|
||||
<Radio.Button
|
||||
id="deceo-tab-vis"
|
||||
titleText="Visualization"
|
||||
value={TimeMachineTab.Visualization}
|
||||
active={activeTab === TimeMachineTab.Visualization}
|
||||
onClick={onSetActiveTab}
|
||||
>
|
||||
Visualization
|
||||
</Radio.Button>
|
||||
</Radio>
|
||||
<TimeMachineTabs
|
||||
activeTab={activeTab}
|
||||
onSetActiveTab={onSetActiveTab}
|
||||
/>
|
||||
</Page.Header.Center>
|
||||
<Page.Header.Right>
|
||||
<Button
|
||||
|
|
|
@ -10,6 +10,7 @@ import {setActiveTimeMachineID} from 'src/shared/actions/v2/timeMachines'
|
|||
|
||||
// Utils
|
||||
import {DE_TIME_MACHINE_ID} from 'src/shared/constants/timeMachine'
|
||||
import {TimeMachineTab} from 'src/types/v2/timeMachine'
|
||||
|
||||
interface StateProps {}
|
||||
|
||||
|
@ -17,7 +18,9 @@ interface DispatchProps {
|
|||
onSetActiveTimeMachineID: typeof setActiveTimeMachineID
|
||||
}
|
||||
|
||||
interface PassedProps {}
|
||||
interface PassedProps {
|
||||
activeTab: TimeMachineTab
|
||||
}
|
||||
|
||||
interface State {}
|
||||
|
||||
|
@ -31,9 +34,13 @@ class DataExplorer extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const {activeTab} = this.props
|
||||
|
||||
return (
|
||||
<div className="data-explorer">
|
||||
<TimeMachine />
|
||||
<div className="time-machine-page">
|
||||
<TimeMachine activeTab={activeTab} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,24 +1,54 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
|
||||
// Components
|
||||
import DataExplorer from 'src/dataExplorer/components/DataExplorer'
|
||||
import TimeMachineTabs from 'src/shared/components/TimeMachineTabs'
|
||||
import {Page} from 'src/pageLayout'
|
||||
|
||||
class DataExplorerPage extends PureComponent {
|
||||
// Types
|
||||
import {TimeMachineTab} from 'src/types/v2/timeMachine'
|
||||
|
||||
interface State {
|
||||
activeTab: TimeMachineTab
|
||||
}
|
||||
|
||||
class DataExplorerPage extends PureComponent<null, State> {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
activeTab: TimeMachineTab.Queries,
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {activeTab} = this.state
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<Page.Header>
|
||||
<Page.Header.Left>
|
||||
<Page.Title title="Data Explorer" />
|
||||
</Page.Header.Left>
|
||||
<Page.Header.Center>
|
||||
<TimeMachineTabs
|
||||
activeTab={activeTab}
|
||||
onSetActiveTab={this.handleSetActiveTab}
|
||||
/>
|
||||
</Page.Header.Center>
|
||||
<Page.Header.Right />
|
||||
</Page.Header>
|
||||
<Page.Contents fullWidth={true} scrollable={false}>
|
||||
<DataExplorer />
|
||||
<DataExplorer activeTab={activeTab} />
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
private handleSetActiveTab = (activeTab: TimeMachineTab): void => {
|
||||
this.setState({activeTab})
|
||||
}
|
||||
}
|
||||
|
||||
export default DataExplorerPage
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import {TimeRange} from 'src/types/v2'
|
||||
import {TimeRange, ViewType} from 'src/types/v2'
|
||||
|
||||
export type Action =
|
||||
| SetActiveTimeMachineIDAction
|
||||
| SetNameAction
|
||||
| SetTimeRangeAction
|
||||
| SetTypeAction
|
||||
|
||||
interface SetActiveTimeMachineIDAction {
|
||||
type: 'SET_ACTIVE_TIME_MACHINE_ID'
|
||||
|
@ -36,3 +37,13 @@ export const setTimeRange = (timeRange: TimeRange): SetTimeRangeAction => ({
|
|||
type: 'SET_TIME_RANGE',
|
||||
payload: {timeRange},
|
||||
})
|
||||
|
||||
interface SetTypeAction {
|
||||
type: 'SET_VIEW_TYPE'
|
||||
payload: {type: ViewType}
|
||||
}
|
||||
|
||||
export const setType = (type: ViewType): SetTypeAction => ({
|
||||
type: 'SET_VIEW_TYPE',
|
||||
payload: {type},
|
||||
})
|
||||
|
|
|
@ -199,9 +199,7 @@ class RefreshingView extends PureComponent<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
const mstp = ({sources, routing}: AppState): StateProps => {
|
||||
const sourceID = routing.locationBeforeTransitions.query.sourceID
|
||||
const source = sources.find(s => s.id === sourceID)
|
||||
const mstp = ({source}: AppState): StateProps => {
|
||||
const link = source.links.query
|
||||
|
||||
return {
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
.time-machine-page {
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border-radius: 0 0 $radius $radius;
|
||||
}
|
||||
|
||||
.time-machine {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.time-machine-container {
|
||||
height: calc(100% - 120px);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.time-machine-top {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 100px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.time-machine-vis {
|
||||
padding: 0 20px 20px 20px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.graph-container {
|
||||
top: 0;
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.time-machine-cusomization {
|
||||
background-color: $g2-kevlar;
|
||||
height: 100%;
|
||||
|
||||
.simple-spinner {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
|
@ -1,17 +1,130 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
import React, {PureComponent, ComponentClass} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
// Components
|
||||
import TimeMachineControls from 'src/shared/components/TimeMachineControls'
|
||||
import ViewComponent from 'src/shared/components/cells/View'
|
||||
import ViewTypeSelector from 'src/shared/components/ViewTypeSelector'
|
||||
import Threesizer from 'src/shared/components/threesizer/Threesizer'
|
||||
|
||||
class TimeMachine extends PureComponent {
|
||||
// Actions
|
||||
import {setType} from 'src/shared/actions/v2/timeMachines'
|
||||
|
||||
// Constants
|
||||
import {HANDLE_HORIZONTAL} from 'src/shared/constants'
|
||||
|
||||
// Types
|
||||
import {AppState, View, TimeRange} from 'src/types/v2'
|
||||
import {TimeMachineTab} from 'src/types/v2/timeMachine'
|
||||
|
||||
interface StateProps {
|
||||
view: View
|
||||
timeRange: TimeRange
|
||||
}
|
||||
|
||||
interface PassedProps {
|
||||
activeTab: TimeMachineTab
|
||||
}
|
||||
interface DispatchProps {
|
||||
onUpdateType: typeof setType
|
||||
}
|
||||
|
||||
type Props = StateProps & PassedProps & DispatchProps
|
||||
class TimeMachine extends PureComponent<Props> {
|
||||
public render() {
|
||||
return (
|
||||
<div className="time-machine">
|
||||
<TimeMachineControls />
|
||||
|
||||
<div className="time-machine-container">
|
||||
<Threesizer
|
||||
orientation={HANDLE_HORIZONTAL}
|
||||
divisions={this.horizontalDivisions}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private get horizontalDivisions() {
|
||||
return [
|
||||
{
|
||||
name: '',
|
||||
handleDisplay: 'none',
|
||||
headerButtons: [],
|
||||
menuOptions: [],
|
||||
render: () => this.visualization,
|
||||
headerOrientation: HANDLE_HORIZONTAL,
|
||||
size: 0.33,
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
handlePixels: 8,
|
||||
headerButtons: [],
|
||||
menuOptions: [],
|
||||
render: () => this.customizationPanels,
|
||||
headerOrientation: HANDLE_HORIZONTAL,
|
||||
size: 0.67,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
private get visualization(): JSX.Element {
|
||||
const {view, timeRange} = this.props
|
||||
const noop = () => {}
|
||||
|
||||
return (
|
||||
<div className="time-machine-top">
|
||||
<div className="time-machine-vis">
|
||||
<div className="graph-container">
|
||||
<ViewComponent
|
||||
view={view}
|
||||
onZoom={noop}
|
||||
templates={[]}
|
||||
timeRange={timeRange}
|
||||
autoRefresh={0}
|
||||
manualRefresh={0}
|
||||
onEditCell={noop}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private get customizationPanels(): JSX.Element {
|
||||
const {view, onUpdateType, activeTab} = this.props
|
||||
|
||||
return (
|
||||
<div className="time-machine-customization">
|
||||
{activeTab === TimeMachineTab.Queries ? (
|
||||
<div />
|
||||
) : (
|
||||
<ViewTypeSelector
|
||||
type={view.properties.type}
|
||||
onUpdateType={onUpdateType}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default TimeMachine
|
||||
const mstp = (state: AppState) => {
|
||||
const {
|
||||
timeMachines: {activeTimeMachineID, timeMachines},
|
||||
} = state
|
||||
const timeMachine = timeMachines[activeTimeMachineID]
|
||||
|
||||
return {
|
||||
view: timeMachine.view,
|
||||
timeRange: timeMachine.timeRange,
|
||||
}
|
||||
}
|
||||
|
||||
const mdtp = {
|
||||
onUpdateType: setType,
|
||||
}
|
||||
|
||||
export default connect(mstp, mdtp)(TimeMachine) as ComponentClass<PassedProps>
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
|
||||
// Components
|
||||
import {Radio, ButtonShape} from 'src/clockface'
|
||||
|
||||
// Types
|
||||
import {TimeMachineTab} from 'src/types/v2/timeMachine'
|
||||
|
||||
interface Props {
|
||||
activeTab: TimeMachineTab
|
||||
onSetActiveTab: (activeTab: TimeMachineTab) => void
|
||||
}
|
||||
|
||||
class TimeMachineTabs extends PureComponent<Props> {
|
||||
public render() {
|
||||
const {activeTab, onSetActiveTab} = this.props
|
||||
|
||||
return (
|
||||
<Radio shape={ButtonShape.StretchToFit}>
|
||||
<Radio.Button
|
||||
id="deceo-tab-queries"
|
||||
titleText="Queries"
|
||||
value={TimeMachineTab.Queries}
|
||||
active={activeTab === TimeMachineTab.Queries}
|
||||
onClick={onSetActiveTab}
|
||||
>
|
||||
Queries
|
||||
</Radio.Button>
|
||||
<Radio.Button
|
||||
id="deceo-tab-vis"
|
||||
titleText="Visualization"
|
||||
value={TimeMachineTab.Visualization}
|
||||
active={activeTab === TimeMachineTab.Visualization}
|
||||
onClick={onSetActiveTab}
|
||||
>
|
||||
Visualization
|
||||
</Radio.Button>
|
||||
</Radio>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default TimeMachineTabs
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
Graph Type Selector Styles
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
$graph-type--card: 190px;
|
||||
$graph-type--margin: 4px;
|
||||
$graph-type--graphic: 150px;
|
||||
|
||||
.graph-type-selector {
|
||||
background-color: $g3-castle;
|
||||
}
|
||||
|
||||
.graph-type-selector--container {
|
||||
min-width: 200px;
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.graph-type-selector--grid {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
margin: 0 (-10px / 2);
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
|
||||
.graph-type-selector--option {
|
||||
float: left;
|
||||
width: $graph-type--card;
|
||||
padding-bottom: $graph-type--card;
|
||||
position: relative;
|
||||
|
||||
> div > p {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 900;
|
||||
position: absolute;
|
||||
bottom: 7%;
|
||||
left: 10px;
|
||||
width: calc(100% - 20px);
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
// Actual "card"
|
||||
> div {
|
||||
background-color: $g2-kevlar;
|
||||
color: $g11-sidewalk;
|
||||
border-radius: $ix-radius;
|
||||
width: $graph-type--card - ($graph-type--margin / 2);
|
||||
height: $graph-type--card - ($graph-type--margin / 2);
|
||||
position: absolute;
|
||||
top: 10px / 2;
|
||||
left: 10px / 2;
|
||||
transition: color 0.25s ease, border-color 0.25s ease,
|
||||
background-color 0.25s ease;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: $g4-onyx;
|
||||
color: $g15-platinum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Active state "card"
|
||||
.graph-type-selector--option.active > div,
|
||||
.graph-type-selector--option.active > div:hover {
|
||||
background-color: $g5-pepper;
|
||||
color: $g18-cloud;
|
||||
}
|
||||
|
||||
.graph-type-selector--graphic {
|
||||
width: $graph-type--graphic;
|
||||
height: $graph-type--graphic;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
> svg,
|
||||
> svg * {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
> svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.graph-type-selector--graphic-line {
|
||||
stroke-width: 1px;
|
||||
fill: none;
|
||||
stroke-linecap: round;
|
||||
stroke-miterlimit: 10;
|
||||
|
||||
&.graphic-line-a {
|
||||
stroke: $g11-sidewalk;
|
||||
}
|
||||
&.graphic-line-b {
|
||||
stroke: $g9-mountain;
|
||||
}
|
||||
&.graphic-line-c {
|
||||
stroke: $g7-graphite;
|
||||
}
|
||||
&.graphic-line-d {
|
||||
stroke: $g13-mist;
|
||||
}
|
||||
}
|
||||
.graph-type-selector--graphic-fill {
|
||||
opacity: 0.045;
|
||||
|
||||
&.graphic-fill-a {
|
||||
fill: $g11-sidewalk;
|
||||
}
|
||||
&.graphic-fill-b {
|
||||
fill: $g9-mountain;
|
||||
}
|
||||
&.graphic-fill-c {
|
||||
fill: $g7-graphite;
|
||||
}
|
||||
&.graphic-fill-d {
|
||||
fill: $g13-mist;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.graph-type-selector--option.active .graph-type-selector--graphic {
|
||||
.graph-type-selector--graphic-line.graphic-line-a {
|
||||
stroke: $c-pool;
|
||||
}
|
||||
.graph-type-selector--graphic-line.graphic-line-b {
|
||||
stroke: $c-dreamsicle;
|
||||
}
|
||||
.graph-type-selector--graphic-line.graphic-line-c {
|
||||
stroke: $c-rainforest;
|
||||
}
|
||||
.graph-type-selector--graphic-line.graphic-line-d {
|
||||
stroke: $g17-whisper;
|
||||
}
|
||||
.graph-type-selector--graphic-fill.graphic-fill-a {
|
||||
fill: $c-pool;
|
||||
}
|
||||
.graph-type-selector--graphic-fill.graphic-fill-b {
|
||||
fill: $c-dreamsicle;
|
||||
}
|
||||
.graph-type-selector--graphic-fill.graphic-fill-c {
|
||||
fill: $c-rainforest;
|
||||
}
|
||||
.graph-type-selector--graphic-fill.graphic-fill-a,
|
||||
.graph-type-selector--graphic-fill.graphic-fill-b,
|
||||
.graph-type-selector--graphic-fill.graphic-fill-c {
|
||||
opacity: 0.22;
|
||||
}
|
||||
.graph-type-selector--graphic-fill.graphic-fill-d {
|
||||
fill: $g17-whisper;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// Libraries
|
||||
import React, {Component} from 'react'
|
||||
import classnames from 'classnames'
|
||||
|
||||
// Constants
|
||||
import {GRAPH_TYPES} from 'src/dashboards/graphics/graph'
|
||||
|
||||
// Decorators
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
// Types
|
||||
import {ViewType} from 'src/types/v2'
|
||||
|
||||
interface Props {
|
||||
type: string
|
||||
onUpdateType: (newType: ViewType) => void
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
class ViewTypeSelector extends Component<Props> {
|
||||
public render() {
|
||||
const {type} = this.props
|
||||
|
||||
return (
|
||||
<div className="graph-type-selector--container">
|
||||
<div className="graph-type-selector--grid">
|
||||
{GRAPH_TYPES.map(graphType => (
|
||||
<div
|
||||
key={graphType.type}
|
||||
className={classnames('graph-type-selector--option', {
|
||||
active: graphType.type === type,
|
||||
})}
|
||||
>
|
||||
<div onClick={this.handleSelectType(graphType.type)}>
|
||||
{graphType.graphic}
|
||||
<p>{graphType.menuOption}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private handleSelectType = (newType: ViewType) => (): void => {
|
||||
this.props.onUpdateType(newType)
|
||||
}
|
||||
}
|
||||
|
||||
export default ViewTypeSelector
|
|
@ -30,7 +30,7 @@ interface Props {
|
|||
orientation: string
|
||||
activeHandleID: string
|
||||
headerOrientation: string
|
||||
render: (visibility: string) => ReactElement<any>
|
||||
render: (visibility: string, pixels: number) => ReactElement<any>
|
||||
onHandleStartDrag: (id: string, e: MouseEvent<HTMLElement>) => void
|
||||
onDoubleClick: (id: string) => void
|
||||
onMaximize: (id: string) => void
|
||||
|
@ -46,15 +46,17 @@ class Division extends PureComponent<Props> {
|
|||
}
|
||||
|
||||
private collapseThreshold: number = 0
|
||||
private ref: React.RefObject<HTMLDivElement>
|
||||
private divisionRef: React.RefObject<HTMLDivElement>
|
||||
private divisionPixels: number = 0
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.ref = React.createRef<HTMLDivElement>()
|
||||
this.divisionRef = React.createRef<HTMLDivElement>()
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
const {name} = this.props
|
||||
this.calcDivisionPixels()
|
||||
|
||||
if (!name) {
|
||||
return 0
|
||||
|
@ -70,18 +72,25 @@ class Division extends PureComponent<Props> {
|
|||
this.collapseThreshold = width + NAME_OFFSET
|
||||
}
|
||||
|
||||
public componentDidUpdate() {
|
||||
this.calcDivisionPixels()
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {render} = this.props
|
||||
|
||||
return (
|
||||
<div
|
||||
className={this.containerClass}
|
||||
style={this.containerStyle}
|
||||
ref={this.ref}
|
||||
ref={this.divisionRef}
|
||||
>
|
||||
{this.renderDragHandle}
|
||||
<div className={this.contentsClass} style={this.contentStyle}>
|
||||
{this.renderHeader}
|
||||
<div className="threesizer--body">{render(this.visibility)}</div>
|
||||
<div className="threesizer--body">
|
||||
{render(this.visibility, this.divisionPixels)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -273,11 +282,11 @@ class Division extends PureComponent<Props> {
|
|||
return true
|
||||
}
|
||||
|
||||
if (!this.ref || this.props.size >= 0.33) {
|
||||
if (!this.divisionRef || this.props.size >= 0.33) {
|
||||
return false
|
||||
}
|
||||
|
||||
const {width} = this.ref.current.getBoundingClientRect()
|
||||
const {width} = this.divisionRef.current.getBoundingClientRect()
|
||||
|
||||
return width <= this.collapseThreshold
|
||||
}
|
||||
|
@ -312,6 +321,19 @@ class Division extends PureComponent<Props> {
|
|||
const {id, onMaximize} = this.props
|
||||
onMaximize(id)
|
||||
}
|
||||
|
||||
private calcDivisionPixels = (): void => {
|
||||
const {orientation} = this.props
|
||||
|
||||
const {clientWidth, clientHeight} = this.divisionRef.current
|
||||
|
||||
let divisionPixels = clientWidth
|
||||
if (orientation === HANDLE_HORIZONTAL) {
|
||||
divisionPixels = clientHeight
|
||||
}
|
||||
|
||||
this.divisionPixels = divisionPixels
|
||||
}
|
||||
}
|
||||
|
||||
export default Division
|
||||
|
|
|
@ -38,7 +38,7 @@ interface DivisionProps {
|
|||
size?: number
|
||||
headerButtons?: JSX.Element[]
|
||||
menuOptions: MenuItem[]
|
||||
render: (visibility?: string) => ReactElement<any>
|
||||
render: (visibility: string, pixels: number) => ReactElement<any>
|
||||
}
|
||||
|
||||
interface DivisionState extends DivisionProps {
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
// Utils
|
||||
import {getNewView} from 'src/dashboards/utils/cellGetters'
|
||||
|
||||
// Constants
|
||||
import {
|
||||
VEO_TIME_MACHINE_ID,
|
||||
|
@ -8,11 +5,12 @@ import {
|
|||
} from 'src/shared/constants/timeMachine'
|
||||
|
||||
// Types
|
||||
import {View, TimeRange} from 'src/types/v2'
|
||||
import {View, TimeRange, ViewType, ViewShape} from 'src/types/v2'
|
||||
import {Action} from 'src/shared/actions/v2/timeMachines'
|
||||
import {InfluxLanguages} from 'src/types/v2/dashboards'
|
||||
|
||||
interface TimeMachineState {
|
||||
view: Partial<View>
|
||||
view: View
|
||||
timeRange: TimeRange
|
||||
}
|
||||
|
||||
|
@ -24,8 +22,77 @@ export interface TimeMachinesState {
|
|||
}
|
||||
|
||||
const initialStateHelper = (): TimeMachineState => ({
|
||||
view: getNewView(),
|
||||
timeRange: {lower: 'now() - 1h'},
|
||||
view: {
|
||||
id: '1',
|
||||
name: 'CELLL YO',
|
||||
properties: {
|
||||
shape: ViewShape.ChronografV2,
|
||||
queries: [
|
||||
{
|
||||
text:
|
||||
'SELECT mean("usage_user") FROM "telegraf"."autogen"."cpu" WHERE time > now() - 15m GROUP BY time(10s) FILL(0)',
|
||||
type: InfluxLanguages.InfluxQL,
|
||||
source: 'v1',
|
||||
},
|
||||
],
|
||||
axes: {
|
||||
x: {
|
||||
bounds: ['', ''],
|
||||
label: '',
|
||||
prefix: '',
|
||||
suffix: '',
|
||||
base: '10',
|
||||
scale: 'linear',
|
||||
},
|
||||
y: {
|
||||
bounds: ['', ''],
|
||||
label: '',
|
||||
prefix: '',
|
||||
suffix: '',
|
||||
base: '10',
|
||||
scale: 'linear',
|
||||
},
|
||||
y2: {
|
||||
bounds: ['', ''],
|
||||
label: '',
|
||||
prefix: '',
|
||||
suffix: '',
|
||||
base: '10',
|
||||
scale: 'linear',
|
||||
},
|
||||
},
|
||||
type: ViewType.Line,
|
||||
colors: [
|
||||
{
|
||||
id: '63b61e02-7649-4d88-84bd-97722e2a2514',
|
||||
type: 'scale',
|
||||
hex: '#31C0F6',
|
||||
name: 'Nineteen Eighty Four',
|
||||
value: '0',
|
||||
},
|
||||
{
|
||||
id: 'd77c12d4-d257-48e1-8ba5-7bee8e3df593',
|
||||
type: 'scale',
|
||||
hex: '#A500A5',
|
||||
name: 'Nineteen Eighty Four',
|
||||
value: '0',
|
||||
},
|
||||
{
|
||||
id: 'cd6948ad-7ae6-40d3-bc37-3aec32f7fe98',
|
||||
type: 'scale',
|
||||
hex: '#FF7E27',
|
||||
name: 'Nineteen Eighty Four',
|
||||
value: '0',
|
||||
},
|
||||
],
|
||||
legend: {},
|
||||
decimalPlaces: {
|
||||
isEnforced: false,
|
||||
digits: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const INITIAL_STATE: TimeMachinesState = {
|
||||
|
@ -70,6 +137,15 @@ const timeMachineReducer = (
|
|||
newActiveTimeMachine = {...activeTimeMachine, timeRange}
|
||||
break
|
||||
}
|
||||
|
||||
case 'SET_VIEW_TYPE': {
|
||||
const {type} = action.payload
|
||||
const properties = {...activeTimeMachine.view.properties, type}
|
||||
const view = {...activeTimeMachine.view, properties}
|
||||
|
||||
newActiveTimeMachine = {...activeTimeMachine, view}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (newActiveTimeMachine) {
|
||||
|
|
|
@ -44,7 +44,9 @@
|
|||
@import 'src/dashboards/components/rename_dashboard/RenameDashboard';
|
||||
@import 'src/dashboards/components/dashboard_empty/DashboardEmpty';
|
||||
@import 'src/dashboards/components/VEO';
|
||||
@import 'src/shared/components/TimeMachine';
|
||||
@import 'src/shared/components/TimeMachineControls';
|
||||
@import 'src/shared/components/ViewTypeSelector';
|
||||
@import 'src/dataExplorer/components/DataExplorer';
|
||||
@import 'src/shared/components/views/Markdown';
|
||||
@import 'src/onboarding/OnboardingWizard.scss';
|
||||
|
|
Loading…
Reference in New Issue