Merge branch 'master' into feature/hosts
commit
9261a4d5a7
|
@ -1,7 +1,10 @@
|
||||||
## v1.3.11.0 [unreleased]
|
## v1.3.11.0 [unreleased]
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
1. [#2157](https://github.com/influxdata/chronograf/pull/2157): Fix logscale producing console errors when only one point in graph
|
||||||
|
1. [#2158](https://github.com/influxdata/chronograf/pull/2158): Fix 'Cannot connect to source' false error flag on Dashboard page
|
||||||
1. [#2167](https://github.com/influxdata/chronograf/pull/2167): Add fractions of seconds to time field in csv export
|
1. [#2167](https://github.com/influxdata/chronograf/pull/2167): Add fractions of seconds to time field in csv export
|
||||||
2. [#1077](https://github.com/influxdata/chronograf/pull/2087): Fix Chronograf requires users to run Telegraf's CPU and system plugins to ensure that all Apps appear on the HOST LIST page.
|
1. [#1077](https://github.com/influxdata/chronograf/pull/2087): Fix Chronograf requiring Telegraf's CPU and system plugins to ensure that all Apps appear on the HOST LIST page.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
### UI Improvements
|
### UI Improvements
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,8 @@ export const updateTempVarValues = (source, dashboard) => async dispatch => {
|
||||||
|
|
||||||
results.forEach(({data}, i) => {
|
results.forEach(({data}, i) => {
|
||||||
const {type, query, id} = tempsWithQueries[i]
|
const {type, query, id} = tempsWithQueries[i]
|
||||||
const vals = parsers[type](data, query.tagKey || query.measurement)[type]
|
const parsed = parsers[type](data, query.tagKey || query.measurement)
|
||||||
|
const vals = parsed[type]
|
||||||
dispatch(editTemplateVariableValues(dashboard.id, id, vals))
|
dispatch(editTemplateVariableValues(dashboard.id, id, vals))
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {Tabber, Tab} from 'src/dashboards/components/Tabber'
|
||||||
import {DISPLAY_OPTIONS, TOOLTIP_CONTENT} from 'src/dashboards/constants'
|
import {DISPLAY_OPTIONS, TOOLTIP_CONTENT} from 'src/dashboards/constants'
|
||||||
|
|
||||||
const {LINEAR, LOG, BASE_2, BASE_10} = DISPLAY_OPTIONS
|
const {LINEAR, LOG, BASE_2, BASE_10} = DISPLAY_OPTIONS
|
||||||
|
const getInputMin = scale => (scale === LOG ? '0' : null)
|
||||||
|
|
||||||
const AxesOptions = ({
|
const AxesOptions = ({
|
||||||
axes: {y: {bounds, label, prefix, suffix, base, scale, defaultYLabel}},
|
axes: {y: {bounds, label, prefix, suffix, base, scale, defaultYLabel}},
|
||||||
|
@ -38,6 +39,7 @@ const AxesOptions = ({
|
||||||
customValue={min}
|
customValue={min}
|
||||||
onSetValue={onSetYAxisBoundMin}
|
onSetValue={onSetYAxisBoundMin}
|
||||||
type="number"
|
type="number"
|
||||||
|
min={getInputMin(scale)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group col-sm-6">
|
<div className="form-group col-sm-6">
|
||||||
|
@ -47,6 +49,7 @@ const AxesOptions = ({
|
||||||
customValue={max}
|
customValue={max}
|
||||||
onSetValue={onSetYAxisBoundMax}
|
onSetValue={onSetYAxisBoundMax}
|
||||||
type="number"
|
type="number"
|
||||||
|
min={getInputMin(scale)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
|
|
|
@ -14,6 +14,7 @@ class ClickOutsideInput extends Component {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
id,
|
id,
|
||||||
|
min,
|
||||||
type,
|
type,
|
||||||
onFocus,
|
onFocus,
|
||||||
onChange,
|
onChange,
|
||||||
|
@ -27,6 +28,7 @@ class ClickOutsideInput extends Component {
|
||||||
<input
|
<input
|
||||||
className="form-control input-sm"
|
className="form-control input-sm"
|
||||||
id={id}
|
id={id}
|
||||||
|
min={min}
|
||||||
type={type}
|
type={type}
|
||||||
name={customPlaceholder}
|
name={customPlaceholder}
|
||||||
ref={onGetRef}
|
ref={onGetRef}
|
||||||
|
@ -43,6 +45,7 @@ class ClickOutsideInput extends Component {
|
||||||
const {func, string} = PropTypes
|
const {func, string} = PropTypes
|
||||||
|
|
||||||
ClickOutsideInput.propTypes = {
|
ClickOutsideInput.propTypes = {
|
||||||
|
min: string,
|
||||||
id: string.isRequired,
|
id: string.isRequired,
|
||||||
type: string.isRequired,
|
type: string.isRequired,
|
||||||
customPlaceholder: string.isRequired,
|
customPlaceholder: string.isRequired,
|
||||||
|
|
|
@ -43,7 +43,6 @@ export default class Dygraph extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const {
|
const {
|
||||||
axes: {y, y2},
|
axes: {y, y2},
|
||||||
ruleValues,
|
|
||||||
isGraphFilled: fillGraph,
|
isGraphFilled: fillGraph,
|
||||||
isBarGraph,
|
isBarGraph,
|
||||||
options,
|
options,
|
||||||
|
@ -63,9 +62,7 @@ export default class Dygraph extends Component {
|
||||||
plugins: [new Dygraphs.Plugins.Crosshair({direction: 'vertical'})],
|
plugins: [new Dygraphs.Plugins.Crosshair({direction: 'vertical'})],
|
||||||
axes: {
|
axes: {
|
||||||
y: {
|
y: {
|
||||||
valueRange: options.stackedGraph
|
valueRange: this.getYRange(timeSeries),
|
||||||
? getStackedRange(y.bounds)
|
|
||||||
: getRange(timeSeries, y.bounds, ruleValues),
|
|
||||||
axisLabelFormatter: (yval, __, opts) =>
|
axisLabelFormatter: (yval, __, opts) =>
|
||||||
numberValueFormatter(yval, opts, y.prefix, y.suffix),
|
numberValueFormatter(yval, opts, y.prefix, y.suffix),
|
||||||
axisLabelWidth: this.getLabelWidth(),
|
axisLabelWidth: this.getLabelWidth(),
|
||||||
|
@ -130,7 +127,7 @@ export default class Dygraph extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
const {labels, axes: {y, y2}, options, ruleValues, isBarGraph} = this.props
|
const {labels, axes: {y, y2}, options, isBarGraph} = this.props
|
||||||
|
|
||||||
const dygraph = this.dygraph
|
const dygraph = this.dygraph
|
||||||
if (!dygraph) {
|
if (!dygraph) {
|
||||||
|
@ -149,9 +146,7 @@ export default class Dygraph extends Component {
|
||||||
ylabel: this.getLabel('y'),
|
ylabel: this.getLabel('y'),
|
||||||
axes: {
|
axes: {
|
||||||
y: {
|
y: {
|
||||||
valueRange: options.stackedGraph
|
valueRange: this.getYRange(timeSeries),
|
||||||
? getStackedRange(y.bounds)
|
|
||||||
: getRange(timeSeries, y.bounds, ruleValues),
|
|
||||||
axisLabelFormatter: (yval, __, opts) =>
|
axisLabelFormatter: (yval, __, opts) =>
|
||||||
numberValueFormatter(yval, opts, y.prefix, y.suffix),
|
numberValueFormatter(yval, opts, y.prefix, y.suffix),
|
||||||
axisLabelWidth: this.getLabelWidth(),
|
axisLabelWidth: this.getLabelWidth(),
|
||||||
|
@ -175,6 +170,24 @@ export default class Dygraph extends Component {
|
||||||
this.resize()
|
this.resize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getYRange = timeSeries => {
|
||||||
|
const {options, axes: {y}, ruleValues} = this.props
|
||||||
|
|
||||||
|
if (options.stackedGraph) {
|
||||||
|
return getStackedRange(y.bounds)
|
||||||
|
}
|
||||||
|
|
||||||
|
const range = getRange(timeSeries, y.bounds, ruleValues)
|
||||||
|
const [min, max] = range
|
||||||
|
|
||||||
|
// Bug in Dygraph calculates a negative range for logscale when min range is 0
|
||||||
|
if (y.scale === LOG && timeSeries.length === 1 && min <= 0) {
|
||||||
|
return [0.1, max]
|
||||||
|
}
|
||||||
|
|
||||||
|
return range
|
||||||
|
}
|
||||||
|
|
||||||
handleZoom = (lower, upper) => {
|
handleZoom = (lower, upper) => {
|
||||||
const {onZoom} = this.props
|
const {onZoom} = this.props
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ class OptIn extends Component {
|
||||||
handleInputRef = el => (this.customValueInput = el)
|
handleInputRef = el => (this.customValueInput = el)
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {fixedPlaceholder, customPlaceholder, type} = this.props
|
const {fixedPlaceholder, customPlaceholder, type, min} = this.props
|
||||||
const {useCustomValue, customValue} = this.state
|
const {useCustomValue, customValue} = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -110,6 +110,7 @@ class OptIn extends Component {
|
||||||
>
|
>
|
||||||
<ClickOutsideInput
|
<ClickOutsideInput
|
||||||
id={this.id}
|
id={this.id}
|
||||||
|
min={min}
|
||||||
type={type}
|
type={type}
|
||||||
customValue={customValue}
|
customValue={customValue}
|
||||||
onGetRef={this.handleInputRef}
|
onGetRef={this.handleInputRef}
|
||||||
|
@ -119,7 +120,6 @@ class OptIn extends Component {
|
||||||
onKeyDown={this.handleKeyDownCustomValueInput}
|
onKeyDown={this.handleKeyDownCustomValueInput}
|
||||||
handleClickOutsideInput={this.handleClickOutsideInput}
|
handleClickOutsideInput={this.handleClickOutsideInput}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className="opt-in--groove-knob-container"
|
className="opt-in--groove-knob-container"
|
||||||
id={this.id}
|
id={this.id}
|
||||||
|
@ -141,15 +141,16 @@ class OptIn extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
OptIn.defaultProps = {
|
OptIn.defaultProps = {
|
||||||
fixedPlaceholder: 'auto',
|
|
||||||
fixedValue: '',
|
fixedValue: '',
|
||||||
customPlaceholder: 'Custom Value',
|
customPlaceholder: 'Custom Value',
|
||||||
|
fixedPlaceholder: 'auto',
|
||||||
customValue: '',
|
customValue: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
const {func, oneOf, string} = PropTypes
|
const {func, oneOf, string} = PropTypes
|
||||||
|
|
||||||
OptIn.propTypes = {
|
OptIn.propTypes = {
|
||||||
|
min: string,
|
||||||
fixedPlaceholder: string,
|
fixedPlaceholder: string,
|
||||||
fixedValue: string,
|
fixedValue: string,
|
||||||
customPlaceholder: string,
|
customPlaceholder: string,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import _ from 'lodash'
|
||||||
import databases from 'shared/parsing/showDatabases'
|
import databases from 'shared/parsing/showDatabases'
|
||||||
import measurements from 'shared/parsing/showMeasurements'
|
import measurements from 'shared/parsing/showMeasurements'
|
||||||
import fieldKeys from 'shared/parsing/showFieldKeys'
|
import fieldKeys from 'shared/parsing/showFieldKeys'
|
||||||
|
@ -8,16 +9,19 @@ const parsers = {
|
||||||
databases,
|
databases,
|
||||||
measurements: data => {
|
measurements: data => {
|
||||||
const {errors, measurementSets} = measurements(data)
|
const {errors, measurementSets} = measurements(data)
|
||||||
return {errors, measurements: measurementSets[0].measurements}
|
return {
|
||||||
|
errors,
|
||||||
|
measurements: _.get(measurementSets, ['0', 'measurements'], []),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
fieldKeys: (data, key) => {
|
fieldKeys: (data, key) => {
|
||||||
const {errors, fieldSets} = fieldKeys(data)
|
const {errors, fieldSets} = fieldKeys(data)
|
||||||
return {errors, fieldKeys: fieldSets[key]}
|
return {errors, fieldKeys: _.get(fieldSets, key, [])}
|
||||||
},
|
},
|
||||||
tagKeys,
|
tagKeys,
|
||||||
tagValues: (data, key) => {
|
tagValues: (data, key) => {
|
||||||
const {errors, tags} = tagValues(data)
|
const {errors, tags} = tagValues(data)
|
||||||
return {errors, tagValues: tags[key]}
|
return {errors, tagValues: _.get(tags, key, [])}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue