Merge pull request #1352 from influxdata/line-display-options

Add display options ui for line graph types
pull/10616/head
Iris Scholten 2018-11-12 16:46:10 -08:00 committed by GitHub
commit b9ad495e58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 873 additions and 45 deletions

View File

@ -1,6 +1,6 @@
import {DEFAULT_TABLE_OPTIONS} from 'src/dashboards/constants'
import {stringifyColorValues} from 'src/shared/constants/colorOperations'
import {ViewType, Axis} from 'src/types/v2/dashboards'
import {ViewType, Axis, Axes} from 'src/types/v2/dashboards'
import {Color} from 'src/types/colors'
export const initializeOptions = (type: ViewType) => {
@ -29,6 +29,16 @@ export const DEFAULT_AXIS: DefaultAxis = {
label: '',
}
export const FULL_DEFAULT_AXIS: Axis = {
...DEFAULT_AXIS,
bounds: ['', ''],
}
export const DEFAULT_AXES: Axes = {
x: FULL_DEFAULT_AXIS,
y: FULL_DEFAULT_AXIS,
}
export const TOOLTIP_Y_VALUE_FORMAT =
'<p><strong>K/M/B</strong> = Thousand / Million / Billion<br/><strong>K/M/G</strong> = Kilo / Mega / Giga </p>'

View File

@ -1,5 +1,8 @@
// Types
import {TimeMachineState} from 'src/shared/reducers/v2/timeMachines'
import {TimeRange, ViewType} from 'src/types/v2'
import {Axes, DecimalPlaces} from 'src/types/v2/dashboards'
import {Color} from 'src/types/colors'
export type Action =
| SetActiveTimeMachineAction
@ -8,6 +11,17 @@ export type Action =
| SetTypeAction
| SetDraftScriptAction
| SubmitScriptAction
| SetDecimalPlaces
| SetAxes
| SetStaticLegend
| SetColors
| SetYAxisLabel
| SetYAxisMinBound
| SetYAxisMaxBound
| SetYAxisPrefix
| SetYAxisSuffix
| SetYAxisBase
| SetYAxisScale
interface SetActiveTimeMachineAction {
type: 'SET_ACTIVE_TIME_MACHINE'
@ -72,3 +86,114 @@ interface SubmitScriptAction {
export const submitScript = (): SubmitScriptAction => ({
type: 'SUBMIT_SCRIPT',
})
interface SetAxes {
type: 'SET_AXES'
payload: {axes: Axes}
}
export const setAxes = (axes: Axes): SetAxes => ({
type: 'SET_AXES',
payload: {axes},
})
interface SetYAxisLabel {
type: 'SET_Y_AXIS_LABEL'
payload: {label: string}
}
export const setYAxisLabel = (label: string): SetYAxisLabel => ({
type: 'SET_Y_AXIS_LABEL',
payload: {label},
})
interface SetYAxisMinBound {
type: 'SET_Y_AXIS_MIN_BOUND'
payload: {min: string}
}
export const setYAxisMinBound = (min: string): SetYAxisMinBound => ({
type: 'SET_Y_AXIS_MIN_BOUND',
payload: {min},
})
interface SetYAxisMaxBound {
type: 'SET_Y_AXIS_MAX_BOUND'
payload: {max: string}
}
export const setYAxisMaxBound = (max: string): SetYAxisMaxBound => ({
type: 'SET_Y_AXIS_MAX_BOUND',
payload: {max},
})
interface SetYAxisPrefix {
type: 'SET_Y_AXIS_PREFIX'
payload: {prefix: string}
}
export const setYAxisPrefix = (prefix: string): SetYAxisPrefix => ({
type: 'SET_Y_AXIS_PREFIX',
payload: {prefix},
})
interface SetYAxisSuffix {
type: 'SET_Y_AXIS_SUFFIX'
payload: {suffix: string}
}
export const setYAxisSuffix = (suffix: string): SetYAxisSuffix => ({
type: 'SET_Y_AXIS_SUFFIX',
payload: {suffix},
})
interface SetYAxisBase {
type: 'SET_Y_AXIS_BASE'
payload: {base: string}
}
export const setYAxisBase = (base: string): SetYAxisBase => ({
type: 'SET_Y_AXIS_BASE',
payload: {base},
})
interface SetYAxisScale {
type: 'SET_Y_AXIS_SCALE'
payload: {scale: string}
}
export const setYAxisScale = (scale: string): SetYAxisScale => ({
type: 'SET_Y_AXIS_SCALE',
payload: {scale},
})
interface SetStaticLegend {
type: 'SET_STATIC_LEGEND'
payload: {staticLegend: boolean}
}
export const setStaticLegend = (staticLegend: boolean): SetStaticLegend => ({
type: 'SET_STATIC_LEGEND',
payload: {staticLegend},
})
interface SetColors {
type: 'SET_COLORS'
payload: {colors: Color[]}
}
export const setColors = (colors: Color[]): SetColors => ({
type: 'SET_COLORS',
payload: {colors},
})
interface SetDecimalPlaces {
type: 'SET_DECIMAL_PLACES'
payload: {decimalPlaces: DecimalPlaces}
}
export const setDecimalPlaces = (
decimalPlaces: DecimalPlaces
): SetDecimalPlaces => ({
type: 'SET_DECIMAL_PLACES',
payload: {decimalPlaces},
})

View File

@ -38,7 +38,6 @@ export default class ColorScaleDropdown extends Component<Props, State> {
public render() {
const {expanded} = this.state
const {selected} = this.props
return (
<ClickOutside onClickOutside={this.handleClickOutside}>
@ -46,9 +45,9 @@ export default class ColorScaleDropdown extends Component<Props, State> {
<div className={this.buttonClassName} onClick={this.handleToggleMenu}>
<div
className="color-dropdown--swatches"
style={this.generateGradientStyle(selected)}
style={this.generateGradientStyle(this.selected)}
/>
<div className="color-dropdown--name">{selected[0].name}</div>
<div className="color-dropdown--name">{this.selected[0].name}</div>
<span className="caret" />
</div>
{expanded && this.renderMenu}
@ -57,9 +56,17 @@ export default class ColorScaleDropdown extends Component<Props, State> {
)
}
private get renderMenu(): JSX.Element {
private get selected(): Color[] {
const {selected} = this.props
if (selected.length) {
return selected
}
return LINE_COLOR_SCALES[0].colors
}
private get renderMenu(): JSX.Element {
return (
<div className="color-dropdown--menu">
<FancyScrollbar
@ -70,7 +77,7 @@ export default class ColorScaleDropdown extends Component<Props, State> {
{LINE_COLOR_SCALES.map(colorScale => (
<div
className={
colorScale.name === selected[0].name
colorScale.name === this.selected[0].name
? 'color-dropdown--item active'
: 'color-dropdown--item'
}

View File

@ -1,34 +1,20 @@
// Libraries
import React, {SFC} from 'react'
import {connect} from 'react-redux'
// Components
import ViewTypeSelector from 'src/shared/components/ViewTypeSelector'
import TimeMachineQueryEditor from 'src/shared/components/TimeMachineQueryEditor'
// Actions
import {setType} from 'src/shared/actions/v2/timeMachines'
import TimeMachineQueryEditor from 'src/shared/components/TimeMachineQueryEditor'
import ViewOptions from 'src/shared/components/view_options/ViewOptions'
// Types
import {AppState, View, NewView} from 'src/types/v2'
import {TimeMachineTab} from 'src/types/v2/timeMachine'
interface StateProps {
view: View | NewView
}
interface DispatchProps {
onUpdateType: typeof setType
}
interface OwnProps {
interface Props {
activeTab: TimeMachineTab
}
type Props = StateProps & DispatchProps & OwnProps
const TimeMachineBottom: SFC<Props> = props => {
const {view, onUpdateType, activeTab} = props
const {activeTab} = props
if (activeTab === TimeMachineTab.Queries) {
return <TimeMachineQueryEditor />
@ -37,10 +23,7 @@ const TimeMachineBottom: SFC<Props> = props => {
if (activeTab === TimeMachineTab.Visualization) {
return (
<div className="time-machine-customization">
<ViewTypeSelector
type={view.properties.type}
onUpdateType={onUpdateType}
/>
<ViewOptions />
</div>
)
}
@ -48,18 +31,4 @@ const TimeMachineBottom: SFC<Props> = props => {
return null
}
const mstp = (state: AppState) => {
const {activeTimeMachineID, timeMachines} = state.timeMachines
const timeMachine = timeMachines[activeTimeMachineID]
return {view: timeMachine.view}
}
const mdtp = {
onUpdateType: setType,
}
export default connect<StateProps, DispatchProps, OwnProps>(
mstp,
mdtp
)(TimeMachineBottom)
export default TimeMachineBottom

View File

@ -0,0 +1,132 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
// Components
import Form from 'src/clockface/components/form_layout/Form'
import YAxisTitle from 'src/shared/components/view_options/options/YAxisTitle'
import YAxisBounds from 'src/shared/components/view_options/options/YAxisBounds'
import YAxisAffixes from 'src/shared/components/view_options/options/YAxisAffixes'
import YAxisBase from 'src/shared/components/view_options/options/YAxisBase'
import YAxisScale from 'src/shared/components/view_options/options/YAxisScale'
import DecimalPlacesOption from 'src/shared/components/view_options/options/DecimalPlaces'
import ColorSelector from 'src/shared/components/view_options/options/ColorSelector'
// Actions
import {
setStaticLegend,
setColors,
setDecimalPlaces,
setYAxisLabel,
setYAxisMinBound,
setYAxisMaxBound,
setYAxisPrefix,
setYAxisSuffix,
setYAxisBase,
setYAxisScale,
} from 'src/shared/actions/v2/timeMachines'
// Types
import {ViewType} from 'src/types/v2'
import {Axes, DecimalPlaces} from 'src/types/v2/dashboards'
import {Color} from 'src/types/colors'
interface OwnProps {
type: ViewType
axes: Axes
colors: Color[]
decimalPlaces?: DecimalPlaces
}
interface DispatchProps {
onUpdateYAxisLabel: (label: string) => void
onUpdateYAxisMinBound: (min: string) => void
onUpdateYAxisMaxBound: (max: string) => void
onUpdateYAxisPrefix: (prefix: string) => void
onUpdateYAxisSuffix: (suffix: string) => void
onUpdateYAxisBase: (base: string) => void
onUpdateYAxisScale: (scale: string) => void
onToggleStaticLegend: (isStaticLegend: boolean) => void
onUpdateColors: (colors: Color[]) => void
onUpdateDecimalPlaces: (decimalPlaces: DecimalPlaces) => void
}
type Props = OwnProps & DispatchProps
class LineOptions extends PureComponent<Props> {
public render() {
const {
axes: {
y: {label, bounds, scale, prefix, suffix, base},
},
colors,
onUpdateColors,
onUpdateYAxisLabel,
onUpdateYAxisMinBound,
onUpdateYAxisMaxBound,
onUpdateYAxisPrefix,
onUpdateYAxisSuffix,
onUpdateYAxisBase,
onUpdateYAxisScale,
} = this.props
const [min, max] = bounds
return (
<Form>
<YAxisTitle label={label} onUpdateYAxisLabel={onUpdateYAxisLabel} />
<ColorSelector colors={colors} onUpdateColors={onUpdateColors} />
<YAxisBounds
min={min}
max={max}
scale={scale}
onUpdateYAxisMaxBound={onUpdateYAxisMaxBound}
onUpdateYAxisMinBound={onUpdateYAxisMinBound}
/>
<YAxisAffixes
prefix={prefix}
suffix={suffix}
onUpdateYAxisPrefix={onUpdateYAxisPrefix}
onUpdateYAxisSuffix={onUpdateYAxisSuffix}
/>
<YAxisBase base={base} onUpdateYAxisBase={onUpdateYAxisBase} />
<YAxisScale scale={scale} onUpdateYAxisScale={onUpdateYAxisScale} />
{this.decimalPlaces}
</Form>
)
}
private get decimalPlaces(): JSX.Element {
const {onUpdateDecimalPlaces, decimalPlaces, type} = this.props
if (type !== ViewType.LinePlusSingleStat || !decimalPlaces) {
return null
}
return (
<DecimalPlacesOption
digits={decimalPlaces.digits}
isEnforced={decimalPlaces.isEnforced}
onDecimalPlacesChange={onUpdateDecimalPlaces}
/>
)
}
}
const mdtp: DispatchProps = {
onUpdateYAxisLabel: setYAxisLabel,
onUpdateYAxisMinBound: setYAxisMinBound,
onUpdateYAxisMaxBound: setYAxisMaxBound,
onUpdateYAxisPrefix: setYAxisPrefix,
onUpdateYAxisSuffix: setYAxisSuffix,
onUpdateYAxisBase: setYAxisBase,
onUpdateYAxisScale: setYAxisScale,
onToggleStaticLegend: setStaticLegend,
onUpdateColors: setColors,
onUpdateDecimalPlaces: setDecimalPlaces,
}
export default connect<{}, DispatchProps, OwnProps>(
null,
mdtp
)(LineOptions)

View File

@ -0,0 +1,29 @@
// Libraries
import React, {PureComponent} from 'react'
// Components
import LineOptions from 'src/shared/components/view_options/LineOptions'
// Types
import {ViewType, View, NewView} from 'src/types/v2'
interface Props {
view: View | NewView
}
class OptionsSwitcher extends PureComponent<Props> {
public render() {
const {view} = this.props
switch (view.properties.type) {
case ViewType.Line:
case ViewType.Stacked:
case ViewType.StepPlot:
case ViewType.Bar:
case ViewType.LinePlusSingleStat:
return <LineOptions {...view.properties} />
default:
return <div />
}
}
}
export default OptionsSwitcher

View File

@ -0,0 +1,78 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
// Actions
import {setType} from 'src/shared/actions/v2/timeMachines'
// Components
import ViewTypeSelector from 'src/shared/components/ViewTypeSelector'
import Threesizer from 'src/shared/components/threesizer/Threesizer'
import OptionsSwitcher from 'src/shared/components/view_options/OptionsSwitcher'
// Constants
import {HANDLE_VERTICAL} from 'src/shared/constants'
// Types
import {View, NewView, AppState} from 'src/types/v2'
interface DispatchProps {
onUpdateType: typeof setType
}
interface StateProps {
view: View | NewView
}
type Props = DispatchProps & StateProps
class ViewOptions extends PureComponent<Props> {
public render() {
return (
<Threesizer orientation={HANDLE_VERTICAL} divisions={this.divisions} />
)
}
private get divisions() {
const {view, onUpdateType} = this.props
return [
{
name: 'Visualization Type',
headerButtons: [],
menuOptions: [],
render: () => (
<ViewTypeSelector
type={view.properties.type}
onUpdateType={onUpdateType}
/>
),
headerOrientation: HANDLE_VERTICAL,
},
{
name: 'Customize',
headerButtons: [],
menuOptions: [],
render: () => <OptionsSwitcher view={view} />,
headerOrientation: HANDLE_VERTICAL,
},
]
}
}
const mstp = (state: AppState): StateProps => {
const {
timeMachines: {activeTimeMachineID, timeMachines},
} = state
const timeMachine = timeMachines[activeTimeMachineID]
return {
view: timeMachine.view,
}
}
const mdtp: DispatchProps = {
onUpdateType: setType,
}
export default connect<StateProps, DispatchProps, {}>(
mstp,
mdtp
)(ViewOptions)

View File

@ -0,0 +1,41 @@
// Libraries
import React, {PureComponent} from 'react'
// Components
import FormElement from 'src/clockface/components/form_layout/FormElement'
import ColorScaleDropdown from 'src/shared/components/ColorScaleDropdown'
// Types
import {Color} from 'src/types/colors'
import {ErrorHandling} from 'src/shared/decorators/errors'
interface Props {
colors: Color[]
onUpdateColors: (colors: Color[]) => void
}
@ErrorHandling
class LineGraphColorSelector extends PureComponent<Props> {
public render() {
const {colors} = this.props
return (
<FormElement label="Line Colors">
<ColorScaleDropdown
onChoose={this.handleSelectColors}
stretchToFit={true}
selected={colors}
/>
</FormElement>
)
}
public handleSelectColors = (colorScale): void => {
const {onUpdateColors} = this.props
const {colors} = colorScale
onUpdateColors(colors)
}
}
export default LineGraphColorSelector

View File

@ -13,7 +13,7 @@ const fixedValueString = 'fixed'
const defaultPlaceholder = 'unlimited'
@ErrorHandling
class GraphOptionsDecimalPlaces extends PureComponent<Props> {
class DecimalPlacesOption extends PureComponent<Props> {
constructor(props: Props) {
super(props)
}
@ -75,4 +75,4 @@ class GraphOptionsDecimalPlaces extends PureComponent<Props> {
}
}
export default GraphOptionsDecimalPlaces
export default DecimalPlacesOption

View File

@ -0,0 +1,48 @@
// Libraries
import React, {PureComponent, ChangeEvent} from 'react'
// Components
import FormElement from 'src/clockface/components/form_layout/FormElement'
import {Input} from 'src/clockface'
interface Props {
prefix: string
suffix: string
onUpdateYAxisPrefix: (prefix: string) => void
onUpdateYAxisSuffix: (suffix: string) => void
}
class YAxisAffixes extends PureComponent<Props> {
public render() {
const {prefix, suffix} = this.props
return (
<>
<FormElement label="Y-Value's Prefix">
<Input value={prefix} onChange={this.handleUpdateYAxisPrefix} />
</FormElement>
<FormElement label="Y-Value's Suffix">
<Input value={suffix} onChange={this.handleUpdateYAxisSuffix} />
</FormElement>
</>
)
}
private handleUpdateYAxisPrefix = (
e: ChangeEvent<HTMLInputElement>
): void => {
const {onUpdateYAxisPrefix} = this.props
const prefix = e.target.value
onUpdateYAxisPrefix(prefix)
}
private handleUpdateYAxisSuffix = (
e: ChangeEvent<HTMLInputElement>
): void => {
const {onUpdateYAxisSuffix} = this.props
const suffix = e.target.value
onUpdateYAxisSuffix(suffix)
}
}
export default YAxisAffixes

View File

@ -0,0 +1,58 @@
// Libraries
import React, {PureComponent} from 'react'
// Components
import FormElement from 'src/clockface/components/form_layout/FormElement'
import {Radio, ButtonShape} from 'src/clockface'
// Constants
import {AXES_SCALE_OPTIONS} from 'src/dashboards/constants/cellEditor'
interface Props {
base: string
onUpdateYAxisBase: (base: string) => void
}
const {BASE_2, BASE_10} = AXES_SCALE_OPTIONS
class YAxisBase extends PureComponent<Props> {
public render() {
const {base, onUpdateYAxisBase} = this.props
return (
<FormElement label="Y-Value's Format">
<Radio shape={ButtonShape.StretchToFit}>
<Radio.Button
id="y-values-format-tab--raw"
value=""
active={base === ''}
titleText="Don't format values"
onClick={onUpdateYAxisBase}
>
Raw
</Radio.Button>
<Radio.Button
id="y-values-format-tab--kmb"
value={BASE_10}
active={base === BASE_10}
titleText="Thousand / Million / Billion"
onClick={onUpdateYAxisBase}
>
K/M/B
</Radio.Button>
<Radio.Button
id="y-values-format-tab--kmg"
value={BASE_2}
active={base === BASE_2}
titleText="Kilo / Mega / Giga"
onClick={onUpdateYAxisBase}
>
K/M/G
</Radio.Button>
</Radio>
</FormElement>
)
}
}
export default YAxisBase

View File

@ -0,0 +1,39 @@
// Libraries
import React, {PureComponent} from 'react'
// Constants
import {AXES_SCALE_OPTIONS} from 'src/dashboards/constants/cellEditor'
// Components
import FormElement from 'src/clockface/components/form_layout/FormElement'
import OptIn from 'src/shared/components/OptIn'
interface Props {
label: string
bound: string
scale: string
onUpdateYAxisBound: (bound: string) => void
}
const {LOG} = AXES_SCALE_OPTIONS
const getInputMin = scale => (scale === LOG ? '0' : null)
class YAxisBound extends PureComponent<Props> {
public render() {
const {label, bound, scale, onUpdateYAxisBound} = this.props
return (
<FormElement label={label}>
<OptIn
customPlaceholder={'min'}
customValue={bound}
onSetValue={onUpdateYAxisBound}
type="number"
min={getInputMin(scale)}
/>
</FormElement>
)
}
}
export default YAxisBound

View File

@ -0,0 +1,45 @@
// Libraries
import React, {PureComponent} from 'react'
// Components
import YAxisBound from 'src/shared/components/view_options/options/YAxisBound'
interface Props {
min: string
max: string
scale: string
onUpdateYAxisMinBound: (min: string) => void
onUpdateYAxisMaxBound: (max: string) => void
}
class YAxisBounds extends PureComponent<Props> {
public render() {
const {
min,
max,
scale,
onUpdateYAxisMinBound,
onUpdateYAxisMaxBound,
} = this.props
return (
<>
<YAxisBound
label="Min"
bound={min}
scale={scale}
onUpdateYAxisBound={onUpdateYAxisMinBound}
/>
<YAxisBound
label="Max"
bound={max}
scale={scale}
onUpdateYAxisBound={onUpdateYAxisMaxBound}
/>
</>
)
}
}
export default YAxisBounds

View File

@ -0,0 +1,49 @@
// Libraries
import React, {PureComponent} from 'react'
// Components
import FormElement from 'src/clockface/components/form_layout/FormElement'
import {Radio, ButtonShape} from 'src/clockface'
// Constants
import {AXES_SCALE_OPTIONS} from 'src/dashboards/constants/cellEditor'
interface Props {
scale: string
onUpdateYAxisScale: (scale: string) => void
}
const {LINEAR, LOG} = AXES_SCALE_OPTIONS
class YAxisBase extends PureComponent<Props> {
public render() {
const {scale, onUpdateYAxisScale} = this.props
return (
<FormElement label="Scale">
<Radio shape={ButtonShape.StretchToFit}>
<Radio.Button
id="y-scale-tab--linear"
value={LINEAR}
active={scale === LINEAR || scale === ''}
titleText="Set Y-Axis to Linear Scale"
onClick={onUpdateYAxisScale}
>
Linear
</Radio.Button>
<Radio.Button
id="y-scale-tab--logarithmic"
value={LOG}
active={scale === LOG}
titleText="Set Y-Axis to Logarithmic Scale"
onClick={onUpdateYAxisScale}
>
Logarithmic
</Radio.Button>
</Radio>
</FormElement>
)
}
}
export default YAxisBase

View File

@ -0,0 +1,33 @@
// Libraries
import React, {PureComponent} from 'react'
// Components
import FormElement from 'src/clockface/components/form_layout/FormElement'
import OptIn from 'src/shared/components/OptIn'
interface Props {
label: string
onUpdateYAxisLabel: (label: string) => void
}
class YAxisTitle extends PureComponent<Props> {
public render() {
const {label, onUpdateYAxisLabel} = this.props
return (
<FormElement label="Title">
<OptIn
type="text"
customValue={label}
onSetValue={onUpdateYAxisLabel}
customPlaceholder={this.defaultYLabel || 'y-axis title'}
/>
</FormElement>
)
}
private get defaultYLabel() {
return ''
}
}
export default YAxisTitle

View File

@ -1,3 +1,6 @@
// Libraries
import _ from 'lodash'
// Utils
import {convertView, createView, replaceQuery} from 'src/shared/utils/view'
@ -111,6 +114,168 @@ const timeMachineReducer = (
}
break
}
case 'SET_AXES': {
const {axes} = action.payload
const {
view,
view: {properties},
} = activeTimeMachine
newActiveTimeMachine = {
...activeTimeMachine,
view: {...view, properties: {...properties, axes}},
}
break
}
case 'SET_Y_AXIS_LABEL': {
const {label} = action.payload
const {
view,
view: {properties},
} = activeTimeMachine
const axes = _.get(properties, 'axes')
const yAxis = {..._.get(axes, 'y'), label}
newActiveTimeMachine = {
...activeTimeMachine,
view: {...view, properties: {...properties, axes: {...axes, y: yAxis}}},
}
break
}
case 'SET_Y_AXIS_MIN_BOUND': {
const {min} = action.payload
const {
view,
view: {properties},
} = activeTimeMachine
const axes = _.get(properties, 'axes')
const yAxis = _.get(axes, 'y')
yAxis.bounds[0] = min
newActiveTimeMachine = {
...activeTimeMachine,
view: {...view, properties: {...properties, axes: {...axes, y: yAxis}}},
}
break
}
case 'SET_Y_AXIS_MAX_BOUND': {
const {max} = action.payload
const {
view,
view: {properties},
} = activeTimeMachine
const axes = _.get(properties, 'axes')
const yAxis = _.get(axes, 'y')
yAxis.bounds[1] = max
newActiveTimeMachine = {
...activeTimeMachine,
view: {...view, properties: {...properties, axes: {...axes, y: yAxis}}},
}
break
}
case 'SET_Y_AXIS_PREFIX': {
const {prefix} = action.payload
const {
view,
view: {properties},
} = activeTimeMachine
const axes = _.get(properties, 'axes')
const yAxis = {..._.get(axes, 'y'), prefix}
newActiveTimeMachine = {
...activeTimeMachine,
view: {...view, properties: {...properties, axes: {...axes, y: yAxis}}},
}
break
}
case 'SET_Y_AXIS_SUFFIX': {
const {suffix} = action.payload
const {
view,
view: {properties},
} = activeTimeMachine
const axes = _.get(properties, 'axes')
const yAxis = {..._.get(axes, 'y'), suffix}
newActiveTimeMachine = {
...activeTimeMachine,
view: {...view, properties: {...properties, axes: {...axes, y: yAxis}}},
}
break
}
case 'SET_Y_AXIS_BASE': {
const {base} = action.payload
const {
view,
view: {properties},
} = activeTimeMachine
const axes = _.get(properties, 'axes')
const yAxis = {..._.get(axes, 'y'), base}
newActiveTimeMachine = {
...activeTimeMachine,
view: {...view, properties: {...properties, axes: {...axes, y: yAxis}}},
}
break
}
case 'SET_Y_AXIS_SCALE': {
const {scale} = action.payload
const {
view,
view: {properties},
} = activeTimeMachine
const axes = _.get(properties, 'axes')
const yAxis = {..._.get(axes, 'y'), scale}
newActiveTimeMachine = {
...activeTimeMachine,
view: {...view, properties: {...properties, axes: {...axes, y: yAxis}}},
}
break
}
case 'SET_COLORS': {
const {colors} = action.payload
const {
view,
view: {properties},
} = activeTimeMachine
newActiveTimeMachine = {
...activeTimeMachine,
view: {...view, properties: {...properties, colors}},
}
break
}
case 'SET_DECIMAL_PLACES': {
const {decimalPlaces} = action.payload
newActiveTimeMachine = {...activeTimeMachine, decimalPlaces}
break
}
case 'SET_STATIC_LEGEND': {
const {staticLegend} = action.payload
newActiveTimeMachine = {...activeTimeMachine, staticLegend}
break
}
}
if (newActiveTimeMachine) {