diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66c97bc51..c8ed7653d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,10 @@
## v1.3.11.0 [unreleased]
### 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
-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
### UI Improvements
diff --git a/ui/src/dashboards/actions/index.js b/ui/src/dashboards/actions/index.js
index b151b5e19..0108e3ab9 100644
--- a/ui/src/dashboards/actions/index.js
+++ b/ui/src/dashboards/actions/index.js
@@ -281,7 +281,8 @@ export const updateTempVarValues = (source, dashboard) => async dispatch => {
results.forEach(({data}, 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))
})
} catch (error) {
diff --git a/ui/src/dashboards/components/AxesOptions.js b/ui/src/dashboards/components/AxesOptions.js
index d44640ea7..fcce69a05 100644
--- a/ui/src/dashboards/components/AxesOptions.js
+++ b/ui/src/dashboards/components/AxesOptions.js
@@ -6,6 +6,7 @@ import {Tabber, Tab} from 'src/dashboards/components/Tabber'
import {DISPLAY_OPTIONS, TOOLTIP_CONTENT} from 'src/dashboards/constants'
const {LINEAR, LOG, BASE_2, BASE_10} = DISPLAY_OPTIONS
+const getInputMin = scale => (scale === LOG ? '0' : null)
const AxesOptions = ({
axes: {y: {bounds, label, prefix, suffix, base, scale, defaultYLabel}},
@@ -38,6 +39,7 @@ const AxesOptions = ({
customValue={min}
onSetValue={onSetYAxisBoundMin}
type="number"
+ min={getInputMin(scale)}
/>
@@ -47,6 +49,7 @@ const AxesOptions = ({
customValue={max}
onSetValue={onSetYAxisBoundMax}
type="number"
+ min={getInputMin(scale)}
/>
numberValueFormatter(yval, opts, y.prefix, y.suffix),
axisLabelWidth: this.getLabelWidth(),
@@ -130,7 +127,7 @@ export default class Dygraph extends Component {
}
componentDidUpdate() {
- const {labels, axes: {y, y2}, options, ruleValues, isBarGraph} = this.props
+ const {labels, axes: {y, y2}, options, isBarGraph} = this.props
const dygraph = this.dygraph
if (!dygraph) {
@@ -149,9 +146,7 @@ export default class Dygraph extends Component {
ylabel: this.getLabel('y'),
axes: {
y: {
- valueRange: options.stackedGraph
- ? getStackedRange(y.bounds)
- : getRange(timeSeries, y.bounds, ruleValues),
+ valueRange: this.getYRange(timeSeries),
axisLabelFormatter: (yval, __, opts) =>
numberValueFormatter(yval, opts, y.prefix, y.suffix),
axisLabelWidth: this.getLabelWidth(),
@@ -175,6 +170,24 @@ export default class Dygraph extends Component {
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) => {
const {onZoom} = this.props
diff --git a/ui/src/shared/components/OptIn.js b/ui/src/shared/components/OptIn.js
index 484af36a2..7f1fee135 100644
--- a/ui/src/shared/components/OptIn.js
+++ b/ui/src/shared/components/OptIn.js
@@ -99,7 +99,7 @@ class OptIn extends Component {
handleInputRef = el => (this.customValueInput = el)
render() {
- const {fixedPlaceholder, customPlaceholder, type} = this.props
+ const {fixedPlaceholder, customPlaceholder, type, min} = this.props
const {useCustomValue, customValue} = this.state
return (
@@ -110,6 +110,7 @@ class OptIn extends Component {
>
-
{
const {errors, measurementSets} = measurements(data)
- return {errors, measurements: measurementSets[0].measurements}
+ return {
+ errors,
+ measurements: _.get(measurementSets, ['0', 'measurements'], []),
+ }
},
fieldKeys: (data, key) => {
const {errors, fieldSets} = fieldKeys(data)
- return {errors, fieldKeys: fieldSets[key]}
+ return {errors, fieldKeys: _.get(fieldSets, key, [])}
},
tagKeys,
tagValues: (data, key) => {
const {errors, tags} = tagValues(data)
- return {errors, tagValues: tags[key]}
+ return {errors, tagValues: _.get(tags, key, [])}
},
}