Commit 56825206 by Torkel Ödegaard

feat(graph): more work on graph panel and support for non time series

parent cd270f14
...@@ -180,6 +180,7 @@ function (_, $, coreModule) { ...@@ -180,6 +180,7 @@ function (_, $, coreModule) {
value: option ? option.text : value, value: option ? option.text : value,
selectMode: attrs.selectMode, selectMode: attrs.selectMode,
}; };
return uiSegmentSrv.newSegment(segment); return uiSegmentSrv.newSegment(segment);
}; };
......
...@@ -49,9 +49,15 @@ ...@@ -49,9 +49,15 @@
</div> </div>
<!-- Table mode --> <!-- Table mode -->
<div class="gf-form" ng-if="ctrl.panel.xaxis.mode === 'custom'"> <div class="gf-form" ng-if="ctrl.panel.xaxis.mode === 'field'">
<label class="gf-form-label width-5">Name</label> <label class="gf-form-label width-5">Name</label>
<metric-segment-model property="ctrl.panel.xaxis.name" get-options="ctrl.getDataPropertyNames()" on-change="ctrl.xAxisOptionChanged()" custom="false" css-class="width-10" select-mode="true"></metric-segment-model> <metric-segment-model property="ctrl.panel.xaxis.name" get-options="ctrl.getDataFieldNames(false)" on-change="ctrl.xAxisOptionChanged()" custom="false" css-class="width-10" select-mode="true"></metric-segment-model>
</div>
<!-- Series mode -->
<div class="gf-form" ng-if="ctrl.panel.xaxis.mode === 'field'">
<label class="gf-form-label width-5">Value</label>
<metric-segment-model property="ctrl.panel.xaxis.values[0]" get-options="ctrl.getDataFieldNames(true)" on-change="ctrl.xAxisOptionChanged()" custom="false" css-class="width-10" select-mode="true"></metric-segment-model>
</div> </div>
<!-- Series mode --> <!-- Series mode -->
......
...@@ -30,7 +30,7 @@ export class AxesEditorCtrl { ...@@ -30,7 +30,7 @@ export class AxesEditorCtrl {
this.xAxisModes = { this.xAxisModes = {
'Time': 'time', 'Time': 'time',
'Series': 'series', 'Series': 'series',
'Custom': 'custom' 'Data field': 'field',
}; };
this.xAxisStatOptions = [ this.xAxisStatOptions = [
...@@ -58,37 +58,15 @@ export class AxesEditorCtrl { ...@@ -58,37 +58,15 @@ export class AxesEditorCtrl {
} }
xAxisOptionChanged() { xAxisOptionChanged() {
switch (this.panel.xaxis.mode) { this.panelCtrl.processor.setPanelDefaultsForNewXAxisMode();
case 'time': { this.panelCtrl.onDataReceived(this.panelCtrl.dataList);
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;
}
}
} }
getDataPropertyNames() { getDataFieldNames(onlyNumbers) {
var props = this.panelCtrl.processor.getDocProperties(this.panelCtrl.dataList); var props = this.panelCtrl.processor.getDataFieldNames(this.panelCtrl.dataList, onlyNumbers);
var items = props.map(prop => { var items = props.map(prop => {
return {text: prop}; return {text: prop, value: prop};
}); });
console.log(items);
return this.$q.when(items); return this.$q.when(items);
} }
......
...@@ -21,22 +21,60 @@ export class DataProcessor { ...@@ -21,22 +21,60 @@ export class DataProcessor {
var firstItem; var firstItem;
if (options.dataList && options.dataList.length > 0) { if (options.dataList && options.dataList.length > 0) {
firstItem = options.dataList[0]; firstItem = options.dataList[0];
if (firstItem.type === 'docs') { let autoDetectMode = this.getAutoDetectXAxisMode(firstItem);
this.panel.xaxis.mode = 'custom'; if (this.panel.xaxis.mode !== autoDetectMode) {
this.panel.xaxis.mode = autoDetectMode;
this.setPanelDefaultsForNewXAxisMode();
} }
} }
switch (this.panel.xaxis.mode) { switch (this.panel.xaxis.mode) {
case 'series': case 'series':
case 'time': { case 'time': {
return options.dataList.map(this.timeSeriesHandler.bind(this)); return options.dataList.map(this.timeSeriesHandler.bind(this));
} }
case 'custom': { case 'field': {
return this.customHandler(firstItem); 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) { seriesHandler(seriesData, index, datapoints, alias) {
var colorIndex = index % colors.length; var colorIndex = index % colors.length;
var color = this.panel.aliasColors[alias] || colors[colorIndex]; var color = this.panel.aliasColors[alias] || colors[colorIndex];
...@@ -71,21 +109,21 @@ export class DataProcessor { ...@@ -71,21 +109,21 @@ export class DataProcessor {
throw {message: 'No field name specified to use for x-axis, check your axes settings'}; throw {message: 'No field name specified to use for x-axis, check your axes settings'};
} }
// let valueField = this.panel.xaxis.esValueField; // let valueField = this.panel.xaxis.esValueField;
// let datapoints = _.map(seriesData.datapoints, (doc) => { // let datapoints = _.map(seriesData.datapoints, (doc) => {
// return [ // return [
// pluckDeep(doc, valueField), // Y value // pluckDeep(doc, valueField), // Y value
// pluckDeep(doc, xField) // X value // pluckDeep(doc, xField) // X value
// ]; // ];
// }); // });
// //
// // Remove empty points // // Remove empty points
// datapoints = _.filter(datapoints, (point) => { // datapoints = _.filter(datapoints, (point) => {
// return point[0] !== undefined; // return point[0] !== undefined;
// }); // });
// //
// var alias = valueField; // var alias = valueField;
// re // re
return []; return [];
} }
...@@ -142,18 +180,37 @@ export class DataProcessor { ...@@ -142,18 +180,37 @@ export class DataProcessor {
} }
} }
getDocProperties(dataList) { getDataFieldNames(dataList, onlyNumbers) {
if (dataList.length === 0) { if (dataList.length === 0) {
return []; return [];
} }
let fields = [];
var firstItem = dataList[0]; var firstItem = dataList[0];
if (firstItem.type === 'docs'){ if (firstItem.type === 'docs'){
if (firstItem.datapoints.length === 0) { if (firstItem.datapoints.length === 0) {
return []; 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 { ...@@ -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) { pluckDeep(obj: any, property: string) {
let propertyParts = property.split('.'); let propertyParts = property.split('.');
let value = obj; let value = obj;
......
...@@ -258,29 +258,26 @@ function (angular, $, moment, _, kbn, GraphTooltip, thresholdManExports) { ...@@ -258,29 +258,26 @@ function (angular, $, moment, _, kbn, GraphTooltip, thresholdManExports) {
} }
} }
if (panel.xaxis.mode === 'series') { switch(panel.xaxis.mode) {
if (data.length) { case 'series': {
options.series.bars.barWidth = 0.7; options.series.bars.barWidth = 0.7;
options.series.bars.align = 'center'; options.series.bars.align = 'center';
addXSeriesAxis(options);
break;
} }
case 'table': {
addXSeriesAxis(options);
} else if (panel.xaxis.mode === 'table' ||
panel.xaxis.mode === 'elastic') {
if (data.length) {
options.series.bars.barWidth = 0.7; options.series.bars.barWidth = 0.7;
options.series.bars.align = 'center'; options.series.bars.align = 'center';
addXTableAxis(options);
break;
} }
default: {
addXTableAxis(options); if (data.length && data[0].stats.timeStep) {
options.series.bars.barWidth = data[0].stats.timeStep / 1.5;
} else { }
if (data.length && data[0].stats.timeStep) { addTimeAxis(options);
options.series.bars.barWidth = data[0].stats.timeStep / 1.5; break;
} }
addTimeAxis(options);
} }
thresholdManager.addPlotOptions(options, panel); thresholdManager.addPlotOptions(options, panel);
......
...@@ -28,11 +28,37 @@ describe('Graph DataProcessor', function() { ...@@ -28,11 +28,37 @@ describe('Graph DataProcessor', function() {
}); });
}); });
it('Should automatically set xaxis mode to custom', () => { it('Should automatically set xaxis mode to field', () => {
expect(panel.xaxis.mode).to.be('custom'); 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');
});
});
}); });
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