I have written a custom visualisation for Kibana 6.5, which has its own custom request and response handlers. It queries elasticsearch and returns all the data for the chosen time period in its raw format. My issue is that I need to apply a filter to this data when I do the search. I want these filters to be chosen on the screen via 2-3 drop down boxes (or something similar), and then once they are chosen I can execute the search.
So for example, my index has fields constellation
and gms
, both of which which are type text
. They each have a certain number of values. So if I choose for constellation constellationValue1
, and for gms gmsValue5
, I then want to execute the search where constellation:"constellationValue1"
and "gms:gmsValue5
, and have all the data that matches this criteria returned (for the chosen time period).
So my question is 2 fold:
- How do I add to my UI the drop down boxes with the options for the filter values?
- How do I pass these choices into my request handler?
For the second part, I know that the requestHandler
takes 3 parameters: params
, queryFilter
and timeFilter
. I already use timeFilter
to search for the given time period, but can I use the other two to pass the values from the drop down boxes into the query? Is that how it would work? I have seen in this documentation on filter context that you can add a filter
to the query. Is this the correct approach?
My code is below for my current visualisation and the request handler, I've also attached a screenshot of what the visualisation looks like at the moment. I want to replace the current metrics and buckets schema
with what I have described above. I simply found the code for those online as a placeholder for where I would like these to go, I don't know what they actually do or how they work at this time.
self_changing_vis.js
import { VisFactoryProvider } from 'ui/vis/vis_factory';
import { VisTypesRegistryProvider } from 'ui/registry/vis_types';
import { SelfChangingEditor } from './self_changing_editor';
import { SelfChangingComponent } from './self_changing_components';
import { Schemas } from 'ui/vis/editors/default/schemas';
import optionsTemplate from './options_template.html';
import { RequestHandlerProvider } from './requestHandler.js';
import handleResponse from './responseHandler.js';
const myResponseHandler = (vis, response) => {
// transform the response (based on vis object?)
console.log('1: ', response);
console.log('2 : ', vis);
return response;
};
function SelfChangingVisType(Private) {
const VisFactory = Private(VisFactoryProvider);
const RequestHandler = Private(RequestHandlerProvider);
return VisFactory.createReactVisualization({
name: 'self_changing_vis',
title: 'Skyplot',
icon: 'visControls',
description: 'This visualization is able to change its own settings, that you could also set in the editor.',
visConfig: {
component: SelfChangingComponent,
defaults: {
counter: 0,
constellation: 'GPS'
},
},
editor: 'default',
editorConfig: {
optionsTemplate: optionsTemplate,
schemas: new Schemas([
{
group: 'metrics',
name: 'metric',
title: 'Metric',
min: 1,
aggFilter: ['!derivative', '!geo_centroid'],
defaults: [
{ type: 'count', schema: 'metric' }
]
}, {
group: 'buckets',
name: 'segment',
title: 'Bucket Split',
min: 0,
max: 1,
aggFilter: ['!geohash_grid', '!filter']
}
]),
},
requestHandler: RequestHandler.handle,
responseHandler: handleResponse,
});
}
VisTypesRegistryProvider.register(SelfChangingVisType);
requestHandler.js
const getRequestBody = (params, queryFilter, timeFilter) => {
console.log('params: ', params);
console.log('queryFilter: ', queryFilter);
const requestBody = {
'query': {
'bool': {
'must': [
{
'range': {
'timestamp': {
'gte': timeFilter.from,
'lte': timeFilter.to
}
}
}
]
}
}
};
return requestBody;
};
export function RequestHandlerProvider(Private, es) {
return {
handle(vis) {
const { timeFilter, queryFilter } = vis.API;
return new Promise(resolve => {
const params = vis.params;
const requestBody = getRequestBody(params, queryFilter, timeFilter._time);
es.search({
index: 'observed_range_error',
body: requestBody
}).then(result => resolve(result));
});
}
};
}
Screenshot