mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
First round of geo filter support
This commit is contained in:
parent
53318003ca
commit
f23aa5f027
13 changed files with 128 additions and 5 deletions
|
@ -49,7 +49,8 @@
|
|||
"requirejs-text": "~2.0.10",
|
||||
"lodash-deep": "spenceralger/lodash-deep#compat",
|
||||
"marked": "~0.3.2",
|
||||
"numeral": "~1.5.3"
|
||||
"numeral": "~1.5.3",
|
||||
"leaflet-draw": "~0.2.4"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
define(function (require) {
|
||||
var decodeGeoHash = require('utils/decode_geo_hash');
|
||||
var _ = require('lodash');
|
||||
|
||||
function readRows(table, agg, index, chart) {
|
||||
var geoJson = chart.geoJson;
|
||||
|
@ -8,6 +9,7 @@ define(function (require) {
|
|||
props.length = table.rows.length;
|
||||
props.min = null;
|
||||
props.max = null;
|
||||
props.agg = agg;
|
||||
|
||||
table.rows.forEach(function (row) {
|
||||
var geohash = row[index.geo].value;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
define(function (require) {
|
||||
var buildGeoBoundingBox = require('components/filter_manager/lib/geo_bounding_box');
|
||||
return function createTermsFilterProvider(Private) {
|
||||
return function (aggConfig, key) {
|
||||
return buildGeoBoundingBox(aggConfig.params.field, key, aggConfig.vis.indexPattern);
|
||||
};
|
||||
};
|
||||
});
|
|
@ -3,6 +3,8 @@ define(function (require) {
|
|||
var _ = require('lodash');
|
||||
var moment = require('moment');
|
||||
var BucketAggType = Private(require('components/agg_types/buckets/_bucket_agg_type'));
|
||||
var createFilter = Private(require('components/agg_types/buckets/create_filter/geohash_grid'));
|
||||
|
||||
var defaultPrecision = 3;
|
||||
|
||||
function getPrecision(precision) {
|
||||
|
@ -24,6 +26,7 @@ define(function (require) {
|
|||
return new BucketAggType({
|
||||
name: 'geohash_grid',
|
||||
title: 'Geohash',
|
||||
createFilter: createFilter,
|
||||
params: [
|
||||
{
|
||||
name: 'field',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
define(function (require) {
|
||||
return function mapDefaultProvider(Promise) {
|
||||
var angular = require('angular');
|
||||
var _ = require('lodash');
|
||||
|
||||
return function (filter) {
|
||||
var key, value;
|
||||
|
@ -8,6 +9,10 @@ define(function (require) {
|
|||
key = 'query';
|
||||
value = angular.toJson(filter.query);
|
||||
return Promise.resolve({ key: key, value: value });
|
||||
} else {
|
||||
var displayFilter = _.clone(filter);
|
||||
delete displayFilter.meta;
|
||||
return Promise.resolve({ key: 'filter', value: angular.toJson(displayFilter)});
|
||||
}
|
||||
return Promise.reject(filter);
|
||||
};
|
||||
|
|
|
@ -26,6 +26,7 @@ define(function (require) {
|
|||
Private(require('./mapExists')),
|
||||
Private(require('./mapMissing')),
|
||||
Private(require('./mapQueryString')),
|
||||
Private(require('./mapGeoBoundingBox')),
|
||||
Private(require('./mapScript')),
|
||||
Private(require('./mapDefault')) // ProTip: last one to get applied
|
||||
];
|
||||
|
|
21
src/kibana/components/filter_bar/lib/mapGeoBoundingBox.js
Normal file
21
src/kibana/components/filter_bar/lib/mapGeoBoundingBox.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
return function mapGeoBoundBoxProvider(Promise, courier) {
|
||||
return function (filter) {
|
||||
var key, value, topLeft, bottomRight, field;
|
||||
if (filter.geo_bounding_box) {
|
||||
return courier
|
||||
.indexPatterns
|
||||
.get(filter.meta.index).then(function (indexPattern) {
|
||||
key = _.keys(filter.geo_bounding_box)[0];
|
||||
field = indexPattern.fields.byName[key];
|
||||
topLeft = field.format.convert(filter.geo_bounding_box[field.name].top_left);
|
||||
bottomRight = field.format.convert(filter.geo_bounding_box[field.name].bottom_right);
|
||||
value = topLeft + ' to ' + bottomRight;
|
||||
return { key: key, value: value };
|
||||
});
|
||||
}
|
||||
return Promise.reject(filter);
|
||||
};
|
||||
};
|
||||
});
|
18
src/kibana/components/filter_bar/push_filter.js
Normal file
18
src/kibana/components/filter_bar/push_filter.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
|
||||
return function (Notifier) {
|
||||
return function ($state) {
|
||||
return function (filter, negate, index) {
|
||||
// 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
|
||||
var filters = _.clone($state.filters);
|
||||
var pendingFilter = { meta: { negate: negate, index: index }};
|
||||
_.extend(pendingFilter, filter);
|
||||
filters.push(pendingFilter);
|
||||
$state.filters = filters;
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
20
src/kibana/components/filter_manager/lib/geo_bounding_box.js
Normal file
20
src/kibana/components/filter_manager/lib/geo_bounding_box.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
return function buildGeoBoundingBoxFilter(field, value, indexPattern) {
|
||||
var filter = { meta: { index: indexPattern.id} };
|
||||
|
||||
if (field.scripted) {
|
||||
filter.script = {
|
||||
script: '(' + field.script + ') == value',
|
||||
lang: field.lang,
|
||||
params: {
|
||||
value: value
|
||||
}
|
||||
};
|
||||
filter.meta.field = field.name;
|
||||
} else {
|
||||
filter.geo_bounding_box = value;
|
||||
}
|
||||
return filter;
|
||||
};
|
||||
});
|
|
@ -13,13 +13,14 @@ define(function (require) {
|
|||
*/
|
||||
|
||||
function Dispatch(handler) {
|
||||
var eventTypes = ['brush', 'click', 'hover', 'mouseup', 'mousedown', 'mouseover', 'mouseout'].concat(handler.vis.eventTypes.enabled);
|
||||
|
||||
if (!(this instanceof Dispatch)) {
|
||||
return new Dispatch(handler);
|
||||
}
|
||||
|
||||
this.handler = handler;
|
||||
this.dispatch = d3.dispatch('brush', 'click', 'hover', 'mouseup',
|
||||
'mousedown', 'mouseover', 'mouseout');
|
||||
this.dispatch = d3.dispatch.apply(this, eventTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,7 +3,9 @@ define(function (require) {
|
|||
var _ = require('lodash');
|
||||
var $ = require('jquery');
|
||||
var L = require('leaflet');
|
||||
require('leaflet-draw');
|
||||
|
||||
var Dispatch = Private(require('components/vislib/lib/dispatch'));
|
||||
var Chart = Private(require('components/vislib/visualizations/_chart'));
|
||||
var errors = require('errors');
|
||||
|
||||
|
@ -32,6 +34,8 @@ define(function (require) {
|
|||
// track the map objects
|
||||
this.maps = [];
|
||||
|
||||
this.events = new Dispatch(handler);
|
||||
|
||||
// add allmin and allmax to geoJson
|
||||
chartData.geoJson.properties.allmin = chartData.geoJson.properties.min;
|
||||
chartData.geoJson.properties.allmax = chartData.geoJson.properties.max;
|
||||
|
@ -85,7 +89,8 @@ define(function (require) {
|
|||
noWrap: true,
|
||||
maxBounds: worldBounds,
|
||||
scrollWheelZoom: false,
|
||||
fadeAnimation: false
|
||||
fadeAnimation: false,
|
||||
drawControl: true
|
||||
};
|
||||
|
||||
var map = L.map(div[0], mapOptions);
|
||||
|
@ -105,6 +110,28 @@ define(function (require) {
|
|||
mapCenter = self._attr.mapCenter = map.getCenter();
|
||||
});
|
||||
|
||||
map.on('draw:created', function (e) {
|
||||
var type = e.layerType;
|
||||
var layer = e.layer;
|
||||
var bounds = layer.getBounds();
|
||||
|
||||
self.events.dispatch.square({
|
||||
e: e,
|
||||
data: self.chartData,
|
||||
bounds: {
|
||||
top_left: {
|
||||
lat: bounds.getNorthWest().lat,
|
||||
lon: bounds.getNorthWest().lng
|
||||
},
|
||||
bottom_right: {
|
||||
lat: bounds.getSouthEast().lat,
|
||||
lon: bounds.getSouthEast().lng
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// add label for splits
|
||||
if (mapData.properties.label) {
|
||||
self.addLabel(mapData.properties.label, map);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
define(function (require) {
|
||||
return function TileMapVisType(Private) {
|
||||
return function TileMapVisType(Private, getAppState) {
|
||||
var VislibVisType = Private(require('plugins/vis_types/vislib/_vislib_vis_type'));
|
||||
var Schemas = Private(require('plugins/vis_types/_schemas'));
|
||||
var geoJsonConverter = Private(require('components/agg_response/geo_json/geo_json'));
|
||||
|
@ -18,6 +18,18 @@ define(function (require) {
|
|||
mapTypes: ['Scaled Circle Markers', 'Shaded Circle Markers', 'Shaded Geohash Grid', 'Pins'],
|
||||
editor: require('text!plugins/vis_types/vislib/editors/tile_map.html')
|
||||
},
|
||||
listeners: {
|
||||
square: function (event) {
|
||||
var pushFilter = Private(require('components/filter_bar/push_filter'))(getAppState());
|
||||
var indexPatternName = event.data.geoJson.properties.agg.geo.vis.indexPattern.id;
|
||||
|
||||
var field = event.data.geoJson.properties.agg.geo.fieldName();
|
||||
var filter = {geo_bounding_box: {}};
|
||||
filter.geo_bounding_box[field] = event.bounds;
|
||||
|
||||
pushFilter(filter, false, indexPatternName);
|
||||
}
|
||||
},
|
||||
responseConverter: geoJsonConverter,
|
||||
schemas: new Schemas([
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@ require.config({
|
|||
inflection: 'bower_components/inflection/lib/inflection',
|
||||
jquery: 'bower_components/jquery/dist/jquery',
|
||||
leaflet: 'bower_components/leaflet/dist/leaflet',
|
||||
'leaflet-draw': 'bower_components/leaflet-draw/dist/leaflet.draw',
|
||||
lodash_src: 'bower_components/lodash/dist/lodash',
|
||||
'lodash-deep': 'bower_components/lodash-deep/factory',
|
||||
moment: 'bower_components/moment/moment',
|
||||
|
@ -56,6 +57,9 @@ require.config({
|
|||
file_saver: {
|
||||
exports: 'saveAs'
|
||||
},
|
||||
'leaflet-draw': {
|
||||
deps: ['leaflet', 'css!bower_components/leaflet-draw/dist/leaflet.draw.css']
|
||||
},
|
||||
leaflet: {
|
||||
deps: ['css!bower_components/leaflet/dist/leaflet.css']
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue