Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter geohash_grid aggregation to map view box with collar #12806

Merged
merged 20 commits into from
Jul 21, 2017

Conversation

nreese
Copy link
Contributor

@nreese nreese commented Jul 12, 2017

Apply geo_bounding_box filter aggregation to narrow the subject area to the map view box with collar as requested in issue #8087

Feature can be toggled off with new controls placed on the buckets aggregation page
screen shot 2017-07-12 at 11 31 31 am

Remaining issues

  • courier.fetch getting called anytime the map fires dragend or events. Kibana map updates the uiState when these event handlers are fired. This PR adds mapCollar to the uiState. As a result, courier shouldQuery unintentionally fires just because the aggs are different.
  • Fit Control does not really work since the entire dataset is no longer loaded in the browser

@thomasneirynck thomasneirynck added Feature:Visualizations Generic visualization features (in case no more specific feature label is available) release_note:enhancement labels Jul 12, 2017
Copy link
Contributor

@thomasneirynck thomasneirynck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, pressed submit review to quick.

@@ -87,7 +91,15 @@ export function MapsVisualizationProvider(serviceSettings, Notifier, getAppState
this._kibanaMap.on('zoomchange', () => {
precisionChange = (previousPrecision !== this._kibanaMap.getAutoPrecision());
previousPrecision = this._kibanaMap.getAutoPrecision();
this.vis.aggs[1].params.precision = previousPrecision;
const agg = this._getGeoHashAgg();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this new guard is breaking these tests: https://github.com/thomasneirynck/kibana/blob/bf63cac183e54f64a054eb781ffba5708270710e/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js#L52-L52

In that mock vis object in the test, will need to add mock aggregation.

<label>
Collar Scale <kbn-info info="Set the size of the geo_bounding_box filter applied to the map bounds. Small values could result in excessive fetches during map panning. Large values could result in trimmed results."></kbn-info>
</label>
<input type="number" class="form-control"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we even need to make this a user-facing setting. I would go for a good default (1.5 is fine). If it proves to be a problem in the wild, let's add it in. So I would just remove this option altogether.

If you think this is important, I'd rework it a little:

@@ -77,6 +79,8 @@ export function MapsVisualizationProvider(serviceSettings, Notifier, getAppState
options.center = centerFromUIState ? centerFromUIState : this.vis.type.visConfig.defaults.mapCenter;

this._kibanaMap = new KibanaMap(containerElement, options);
this._lastFetchedMapCollar = scaleBounds(this._kibanaMap.getBounds(), this._getCollarScale());
uiState.set('mapCollar', this._lastFetchedMapCollar);
this._kibanaMap.addDrawControl();
this._kibanaMap.addFitControl();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hide the fit-control when _isFilteredByCollar

@@ -300,7 +301,7 @@ export class KibanaMap extends EventEmitter {
return zoomToPrecision(this._leafletMap.getZoom(), 12, this._leafletMap.getMaxZoom());
}

getBounds() {
getBounds(isTrimmed = true) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider not having the default param and create different method called getTrimmedBounds

@thomasneirynck thomasneirynck self-requested a review July 12, 2017 22:58
Copy link
Contributor

@thomasneirynck thomasneirynck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at this only briefly, but this is pretty pretty cool!!

Some minor preliminary comments throughout.

We need to look into the following as well.
https://github.com/thomasneirynck/kibana/blob/b86f97ce0f83c50b8737c3cef75773f54d4df64a/src/core_plugins/tile_map/public/geohash_layer.js#L71-L71

The above hook is a carry-over from the depths of time in Kibana. It applies a client-side filter on the layer in leaflet on the collar, so not all svg elements are added to the screen. The downside is that we need to recreate these layer on each pan. This is kind of a hack. It may also be unncessary in later versions of Leaflet.

Now, by introducing a mode to do server-side filtering, this check is unncessary. So we need a way to propagate this to the geohash layer so it doesn't do this client-side filtering when server-side filtering is turned on.

Copy link
Contributor

@thomasneirynck thomasneirynck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, pretty nice!

Most of the comments relate to the wiring of the bounds and collar determination. I think that will simplify some things, and get the Region Map working again.

Good find on #12919. Let's solve this separately.

return true;
}

export function scaleBounds(bounds, scale) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove scale parameter and define 1.5 constant here. you can remove the safeScale justification then.

<input type="checkbox"
name="useFilter"
ng-model="agg.params.useFilter">
Enable collar (geo_bounding_box filter)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rename to something like:
'Only request data within the extent of the map'. Maybe with a little kbn-info button that refers to ES's geo_bounding_box filter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to shorten the description to get it to fit in the options width constraints. I set it to Only request data around extent of map <kbn-info info="Apply geo_bounding_box filter aggregation to narrow the subject area to the map view box with collar."></kbn-info>

@@ -58,6 +63,11 @@ export function AggTypesBucketsGeoHashProvider(Private, config) {
write: _.noop
},
{
name: 'useFilter',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rename to isFilteredByCollar, to match all the other usage.

@@ -517,7 +506,9 @@ export class KibanaMap extends EventEmitter {
}

_updateExtent() {
this._layers.forEach(layer => layer.updateExtent());
if (!this._isFilteredByCollar()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove this check from kibana_map, and check in geohash_layer instead. IMO, each layer should make the determination what to do when the extent is updated. It would also avoid the need to pass functions around to make this call.

@@ -309,15 +308,8 @@ export class KibanaMap extends EventEmitter {

const southEast = bounds.getSouthEast();
const northWest = bounds.getNorthWest();
let southEastLng = southEast.lng;
if (southEastLng > 180) {
southEastLng -= 360;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this no longer necessary? this was to prevent date-line wrapping, ES chokes on it. I may be missing something though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This trimming functionality does not return the correct bounding box when at a high zoom level. The returned value has a bottom_right that is to the left of top_left. In the original commit, this function was enhanced with a isTrimmed parameter so both cases could be satisfied and original consumers did not have to change their usage. Should I add the isTrimmed parameter back?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally not a fan of default params, since they hurt searchability in the code, especially in a language like JS. Would add a parallel method, getBoundsTrimmed, or getBoundsWithoutTrimming, whatever would require the least changes.

Anyways, it's your call ;) as long as we avoid regressing on #8946.

@@ -261,10 +272,47 @@ export function MapsVisualizationProvider(serviceSettings, Notifier, getAppState
this.vis.updateState();
}

}
async getGeohashBounds() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this.

Each layer should determine its bounds. We're throwing that away when creating this function that needs to be supplied to the FitControl.

I'd move this method to geohash_bounds, and modify fitToData so it can work with async results.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function is now passed to the geohash_layer. I did this instead of migrating the code to geohash_layer because several dependencies are not available in geohash_layer, like Private and vis index pattern.

@@ -75,10 +79,13 @@ export function MapsVisualizationProvider(serviceSettings, Notifier, getAppState
const centerFromUIState = uiState.get('mapCenter');
options.zoom = !isNaN(zoomFromUiState) ? zoomFromUiState : this.vis.type.visConfig.defaults.mapZoom;
options.center = centerFromUIState ? centerFromUIState : this.vis.type.visConfig.defaults.mapCenter;
options.isFilteredByCollar = this._isFilteredByCollar.bind(this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this functional approach. Also, this breaks the Region Map, because this option isn't applied See other comments on moving this to geohash_layer for different approach.

@@ -95,6 +95,7 @@ export class KibanaMap extends EventEmitter {
this._layers = [];
this._listeners = [];
this._showTooltip = false;
this._isFilteredByCollar = options.isFilteredByCollar;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see other related comments.

@thomasneirynck
Copy link
Contributor

jenkins, test this

@thomasneirynck
Copy link
Contributor

CI failing with:

Running "licenses" task
Fatal error: Non-conforming licenses: 
  ua-parser-js
    version: 0.7.14
    all licenses: (GPL-2.0 OR MIT)
    invalid licenses: (GPL-2.0 OR MIT)
    path: node_modules/ua-parser-js

https://kibana-ci.elastic.co/job/elastic+kibana+pull-request+multijob-intake/9165/console

?!?!?

@thomasneirynck
Copy link
Contributor

Rebasing with master should fix the CI error: cf. c3713a8

Copy link
Contributor

@thomasneirynck thomasneirynck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small thing still outstanding I think.

Collapsing the side bar increases the collar of the map. This may require a fetch of new data (similar with expanding the browser window). We can use the status.resize flag to detect this.

This also will need rebase for CI to work.

It would be nice to get in #12931 at the same time.

apart from that, lgtm! :)

@nreese nreese force-pushed the filter_geo_hash2 branch from cd3b0de to c54989e Compare July 19, 2017 16:59
Copy link
Member

@ppisljar ppisljar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really nice addition @nreese LGTM

@nreese nreese force-pushed the filter_geo_hash2 branch from c54989e to 9171cab Compare July 20, 2017 16:34
@thomasneirynck
Copy link
Contributor

looks good. CI is failing all PRs now, so let's just wait until done.

@nreese nreese force-pushed the filter_geo_hash2 branch from b0e49a0 to 98cc386 Compare July 21, 2017 00:24
@nreese
Copy link
Contributor Author

nreese commented Jul 21, 2017

jenkins, test this

@nreese nreese merged commit 72f6b8a into elastic:master Jul 21, 2017
@@ -182,26 +202,28 @@ export default function ({ getService, getPageObjects }) {
** changed, then open the saved viz and check that it's back to the original data.
*/
it('should save with zoom level and load, take screenshot', function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test failed on master

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Visualizations Generic visualization features (in case no more specific feature label is available) release_note:enhancement v6.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants