From 5682520603dfa886e78a1cf4d2caa968334d6b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 24 Sep 2016 13:08:58 +0200 Subject: [PATCH] feat(graph): more work on graph panel and support for non time series --- public/app/core/directives/metric_segment.js | 1 + .../app/plugins/panel/graph/axes_editor.html | 10 +- public/app/plugins/panel/graph/axes_editor.ts | 34 +---- .../app/plugins/panel/graph/data_processor.ts | 120 ++++++++++++------ public/app/plugins/panel/graph/graph.js | 29 ++--- .../panel/graph/specs/data_processor_specs.ts | 30 ++++- 6 files changed, 134 insertions(+), 90 deletions(-) diff --git a/public/app/core/directives/metric_segment.js b/public/app/core/directives/metric_segment.js index 98921753997..381f9110c65 100644 --- a/public/app/core/directives/metric_segment.js +++ b/public/app/core/directives/metric_segment.js @@ -180,6 +180,7 @@ function (_, $, coreModule) { value: option ? option.text : value, selectMode: attrs.selectMode, }; + return uiSegmentSrv.newSegment(segment); }; diff --git a/public/app/plugins/panel/graph/axes_editor.html b/public/app/plugins/panel/graph/axes_editor.html index 74af39aa4ed..4c89b5b8b73 100644 --- a/public/app/plugins/panel/graph/axes_editor.html +++ b/public/app/plugins/panel/graph/axes_editor.html @@ -49,9 +49,15 @@ -
+
- + +
+ + +
+ +
diff --git a/public/app/plugins/panel/graph/axes_editor.ts b/public/app/plugins/panel/graph/axes_editor.ts index d943d2c2c1f..591cfba4f17 100644 --- a/public/app/plugins/panel/graph/axes_editor.ts +++ b/public/app/plugins/panel/graph/axes_editor.ts @@ -30,7 +30,7 @@ export class AxesEditorCtrl { this.xAxisModes = { 'Time': 'time', 'Series': 'series', - 'Custom': 'custom' + 'Data field': 'field', }; this.xAxisStatOptions = [ @@ -58,37 +58,15 @@ export class AxesEditorCtrl { } xAxisOptionChanged() { - switch (this.panel.xaxis.mode) { - case 'time': { - this.panel.bars = false; - this.panel.lines = true; - this.panel.points = false; - this.panel.legend.show = true; - this.panel.tooltip.shared = true; - this.panel.xaxis.values = []; - this.panelCtrl.onDataReceived(this.panelCtrl.dataList); - break; - } - case 'series': { - this.panel.bars = true; - this.panel.lines = false; - this.panel.points = false; - this.panel.stack = false; - this.panel.legend.show = false; - this.panel.tooltip.shared = false; - this.panelCtrl.processor.validateXAxisSeriesValue(); - this.panelCtrl.onDataReceived(this.panelCtrl.dataList); - break; - } - } + this.panelCtrl.processor.setPanelDefaultsForNewXAxisMode(); + this.panelCtrl.onDataReceived(this.panelCtrl.dataList); } - getDataPropertyNames() { - var props = this.panelCtrl.processor.getDocProperties(this.panelCtrl.dataList); + getDataFieldNames(onlyNumbers) { + var props = this.panelCtrl.processor.getDataFieldNames(this.panelCtrl.dataList, onlyNumbers); var items = props.map(prop => { - return {text: prop}; + return {text: prop, value: prop}; }); - console.log(items); return this.$q.when(items); } diff --git a/public/app/plugins/panel/graph/data_processor.ts b/public/app/plugins/panel/graph/data_processor.ts index a61e7fa7ffa..b4ff3968fcb 100644 --- a/public/app/plugins/panel/graph/data_processor.ts +++ b/public/app/plugins/panel/graph/data_processor.ts @@ -21,22 +21,60 @@ export class DataProcessor { var firstItem; if (options.dataList && options.dataList.length > 0) { firstItem = options.dataList[0]; - if (firstItem.type === 'docs') { - this.panel.xaxis.mode = 'custom'; + let autoDetectMode = this.getAutoDetectXAxisMode(firstItem); + if (this.panel.xaxis.mode !== autoDetectMode) { + this.panel.xaxis.mode = autoDetectMode; + this.setPanelDefaultsForNewXAxisMode(); } } switch (this.panel.xaxis.mode) { case 'series': - case 'time': { + case 'time': { return options.dataList.map(this.timeSeriesHandler.bind(this)); } - case 'custom': { + case 'field': { return this.customHandler(firstItem); } } } + getAutoDetectXAxisMode(firstItem) { + switch (firstItem.type) { + case 'docs': return 'field'; + case 'table': return 'field'; + default: { + if (this.panel.xaxis.mode === 'series') { + return 'series'; + } + return 'time'; + } + } + } + + setPanelDefaultsForNewXAxisMode() { + switch (this.panel.xaxis.mode) { + case 'time': { + this.panel.bars = false; + this.panel.lines = true; + this.panel.points = false; + this.panel.legend.show = true; + this.panel.tooltip.shared = true; + this.panel.xaxis.values = []; + break; + } + case 'series': { + this.panel.bars = true; + this.panel.lines = false; + this.panel.points = false; + this.panel.stack = false; + this.panel.legend.show = false; + this.panel.tooltip.shared = false; + break; + } + } + } + seriesHandler(seriesData, index, datapoints, alias) { var colorIndex = index % colors.length; var color = this.panel.aliasColors[alias] || colors[colorIndex]; @@ -71,21 +109,21 @@ export class DataProcessor { throw {message: 'No field name specified to use for x-axis, check your axes settings'}; } - // let valueField = this.panel.xaxis.esValueField; - // let datapoints = _.map(seriesData.datapoints, (doc) => { - // return [ - // pluckDeep(doc, valueField), // Y value - // pluckDeep(doc, xField) // X value - // ]; - // }); - // - // // Remove empty points - // datapoints = _.filter(datapoints, (point) => { - // return point[0] !== undefined; - // }); - // - // var alias = valueField; - // re + // let valueField = this.panel.xaxis.esValueField; + // let datapoints = _.map(seriesData.datapoints, (doc) => { + // return [ + // pluckDeep(doc, valueField), // Y value + // pluckDeep(doc, xField) // X value + // ]; + // }); + // + // // Remove empty points + // datapoints = _.filter(datapoints, (point) => { + // return point[0] !== undefined; + // }); + // + // var alias = valueField; + // re return []; } @@ -142,18 +180,37 @@ export class DataProcessor { } } - getDocProperties(dataList) { + getDataFieldNames(dataList, onlyNumbers) { if (dataList.length === 0) { return []; } + let fields = []; var firstItem = dataList[0]; if (firstItem.type === 'docs'){ if (firstItem.datapoints.length === 0) { return []; } - return this.getPropertiesFromDoc(firstItem.datapoints[0]); + let fieldParts = []; + + function getPropertiesRecursive(obj) { + _.forEach(obj, (value, key) => { + if (_.isObject(value)) { + fieldParts.push(key); + getPropertiesRecursive(value); + } else { + if (!onlyNumbers || _.isNumber(value)) { + let field = fieldParts.concat(key).join('.'); + fields.push(field); + } + } + }); + fieldParts.pop(); + } + + getPropertiesRecursive(firstItem.datapoints[0]); + return fields; } } @@ -174,27 +231,6 @@ export class DataProcessor { } } - getPropertiesFromDoc(doc) { - let props = []; - let propParts = []; - - function getPropertiesRecursive(obj) { - _.forEach(obj, (value, key) => { - if (_.isObject(value)) { - propParts.push(key); - getPropertiesRecursive(value); - } else { - let field = propParts.concat(key).join('.'); - props.push(field); - } - }); - propParts.pop(); - } - - getPropertiesRecursive(doc); - return props; - } - pluckDeep(obj: any, property: string) { let propertyParts = property.split('.'); let value = obj; diff --git a/public/app/plugins/panel/graph/graph.js b/public/app/plugins/panel/graph/graph.js index 08809d95964..2253798be5d 100755 --- a/public/app/plugins/panel/graph/graph.js +++ b/public/app/plugins/panel/graph/graph.js @@ -258,29 +258,26 @@ function (angular, $, moment, _, kbn, GraphTooltip, thresholdManExports) { } } - if (panel.xaxis.mode === 'series') { - if (data.length) { + switch(panel.xaxis.mode) { + case 'series': { options.series.bars.barWidth = 0.7; options.series.bars.align = 'center'; + addXSeriesAxis(options); + break; } - - addXSeriesAxis(options); - - } else if (panel.xaxis.mode === 'table' || - panel.xaxis.mode === 'elastic') { - if (data.length) { + case 'table': { options.series.bars.barWidth = 0.7; options.series.bars.align = 'center'; + addXTableAxis(options); + break; } - - addXTableAxis(options); - - } else { - if (data.length && data[0].stats.timeStep) { - options.series.bars.barWidth = data[0].stats.timeStep / 1.5; + default: { + if (data.length && data[0].stats.timeStep) { + options.series.bars.barWidth = data[0].stats.timeStep / 1.5; + } + addTimeAxis(options); + break; } - - addTimeAxis(options); } thresholdManager.addPlotOptions(options, panel); diff --git a/public/app/plugins/panel/graph/specs/data_processor_specs.ts b/public/app/plugins/panel/graph/specs/data_processor_specs.ts index 6d6e28b3629..bdc1943e9fb 100644 --- a/public/app/plugins/panel/graph/specs/data_processor_specs.ts +++ b/public/app/plugins/panel/graph/specs/data_processor_specs.ts @@ -28,11 +28,37 @@ describe('Graph DataProcessor', function() { }); }); - it('Should automatically set xaxis mode to custom', () => { - expect(panel.xaxis.mode).to.be('custom'); + it('Should automatically set xaxis mode to field', () => { + expect(panel.xaxis.mode).to.be('field'); }); }); + describe('getDataFieldNames(', () => { + var dataList = [{ + type: 'docs', datapoints: [ + { + hostname: "server1", + valueField: 11, + nested: { + prop1: 'server2', value2: 23} + } + ] + }]; + + it('Should return all field names', () => { + var fields = processor.getDataFieldNames(dataList, false); + expect(fields).to.contain('hostname'); + expect(fields).to.contain('valueField'); + expect(fields).to.contain('nested.prop1'); + expect(fields).to.contain('nested.value2'); + }); + + it('Should return all number fields', () => { + var fields = processor.getDataFieldNames(dataList, true); + expect(fields).to.contain('valueField'); + expect(fields).to.contain('nested.value2'); + }); + }); });