Skip to content

Commit

Permalink
[Maps] choropleth layer wizard (#69699)
Browse files Browse the repository at this point in the history
* [Maps] choropleth layer wizard

* add boundaries radio group

* geo_index_pattern_select

* consolidate more logic into geo_index_pattern_select

* small clean-up

* left geo field and join field

* move EuiPanel into render wizard

* cleanup

* right panel

* createEmsChoroplethLayerDescriptor

* createEsChoroplethLayerDescriptor

* i18n cleanup

* tslint

* snapshot update

* review feedback

* review feedback

* update snapshot

* make EMS default source

* tslint

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
nreese and elasticmachine authored Jun 29, 2020
1 parent 7db95a1 commit 9175981
Show file tree
Hide file tree
Showing 34 changed files with 1,337 additions and 440 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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.
*/

import React from 'react';
import { i18n } from '@kbn/i18n';
import { LAYER_WIZARD_CATEGORY } from '../../../../common/constants';
import { LayerWizard, RenderWizardArguments } from '../layer_wizard_registry';
import { LayerTemplate } from './layer_template';

export const choroplethLayerWizardConfig: LayerWizard = {
categories: [LAYER_WIZARD_CATEGORY.ELASTICSEARCH],
description: i18n.translate('xpack.maps.choropleth.desc', {
defaultMessage: 'Shaded areas to compare statistics across boundaries',
}),
icon: 'logoElasticsearch',
renderWizard: (renderWizardArguments: RenderWizardArguments) => {
return <LayerTemplate {...renderWizardArguments} />;
},
title: i18n.translate('xpack.maps.choropleth.title', {
defaultMessage: 'Choropleth',
}),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* 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.
*/

import uuid from 'uuid/v4';
import {
AGG_TYPE,
COLOR_MAP_TYPE,
FIELD_ORIGIN,
SCALING_TYPES,
SOURCE_TYPES,
STYLE_TYPE,
VECTOR_STYLES,
} from '../../../../common/constants';
import { getJoinAggKey } from '../../../../common/get_agg_key';
import {
AggDescriptor,
ColorDynamicOptions,
EMSFileSourceDescriptor,
ESSearchSourceDescriptor,
} from '../../../../common/descriptor_types';
import { VectorStyle } from '../../styles/vector/vector_style';
import { VectorLayer } from '../vector_layer/vector_layer';
import { EMSFileSource } from '../../sources/ems_file_source';
// @ts-ignore
import { ESSearchSource } from '../../sources/es_search_source';
import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults';

const defaultDynamicProperties = getDefaultDynamicProperties();

function createChoroplethLayerDescriptor({
sourceDescriptor,
leftField,
rightIndexPatternId,
rightIndexPatternTitle,
rightTermField,
}: {
sourceDescriptor: EMSFileSourceDescriptor | ESSearchSourceDescriptor;
leftField: string;
rightIndexPatternId: string;
rightIndexPatternTitle: string;
rightTermField: string;
}) {
const metricsDescriptor: AggDescriptor = { type: AGG_TYPE.COUNT };
const joinId = uuid();
const joinKey = getJoinAggKey({
aggType: metricsDescriptor.type,
aggFieldName: metricsDescriptor.field ? metricsDescriptor.field : '',
rightSourceId: joinId,
});
return VectorLayer.createDescriptor({
joins: [
{
leftField,
right: {
type: SOURCE_TYPES.ES_TERM_SOURCE,
id: joinId,
indexPatternId: rightIndexPatternId,
indexPatternTitle: rightIndexPatternTitle,
term: rightTermField,
metrics: [metricsDescriptor],
},
},
],
sourceDescriptor,
style: VectorStyle.createDescriptor({
[VECTOR_STYLES.FILL_COLOR]: {
type: STYLE_TYPE.DYNAMIC,
options: {
...(defaultDynamicProperties[VECTOR_STYLES.FILL_COLOR]!.options as ColorDynamicOptions),
field: {
name: joinKey,
origin: FIELD_ORIGIN.JOIN,
},
color: 'Yellow to Red',
type: COLOR_MAP_TYPE.ORDINAL,
},
},
[VECTOR_STYLES.LINE_COLOR]: {
type: STYLE_TYPE.STATIC,
options: {
color: '#3d3d3d',
},
},
}),
});
}

export function createEmsChoroplethLayerDescriptor({
leftEmsFileId,
leftEmsField,
rightIndexPatternId,
rightIndexPatternTitle,
rightTermField,
}: {
leftEmsFileId: string;
leftEmsField: string;
rightIndexPatternId: string;
rightIndexPatternTitle: string;
rightTermField: string;
}) {
return createChoroplethLayerDescriptor({
sourceDescriptor: EMSFileSource.createDescriptor({
id: leftEmsFileId,
tooltipProperties: [leftEmsField],
}),
leftField: leftEmsField,
rightIndexPatternId,
rightIndexPatternTitle,
rightTermField,
});
}

export function createEsChoroplethLayerDescriptor({
leftIndexPatternId,
leftGeoField,
leftJoinField,
rightIndexPatternId,
rightIndexPatternTitle,
rightTermField,
}: {
leftIndexPatternId: string;
leftGeoField: string;
leftJoinField: string;
rightIndexPatternId: string;
rightIndexPatternTitle: string;
rightTermField: string;
}) {
return createChoroplethLayerDescriptor({
sourceDescriptor: ESSearchSource.createDescriptor({
indexPatternId: leftIndexPatternId,
geoField: leftGeoField,
scalingType: SCALING_TYPES.LIMIT,
tooltipProperties: [leftJoinField],
applyGlobalQuery: false,
}),
leftField: leftJoinField,
rightIndexPatternId,
rightIndexPatternTitle,
rightTermField,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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 { choroplethLayerWizardConfig } from './choropleth_layer_wizard';
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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.
*/

jest.mock('../../../kibana_services', () => {
const MockIndexPatternSelect = (props: unknown) => {
return <div />;
};
return {
getIndexPatternSelectComponent: () => {
return MockIndexPatternSelect;
},
};
});

import React from 'react';
import { shallow } from 'enzyme';
import { BOUNDARIES_SOURCE, LayerTemplate } from './layer_template';

const renderWizardArguments = {
previewLayers: () => {},
mapColors: [],
currentStepId: null,
enableNextBtn: () => {},
disableNextBtn: () => {},
startStepLoading: () => {},
stopStepLoading: () => {},
advanceToNextStep: () => {},
};

test('should render elasticsearch UI when left source is BOUNDARIES_SOURCE.ELASTICSEARCH', async () => {
const component = shallow(<LayerTemplate {...renderWizardArguments} />);
component.setState({ leftSource: BOUNDARIES_SOURCE.ELASTICSEARCH });
expect(component).toMatchSnapshot();
});

test('should render EMS UI when left source is BOUNDARIES_SOURCE.EMS', async () => {
const component = shallow(<LayerTemplate {...renderWizardArguments} />);
component.setState({ leftSource: BOUNDARIES_SOURCE.EMS });
expect(component).toMatchSnapshot();
});
Loading

0 comments on commit 9175981

Please sign in to comment.