From 430a7edce50c7bdcc2ab73dc082c8e7014759a05 Mon Sep 17 00:00:00 2001 From: deniz kusefoglu Date: Fri, 12 Jan 2018 16:17:49 -0800 Subject: [PATCH 1/5] Always display time() around GROUP BY interval --- ui/src/utils/influxql.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/utils/influxql.js b/ui/src/utils/influxql.js index 71838775d..8a1ebf27d 100644 --- a/ui/src/utils/influxql.js +++ b/ui/src/utils/influxql.js @@ -157,9 +157,9 @@ function _buildGroupByTime(groupBy) { return '' } - return ` GROUP BY ${groupBy.time === AUTO_GROUP_BY + return ` GROUP BY time(${groupBy.time === AUTO_GROUP_BY ? TEMP_VAR_INTERVAL - : `time(${groupBy.time})`}` + : `${groupBy.time}`})` } function _buildGroupByTags(groupBy) { From c93d020190c959e7a35af1e5eee18ee4a1f60672 Mon Sep 17 00:00:00 2001 From: Michael Desa Date: Thu, 22 Feb 2018 13:17:49 -0500 Subject: [PATCH 2/5] Create new point template var template value Previously users specify `resolution` and `pixelsPerPoint`. This has been change and the front end will now need to specify `points` which is the number of points it'd like to get back from the query. --- influx/templates.go | 30 ++++++++++++++++++++++++++++++ influx/templates_test.go | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/influx/templates.go b/influx/templates.go index 4dfe76fe1..6402fbba3 100644 --- a/influx/templates.go +++ b/influx/templates.go @@ -58,6 +58,20 @@ func RenderTemplate(query string, t chronograf.TemplateVar, now time.Time) (stri tv[t.Values[i].Type] = t.Values[i].Value } + if pts, ok := tv["points"]; ok { + points, err := strconv.ParseInt(pts, 0, 64) + if err != nil { + return "", err + } + + dur, err := ParseTime(query, now) + if err != nil { + return "", err + } + interval := AutoInterval(points, dur) + return strings.Replace(query, t.Var, interval, -1), nil + } + if res, ok := tv["resolution"]; ok { resolution, err := strconv.ParseInt(res, 0, 64) if err != nil { @@ -82,6 +96,22 @@ func RenderTemplate(query string, t chronograf.TemplateVar, now time.Time) (stri return query, nil } +func AutoInterval(points int64, duration time.Duration) string { + // The function is: ((total_seconds * millisecond_converstion) / group_by) = pixels / 3 + // Number of points given the pixels + pixels := float64(points) + msPerPixel := float64(duration/time.Millisecond) / pixels + secPerPixel := float64(duration/time.Second) / pixels + if secPerPixel < 1.0 { + if msPerPixel < 1.0 { + msPerPixel = 1.0 + } + return strconv.FormatInt(int64(msPerPixel), 10) + "ms" + } + // If groupby is more than 1 second round to the second + return strconv.FormatInt(int64(secPerPixel), 10) + "s" +} + func AutoGroupBy(resolution, pixelsPerPoint int64, duration time.Duration) string { // The function is: ((total_seconds * millisecond_converstion) / group_by) = pixels / 3 // Number of points given the pixels diff --git a/influx/templates_test.go b/influx/templates_test.go index c1e4d6277..6c1e74c67 100644 --- a/influx/templates_test.go +++ b/influx/templates_test.go @@ -125,6 +125,38 @@ func TestTemplateReplace(t *testing.T) { }, want: `SELECT :field: FROM "cpu"`, }, + { + name: "auto interval", + query: `SELECT mean(usage_idle) from "cpu" where time > now() - 4320h group by time(:interval:)`, + vars: []chronograf.TemplateVar{ + { + Var: ":interval:", + Values: []chronograf.TemplateValue{ + { + Value: "333", + Type: "points", + }, + }, + }, + }, + want: `SELECT mean(usage_idle) from "cpu" where time > now() - 4320h group by time(46702s)`, + }, + { + name: "auto interval", + query: `SELECT derivative(mean(usage_idle),:interval:) from "cpu" where time > now() - 4320h group by time(:interval:)`, + vars: []chronograf.TemplateVar{ + { + Var: ":interval:", + Values: []chronograf.TemplateValue{ + { + Value: "333", + Type: "points", + }, + }, + }, + }, + want: `SELECT derivative(mean(usage_idle),46702s) from "cpu" where time > now() - 4320h group by time(46702s)`, + }, { name: "auto group by", query: `SELECT mean(usage_idle) from "cpu" where time > now() - 4320h group by :interval:`, @@ -133,7 +165,7 @@ func TestTemplateReplace(t *testing.T) { Var: ":interval:", Values: []chronograf.TemplateValue{ { - Value: "1000", + Value: "999", Type: "resolution", }, { @@ -143,7 +175,7 @@ func TestTemplateReplace(t *testing.T) { }, }, }, - want: `SELECT mean(usage_idle) from "cpu" where time > now() - 4320h group by time(46655s)`, + want: `SELECT mean(usage_idle) from "cpu" where time > now() - 4320h group by time(46702s)`, }, { name: "auto group by without duration", @@ -153,7 +185,7 @@ func TestTemplateReplace(t *testing.T) { Var: ":interval:", Values: []chronograf.TemplateValue{ { - Value: "1000", + Value: "999", Type: "resolution", }, { @@ -163,7 +195,7 @@ func TestTemplateReplace(t *testing.T) { }, }, }, - want: `SELECT mean(usage_idle) from "cpu" WHERE time > now() - 4320h group by time(46655s)`, + want: `SELECT mean(usage_idle) from "cpu" WHERE time > now() - 4320h group by time(46702s)`, }, { name: "auto group by with :dashboardTime:", From 30fc37d47b8bd799063878e412ad82b3d6e46685 Mon Sep 17 00:00:00 2001 From: Deniz Kusefoglu Date: Fri, 23 Feb 2018 12:32:14 -0800 Subject: [PATCH 3/5] WIP Frontend interval values from ppp and resolution to points --- ui/src/dashboards/containers/DashboardPage.js | 20 +----------- ui/src/data_explorer/components/Table.js | 2 +- ui/src/data_explorer/components/VisHeader.js | 2 +- ui/src/data_explorer/constants/index.js | 13 -------- .../data_explorer/containers/DataExplorer.js | 14 ++++---- ui/src/shared/components/AutoRefresh.js | 32 ++++++++++++------- ui/src/shared/constants/index.js | 14 ++++++++ 7 files changed, 45 insertions(+), 52 deletions(-) diff --git a/ui/src/dashboards/containers/DashboardPage.js b/ui/src/dashboards/containers/DashboardPage.js index 4cb268ec0..094cb0a43 100644 --- a/ui/src/dashboards/containers/DashboardPage.js +++ b/ui/src/dashboards/containers/DashboardPage.js @@ -26,6 +26,7 @@ import { templateControlBarVisibilityToggled as templateControlBarVisibilityToggledAction, } from 'shared/actions/app' import {presentationButtonDispatcher} from 'shared/dispatchers' +import {interval} from 'src/shared/constants' const FORMAT_INFLUXQL = 'influxql' const defaultTimeRange = { @@ -283,25 +284,6 @@ class DashboardPage extends Component { ], } - const interval = { - id: 'interval', - type: 'autoGroupBy', - tempVar: ':interval:', - label: 'automatically determine the best group by time', - values: [ - { - value: '1000', // pixels - type: 'resolution', - selected: true, - }, - { - value: '3', - type: 'pointsPerPixel', - selected: true, - }, - ], - } - let templatesIncludingDashTime if (dashboard) { templatesIncludingDashTime = [ diff --git a/ui/src/data_explorer/components/Table.js b/ui/src/data_explorer/components/Table.js index 86b9d38c4..aeab7c975 100644 --- a/ui/src/data_explorer/components/Table.js +++ b/ui/src/data_explorer/components/Table.js @@ -7,7 +7,7 @@ import {Table, Column, Cell} from 'fixed-data-table' import Dropdown from 'shared/components/Dropdown' import CustomCell from 'src/data_explorer/components/CustomCell' import TabItem from 'src/data_explorer/components/TableTabItem' -import {TEMPLATES} from 'src/data_explorer/constants' +import {TEMPLATES} from 'src/shared/constants' import {fetchTimeSeriesAsync} from 'shared/actions/timeSeries' diff --git a/ui/src/data_explorer/components/VisHeader.js b/ui/src/data_explorer/components/VisHeader.js index 478f0a38b..f601668db 100644 --- a/ui/src/data_explorer/components/VisHeader.js +++ b/ui/src/data_explorer/components/VisHeader.js @@ -5,7 +5,7 @@ import _ from 'lodash' import {fetchTimeSeriesAsync} from 'shared/actions/timeSeries' import {resultsToCSV} from 'src/shared/parsing/resultsToCSV.js' import download from 'src/external/download.js' -import {TEMPLATES} from 'src/data_explorer/constants' +import {TEMPLATES} from 'src/shared/constants' const getCSV = (query, errorThrown) => async () => { try { diff --git a/ui/src/data_explorer/constants/index.js b/ui/src/data_explorer/constants/index.js index e6e94c4f9..c6e9bf076 100644 --- a/ui/src/data_explorer/constants/index.js +++ b/ui/src/data_explorer/constants/index.js @@ -81,16 +81,3 @@ export const QUERY_TEMPLATES = [ {text: 'Show Stats', query: 'SHOW STATS'}, {text: 'Show Diagnostics', query: 'SHOW DIAGNOSTICS'}, ] - -const interval = { - id: 'interval', - type: 'autoGroupBy', - tempVar: ':interval:', - label: 'automatically determine the best group by time', - values: [ - {value: '1000', type: 'resolution', selected: true}, - {value: '3', type: 'pointsPerPixel', selected: true}, - ], -} // pixels - -export const TEMPLATES = [interval] diff --git a/ui/src/data_explorer/containers/DataExplorer.js b/ui/src/data_explorer/containers/DataExplorer.js index 8ddc15376..e5627d778 100644 --- a/ui/src/data_explorer/containers/DataExplorer.js +++ b/ui/src/data_explorer/containers/DataExplorer.js @@ -6,16 +6,16 @@ import queryString from 'query-string' import _ from 'lodash' -import QueryMaker from '../components/QueryMaker' -import Visualization from '../components/Visualization' +import QueryMaker from 'src/data_explorer/components/QueryMaker' +import Visualization from 'src/data_explorer/components/Visualization' import WriteDataForm from 'src/data_explorer/components/WriteDataForm' -import Header from '../containers/Header' -import ResizeContainer from 'shared/components/ResizeContainer' -import OverlayTechnologies from 'shared/components/OverlayTechnologies' +import Header from 'src/data_explorer/containers/Header' +import ResizeContainer from 'src/shared/components/ResizeContainer' +import OverlayTechnologies from 'src/shared/components/OverlayTechnologies' import ManualRefresh from 'src/shared/components/ManualRefresh' -import {VIS_VIEWS, AUTO_GROUP_BY} from 'shared/constants' -import {MINIMUM_HEIGHTS, INITIAL_HEIGHTS, TEMPLATES} from '../constants' +import {VIS_VIEWS, AUTO_GROUP_BY, TEMPLATES} from 'src/shared/constants' +import {MINIMUM_HEIGHTS, INITIAL_HEIGHTS} from 'src/data_explorer/constants' import {errorThrown} from 'shared/actions/errors' import {setAutoRefresh} from 'shared/actions/app' import * as dataExplorerActionCreators from 'src/data_explorer/actions/view' diff --git a/ui/src/shared/components/AutoRefresh.js b/ui/src/shared/components/AutoRefresh.js index 003f1c157..1cf6106ca 100644 --- a/ui/src/shared/components/AutoRefresh.js +++ b/ui/src/shared/components/AutoRefresh.js @@ -3,6 +3,7 @@ import _ from 'lodash' import {fetchTimeSeriesAsync} from 'shared/actions/timeSeries' import {removeUnselectedTemplateValues} from 'src/dashboards/constants' +import {intervalValuesPoints} from 'src/shared/constants' const AutoRefresh = ComposedComponent => { class wrapper extends Component { @@ -78,31 +79,39 @@ const AutoRefresh = ComposedComponent => { const timeSeriesPromises = queries.map(query => { const {host, database, rp} = query - const templatesWithResolution = templates.map(temp => { + const templatesWithIntervalVals = templates.map(temp => { if (temp.tempVar === ':interval:') { if (resolution) { + // resize event return { ...temp, - values: temp.values.map( - v => (temp.type === 'resolution' ? {...v, resolution} : v) - ), + values: temp.values.map(v => { + if (v.type === 'resolution') { + return {...v, value: `${resolution}`} + } + if (v.type === 'points') { + return { + ...v, + value: `${_.toInteger(Number(resolution) / 3)}`, + } + } + return v + }), } } return { ...temp, - values: [ - ...temp.values, - {value: '1000', type: 'resolution', selected: true}, - ], + values: intervalValuesPoints, } } - return temp }) - const tempVars = removeUnselectedTemplateValues(templatesWithResolution) - + const tempVars = removeUnselectedTemplateValues( + templatesWithIntervalVals + ) + console.log(tempVars) return fetchTimeSeriesAsync( { source: host, @@ -120,6 +129,7 @@ const AutoRefresh = ComposedComponent => { const timeSeries = await Promise.all(timeSeriesPromises) const newSeries = timeSeries.map(response => ({response})) const lastQuerySuccessful = this._resultsForQuery(newSeries) + console.log(newSeries) this.setState({ timeSeries: newSeries, diff --git a/ui/src/shared/constants/index.js b/ui/src/shared/constants/index.js index 63d64e782..2d387df13 100644 --- a/ui/src/shared/constants/index.js +++ b/ui/src/shared/constants/index.js @@ -424,4 +424,18 @@ export const DEFAULT_SOURCE = { metaUrl: '', } +export const intervalValuesPoints = [ + {value: '333', type: 'points', selected: true}, +] + +export const interval = { + id: 'interval', + type: 'autoGroupBy', + tempVar: ':interval:', + label: 'automatically determine the best group by time', + values: intervalValuesPoints, +} + +export const TEMPLATES = [interval] + export const linksLink = '/chronograf/v1' From c9929d59081f483cba4e1e4453f7ac09121979e5 Mon Sep 17 00:00:00 2001 From: Luke Morris Date: Tue, 27 Feb 2018 16:34:35 -0800 Subject: [PATCH 4/5] Remove logs --- ui/src/shared/components/AutoRefresh.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/ui/src/shared/components/AutoRefresh.js b/ui/src/shared/components/AutoRefresh.js index 1cf6106ca..b9d35f892 100644 --- a/ui/src/shared/components/AutoRefresh.js +++ b/ui/src/shared/components/AutoRefresh.js @@ -111,7 +111,6 @@ const AutoRefresh = ComposedComponent => { const tempVars = removeUnselectedTemplateValues( templatesWithIntervalVals ) - console.log(tempVars) return fetchTimeSeriesAsync( { source: host, @@ -129,7 +128,6 @@ const AutoRefresh = ComposedComponent => { const timeSeries = await Promise.all(timeSeriesPromises) const newSeries = timeSeries.map(response => ({response})) const lastQuerySuccessful = this._resultsForQuery(newSeries) - console.log(newSeries) this.setState({ timeSeries: newSeries, From 63b1848adb850ba4587041af17a3c2cd512ffdb7 Mon Sep 17 00:00:00 2001 From: Luke Morris Date: Tue, 27 Feb 2018 18:02:38 -0800 Subject: [PATCH 5/5] :interval: relies on others, and should always come last --- influx/templates.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/influx/templates.go b/influx/templates.go index 6402fbba3..5bbd885a9 100644 --- a/influx/templates.go +++ b/influx/templates.go @@ -11,6 +11,10 @@ import ( func SortTemplates(ts []chronograf.TemplateVar) []chronograf.TemplateVar { sort.Slice(ts, func(i, j int) bool { + if ts[i].Var == ":interval:" { + return false + } + if len(ts[i].Values) != len(ts[j].Values) { return len(ts[i].Values) < len(ts[j].Values) }