diff --git a/public/app/plugins/datasource/graphite/func_editor.js b/public/app/plugins/datasource/graphite/func_editor.js index 57cdc844375..534b0886fff 100644 --- a/public/app/plugins/datasource/graphite/func_editor.js +++ b/public/app/plugins/datasource/graphite/func_editor.js @@ -208,7 +208,7 @@ function (angular, _, $) { if ($target.hasClass('fa-arrow-left')) { $scope.$apply(function() { - _.move(ctrl.functions, $scope.$index, $scope.$index - 1); + _.move(ctrl.queryModel.functions, $scope.$index, $scope.$index - 1); ctrl.targetChanged(); }); return; @@ -216,7 +216,7 @@ function (angular, _, $) { if ($target.hasClass('fa-arrow-right')) { $scope.$apply(function() { - _.move(ctrl.functions, $scope.$index, $scope.$index + 1); + _.move(ctrl.queryModel.functions, $scope.$index, $scope.$index + 1); ctrl.targetChanged(); }); return; diff --git a/public/app/plugins/datasource/graphite/graphite_query.ts b/public/app/plugins/datasource/graphite/graphite_query.ts index 2a70667fdac..54504219dad 100644 --- a/public/app/plugins/datasource/graphite/graphite_query.ts +++ b/public/app/plugins/datasource/graphite/graphite_query.ts @@ -46,7 +46,7 @@ export default class GraphiteQuery { } try { - this.parseTargetRecursive(astNode, null, 0); + this.parseTargetRecursive(astNode, null); } catch (err) { console.log('error parsing target:', err.message); this.error = err.message; @@ -75,7 +75,7 @@ export default class GraphiteQuery { }, ""); } - parseTargetRecursive(astNode, func, index) { + parseTargetRecursive(astNode, func) { if (astNode === null) { return null; } @@ -83,42 +83,35 @@ export default class GraphiteQuery { switch (astNode.type) { case 'function': var innerFunc = gfunc.createFuncInstance(astNode.name, { withDefaultParams: false }); - _.each(astNode.params, (param, index) => { - this.parseTargetRecursive(param, innerFunc, index); + _.each(astNode.params, param => { + this.parseTargetRecursive(param, innerFunc); }); innerFunc.updateText(); this.functions.push(innerFunc); break; case 'series-ref': - this.addFunctionParameter(func, astNode.value, index, this.segments.length > 0); + if (this.segments.length > 0) { + this.addFunctionParameter(func, astNode.value); + } else { + this.segments.push(astNode); + } break; case 'bool': case 'string': case 'number': - if ((index-1) >= func.def.params.length) { - throw { message: 'invalid number of parameters to method ' + func.def.name }; - } - var shiftBack = this.isShiftParamsBack(func); - this.addFunctionParameter(func, astNode.value, index, shiftBack); - break; + this.addFunctionParameter(func, astNode.value); + break; case 'metric': if (this.segments.length > 0) { - if (astNode.segments.length !== 1) { - throw { message: 'Multiple metric params not supported, use text editor.' }; + this.addFunctionParameter(func, _.join(_.map(astNode.segments, 'value'), '.')); + } else { + this.segments = astNode.segments; } - this.addFunctionParameter(func, astNode.segments[0].value, index, true); break; - } - - this.segments = astNode.segments; } } - isShiftParamsBack(func) { - return func.def.name !== 'seriesByTag'; - } - updateSegmentValue(segment, index) { this.segments[index].value = segment.value; } @@ -145,11 +138,11 @@ export default class GraphiteQuery { } } - addFunctionParameter(func, value, index, shiftBack) { - if (shiftBack) { - index = Math.max(index - 1, 0); + addFunctionParameter(func, value) { + if (func.params.length >= func.def.params.length) { + throw { message: 'too many parameters for function ' + func.def.name }; } - func.params[index] = value; + func.params.push(value); } removeFunction(func) { @@ -159,7 +152,7 @@ export default class GraphiteQuery { updateModelTarget(targets) { // render query if (!this.target.textEditor) { - var metricPath = this.getSegmentPathUpTo(this.segments.length); + var metricPath = this.getSegmentPathUpTo(this.segments.length).replace(/\.select metric$/, ''); this.target.target = _.reduce(this.functions, wrapFunction, metricPath); } diff --git a/public/app/plugins/datasource/graphite/query_ctrl.ts b/public/app/plugins/datasource/graphite/query_ctrl.ts index c14836b4bdd..d00ac90fe65 100644 --- a/public/app/plugins/datasource/graphite/query_ctrl.ts +++ b/public/app/plugins/datasource/graphite/query_ctrl.ts @@ -62,6 +62,10 @@ export class GraphiteQueryCtrl extends QueryCtrl { } checkOtherSegments(fromIndex) { + if (this.queryModel.segments.length === 1 && this.queryModel.segments[0].type === 'series-ref') { + return; + } + if (fromIndex === 0) { this.addSelectMetricSegment(); return; @@ -108,8 +112,23 @@ export class GraphiteQueryCtrl extends QueryCtrl { if (altSegments.length === 0) { return altSegments; } + // add query references + if (index === 0) { + _.eachRight(this.panelCtrl.panel.targets, target => { + if (target.refId === this.queryModel.target.refId) { + return; + } + + altSegments.unshift(this.uiSegmentSrv.newSegment({ + type: 'series-ref', + value: '#' + target.refId, + expandable: false, + })); + }); + } + // add template variables - _.each(this.templateSrv.variables, variable => { + _.eachRight(this.templateSrv.variables, variable => { altSegments.unshift(this.uiSegmentSrv.newSegment({ type: 'template', value: '$' + variable.name, @@ -200,10 +219,7 @@ export class GraphiteQueryCtrl extends QueryCtrl { this.updateModelTarget(); if (this.queryModel.target !== oldTarget) { - var lastSegment = this.segments.length > 0 ? this.segments[this.segments.length - 1] : {}; - if (lastSegment.value !== 'select metric') { - this.panelCtrl.refresh(); - } + this.panelCtrl.refresh(); } } diff --git a/public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts b/public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts index 177c1e2a0d6..86c32c3c018 100644 --- a/public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts +++ b/public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts @@ -95,11 +95,11 @@ describe('GraphiteQueryCtrl', function() { }); it('should not add select metric segment', function() { - expect(ctx.ctrl.segments.length).to.be(0); + expect(ctx.ctrl.segments.length).to.be(1); }); - it('should add both series refs as params', function() { - expect(ctx.ctrl.queryModel.functions[0].params.length).to.be(2); + it('should add second series ref as param', function() { + expect(ctx.ctrl.queryModel.functions[0].params.length).to.be(1); }); }); @@ -170,7 +170,7 @@ describe('GraphiteQueryCtrl', function() { describe('when updating targets with nested query', function() { beforeEach(function() { - ctx.ctrl.target.target = 'scaleToSeconds(#A)'; + ctx.ctrl.target.target = 'scaleToSeconds(#A, 60)'; ctx.ctrl.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([{expandable: false}])); ctx.ctrl.parseTarget(); @@ -183,11 +183,11 @@ describe('GraphiteQueryCtrl', function() { }); it('target should remain the same', function() { - expect(ctx.ctrl.target.target).to.be('scaleToSeconds(#A)'); + expect(ctx.ctrl.target.target).to.be('scaleToSeconds(#A, 60)'); }); it('targetFull should include nexted queries', function() { - expect(ctx.ctrl.target.targetFull).to.be('scaleToSeconds(nested.query.count)'); + expect(ctx.ctrl.target.targetFull).to.be('scaleToSeconds(nested.query.count, 60)'); }); });