First round of geo filter support

This commit is contained in:
Rashid Khan 2015-04-21 16:18:26 -07:00
parent 53318003ca
commit f23aa5f027
13 changed files with 128 additions and 5 deletions

View file

@ -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": {}
}

View file

@ -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;

View file

@ -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);
};
};
});

View file

@ -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',

View file

@ -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);
};

View file

@ -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
];

View 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);
};
};
});

View 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;
};
};
};
});

View 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;
};
});

View file

@ -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);
}
/**

View file

@ -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);

View file

@ -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([
{

View file

@ -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']
},