mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
parent
c0b715dde7
commit
f1b1d9e043
6 changed files with 2084 additions and 5 deletions
|
@ -0,0 +1,230 @@
|
|||
import expect from 'expect.js';
|
||||
import ngMock from 'ng_mock';
|
||||
import { CoordinateMapsVisualizationProvider } from '../coordinate_maps_visualization';
|
||||
import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern';
|
||||
import * as visModule from 'ui/vis';
|
||||
import { ImageComparator } from 'test_utils/image_comparator';
|
||||
import sinon from 'sinon';
|
||||
import dummyESResponse from './dummy_es_response.json';
|
||||
import initial from './initial.png';
|
||||
import heatmapRaw from './heatmap_raw.png';
|
||||
|
||||
function mockRawData() {
|
||||
const stack = [dummyESResponse];
|
||||
let node;
|
||||
do {
|
||||
node = stack.pop();
|
||||
if (typeof node === 'object') {
|
||||
for (const key in node) {
|
||||
if (node.hasOwnProperty(key)) {
|
||||
if (key === 'aggConfig') {
|
||||
node[key].makeLabel = () => 'foobar';
|
||||
}
|
||||
}
|
||||
stack.push(node[key]);
|
||||
}
|
||||
}
|
||||
} while (stack.length);
|
||||
}
|
||||
mockRawData();
|
||||
|
||||
|
||||
const manifestUrl = 'https://staging-dot-catalogue-dot-elastic-layer.appspot.com/v1/manifest';
|
||||
const tmsManifestUrl = `"https://tiles-maps-stage.elastic.co/v2/manifest`;
|
||||
const manifest = {
|
||||
'services': [{
|
||||
'id': 'tiles_v2',
|
||||
'name': 'Elastic Tile Service',
|
||||
'manifest': tmsManifestUrl,
|
||||
'type': 'tms'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const tmsManifest = {
|
||||
'services': [{
|
||||
'id': 'road_map',
|
||||
'url': 'https://tiles.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana',
|
||||
'minZoom': 0,
|
||||
'maxZoom': 10,
|
||||
'attribution': '© [OpenStreetMap](http://www.openstreetmap.org/copyright) © [Elastic Maps Service](https://www.elastic.co/elastic-maps-service)'
|
||||
}]
|
||||
};
|
||||
|
||||
|
||||
const THRESHOLD = 0.45;
|
||||
const PIXEL_DIFF = 64;
|
||||
|
||||
describe('CoordinateMapsVisualizationTest', function () {
|
||||
|
||||
let domNode;
|
||||
let CoordinateMapsVisualization;
|
||||
let Vis;
|
||||
let indexPattern;
|
||||
let vis;
|
||||
|
||||
let imageComparator;
|
||||
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject((Private, $injector) => {
|
||||
|
||||
Vis = Private(visModule.VisProvider);
|
||||
CoordinateMapsVisualization = Private(CoordinateMapsVisualizationProvider);
|
||||
indexPattern = Private(LogstashIndexPatternStubProvider);
|
||||
|
||||
|
||||
const serviceSettings = $injector.get('serviceSettings');
|
||||
sinon.stub(serviceSettings, '_getManifest', function (url) {
|
||||
let contents = null;
|
||||
if (url.startsWith(tmsManifestUrl)) {
|
||||
contents = tmsManifest;
|
||||
} else if (url.startsWith(manifestUrl)) {
|
||||
contents = manifest;
|
||||
}
|
||||
return {
|
||||
data: contents
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
}));
|
||||
|
||||
describe('CoordinateMapsVisualization - basics', function () {
|
||||
|
||||
beforeEach(async function () {
|
||||
|
||||
setupDOM('512px', '512px');
|
||||
|
||||
imageComparator = new ImageComparator();
|
||||
vis = new Vis(indexPattern, {
|
||||
type: 'region_map'
|
||||
});
|
||||
vis.params = {
|
||||
mapType: 'Scaled Circle Markers',
|
||||
isDesaturated: true,
|
||||
addTooltip: true,
|
||||
heatClusterSize: 1.5,
|
||||
legendPosition: 'bottomright',
|
||||
mapZoom: 2,
|
||||
mapCenter: [0, 0],
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
teardownDOM();
|
||||
imageComparator.destroy();
|
||||
});
|
||||
|
||||
it('should initialize OK', async function () {
|
||||
const coordinateMapVisualization = new CoordinateMapsVisualization(domNode, vis);
|
||||
await coordinateMapVisualization.render(dummyESResponse, {
|
||||
resize: false,
|
||||
params: true,
|
||||
aggs: true,
|
||||
data: true,
|
||||
uiState: false
|
||||
});
|
||||
|
||||
const mismatchedPixels = await compareImage(initial, 0);
|
||||
coordinateMapVisualization.destroy();
|
||||
expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF);
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
it('should toggle to Heatmap OK', async function () {
|
||||
|
||||
const coordinateMapVisualization = new CoordinateMapsVisualization(domNode, vis);
|
||||
await coordinateMapVisualization.render(dummyESResponse, {
|
||||
resize: false,
|
||||
params: true,
|
||||
aggs: true,
|
||||
data: true,
|
||||
uiState: false
|
||||
});
|
||||
|
||||
|
||||
vis.params.mapType = 'Heatmap';
|
||||
await coordinateMapVisualization.render(dummyESResponse, {
|
||||
resize: false,
|
||||
params: true,
|
||||
aggs: false,
|
||||
data: false,
|
||||
uiState: false
|
||||
});
|
||||
|
||||
const mismatchedPixels = await compareImage(heatmapRaw, 1);
|
||||
coordinateMapVisualization.destroy();
|
||||
expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF);
|
||||
|
||||
|
||||
});
|
||||
|
||||
it('should toggle back&forth OK between mapTypes', async function () {
|
||||
|
||||
const coordinateMapVisualization = new CoordinateMapsVisualization(domNode, vis);
|
||||
await coordinateMapVisualization.render(dummyESResponse, {
|
||||
resize: false,
|
||||
params: true,
|
||||
aggs: true,
|
||||
data: true,
|
||||
uiState: false
|
||||
});
|
||||
|
||||
vis.params.mapType = 'Heatmap';
|
||||
await coordinateMapVisualization.render(dummyESResponse, {
|
||||
resize: false,
|
||||
params: true,
|
||||
aggs: false,
|
||||
data: false,
|
||||
uiState: false
|
||||
});
|
||||
|
||||
vis.params.mapType = 'Scaled Circle Markers';
|
||||
await coordinateMapVisualization.render(dummyESResponse, {
|
||||
resize: false,
|
||||
params: true,
|
||||
aggs: false,
|
||||
data: false,
|
||||
uiState: false
|
||||
});
|
||||
|
||||
const mismatchedPixels = await compareImage(initial, 0);
|
||||
coordinateMapVisualization.destroy();
|
||||
expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF);
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
async function compareImage(expectedImageSource, index) {
|
||||
const elementList = domNode.querySelectorAll('canvas');
|
||||
// expect(elementList.length).to.equal(1);
|
||||
const firstCanvasOnMap = elementList[index];
|
||||
return imageComparator.compareImage(firstCanvasOnMap, expectedImageSource, THRESHOLD);
|
||||
}
|
||||
|
||||
|
||||
function setupDOM(width, height) {
|
||||
domNode = document.createElement('div');
|
||||
domNode.style.top = '0';
|
||||
domNode.style.left = '0';
|
||||
domNode.style.width = width;
|
||||
domNode.style.height = height;
|
||||
domNode.style.position = 'fixed';
|
||||
domNode.style.border = '1px solid blue';
|
||||
domNode.style['pointer-events'] = 'none';
|
||||
document.body.appendChild(domNode);
|
||||
}
|
||||
|
||||
function teardownDOM() {
|
||||
domNode.innerHTML = '';
|
||||
document.body.removeChild(domNode);
|
||||
}
|
||||
|
||||
});
|
||||
|
1836
src/core_plugins/tile_map/public/__tests__/dummy_es_response.json
Normal file
1836
src/core_plugins/tile_map/public/__tests__/dummy_es_response.json
Normal file
File diff suppressed because it is too large
Load diff
BIN
src/core_plugins/tile_map/public/__tests__/heatmap_raw.png
Normal file
BIN
src/core_plugins/tile_map/public/__tests__/heatmap_raw.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
src/core_plugins/tile_map/public/__tests__/initial.png
Normal file
BIN
src/core_plugins/tile_map/public/__tests__/initial.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -73,13 +73,22 @@ export function CoordinateMapsVisualizationProvider(Notifier, Private) {
|
|||
|
||||
if (this._geohashLayer) {
|
||||
this._kibanaMap.removeLayer(this._geohashLayer);
|
||||
this._geohashLayer = null;
|
||||
}
|
||||
if (!this._chartData || !this._chartData.geoJson) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._recreateGeohashLayer(this._chartData.geoJson);
|
||||
}
|
||||
|
||||
_recreateGeohashLayer(geojsonData) {
|
||||
if (this._geohashLayer) {
|
||||
this._kibanaMap.removeLayer(this._geohashLayer);
|
||||
this._geohashLayer = null;
|
||||
}
|
||||
const geohashOptions = this._getGeohashOptions();
|
||||
this._geohashLayer = new GeohashLayer(this._chartData.geoJson, geohashOptions, this._kibanaMap.getZoomLevel(), this._kibanaMap);
|
||||
this._geohashLayer = new GeohashLayer(geojsonData, geohashOptions, this._kibanaMap.getZoomLevel(), this._kibanaMap);
|
||||
this._kibanaMap.addLayer(this._geohashLayer);
|
||||
}
|
||||
|
||||
|
@ -88,11 +97,15 @@ export function CoordinateMapsVisualizationProvider(Notifier, Private) {
|
|||
await super._updateParams();
|
||||
|
||||
this._kibanaMap.setDesaturateBaseLayer(this.vis.params.isDesaturated);
|
||||
|
||||
//avoid recreating the leaflet layer when there are option-changes that do not effect the representation
|
||||
//e.g. tooltip-visibility, legend position, basemap-desaturation, ...
|
||||
const geohashOptions = this._getGeohashOptions();
|
||||
if (!this._geohashLayer || !this._geohashLayer.isReusable(geohashOptions)) {
|
||||
this._updateData(this._chartData);
|
||||
if (this._chartData && this._chartData.geoJson) {
|
||||
this._recreateGeohashLayer(this._chartData.geoJson);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ export class ScaledCirclesMarkers extends EventEmitter {
|
|||
this._geohashGeoJson = featureCollection;
|
||||
this._zoom = targetZoom;
|
||||
|
||||
this._valueFormatter = options.valueFormatter;
|
||||
this._tooltipFormatter = options.tooltipFormatter;
|
||||
this._valueFormatter = options.valueFormatter || ((x) => {x;});
|
||||
this._tooltipFormatter = options.tooltipFormatter || ((x) => {x;});
|
||||
|
||||
this._legendColors = null;
|
||||
this._legendQuantizer = null;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue