Commit c3bd07f9 by Torkel Ödegaard

testdata: added manual entry mode to test data

parent fec37f22
package testdata package testdata
import ( import (
"encoding/json"
"math/rand" "math/rand"
"strconv" "strconv"
"strings" "strings"
...@@ -143,6 +144,45 @@ func init() { ...@@ -143,6 +144,45 @@ func init() {
}) })
registerScenario(&Scenario{ registerScenario(&Scenario{
Id: "manual_entry",
Name: "Manual Entry",
Handler: func(query *tsdb.Query, context *tsdb.TsdbQuery) *tsdb.QueryResult {
queryRes := tsdb.NewQueryResult()
points := query.Model.Get("points").MustArray()
series := newSeriesForQuery(query)
startTime := context.TimeRange.GetFromAsMsEpoch()
endTime := context.TimeRange.GetToAsMsEpoch()
for _, val := range points {
pointValues := val.([]interface{})
var value null.Float
var time int64
if valueFloat, err := strconv.ParseFloat(string(pointValues[0].(json.Number)), 64); err == nil {
value = null.FloatFrom(valueFloat)
}
if timeInt, err := strconv.ParseInt(string(pointValues[1].(json.Number)), 10, 64); err != nil {
continue
} else {
time = timeInt
}
if time >= startTime && time <= endTime {
series.Points = append(series.Points, tsdb.NewTimePoint(value, float64(time)))
}
}
queryRes.Series = append(queryRes.Series, series)
return queryRes
},
})
registerScenario(&Scenario{
Id: "csv_metric_values", Id: "csv_metric_values",
Name: "CSV Metric Values", Name: "CSV Metric Values",
StringInput: "1,20,90,30,5,0", StringInput: "1,20,90,30,5,0",
......
///<reference path="../../../headers/common.d.ts" />
import moment from 'moment'; import moment from 'moment';
import * as dateMath from 'app/core/utils/datemath'; import * as dateMath from 'app/core/utils/datemath';
...@@ -7,16 +5,16 @@ export function inputDateDirective() { ...@@ -7,16 +5,16 @@ export function inputDateDirective() {
return { return {
restrict: 'A', restrict: 'A',
require: 'ngModel', require: 'ngModel',
link: function ($scope, $elem, attrs, ngModel) { link: function($scope, $elem, attrs, ngModel) {
var format = 'YYYY-MM-DD HH:mm:ss'; var format = 'YYYY-MM-DD HH:mm:ss';
var fromUser = function (text) { var fromUser = function(text) {
if (text.indexOf('now') !== -1) { if (text.indexOf('now') !== -1) {
if (!dateMath.isValid(text)) { if (!dateMath.isValid(text)) {
ngModel.$setValidity("error", false); ngModel.$setValidity('error', false);
return undefined; return undefined;
} }
ngModel.$setValidity("error", true); ngModel.$setValidity('error', true);
return text; return text;
} }
...@@ -28,15 +26,15 @@ export function inputDateDirective() { ...@@ -28,15 +26,15 @@ export function inputDateDirective() {
} }
if (!parsed.isValid()) { if (!parsed.isValid()) {
ngModel.$setValidity("error", false); ngModel.$setValidity('error', false);
return undefined; return undefined;
} }
ngModel.$setValidity("error", true); ngModel.$setValidity('error', true);
return parsed; return parsed;
}; };
var toUser = function (currentValue) { var toUser = function(currentValue) {
if (moment.isMoment(currentValue)) { if (moment.isMoment(currentValue)) {
return currentValue.format(format); return currentValue.format(format);
} else { } else {
...@@ -46,7 +44,6 @@ export function inputDateDirective() { ...@@ -46,7 +44,6 @@ export function inputDateDirective() {
ngModel.$parsers.push(fromUser); ngModel.$parsers.push(fromUser);
ngModel.$formatters.push(toUser); ngModel.$formatters.push(toUser);
} },
}; };
} }
///<reference path="../../../../headers/common.d.ts" />
import _ from 'lodash'; import _ from 'lodash';
import angular from 'angular';
class TestDataDatasource { class TestDataDatasource {
id: any; id: any;
...@@ -21,7 +18,8 @@ class TestDataDatasource { ...@@ -21,7 +18,8 @@ class TestDataDatasource {
intervalMs: options.intervalMs, intervalMs: options.intervalMs,
maxDataPoints: options.maxDataPoints, maxDataPoints: options.maxDataPoints,
stringInput: item.stringInput, stringInput: item.stringInput,
jsonInput: angular.fromJson(item.jsonInput), points: item.points,
alias: item.alias,
datasourceId: this.id, datasourceId: this.id,
}; };
}); });
......
///<reference path="../../../../headers/common.d.ts" />
import {TestDataDatasource} from './datasource'; import {TestDataDatasource} from './datasource';
import {TestDataQueryCtrl} from './query_ctrl'; import {TestDataQueryCtrl} from './query_ctrl';
......
///<reference path="../../../../headers/common.d.ts" />
import _ from 'lodash'; import _ from 'lodash';
import {QueryCtrl} from 'app/plugins/sdk'; import { QueryCtrl } from 'app/plugins/sdk';
import moment from 'moment';
export class TestDataQueryCtrl extends QueryCtrl { export class TestDataQueryCtrl extends QueryCtrl {
static templateUrl = 'partials/query.editor.html'; static templateUrl = 'partials/query.editor.html';
scenarioList: any; scenarioList: any;
scenario: any; scenario: any;
newPointValue: number;
newPointTime: any;
selectedPoint: any;
/** @ngInject **/ /** @ngInject **/
constructor($scope, $injector, private backendSrv) { constructor($scope, $injector, private backendSrv) {
...@@ -16,19 +18,53 @@ export class TestDataQueryCtrl extends QueryCtrl { ...@@ -16,19 +18,53 @@ export class TestDataQueryCtrl extends QueryCtrl {
this.target.scenarioId = this.target.scenarioId || 'random_walk'; this.target.scenarioId = this.target.scenarioId || 'random_walk';
this.scenarioList = []; this.scenarioList = [];
this.newPointTime = moment();
this.selectedPoint = { text: 'Select point', value: null };
}
getPoints() {
return _.map(this.target.points, (point, index) => {
return {
text: moment(point[1]).format('MMMM Do YYYY, H:mm:ss') + ' : ' + point[0],
value: index,
};
});
}
pointSelected(option) {
this.selectedPoint = option;
}
deletePoint() {
this.target.points.splice(this.selectedPoint.value, 1);
this.selectedPoint = { text: 'Select point', value: null };
this.refresh();
}
addPoint() {
this.target.points = this.target.points || [];
this.target.points.push([this.newPointValue, this.newPointTime.valueOf()]);
this.target.points = _.sortBy(this.target.points, p => p[1]);
this.refresh();
} }
$onInit() { $onInit() {
return this.backendSrv.get('/api/tsdb/testdata/scenarios').then(res => { return this.backendSrv.get('/api/tsdb/testdata/scenarios').then(res => {
this.scenarioList = res; this.scenarioList = res;
this.scenario = _.find(this.scenarioList, {id: this.target.scenarioId}); this.scenario = _.find(this.scenarioList, { id: this.target.scenarioId });
}); });
} }
scenarioChanged() { scenarioChanged() {
this.scenario = _.find(this.scenarioList, {id: this.target.scenarioId}); this.scenario = _.find(this.scenarioList, { id: this.target.scenarioId });
this.target.stringInput = this.scenario.stringInput; this.target.stringInput = this.scenario.stringInput;
if (this.target.scenarioId === 'manual_entry') {
this.target.points = this.target.points || [];
} else {
delete this.target.points;
}
this.refresh(); this.refresh();
} }
} }
<query-editor-row query-ctrl="ctrl" has-text-edit-mode="false"> <query-editor-row query-ctrl="ctrl" has-text-edit-mode="false">
<div class="gf-form-inline"> <div class="gf-form-inline">
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label query-keyword">Scenario</label> <label class="gf-form-label query-keyword width-7">Scenario</label>
<div class="gf-form-select-wrapper"> <div class="gf-form-select-wrapper width-15">
<select class="gf-form-input" ng-model="ctrl.target.scenarioId" ng-options="v.id as v.name for v in ctrl.scenarioList" ng-change="ctrl.scenarioChanged()"></select> <select class="gf-form-input" ng-model="ctrl.target.scenarioId" ng-options="v.id as v.name for v in ctrl.scenarioList" ng-change="ctrl.scenarioChanged()"></select>
</div> </div>
</div> </div>
...@@ -18,5 +18,23 @@ ...@@ -18,5 +18,23 @@
<div class="gf-form-label gf-form-label--grow"></div> <div class="gf-form-label gf-form-label--grow"></div>
</div> </div>
</div> </div>
<div class="gf-form-inline" ng-if="ctrl.scenario.id === 'manual_entry'">
<div class="gf-form gf-form">
<label class="gf-form-label query-keyword width-7">New value</label>
<input type="number" class="gf-form-input width-15" placeholder="value" ng-model="ctrl.newPointValue">
<label class="gf-form-label query-keyword">Time</label>
<input type="string" class="gf-form-input width-12" placeholder="time" ng-model="ctrl.newPointTime" input-datetime>
<button class="btn btn-secondary gf-form-btn" ng-click="ctrl.addPoint()">Add</button>
<label class="gf-form-label query-keyword">All values</label>
<gf-form-dropdown css-class="width-12" model="ctrl.selectedPoint" get-options="ctrl.getPoints()" on-change="ctrl.pointSelected($option)">
</gf-form-dropdown>
</div>
<div class="gf-form gf-form" ng-if="ctrl.selectedPoint.value !== null">
<button class="btn btn-danger gf-form-btn" ng-click="ctrl.deletePoint()">Delete</button>
</div>
<div class="gf-form gf-form--grow">
<div class="gf-form-label gf-form-label--grow"></div>
</div>
</div>
</query-editor-row> </query-editor-row>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment