Skip to content

Commit

Permalink
Configurable heatmap maximum bucket number (#39578)
Browse files Browse the repository at this point in the history
* Add visualization:heatmap:maxBuckets to settings (default: 50)

* Use visualization:heatmap:maxBuckets at heatmap (before it was hardcoded)

* Convert heatmap tests from mocha to jest
  • Loading branch information
kertal authored Jul 11, 2019
1 parent b011b9a commit 2f29d5c
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 46 deletions.
13 changes: 13 additions & 0 deletions src/legacy/core_plugins/kibana/ui_setting_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,19 @@ export function getUiSettingDefaults() {
}),
category: ['visualization'],
},
'visualization:heatmap:maxBuckets': {
name: i18n.translate('kbn.advancedSettings.visualization.heatmap.maxBucketsTitle', {
defaultMessage: 'Heatmap maximum buckets',
}),
value: 50,
type: 'number',
description: i18n.translate('kbn.advancedSettings.visualization.heatmap.maxBucketsText', {
defaultMessage:
'The maximum number of buckets a single datasource can return. ' +
'A higher number might have negative impact on browser rendering performance'
}),
category: ['visualization'],
},
'csv:separator': {
name: i18n.translate('kbn.advancedSettings.csv.separatorTitle', {
defaultMessage: 'CSV separator',
Expand Down
41 changes: 0 additions & 41 deletions src/legacy/ui/public/vislib/__tests__/lib/types/point_series.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import ngMock from 'ng_mock';
import expect from '@kbn/expect';
import stackedSeries from 'fixtures/vislib/mock_data/date_histogram/_stacked_series';
import { vislibPointSeriesTypes as pointSeriesConfig } from '../../../lib/types/point_series';
import percentileTestdata from './testdata_linechart_percentile.json';
import percentileTestdataResult from './testdata_linechart_percentile_result.json';
Expand Down Expand Up @@ -47,18 +46,6 @@ describe('Point Series Config Type Class Test Suite', function () {
}]
};

const heatmapConfig = {
type: 'heatmap',
addLegend: true,
addTooltip: true,
colorsNumber: 4,
colorSchema: 'Greens',
setColorRange: false,
percentageMode: true,
invertColors: false,
colorsRange: []
};

const data = {
get: (prop) => { return data[prop] || data.data[prop] || null; },
getLabels: () => [],
Expand Down Expand Up @@ -135,32 +122,4 @@ describe('Point Series Config Type Class Test Suite', function () {
});
});


describe('heatmap chart', function () {
beforeEach(function () {
const stackedData = {
get: (prop) => { return data[prop] || null; },
getLabels: () => [],
data: stackedSeries
};
parsedConfig = pointSeriesConfig.heatmap(heatmapConfig, stackedData);
});

it('should throw an error when more than 25 series are provided', function () {
parsedConfig = pointSeriesConfig.heatmap(heatmapConfig, data);
expect(parsedConfig.error).to.be('There are too many series defined.');
});

it('should not throw an error when less than 25 series are provided', function () {
expect(parsedConfig.error).to.be.undefined;
});

it('should hide first value axis', function () {
expect(parsedConfig.valueAxes[0].show).to.be(false);
});

it('should add second category axis', function () {
expect(parsedConfig.categoryAxes.length).to.equal(2);
});
});
});
14 changes: 10 additions & 4 deletions src/legacy/ui/public/vislib/lib/types/point_series.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import _ from 'lodash';

import { i18n } from '@kbn/i18n';

const createSeriesFromParams = (cfg, seri) => {
//percentile data id format is {mainId}.{percentileValue}, this has to be cleaned
Expand Down Expand Up @@ -203,11 +203,17 @@ export const vislibPointSeriesTypes = {

heatmap: (cfg, data) => {
const defaults = create()(cfg, data);
const seriesLimit = 25;
const hasCharts = defaults.charts.length;
const tooManySeries = defaults.charts.length && defaults.charts[0].series.length > seriesLimit;
const tooManySeries = defaults.charts.length && defaults.charts[0].series.length > cfg.heatmapMaxBuckets;
if (hasCharts && tooManySeries) {
defaults.error = 'There are too many series defined.';
defaults.error = i18n.translate('common.ui.vislib.heatmap.maxBucketsText', {
defaultMessage: 'There are too many series defined ({nr}). The configured maximum is {max}.',
values: {
max: cfg.heatmapMaxBuckets,
nr: defaults.charts[0].series.length
},
description: 'This message appears at heatmap visualizations'
});
}
defaults.valueAxes[0].show = false;
defaults.categoryAxes[0].style = {
Expand Down
108 changes: 108 additions & 0 deletions src/legacy/ui/public/vislib/lib/types/point_series.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import stackedSeries from '../../../../../../fixtures/vislib/mock_data/date_histogram/_stacked_series';
import { vislibPointSeriesTypes } from './point_series';

describe('vislibPointSeriesTypes', () => {
const heatmapConfig = {
type: 'heatmap',
addLegend: true,
addTooltip: true,
colorsNumber: 4,
colorSchema: 'Greens',
setColorRange: false,
percentageMode: true,
invertColors: false,
colorsRange: [],
heatmapMaxBuckets: 20
};

const stackedData = {
get: prop => {
return stackedSeries[prop] || null;
},
getLabels: () => [],
data: stackedSeries,
};

const maxBucketData = {
get: prop => {
return maxBucketData[prop] || maxBucketData.data[prop] || null;
},
getLabels: () => [],
data: {
hits: 621,
ordered: {
date: true,
interval: 30000,
max: 1408734982458,
min: 1408734082458,
},
series: [
{ label: 's1', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's2', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's3', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's4', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's5', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's6', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's7', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's8', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's9', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's10', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's11', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's12', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's13', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's14', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's15', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's16', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's17', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's18', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's19', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's20', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's21', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's22', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's23', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's24', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's25', values: [{ x: 1408734060000, y: 8 }] },
{ label: 's26', values: [{ x: 1408734060000, y: 8 }] },
],
xAxisLabel: 'Date Histogram',
yAxisLabel: 'series',
yAxisFormatter: () => 'test',
},
};

describe('heatmap()', () => {
it('should return an error when more than 20 series are provided', () => {
const parsedConfig = vislibPointSeriesTypes.heatmap(heatmapConfig, maxBucketData);
expect(parsedConfig.error).toMatchInlineSnapshot(
`"There are too many series defined (26). The configured maximum is 20."`
);
});

it('should return valid config when less than 20 series are provided', () => {
const parsedConfig = vislibPointSeriesTypes.heatmap(heatmapConfig, stackedData);
expect(parsedConfig.error).toBeUndefined();
expect(parsedConfig.valueAxes[0].show).toBeFalsy();
expect(parsedConfig.categoryAxes.length).toBe(2);
expect(parsedConfig.error).toBeUndefined();
});

});
});
2 changes: 1 addition & 1 deletion src/legacy/ui/public/vislib/vis.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function VislibVisProvider(Private, config) {
this.el = $el.get ? $el.get(0) : $el;
this.visConfigArgs = _.cloneDeep(visConfigArgs);
this.visConfigArgs.dimmingOpacity = config.get('visualization:dimmingOpacity');

this.visConfigArgs.heatmapMaxBuckets = config.get('visualization:heatmap:maxBuckets');
}

hasLegend() {
Expand Down

0 comments on commit 2f29d5c

Please sign in to comment.