Skip to content

Commit

Permalink
bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasneirynck committed Feb 21, 2017
1 parent 2796e77 commit 3ffdc35
Show file tree
Hide file tree
Showing 24 changed files with 1,349 additions and 1,423 deletions.
9 changes: 9 additions & 0 deletions src/core_plugins/choropleth/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function (kibana) {

return new kibana.Plugin({
uiExports: {
visTypes: ['plugins/choropleth/choropleth_vis']
}
});

}
4 changes: 4 additions & 0 deletions src/core_plugins/choropleth/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "choropleth",
"version": "kibana"
}
7 changes: 7 additions & 0 deletions src/core_plugins/choropleth/public/choropleth.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.choropleth-vis {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
3 changes: 3 additions & 0 deletions src/core_plugins/choropleth/public/choropleth_controller.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div ng-controller="KbnChoroplethController" class="choropleth-vis">

</div>
98 changes: 98 additions & 0 deletions src/core_plugins/choropleth/public/choropleth_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import uiModules from 'ui/modules';
import _ from 'lodash';
import AggConfigResult from 'ui/vis/agg_config_result';
import KibanaMap from 'ui/vis_maps/kibana_map.js';
import FilterBarFilterBarClickHandlerProvider from 'ui/filter_bar/filter_bar_click_handler';
import colorramps from 'ui/vislib/components/color/colormaps';

const module = uiModules.get('kibana/choropleth', ['kibana']);
module.controller('KbnChoroplethController', function ($scope, $element, Private, getAppState, tilemapSettings) {

const containerNode = $element[0];
const kibanaMap = new KibanaMap(containerNode);
const url = tilemapSettings.getUrl();
const options = tilemapSettings.getTMSOptions();
kibanaMap.setBaseLayer({
baseLayerType: 'tms',
options: { url, ...options }
});

const filterBarClickHandler = Private(FilterBarFilterBarClickHandlerProvider);

kibanaMap.on('choropleth:select', function (event) {
const appState = getAppState();
const clickHandler = filterBarClickHandler(appState);
const aggs = $scope.vis.aggs.getResponseAggs();
const aggConfigResult = new AggConfigResult(aggs[0], false, event, event);
clickHandler({ point: { aggConfigResult: aggConfigResult } });
});

$scope.$watch('esResponse', async function (response) {


const termAggId = _.first(_.pluck($scope.vis.aggs.bySchemaName.segment, 'id'));

let results;
if (!response || !response.aggregations) {
results = [];
} else {
const metricsAgg = _.first($scope.vis.aggs.bySchemaName.metric);
const buckets = response.aggregations[termAggId].buckets;
results = buckets.map((bucket) => {
return {
term: bucket.key,
value: getValue(metricsAgg, bucket)
};
});
}



const options = $scope.vis.params;
// if (!options.selectedLayer.url || !options.selectedJoinField) {
// console.log('invalid selection');//todo: fix this
// return;
// }

if (!options.selectedJoinField) {
options.selectedJoinField = options.selectedLayer.fields[0];
}

kibanaMap.setChoroplethLayer(options.selectedLayer.url, options.selectedJoinField);
kibanaMap.setChoroplethMetrics(results);
kibanaMap.resize();

});

$scope.$watch('vis.params', (options) => {
if (!options.selectedJoinField) {
options.selectedJoinField = options.selectedLayer.fields[0];
}
kibanaMap.setChoroplethLayer(options.selectedLayer.url, options.selectedJoinField);
kibanaMap.setChoroplethColorRamp(colorramps[options.colorSchema]);
kibanaMap.resize();
});

$scope.$watch(getContainerSize, _.debounce(() => {
kibanaMap.resize();
}, 500, { trailing: true }), true);

function getContainerSize() {
return { width: $element.width(), height: $element.height() };
}

});


function getValue(metricsAgg, bucket) {
let size = metricsAgg.getValue(bucket);
if (typeof size !== 'number' || isNaN(size)) {
try {
size = bucket[1].values[0].value;//lift out first value (e.g. median aggregations return as array)
} catch (e) {
size = 1;//punt
}
}
return size;
}

57 changes: 57 additions & 0 deletions src/core_plugins/choropleth/public/choropleth_vis.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'plugins/choropleth/choropleth.less';
import 'plugins/choropleth/choropleth_controller';
import 'plugins/choropleth/choropleth_vis_params';
import TemplateVisTypeTemplateVisTypeProvider from 'ui/template_vis_type/template_vis_type';
import VisSchemasProvider from 'ui/vis/schemas';
import choroplethTemplate from 'plugins/choropleth/choropleth_controller.html';
import visTypes from 'ui/registry/vis_types';
import colorramps from 'ui/vislib/components/color/colormaps';
import vectorMaps from 'plugins/choropleth/vector_maps';

visTypes.register(function ChoroplethProvider(Private) {
const TemplateVisType = Private(TemplateVisTypeTemplateVisTypeProvider);
const Schemas = Private(VisSchemasProvider);

return new TemplateVisType({
name: 'choropleth',
title: 'Vector Map',
implementsRenderComplete: true,
description: 'Show metrics on a thematic map. Darker colors represent higher values.',
icon: 'fa-globe',
template: choroplethTemplate,
params: {
defaults: {
colorSchema: 'Yellow to Red',
selectedLayer: vectorMaps.Countries,
selectedJoinField: vectorMaps.Countries.fields[0]
},
colorSchemas: Object.keys(colorramps),
vectorMaps: vectorMaps,
editor: '<choropleth-vis-params></choropleth-vis-params>'
},
schemas: new Schemas([
{
group: 'metrics',
name: 'metric',
title: '',
min: 1,
max: 1,
aggFilter: ['!std_dev', '!percentiles', '!percentile_ranks'],
defaults: [
{ schema: 'metric', type: 'count' }
]
},
{
group: 'buckets',
name: 'segment',
icon: 'fa fa-globe',
title: 'shape field',
min: 1,
max: 1,
aggFilter: ['terms']
}
])
});
});


46 changes: 46 additions & 0 deletions src/core_plugins/choropleth/public/choropleth_vis_params.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<div class="form-group">
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="colorSchema">
Color Schema
</label>
<div class="kuiSideBarFormRow__control">
<select
id="colorSchema"
class="kuiSelect kuiSideBarSelect"
ng-model="vis.params.colorSchema"
ng-options="mode for mode in vis.type.params.colorSchemas"
></select>
</div>
</div>
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="vectorMap">
Vector map
</label>
<div class="kuiSideBarFormRow__control">
<select
id="vectorMap"
class="kuiSelect kuiSideBarSelect"
ng-model="vis.params.selectedLayer"
ng-options="layer for (layer, meta) in vis.type.params.vectorMaps"
></select>
</div>
</div>

<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="joinField">
Join on field
</label>
<div class="kuiSideBarFormRow__control">
<select id="joinField"
ng-model="vis.params.selectedJoinField"
ng-options="field for field in vis.params.selectedLayer.fields"
ng-init="vis.params.selectedJoinField=vis.params.selectedLayer.fields[0]"
>
<option value=''>Select</option></select>
</div>
</div>




</div>
13 changes: 13 additions & 0 deletions src/core_plugins/choropleth/public/choropleth_vis_params.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import uiModules from 'ui/modules';
import choroplethVisParamsTemplate from 'plugins/choropleth/choropleth_vis_params.html';

uiModules.get('kibana/choropleth')
.directive('choroplethVisParams', function () {
return {
restrict: 'E',
template: choroplethVisParamsTemplate,
link: function ($scope, $element) {

}
};
});
29 changes: 29 additions & 0 deletions src/core_plugins/choropleth/public/vector_maps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const vectorMaps = {
'Countries': {
url: '../plugins/choropleth/data/world_countries.geojson',
fields: ['iso']
},
'States': {
url: '../plugins/choropleth/data/us_states.geojson',
fields: ['NAME']
}
};

// const vectorMaps = {
// 'Countries': ['iso'],
// 'States': ['name', 'abbr']
// };
//
// const vectorMaps = [{
// name: 'Countries',
// url: '../plugins/choropleth/data/world_countries.geojson',
// fields: ['iso']
// },
// {
// name: 'States',
// url: '../plugins/choropleth/data/us_states.geojson',
// fields: ['name', 'abbr']
// }];


export default vectorMaps;
62 changes: 31 additions & 31 deletions src/core_plugins/kbn_vislib_vis_types/public/tile_map.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,37 +49,37 @@ export default function TileMapVisType(Private, getAppState, courier, config) {
canDesaturate: !!supports.cssFilters,
editor: tileMapTemplate
},
listeners: {
rectangle: function (event) {
const agg = _.get(event, 'chart.geohashGridAgg');
if (!agg) return;

const pushFilter = Private(FilterBarPushFilterProvider)(getAppState());
const indexPatternName = agg.vis.indexPattern.id;
const field = agg.fieldName();
const filter = { geo_bounding_box: {} };
filter.geo_bounding_box[field] = event.bounds;

pushFilter(filter, false, indexPatternName);
},
mapMoveEnd: function (event) {
const vis = _.get(event, 'chart.geohashGridAgg.vis');
if (vis && vis.hasUiState()) {
vis.getUiState().set('mapCenter', event.center);
}
},
mapZoomEnd: function (event) {
const vis = _.get(event, 'chart.geohashGridAgg.vis');
if (vis && vis.hasUiState()) {
vis.getUiState().set('mapZoom', event.zoom);
}

const autoPrecision = _.get(event, 'chart.geohashGridAgg.params.autoPrecision');
if (autoPrecision) {
courier.fetch();
}
}
},
// listeners: {
// rectangle: function (event) {
// const agg = _.get(event, 'chart.geohashGridAgg');
// if (!agg) return;
//
// const pushFilter = Private(FilterBarPushFilterProvider)(getAppState());
// const indexPatternName = agg.vis.indexPattern.id;
// const field = agg.fieldName();
// const filter = { geo_bounding_box: {} };
// filter.geo_bounding_box[field] = event.bounds;
//
// pushFilter(filter, false, indexPatternName);
// },
// mapMoveEnd: function (event) {
// const vis = _.get(event, 'chart.geohashGridAgg.vis');
// if (vis && vis.hasUiState()) {
// vis.getUiState().set('mapCenter', event.center);
// }
// },
// mapZoomEnd: function (event) {
// const vis = _.get(event, 'chart.geohashGridAgg.vis');
// if (vis && vis.hasUiState()) {
// vis.getUiState().set('mapZoom', event.zoom);
// }
//
// const autoPrecision = _.get(event, 'chart.geohashGridAgg.params.autoPrecision');
// if (autoPrecision) {
// courier.fetch();
// }
// }
// },
responseConverter: geoJsonConverter,
implementsRenderComplete: true,
schemas: new Schemas([
Expand Down
36 changes: 36 additions & 0 deletions src/ui/public/filter_bar/put_filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import _ from 'lodash';

export default function () {

return function ($state) {
if (!_.isObject($state)) throw new Error('pushFilters requires a state object');
return function (filter, negate, index, filterId) {
// Hierarchical and tabular data set their aggConfigResult parameter
// differently because of how the point is rewritten between the two. So
// we need to check if the point.orig is set, if not use try the point.aggConfigResult
const filters = _.clone($state.filters || []);
let position = -1;
if (filterId) {
filters.forEach((filter, ind) => {
if (filterId === filter.meta._id) {
position = ind;
}
});

if (position > -1) {
const pendingFilter = { meta: { negate: negate, index: index, _id: filterId } };
_.extend(pendingFilter, filter);
filters[position] = pendingFilter;
$state.filters = filters;
return false;
}
}

const pendingFilter = { meta: { negate: negate, index: index, _id: filterId } };
_.extend(pendingFilter, filter);
filters.push(pendingFilter);
$state.filters = filters;
return true;
};
};
}
Loading

0 comments on commit 3ffdc35

Please sign in to comment.