mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
This commit is contained in:
parent
1288e82208
commit
af0e157f99
7 changed files with 391 additions and 104 deletions
|
@ -33,6 +33,7 @@ export const ZOOM_PRECISION = 2;
|
|||
export const ES_SIZE_LIMIT = 10000;
|
||||
|
||||
export const FEATURE_ID_PROPERTY_NAME = '__kbn__feature_id__';
|
||||
export const FEATURE_VISIBLE_PROPERTY_NAME = '__kbn__isvisible__';
|
||||
|
||||
export const ES_GEO_FIELD_TYPE = {
|
||||
GEO_POINT: 'geo_point',
|
||||
|
|
|
@ -162,13 +162,9 @@ export function LayerSettings(props) {
|
|||
</EuiFlexGroup>
|
||||
|
||||
<EuiSpacer size="m"/>
|
||||
|
||||
{renderLabel()}
|
||||
|
||||
{renderZoomSliders()}
|
||||
|
||||
{renderAlphaSlider()}
|
||||
|
||||
{renderApplyGlobalQueryCheckbox()}
|
||||
</EuiPanel>
|
||||
|
||||
|
|
|
@ -27,8 +27,12 @@ export class LeftInnerJoin {
|
|||
return false;
|
||||
}
|
||||
|
||||
getRightMetricFields() {
|
||||
return this._rightSource.getMetricFields();
|
||||
}
|
||||
|
||||
getJoinFields() {
|
||||
return this._rightSource.getMetricFields().map(({ propertyKey: name, propertyLabel: label }) => {
|
||||
return this.getRightMetricFields().map(({ propertyKey: name, propertyLabel: label }) => {
|
||||
return { label, name };
|
||||
});
|
||||
}
|
||||
|
@ -44,21 +48,20 @@ export class LeftInnerJoin {
|
|||
return this._descriptor.leftField;
|
||||
}
|
||||
|
||||
joinPropertiesToFeatureCollection(featureCollection, propertiesMap) {
|
||||
const joinFields = this._rightSource.getMetricFields();
|
||||
featureCollection.features.forEach(feature => {
|
||||
// Clean up old join property values
|
||||
joinFields.forEach(({ propertyKey }) => {
|
||||
delete feature.properties[propertyKey];
|
||||
const stylePropertyName = VectorStyle.getComputedFieldName(propertyKey);
|
||||
delete feature.properties[stylePropertyName];
|
||||
});
|
||||
|
||||
const joinKey = feature.properties[this._descriptor.leftField];
|
||||
if (propertiesMap && propertiesMap.has(joinKey)) {
|
||||
Object.assign(feature.properties, propertiesMap.get(joinKey));
|
||||
}
|
||||
});
|
||||
joinPropertiesToFeature(feature, propertiesMap, rightMetricFields) {
|
||||
for (let j = 0; j < rightMetricFields.length; j++) {
|
||||
const { propertyKey } = rightMetricFields[j];
|
||||
delete feature.properties[propertyKey];
|
||||
const stylePropertyName = VectorStyle.getComputedFieldName(propertyKey);
|
||||
delete feature.properties[stylePropertyName];
|
||||
}
|
||||
const joinKey = feature.properties[this._descriptor.leftField];
|
||||
if (propertiesMap && propertiesMap.has(joinKey)) {
|
||||
Object.assign(feature.properties, propertiesMap.get(joinKey));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
getRightJoinSource() {
|
||||
|
|
|
@ -28,45 +28,42 @@ const leftJoin = new LeftInnerJoin({
|
|||
}
|
||||
});
|
||||
|
||||
describe('joinPropertiesToFeatureCollection', () => {
|
||||
describe('joinPropertiesToFeature', () => {
|
||||
const COUNT_PROPERTY_NAME = '__kbnjoin__count_groupby_kibana_sample_data_logs.geo.dest';
|
||||
|
||||
it('Should add join property to features in feature collection', () => {
|
||||
const featureCollection = {
|
||||
features: [
|
||||
{
|
||||
properties: {
|
||||
iso2: 'CN',
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
const feature = {
|
||||
properties: {
|
||||
iso2: 'CN',
|
||||
}
|
||||
}
|
||||
;
|
||||
const propertiesMap = new Map();
|
||||
propertiesMap.set('CN', { [COUNT_PROPERTY_NAME]: 61 });
|
||||
|
||||
leftJoin.joinPropertiesToFeatureCollection(featureCollection, propertiesMap);
|
||||
expect(featureCollection.features[0].properties).toEqual({
|
||||
leftJoin.joinPropertiesToFeature(feature, propertiesMap, [{
|
||||
propertyKey: COUNT_PROPERTY_NAME
|
||||
}]);
|
||||
expect(feature.properties).toEqual({
|
||||
iso2: 'CN',
|
||||
[COUNT_PROPERTY_NAME]: 61,
|
||||
});
|
||||
});
|
||||
|
||||
it('Should delete previous join property values from features in feature collection', () => {
|
||||
const featureCollection = {
|
||||
features: [
|
||||
{
|
||||
properties: {
|
||||
iso2: 'CN',
|
||||
[COUNT_PROPERTY_NAME]: 61,
|
||||
[`__kbn__scaled(${COUNT_PROPERTY_NAME})`]: 1,
|
||||
}
|
||||
}
|
||||
]
|
||||
it('Should delete previous join property values from feature', () => {
|
||||
const feature = {
|
||||
properties: {
|
||||
iso2: 'CN',
|
||||
[COUNT_PROPERTY_NAME]: 61,
|
||||
[`__kbn__scaled(${COUNT_PROPERTY_NAME})`]: 1,
|
||||
}
|
||||
};
|
||||
const propertiesMap = new Map();
|
||||
|
||||
leftJoin.joinPropertiesToFeatureCollection(featureCollection, propertiesMap);
|
||||
expect(featureCollection.features[0].properties).toEqual({
|
||||
leftJoin.joinPropertiesToFeature(feature, propertiesMap, [{
|
||||
propertyKey: COUNT_PROPERTY_NAME
|
||||
}]);
|
||||
expect(feature.properties).toEqual({
|
||||
iso2: 'CN',
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,7 +9,12 @@ import React from 'react';
|
|||
import { AbstractLayer } from './layer';
|
||||
import { VectorStyle } from './styles/vector_style';
|
||||
import { LeftInnerJoin } from './joins/left_inner_join';
|
||||
import { FEATURE_ID_PROPERTY_NAME, SOURCE_DATA_ID_ORIGIN, GEO_JSON_TYPE } from '../../../common/constants';
|
||||
import {
|
||||
GEO_JSON_TYPE,
|
||||
FEATURE_ID_PROPERTY_NAME,
|
||||
SOURCE_DATA_ID_ORIGIN,
|
||||
FEATURE_VISIBLE_PROPERTY_NAME
|
||||
} from '../../../common/constants';
|
||||
import _ from 'lodash';
|
||||
import { JoinTooltipProperty } from './tooltips/join_tooltip_property';
|
||||
import { isRefreshOnlyQuery } from './util/is_refresh_only_query';
|
||||
|
@ -21,28 +26,44 @@ const EMPTY_FEATURE_COLLECTION = {
|
|||
features: []
|
||||
};
|
||||
|
||||
const CLOSED_SHAPE_MB_FILTER = [
|
||||
'any',
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.POLYGON],
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POLYGON]
|
||||
const VISIBILITY_FILTER_CLAUSE = ['all',
|
||||
[
|
||||
'==',
|
||||
['get', FEATURE_VISIBLE_PROPERTY_NAME],
|
||||
true
|
||||
]
|
||||
];
|
||||
|
||||
const ALL_SHAPE_MB_FILTER = [
|
||||
'any',
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.POLYGON],
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POLYGON],
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.LINE_STRING],
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_LINE_STRING]
|
||||
const FILL_LAYER_MB_FILTER = [
|
||||
...VISIBILITY_FILTER_CLAUSE,
|
||||
[
|
||||
'any',
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.POLYGON],
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POLYGON]
|
||||
]
|
||||
];
|
||||
|
||||
const POINT_MB_FILTER = [
|
||||
'any',
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.POINT],
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POINT]
|
||||
const LINE_LAYER_MB_FILTER = [...VISIBILITY_FILTER_CLAUSE,
|
||||
[
|
||||
'any',
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.POLYGON],
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POLYGON],
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.LINE_STRING],
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_LINE_STRING]
|
||||
]
|
||||
];
|
||||
|
||||
const POINT_LAYER_MB_FILTER = [...VISIBILITY_FILTER_CLAUSE,
|
||||
[
|
||||
'any',
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.POINT],
|
||||
['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POINT]
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
let idCounter = 0;
|
||||
|
||||
function generateNumericalId() {
|
||||
const newId = idCounter < Number.MAX_SAFE_INTEGER ? idCounter : 0;
|
||||
idCounter = newId + 1;
|
||||
|
@ -68,7 +89,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
|
||||
constructor(options) {
|
||||
super(options);
|
||||
this._joins = [];
|
||||
this._joins = [];
|
||||
if (options.layerDescriptor.joins) {
|
||||
options.layerDescriptor.joins.forEach((joinDescriptor) => {
|
||||
this._joins.push(new LeftInnerJoin(joinDescriptor, this._source.getInspectorAdapters()));
|
||||
|
@ -115,25 +136,39 @@ export class VectorLayer extends AbstractLayer {
|
|||
getCustomIconAndTooltipContent() {
|
||||
const sourceDataRequest = this.getSourceDataRequest();
|
||||
const featureCollection = sourceDataRequest ? sourceDataRequest.getData() : null;
|
||||
|
||||
|
||||
const noResultsIcon = (
|
||||
<EuiIcon
|
||||
size="m"
|
||||
color="subdued"
|
||||
type="minusInCircle"
|
||||
/>
|
||||
);
|
||||
if (!featureCollection || featureCollection.features.length === 0) {
|
||||
return {
|
||||
icon: (
|
||||
<EuiIcon
|
||||
size="m"
|
||||
color="subdued"
|
||||
type="minusInCircle"
|
||||
/>
|
||||
),
|
||||
icon: noResultsIcon,
|
||||
tooltipContent: i18n.translate('xpack.maps.vectorLayer.noResultsFoundTooltip', {
|
||||
defaultMessage: `No results found.`
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
if (this._joins.length &&
|
||||
!featureCollection.features.some((feature) => feature.properties[FEATURE_VISIBLE_PROPERTY_NAME])
|
||||
) {
|
||||
return {
|
||||
icon: noResultsIcon,
|
||||
tooltipContent: i18n.translate('xpack.maps.vectorLayer.noResultsFoundInJoinTooltip', {
|
||||
defaultMessage: `No matching results found in term joins`
|
||||
})
|
||||
};
|
||||
}
|
||||
return {
|
||||
icon: this._style.getIcon(),
|
||||
tooltipContent: this._source.getSourceTooltipContent(sourceDataRequest)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
getLayerTypeIconName() {
|
||||
|
@ -153,7 +188,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
if (!featureCollection) {
|
||||
return null;
|
||||
}
|
||||
const bbox = turf.bbox(featureCollection);
|
||||
const bbox = turf.bbox(featureCollection);
|
||||
return {
|
||||
min_lon: bbox[0],
|
||||
min_lat: bbox[1],
|
||||
|
@ -331,7 +366,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
join: join,
|
||||
propertiesMap: propertiesMap,
|
||||
};
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
onLoadError(sourceDataId, requestToken, `Join error: ${e.message}`);
|
||||
return {
|
||||
dataHasChanged: false,
|
||||
|
@ -368,6 +403,43 @@ export class VectorLayer extends AbstractLayer {
|
|||
};
|
||||
}
|
||||
|
||||
async _performInnerJoins(sourceResult, joinStates, updateSourceData) {
|
||||
|
||||
//should update the store if
|
||||
//-- source result was refreshed
|
||||
//-- any of the join configurations changed (joinState changed)
|
||||
//-- visibility of any of the features has changed
|
||||
|
||||
let shouldUpdateStore = sourceResult.refreshed || joinStates.some((joinState) => joinState.dataHasChanged);
|
||||
|
||||
if (!shouldUpdateStore) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < sourceResult.featureCollection.features.length; i++) {
|
||||
const feature = sourceResult.featureCollection.features[i];
|
||||
const oldVisbility = feature.properties[FEATURE_VISIBLE_PROPERTY_NAME];
|
||||
let isFeatureVisible = true;
|
||||
for (let j = 0; j < joinStates.length; j++) {
|
||||
const joinState = joinStates[j];
|
||||
const leftInnerJoin = joinState.join;
|
||||
const rightMetricFields = leftInnerJoin.getRightMetricFields();
|
||||
const canJoinOnCurrent = leftInnerJoin.joinPropertiesToFeature(feature, joinState.propertiesMap, rightMetricFields);
|
||||
isFeatureVisible = isFeatureVisible && canJoinOnCurrent;
|
||||
}
|
||||
|
||||
if (oldVisbility !== isFeatureVisible) {
|
||||
shouldUpdateStore = true;
|
||||
}
|
||||
|
||||
feature.properties[FEATURE_VISIBLE_PROPERTY_NAME] = isFeatureVisible;
|
||||
}
|
||||
|
||||
if (shouldUpdateStore) {
|
||||
updateSourceData({ ...sourceResult.featureCollection });
|
||||
}
|
||||
}
|
||||
|
||||
async _syncSource({ startLoading, stopLoading, onLoadError, dataFilters }) {
|
||||
|
||||
const requestToken = Symbol(`layer-source-refresh:${ this.getId()} - source`);
|
||||
|
@ -394,7 +466,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
};
|
||||
} catch (error) {
|
||||
onLoadError(SOURCE_DATA_ID_ORIGIN, requestToken, error.message);
|
||||
return {
|
||||
return {
|
||||
refreshed: false
|
||||
};
|
||||
}
|
||||
|
@ -415,26 +487,13 @@ export class VectorLayer extends AbstractLayer {
|
|||
}
|
||||
|
||||
const sourceResult = await this._syncSource({ startLoading, stopLoading, onLoadError, dataFilters });
|
||||
|
||||
if (sourceResult.featureCollection && sourceResult.featureCollection.features.length) {
|
||||
const joinStates = await this._syncJoins({ startLoading, stopLoading, onLoadError, dataFilters });
|
||||
const activeJoinStates = joinStates.filter(joinState => {
|
||||
// Perform join when
|
||||
// - source data changed but join data has not
|
||||
// - join data changed but source data has not
|
||||
// - both source and join data changed
|
||||
return sourceResult.refreshed || joinState.dataHasChanged;
|
||||
});
|
||||
|
||||
if (activeJoinStates.length) {
|
||||
activeJoinStates.forEach(joinState => {
|
||||
joinState.join.joinPropertiesToFeatureCollection(
|
||||
sourceResult.featureCollection,
|
||||
joinState.propertiesMap);
|
||||
});
|
||||
updateSourceData(sourceResult.featureCollection);
|
||||
}
|
||||
if (!sourceResult.featureCollection || !sourceResult.featureCollection.features.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const joinStates = await this._syncJoins({ startLoading, stopLoading, onLoadError, dataFilters });
|
||||
await this._performInnerJoins(sourceResult, joinStates, updateSourceData);
|
||||
|
||||
}
|
||||
|
||||
_getSourceFeatureCollection() {
|
||||
|
@ -507,7 +566,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
source: sourceId,
|
||||
paint: {}
|
||||
});
|
||||
mbMap.setFilter(pointLayerId, POINT_MB_FILTER);
|
||||
mbMap.setFilter(pointLayerId, POINT_LAYER_MB_FILTER);
|
||||
}
|
||||
|
||||
this._style.setMBPaintPropertiesForPoints({
|
||||
|
@ -528,7 +587,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
type: 'symbol',
|
||||
source: sourceId,
|
||||
});
|
||||
mbMap.setFilter(symbolLayerId, POINT_MB_FILTER);
|
||||
mbMap.setFilter(symbolLayerId, POINT_LAYER_MB_FILTER);
|
||||
}
|
||||
|
||||
this._style.setMBSymbolPropertiesForPoints({
|
||||
|
@ -549,7 +608,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
source: sourceId,
|
||||
paint: {}
|
||||
});
|
||||
mbMap.setFilter(fillLayerId, CLOSED_SHAPE_MB_FILTER);
|
||||
mbMap.setFilter(fillLayerId, FILL_LAYER_MB_FILTER);
|
||||
}
|
||||
if (!mbMap.getLayer(lineLayerId)) {
|
||||
mbMap.addLayer({
|
||||
|
@ -558,7 +617,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
source: sourceId,
|
||||
paint: {}
|
||||
});
|
||||
mbMap.setFilter(lineLayerId, ALL_SHAPE_MB_FILTER);
|
||||
mbMap.setFilter(lineLayerId, LINE_LAYER_MB_FILTER);
|
||||
}
|
||||
this._style.setMBPaintProperties({
|
||||
alpha: this.getAlpha(),
|
||||
|
@ -594,11 +653,11 @@ export class VectorLayer extends AbstractLayer {
|
|||
}
|
||||
|
||||
_getMbPointLayerId() {
|
||||
return this.getId() + '_circle';
|
||||
return this.getId() + '_circle';
|
||||
}
|
||||
|
||||
_getMbSymbolLayerId() {
|
||||
return this.getId() + '_symbol';
|
||||
return this.getId() + '_symbol';
|
||||
}
|
||||
|
||||
_getMbLineLayerId() {
|
||||
|
@ -630,7 +689,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
|
||||
async getPropertiesForTooltip(properties) {
|
||||
|
||||
let allTooltips = await this._source.filterAndFormatPropertiesToHtml(properties);
|
||||
let allTooltips = await this._source.filterAndFormatPropertiesToHtml(properties);
|
||||
this._addJoinsToSourceTooltips(allTooltips);
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
import { MAPBOX_STYLES } from './mapbox_styles';
|
||||
|
||||
const JOIN_PROPERTY_NAME = '__kbnjoin__max_of_prop1_groupby_meta_for_geo_shapes*.shape_name';
|
||||
const EXPECTED_JOIN_VALUES = {
|
||||
alpha: 10,
|
||||
|
@ -78,20 +80,28 @@ export default function ({ getPageObjects, getService }) {
|
|||
});
|
||||
|
||||
//circle layer for points
|
||||
// eslint-disable-next-line max-len
|
||||
expect(layersForVectorSource[0]).to.eql({ 'id': 'n1t6f_circle', 'type': 'circle', 'source': 'n1t6f', 'minzoom': 0, 'maxzoom': 24, 'filter': ['any', ['==', ['geometry-type'], 'Point'], ['==', ['geometry-type'], 'MultiPoint']], 'layout': { 'visibility': 'visible' }, 'paint': { 'circle-color': ['interpolate', ['linear'], ['coalesce', ['feature-state', '__kbn__scaled(__kbnjoin__max_of_prop1_groupby_meta_for_geo_shapes*.shape_name)'], -1], -1, 'rgba(0,0,0,0)', 0, '#f7faff', 0.125, '#ddeaf7', 0.25, '#c5daee', 0.375, '#9dc9e0', 0.5, '#6aadd5', 0.625, '#4191c5', 0.75, '#2070b4', 0.875, '#072f6b'], 'circle-opacity': 0.75, 'circle-stroke-color': '#FFFFFF', 'circle-stroke-opacity': 0.75, 'circle-stroke-width': 1, 'circle-radius': 10 } });
|
||||
expect(layersForVectorSource[0]).to.eql(MAPBOX_STYLES.POINT_LAYER);
|
||||
|
||||
//fill layer
|
||||
// eslint-disable-next-line max-len
|
||||
expect(layersForVectorSource[1]).to.eql({ 'id': 'n1t6f_fill', 'type': 'fill', 'source': 'n1t6f', 'minzoom': 0, 'maxzoom': 24, 'filter': ['any', ['==', ['geometry-type'], 'Polygon'], ['==', ['geometry-type'], 'MultiPolygon']], 'layout': { 'visibility': 'visible' }, 'paint': { 'fill-color': ['interpolate', ['linear'], ['coalesce', ['feature-state', '__kbn__scaled(__kbnjoin__max_of_prop1_groupby_meta_for_geo_shapes*.shape_name)'], -1], -1, 'rgba(0,0,0,0)', 0, '#f7faff', 0.125, '#ddeaf7', 0.25, '#c5daee', 0.375, '#9dc9e0', 0.5, '#6aadd5', 0.625, '#4191c5', 0.75, '#2070b4', 0.875, '#072f6b'], 'fill-opacity': 0.75 } }
|
||||
);
|
||||
expect(layersForVectorSource[1]).to.eql(MAPBOX_STYLES.FILL_LAYER);
|
||||
|
||||
//line layer for borders
|
||||
// eslint-disable-next-line max-len
|
||||
expect(layersForVectorSource[2]).to.eql({ 'id': 'n1t6f_line', 'type': 'line', 'source': 'n1t6f', 'minzoom': 0, 'maxzoom': 24, 'filter': ['any', ['==', ['geometry-type'], 'Polygon'], ['==', ['geometry-type'], 'MultiPolygon'], ['==', ['geometry-type'], 'LineString'], ['==', ['geometry-type'], 'MultiLineString']], 'layout': { 'visibility': 'visible' }, 'paint': { 'line-color': '#FFFFFF', 'line-opacity': 0.75, 'line-width': 1 } });
|
||||
expect(layersForVectorSource[2]).to.eql(MAPBOX_STYLES.LINE_LAYER);
|
||||
|
||||
});
|
||||
|
||||
it('should flag only the joined features as visible', async () => {
|
||||
const mapboxStyle = await PageObjects.maps.getMapboxStyle();
|
||||
const vectorSource = mapboxStyle.sources[VECTOR_SOURCE_ID];
|
||||
|
||||
const visibilitiesOfFeatures = vectorSource.data.features.map(feature => {
|
||||
return feature.properties.__kbn__isvisible__;
|
||||
});
|
||||
|
||||
expect(visibilitiesOfFeatures).to.eql([true, true, true, false]);
|
||||
});
|
||||
|
||||
|
||||
describe('query bar', () => {
|
||||
before(async () => {
|
||||
await PageObjects.maps.setAndSubmitQuery('prop1 < 10 or _index : "geo_shapes*"');
|
||||
|
@ -156,6 +166,19 @@ export default function ({ getPageObjects, getService }) {
|
|||
const max = split[2];
|
||||
expect(max).to.equal('12');
|
||||
});
|
||||
|
||||
it('should flag only the joined features as visible', async () => {
|
||||
const mapboxStyle = await PageObjects.maps.getMapboxStyle();
|
||||
const vectorSource = mapboxStyle.sources[VECTOR_SOURCE_ID];
|
||||
|
||||
const visibilitiesOfFeatures = vectorSource.data.features.map(feature => {
|
||||
return feature.properties.__kbn__isvisible__;
|
||||
});
|
||||
|
||||
expect(visibilitiesOfFeatures).to.eql([false, false, true, false]);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('inspector', () => {
|
||||
|
|
208
x-pack/test/functional/apps/maps/mapbox_styles.js
Normal file
208
x-pack/test/functional/apps/maps/mapbox_styles.js
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
|
||||
export const MAPBOX_STYLES = {
|
||||
POINT_LAYER: {
|
||||
'id': 'n1t6f_circle',
|
||||
'type': 'circle',
|
||||
'source': 'n1t6f',
|
||||
'minzoom': 0,
|
||||
'maxzoom': 24,
|
||||
'filter': [
|
||||
'all',
|
||||
[
|
||||
'==',
|
||||
['get', '__kbn__isvisible__'],
|
||||
true
|
||||
],
|
||||
[
|
||||
'any',
|
||||
[
|
||||
'==',
|
||||
[
|
||||
'geometry-type'
|
||||
],
|
||||
'Point'
|
||||
],
|
||||
[
|
||||
'==',
|
||||
[
|
||||
'geometry-type'
|
||||
],
|
||||
'MultiPoint'
|
||||
]
|
||||
]
|
||||
],
|
||||
'layout': {
|
||||
'visibility': 'visible'
|
||||
},
|
||||
'paint': {
|
||||
'circle-color': [
|
||||
'interpolate',
|
||||
[
|
||||
'linear'
|
||||
],
|
||||
[
|
||||
'coalesce',
|
||||
[
|
||||
'feature-state',
|
||||
'__kbn__scaled(__kbnjoin__max_of_prop1_groupby_meta_for_geo_shapes*.shape_name)'
|
||||
],
|
||||
-1
|
||||
],
|
||||
-1,
|
||||
'rgba(0,0,0,0)',
|
||||
0,
|
||||
'#f7faff',
|
||||
0.125,
|
||||
'#ddeaf7',
|
||||
0.25,
|
||||
'#c5daee',
|
||||
0.375,
|
||||
'#9dc9e0',
|
||||
0.5,
|
||||
'#6aadd5',
|
||||
0.625,
|
||||
'#4191c5',
|
||||
0.75,
|
||||
'#2070b4',
|
||||
0.875,
|
||||
'#072f6b'
|
||||
],
|
||||
'circle-opacity': 0.75,
|
||||
'circle-stroke-color': '#FFFFFF',
|
||||
'circle-stroke-opacity': 0.75,
|
||||
'circle-stroke-width': 1,
|
||||
'circle-radius': 10
|
||||
}
|
||||
},
|
||||
FILL_LAYER: {
|
||||
'id': 'n1t6f_fill',
|
||||
'type': 'fill',
|
||||
'source': 'n1t6f',
|
||||
'minzoom': 0,
|
||||
'maxzoom': 24,
|
||||
'filter': [
|
||||
'all',
|
||||
[
|
||||
'==',
|
||||
['get', '__kbn__isvisible__'],
|
||||
true
|
||||
],
|
||||
[
|
||||
'any',
|
||||
[
|
||||
'==',
|
||||
[
|
||||
'geometry-type'
|
||||
],
|
||||
'Polygon'
|
||||
],
|
||||
[
|
||||
'==',
|
||||
[
|
||||
'geometry-type'
|
||||
],
|
||||
'MultiPolygon'
|
||||
]
|
||||
]
|
||||
],
|
||||
'layout': {
|
||||
'visibility': 'visible'
|
||||
},
|
||||
'paint': {
|
||||
'fill-color': [
|
||||
'interpolate',
|
||||
[
|
||||
'linear'
|
||||
],
|
||||
[
|
||||
'coalesce',
|
||||
[
|
||||
'feature-state',
|
||||
'__kbn__scaled(__kbnjoin__max_of_prop1_groupby_meta_for_geo_shapes*.shape_name)'
|
||||
],
|
||||
-1
|
||||
],
|
||||
-1,
|
||||
'rgba(0,0,0,0)',
|
||||
0,
|
||||
'#f7faff',
|
||||
0.125,
|
||||
'#ddeaf7',
|
||||
0.25,
|
||||
'#c5daee',
|
||||
0.375,
|
||||
'#9dc9e0',
|
||||
0.5,
|
||||
'#6aadd5',
|
||||
0.625,
|
||||
'#4191c5',
|
||||
0.75,
|
||||
'#2070b4',
|
||||
0.875,
|
||||
'#072f6b'
|
||||
],
|
||||
'fill-opacity': 0.75
|
||||
}
|
||||
|
||||
},
|
||||
LINE_LAYER: {
|
||||
'id': 'n1t6f_line',
|
||||
'type': 'line',
|
||||
'source': 'n1t6f',
|
||||
'minzoom': 0,
|
||||
'maxzoom': 24,
|
||||
'filter': [
|
||||
'all',
|
||||
[
|
||||
'==',
|
||||
['get', '__kbn__isvisible__'],
|
||||
true
|
||||
],
|
||||
[
|
||||
'any',
|
||||
[
|
||||
'==',
|
||||
[
|
||||
'geometry-type'
|
||||
],
|
||||
'Polygon'
|
||||
],
|
||||
[
|
||||
'==',
|
||||
[
|
||||
'geometry-type'
|
||||
],
|
||||
'MultiPolygon'
|
||||
],
|
||||
[
|
||||
'==',
|
||||
[
|
||||
'geometry-type'
|
||||
],
|
||||
'LineString'
|
||||
],
|
||||
[
|
||||
'==',
|
||||
[
|
||||
'geometry-type'
|
||||
],
|
||||
'MultiLineString'
|
||||
]
|
||||
]
|
||||
],
|
||||
'layout': {
|
||||
'visibility': 'visible'
|
||||
},
|
||||
'paint': {
|
||||
'line-color': '#FFFFFF',
|
||||
'line-opacity': 0.75,
|
||||
'line-width': 1
|
||||
}
|
||||
}
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue