Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions x-pack/legacy/plugins/maps/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ export const FIELD_ORIGIN = {
export const SOURCE_DATA_ID_ORIGIN = 'source';
export const META_ID_ORIGIN_SUFFIX = 'meta';
export const SOURCE_META_ID_ORIGIN = `${SOURCE_DATA_ID_ORIGIN}_${META_ID_ORIGIN_SUFFIX}`;
export const FORMATTERS_ID_ORIGIN_SUFFIX = 'formatters';
export const SOURCE_FORMATTERS_ID_ORIGIN = `${SOURCE_DATA_ID_ORIGIN}_${FORMATTERS_ID_ORIGIN_SUFFIX}`;

export const GEOJSON_FILE = 'GEOJSON_FILE';

Expand Down
6 changes: 5 additions & 1 deletion x-pack/legacy/plugins/maps/public/layers/joins/inner_join.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { ESTermSource } from '../sources/es_term_source';
import { getComputedFieldNamePrefix } from '../styles/vector/style_util';
import { META_ID_ORIGIN_SUFFIX } from '../../../common/constants';
import { META_ID_ORIGIN_SUFFIX, FORMATTERS_ID_ORIGIN_SUFFIX } from '../../../common/constants';

export class InnerJoin {
constructor(joinDescriptor, leftSource) {
Expand Down Expand Up @@ -45,6 +45,10 @@ export class InnerJoin {
return `${this.getSourceDataRequestId()}_${META_ID_ORIGIN_SUFFIX}`;
}

getSourceFormattersDataRequestId() {
return `${this.getSourceDataRequestId()}_${FORMATTERS_ID_ORIGIN_SUFFIX}`;
}

getLeftField() {
return this._leftField;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ export class AbstractESAggSource extends AbstractESSource {
});
}

hasMatchingMetricField(fieldName) {
const matchingField = this.getMetricFieldForName(fieldName);
return !!matchingField;
}

getMetricFieldForName(fieldName) {
return this.getMetricFields().find(metricField => {
return metricField.getName() === fieldName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
FIELD_ORIGIN,
STYLE_TYPE,
SOURCE_META_ID_ORIGIN,
SOURCE_FORMATTERS_ID_ORIGIN,
LAYER_STYLE_TYPE,
} from '../../../../common/constants';
import { VectorIcon } from './components/legend/vector_icon';
Expand Down Expand Up @@ -294,14 +295,17 @@ export class VectorStyle extends AbstractStyle {
return this._isOnlySingleFeatureType(VECTOR_SHAPE_TYPES.POLYGON);
};

_getFieldMeta = fieldName => {
const fieldMetaFromLocalFeatures = _.get(this._descriptor, ['__styleMeta', fieldName]);

_getDynamicPropertyByFieldName(fieldName) {
const dynamicProps = this.getDynamicPropertiesArray();
const dynamicProp = dynamicProps.find(dynamicProp => {
return dynamicProps.find(dynamicProp => {
return fieldName === dynamicProp.getField().getName();
});
}

_getFieldMeta = fieldName => {
const fieldMetaFromLocalFeatures = _.get(this._descriptor, ['__styleMeta', fieldName]);

const dynamicProp = this._getDynamicPropertyByFieldName(fieldName);
if (!dynamicProp || !dynamicProp.isFieldMetaEnabled()) {
return fieldMetaFromLocalFeatures;
}
Expand All @@ -311,8 +315,7 @@ export class VectorStyle extends AbstractStyle {
dataRequestId = SOURCE_META_ID_ORIGIN;
} else {
const join = this._layer.getValidJoins().find(join => {
const matchingField = join.getRightJoinSource().getMetricFieldForName(fieldName);
return !!matchingField;
return join.getRightJoinSource().hasMatchingMetricField(fieldName);
});
if (join) {
dataRequestId = join.getSourceMetaDataRequestId();
Expand All @@ -323,7 +326,7 @@ export class VectorStyle extends AbstractStyle {
return fieldMetaFromLocalFeatures;
}

const styleMetaDataRequest = this._layer._findDataRequestForSource(dataRequestId);
const styleMetaDataRequest = this._layer._findDataRequestById(dataRequestId);
if (!styleMetaDataRequest || !styleMetaDataRequest.hasData()) {
return fieldMetaFromLocalFeatures;
}
Expand All @@ -334,6 +337,37 @@ export class VectorStyle extends AbstractStyle {
return fieldMeta ? fieldMeta : fieldMetaFromLocalFeatures;
};

_getFieldFormatter(fieldName) {
const dynamicProp = this._getDynamicPropertyByFieldName(fieldName);
if (!dynamicProp) {
return null;
}

let dataRequestId;
if (dynamicProp.getFieldOrigin() === FIELD_ORIGIN.SOURCE) {
dataRequestId = SOURCE_FORMATTERS_ID_ORIGIN;
} else {
const join = this._layer.getValidJoins().find(join => {
return join.getRightJoinSource().hasMatchingMetricField(fieldName);
});
if (join) {
dataRequestId = join.getSourceFormattersDataRequestId();
}
}

if (!dataRequestId) {
return null;
}

const formattersDataRequest = this._layer._findDataRequestById(dataRequestId);
if (!formattersDataRequest || !formattersDataRequest.hasData()) {
return null;
}

const formatters = formattersDataRequest.getData();
return formatters[fieldName];
}

_getStyleMeta = () => {
return _.get(this._descriptor, '__styleMeta', {});
};
Expand Down Expand Up @@ -382,7 +416,7 @@ export class VectorStyle extends AbstractStyle {
const promises = styles.map(async style => {
return {
label: await style.getField().getLabel(),
fieldFormatter: await this._source.getFieldFormatter(style.getField().getName()),
fieldFormatter: this._getFieldFormatter(style.getField().getName()),
meta: this._getFieldMeta(style.getField().getName()),
style,
};
Expand Down Expand Up @@ -539,14 +573,10 @@ export class VectorStyle extends AbstractStyle {
fieldName: fieldDescriptor.name,
});
} else if (fieldDescriptor.origin === FIELD_ORIGIN.JOIN) {
let matchingField = null;
const joins = this._layer.getValidJoins();
joins.find(join => {
const aggSource = join.getRightJoinSource();
matchingField = aggSource.getMetricFieldForName(fieldDescriptor.name);
return !!matchingField;
const join = this._layer.getValidJoins().find(join => {
return join.getRightJoinSource().hasMatchingMetricField(fieldDescriptor.name);
});
return matchingField;
return join ? join.getRightJoinSource().getMetricFieldForName(fieldDescriptor.name) : null;
} else {
throw new Error(`Unknown origin-type ${fieldDescriptor.origin}`);
}
Expand Down
12 changes: 12 additions & 0 deletions x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,15 @@ export function canSkipStyleMetaUpdate({ prevDataRequest, nextMeta }) {
!updateDueToFields && !updateDueToSourceQuery && !updateDueToIsTimeAware && !updateDueToTime
);
}

export function canSkipFormattersUpdate({ prevDataRequest, nextMeta }) {
if (!prevDataRequest) {
return false;
}
const prevMeta = prevDataRequest.getMeta();
if (!prevMeta) {
return false;
}

return !_.isEqual(prevMeta.fieldNames, nextMeta.fieldNames);
}
93 changes: 87 additions & 6 deletions x-pack/legacy/plugins/maps/public/layers/vector_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
FEATURE_ID_PROPERTY_NAME,
SOURCE_DATA_ID_ORIGIN,
SOURCE_META_ID_ORIGIN,
SOURCE_FORMATTERS_ID_ORIGIN,
FEATURE_VISIBLE_PROPERTY_NAME,
EMPTY_FEATURE_COLLECTION,
LAYER_TYPE,
Expand All @@ -24,7 +25,11 @@ import { JoinTooltipProperty } from './tooltips/join_tooltip_property';
import { EuiIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { DataRequestAbortError } from './util/data_request';
import { canSkipSourceUpdate, canSkipStyleMetaUpdate } from './util/can_skip_fetch';
import {
canSkipSourceUpdate,
canSkipStyleMetaUpdate,
canSkipFormattersUpdate,
} from './util/can_skip_fetch';
import { assignFeatureIds } from './util/assign_feature_ids';
import {
getFillFilterExpression,
Expand Down Expand Up @@ -220,7 +225,7 @@ export class VectorLayer extends AbstractLayer {
return indexPatternIds;
}

_findDataRequestForSource(sourceDataId) {
_findDataRequestById(sourceDataId) {
return this._dataRequests.find(dataRequest => dataRequest.getDataId() === sourceDataId);
}

Expand All @@ -241,7 +246,7 @@ export class VectorLayer extends AbstractLayer {
sourceQuery: joinSource.getWhereQuery(),
applyGlobalQuery: joinSource.getApplyGlobalQuery(),
};
const prevDataRequest = this._findDataRequestForSource(sourceDataId);
const prevDataRequest = this._findDataRequestById(sourceDataId);

const canSkipFetch = await canSkipSourceUpdate({
source: joinSource,
Expand Down Expand Up @@ -286,6 +291,7 @@ export class VectorLayer extends AbstractLayer {
async _syncJoins(syncContext) {
const joinSyncs = this.getValidJoins().map(async join => {
await this._syncJoinStyleMeta(syncContext, join);
await this._syncJoinFormatters(syncContext, join);
return this._syncJoin({ join, ...syncContext });
});

Expand Down Expand Up @@ -355,7 +361,7 @@ export class VectorLayer extends AbstractLayer {
registerCancelCallback,
dataFilters,
}) {
const requestToken = Symbol(`layer-source-data:${this.getId()}`);
const requestToken = Symbol(`layer-${this.getId()}-${SOURCE_DATA_ID_ORIGIN}`);
const searchFilters = this._getSearchFilters(dataFilters);
const prevDataRequest = this.getSourceDataRequest();

Expand Down Expand Up @@ -459,13 +465,13 @@ export class VectorLayer extends AbstractLayer {
isTimeAware: this._style.isTimeAware() && (await source.isTimeAware()),
timeFilters: dataFilters.timeFilters,
};
const prevDataRequest = this._findDataRequestForSource(dataRequestId);
const prevDataRequest = this._findDataRequestById(dataRequestId);
const canSkipFetch = canSkipStyleMetaUpdate({ prevDataRequest, nextMeta });
if (canSkipFetch) {
return;
}

const requestToken = Symbol(`layer-${this.getId()}-style-meta`);
const requestToken = Symbol(`layer-${this.getId()}-${dataRequestId}`);
try {
startLoading(dataRequestId, requestToken, nextMeta);
const layerName = await this.getDisplayName();
Expand All @@ -484,12 +490,87 @@ export class VectorLayer extends AbstractLayer {
}
}

async _syncSourceFormatters(syncContext) {
if (this._style.constructor.type !== LAYER_STYLE_TYPE.VECTOR) {
return;
}

return this._syncFormatters({
source: this._source,
dataRequestId: SOURCE_FORMATTERS_ID_ORIGIN,
fields: this._style
.getDynamicPropertiesArray()
.filter(dynamicStyleProp => {
return dynamicStyleProp.getFieldOrigin() === FIELD_ORIGIN.SOURCE;
})
.map(dynamicStyleProp => {
return dynamicStyleProp.getField();
}),
...syncContext,
});
}

async _syncJoinFormatters(syncContext, join) {
const joinSource = join.getRightJoinSource();
return this._syncFormatters({
source: joinSource,
dataRequestId: join.getSourceFormattersDataRequestId(),
fields: this._style
.getDynamicPropertiesArray()
.filter(dynamicStyleProp => {
const matchingField = joinSource.getMetricFieldForName(
dynamicStyleProp.getField().getName()
);
return dynamicStyleProp.getFieldOrigin() === FIELD_ORIGIN.JOIN && !!matchingField;
})
.map(dynamicStyleProp => {
return dynamicStyleProp.getField();
}),
...syncContext,
});
}

async _syncFormatters({ source, dataRequestId, fields, startLoading, stopLoading, onLoadError }) {
if (fields.length === 0) {
return;
}

const fieldNames = fields.map(field => {
return field.getName();
});
const nextMeta = {
fieldNames: _.uniq(fieldNames).sort(),
};
const prevDataRequest = this._findDataRequestById(dataRequestId);
const canSkipUpdate = canSkipFormattersUpdate({ prevDataRequest, nextMeta });
if (canSkipUpdate) {
return;
}

const requestToken = Symbol(`layer-${this.getId()}-${dataRequestId}`);
try {
startLoading(dataRequestId, requestToken, nextMeta);

const formatters = {};
const promises = fields.map(async field => {
const fieldName = field.getName();
formatters[fieldName] = await source.getFieldFormatter(fieldName);
});
await Promise.all(promises);

stopLoading(dataRequestId, requestToken, formatters, nextMeta);
} catch (error) {
onLoadError(dataRequestId, requestToken, error.message);
}
}

async syncData(syncContext) {
if (!this.isVisible() || !this.showAtZoomLevel(syncContext.dataFilters.zoom)) {
return;
}

await this._syncSourceStyleMeta(syncContext);
await this._syncSourceFormatters(syncContext);
const sourceResult = await this._syncSource(syncContext);
if (
!sourceResult.featureCollection ||
Expand Down