mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
changing vis.API.events (#25280)
This commit is contained in:
parent
33f61a8fa2
commit
6dd2c1c0da
19 changed files with 211 additions and 184 deletions
|
@ -80,6 +80,9 @@ export default function GaugeVisType(Private, i18n) {
|
|||
}
|
||||
},
|
||||
},
|
||||
events: {
|
||||
brush: { disabled: true },
|
||||
},
|
||||
editorConfig: {
|
||||
collections: {
|
||||
gaugeTypes: ['Arc', 'Circle'],
|
||||
|
|
|
@ -76,6 +76,9 @@ export default function GoalVisType(Private, i18n) {
|
|||
}
|
||||
},
|
||||
},
|
||||
events: {
|
||||
brush: { disabled: true },
|
||||
},
|
||||
editorConfig: {
|
||||
collections: {
|
||||
gaugeTypes: ['Arc', 'Circle'],
|
||||
|
|
|
@ -46,6 +46,9 @@ export default function HistogramVisType(Private, i18n) {
|
|||
}
|
||||
},
|
||||
},
|
||||
events: {
|
||||
brush: { disabled: true },
|
||||
},
|
||||
editorConfig: {
|
||||
collections: {
|
||||
legendPositions: [{
|
||||
|
|
|
@ -159,7 +159,7 @@ export class MetricVisComponent extends Component {
|
|||
return;
|
||||
}
|
||||
const table = this.props.visData;
|
||||
this.props.vis.API.events.addFilter(table, metric.columnIndex, metric.rowIndex);
|
||||
this.props.vis.API.events.filter({ table, column: metric.columnIndex, row: metric.rowIndex });
|
||||
};
|
||||
|
||||
_renderMetric = (metric, index) => {
|
||||
|
|
|
@ -154,7 +154,7 @@ export function RegionMapsVisualizationProvider(Private, config, i18n) {
|
|||
}
|
||||
|
||||
const rowIndex = this._chartData.rows.findIndex(row => row[0] === event);
|
||||
this._vis.API.events.addFilter(this._chartData, 0, rowIndex, event);
|
||||
this._vis.API.events.filter({ table: this._chartData, column: 0, row: rowIndex, value: event });
|
||||
});
|
||||
|
||||
this._choroplethLayer.on('styleChanged', (event) => {
|
||||
|
|
|
@ -47,9 +47,9 @@ export class TagCloudVisualization {
|
|||
if (!this._bucketAgg) {
|
||||
return;
|
||||
}
|
||||
this._vis.API.events.addFilter(
|
||||
event.meta.data, 0, event.meta.rowIndex
|
||||
);
|
||||
this._vis.API.events.filter({
|
||||
table: event.meta.data, column: 0, row: event.meta.rowIndex
|
||||
});
|
||||
});
|
||||
this._renderComplete$ = Rx.fromEvent(this._tagCloud, 'renderComplete');
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
import ngMock from 'ng_mock';
|
||||
import sinon from 'sinon';
|
||||
import expect from 'expect.js';
|
||||
import { VisProvider } from '..';
|
||||
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
|
||||
|
@ -42,15 +41,6 @@ describe('Vis Class', function () {
|
|||
listeners: { click: _.noop }
|
||||
};
|
||||
|
||||
// Wrap the given vis type definition in a state, that can be passed to vis
|
||||
const state = (type) => ({
|
||||
type: {
|
||||
visConfig: { defaults: {} },
|
||||
schemas: {},
|
||||
...type,
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
Vis = Private(VisProvider);
|
||||
|
@ -116,41 +106,4 @@ describe('Vis Class', function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe('vis addFilter method', () => {
|
||||
let aggConfig;
|
||||
let data;
|
||||
|
||||
beforeEach(() => {
|
||||
aggConfig = {
|
||||
type: { name: 'terms' },
|
||||
params: {},
|
||||
createFilter: sinon.stub()
|
||||
};
|
||||
|
||||
data = {
|
||||
columns: [{
|
||||
id: 'col-0',
|
||||
title: 'test',
|
||||
aggConfig
|
||||
}],
|
||||
rows: [{ 'col-0': 'US' }]
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
it('adds a simple filter', () => {
|
||||
const vis = new Vis(indexPattern, state({ requestHandler: 'none' }));
|
||||
vis.API.events.addFilter(data, 0, 0);
|
||||
expect(aggConfig.createFilter.callCount).to.be(1);
|
||||
expect(aggConfig.createFilter.getCall(0).args[0]).to.be('US');
|
||||
});
|
||||
|
||||
it('adds a filter if value is provided instead of row index', () => {
|
||||
const vis = new Vis(indexPattern, state({ requestHandler: 'none' }));
|
||||
vis.API.events.addFilter(data, 0, -1, 'UK');
|
||||
expect(aggConfig.createFilter.callCount).to.be(1);
|
||||
expect(aggConfig.createFilter.getCall(0).args[0]).to.be('UK');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -18,9 +18,16 @@
|
|||
*/
|
||||
|
||||
import expect from 'expect.js';
|
||||
import { BaseVisType } from '../../vis_types/base_vis_type';
|
||||
import ngMock from 'ng_mock';
|
||||
import { BaseVisTypeProvider } from '../../vis_types/base_vis_type';
|
||||
|
||||
describe('Base Vis Type', function () {
|
||||
let BaseVisType;
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
BaseVisType = Private(BaseVisTypeProvider);
|
||||
}));
|
||||
|
||||
describe('initialization', () => {
|
||||
it('should throw if mandatory properties are missing', () => {
|
||||
|
|
|
@ -18,10 +18,13 @@
|
|||
*/
|
||||
|
||||
import expect from 'expect.js';
|
||||
import { ReactVisType } from '../../vis_types/react_vis_type';
|
||||
import ngMock from 'ng_mock';
|
||||
import { ReactVisTypeProvider } from '../../vis_types/react_vis_type';
|
||||
|
||||
describe('React Vis Type', function () {
|
||||
|
||||
let ReactVisType;
|
||||
|
||||
const visConfig = {
|
||||
name: 'test',
|
||||
title: 'test',
|
||||
|
@ -31,6 +34,11 @@ describe('React Vis Type', function () {
|
|||
type: { visConfig: { component: 'test' } }
|
||||
};
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
ReactVisType = Private(ReactVisTypeProvider);
|
||||
}));
|
||||
|
||||
describe('initialization', () => {
|
||||
it('should throw if component is not set', () => {
|
||||
expect(() => {
|
||||
|
|
|
@ -32,20 +32,17 @@ import _ from 'lodash';
|
|||
import { VisTypesRegistryProvider } from '../registry/vis_types';
|
||||
import { AggConfigs } from './agg_configs';
|
||||
import { PersistedState } from '../persisted_state';
|
||||
import { onBrushEvent } from '../utils/brush_event';
|
||||
import { FilterBarQueryFilterProvider } from '../filter_bar/query_filter';
|
||||
import { updateVisualizationConfig } from './vis_update';
|
||||
import { SearchSourceProvider } from '../courier/search_source';
|
||||
import { SavedObjectsClientProvider } from '../saved_objects';
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
import { VisFiltersProvider } from './vis_filters';
|
||||
|
||||
export function VisProvider(Private, indexPatterns, getAppState) {
|
||||
const visTypes = Private(VisTypesRegistryProvider);
|
||||
const queryFilter = Private(FilterBarQueryFilterProvider);
|
||||
const SearchSource = Private(SearchSourceProvider);
|
||||
const savedObjectsClient = Private(SavedObjectsClientProvider);
|
||||
const visFilter = Private(VisFiltersProvider);
|
||||
|
||||
class Vis extends EventEmitter {
|
||||
constructor(indexPattern, visState) {
|
||||
|
@ -73,14 +70,8 @@ export function VisProvider(Private, indexPatterns, getAppState) {
|
|||
timeFilter: timefilter,
|
||||
queryFilter: queryFilter,
|
||||
events: {
|
||||
// the filter method will be removed in the near feature
|
||||
// you should rather use addFilter method below
|
||||
filter: visFilter.filter,
|
||||
createFilter: visFilter.createFilter,
|
||||
addFilter: visFilter.addFilter,
|
||||
brush: (event) => {
|
||||
onBrushEvent(event, getAppState());
|
||||
}
|
||||
filter: data => this.eventsSubject.next({ name: 'filterBucket', data }),
|
||||
brush: data => this.eventsSubject.next({ name: 'brush', data }),
|
||||
},
|
||||
getAppState,
|
||||
};
|
||||
|
|
|
@ -17,11 +17,13 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { BaseVisType, AngularVisTypeProvider, ReactVisType, VislibVisTypeProvider } from './vis_types';
|
||||
import { BaseVisTypeProvider, AngularVisTypeProvider, ReactVisTypeProvider, VislibVisTypeProvider } from './vis_types';
|
||||
|
||||
export const VisFactoryProvider = (Private) => {
|
||||
const AngularVisType = Private(AngularVisTypeProvider);
|
||||
const VislibVisType = Private(VislibVisTypeProvider);
|
||||
const BaseVisType = Private(BaseVisTypeProvider);
|
||||
const ReactVisType = Private(ReactVisTypeProvider);
|
||||
|
||||
return {
|
||||
createBaseVisualization: (config) => {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import _ from 'lodash';
|
||||
import { FilterBarPushFiltersProvider } from '../filter_bar/push_filters';
|
||||
import { FilterBarQueryFilterProvider } from '../filter_bar/query_filter';
|
||||
import { onBrushEvent } from '../utils/brush_event';
|
||||
|
||||
const getTerms = (table, columnIndex, rowIndex) => {
|
||||
if (rowIndex === -1) {
|
||||
|
@ -41,26 +42,26 @@ const getTerms = (table, columnIndex, rowIndex) => {
|
|||
}))];
|
||||
};
|
||||
|
||||
export function VisFiltersProvider(Private, getAppState) {
|
||||
const createFilter = (data, columnIndex, rowIndex, cellValue) => {
|
||||
const { aggConfig, id: columnId } = data.columns[columnIndex];
|
||||
let filter = [];
|
||||
const value = rowIndex > -1 ? data.rows[rowIndex][columnId] : cellValue;
|
||||
if (value === null || value === undefined) {
|
||||
return;
|
||||
}
|
||||
if (aggConfig.type.name === 'terms' && aggConfig.params.otherBucket) {
|
||||
const terms = getTerms(data, columnIndex, rowIndex);
|
||||
filter = aggConfig.createFilter(value, { terms });
|
||||
} else {
|
||||
filter = aggConfig.createFilter(value);
|
||||
}
|
||||
return filter;
|
||||
};
|
||||
|
||||
const VisFiltersProvider = (Private, getAppState) => {
|
||||
const filterBarPushFilters = Private(FilterBarPushFiltersProvider);
|
||||
const queryFilter = Private(FilterBarQueryFilterProvider);
|
||||
|
||||
const createFilter = (data, columnIndex, rowIndex, cellValue) => {
|
||||
const { aggConfig, id: columnId } = data.columns[columnIndex];
|
||||
let filter = [];
|
||||
const value = rowIndex > -1 ? data.rows[rowIndex][columnId] : cellValue;
|
||||
if (value === null || value === undefined) {
|
||||
return;
|
||||
}
|
||||
if (aggConfig.type.name === 'terms' && aggConfig.params.otherBucket) {
|
||||
const terms = getTerms(data, columnIndex, rowIndex);
|
||||
filter = aggConfig.createFilter(value, { terms });
|
||||
} else {
|
||||
filter = aggConfig.createFilter(value);
|
||||
}
|
||||
return filter;
|
||||
};
|
||||
|
||||
const filter = (event, { simulate } = {}) => {
|
||||
let data = event.datum.aggConfigResult;
|
||||
const filters = [];
|
||||
|
@ -87,14 +88,18 @@ export function VisFiltersProvider(Private, getAppState) {
|
|||
return filters;
|
||||
};
|
||||
|
||||
const addFilter = (data, columnIndex, rowIndex, cellValue) => {
|
||||
const filter = createFilter(data, columnIndex, rowIndex, cellValue);
|
||||
const addFilter = (event) => {
|
||||
const filter = createFilter(event.table, event.column, event.row, event.value);
|
||||
queryFilter.addFilters(filter);
|
||||
};
|
||||
|
||||
return {
|
||||
createFilter,
|
||||
addFilter,
|
||||
filter
|
||||
filter,
|
||||
brush: (event) => {
|
||||
onBrushEvent(event, getAppState());
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export { VisFiltersProvider, createFilter };
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { BaseVisType } from './base_vis_type';
|
||||
import { BaseVisTypeProvider } from './base_vis_type';
|
||||
import $ from 'jquery';
|
||||
|
||||
|
||||
export function AngularVisTypeProvider($compile, $rootScope) {
|
||||
export function AngularVisTypeProvider(Private, $compile, $rootScope) {
|
||||
const BaseVisType = Private(BaseVisTypeProvider);
|
||||
|
||||
class AngularVisController {
|
||||
constructor(domeElement, vis) {
|
||||
|
|
|
@ -19,65 +19,77 @@
|
|||
|
||||
import { CATEGORY } from '../vis_category';
|
||||
import _ from 'lodash';
|
||||
import { VisFiltersProvider } from '../vis_filters';
|
||||
|
||||
export class BaseVisType {
|
||||
constructor(opts = {}) {
|
||||
export function BaseVisTypeProvider(Private) {
|
||||
const visFilters = Private(VisFiltersProvider);
|
||||
|
||||
if (!opts.name) {
|
||||
throw('vis_type must define its name');
|
||||
}
|
||||
if (!opts.title) {
|
||||
throw('vis_type must define its title');
|
||||
}
|
||||
if (!opts.description) {
|
||||
throw('vis_type must define its description');
|
||||
}
|
||||
if (!opts.icon && !opts.image && !opts.legacyIcon) {
|
||||
throw('vis_type must define its icon or image');
|
||||
}
|
||||
if (!opts.visualization) {
|
||||
throw('vis_type must define visualization controller');
|
||||
class BaseVisType {
|
||||
constructor(opts = {}) {
|
||||
|
||||
if (!opts.name) {
|
||||
throw('vis_type must define its name');
|
||||
}
|
||||
if (!opts.title) {
|
||||
throw('vis_type must define its title');
|
||||
}
|
||||
if (!opts.description) {
|
||||
throw('vis_type must define its description');
|
||||
}
|
||||
if (!opts.icon && !opts.image && !opts.legacyIcon) {
|
||||
throw('vis_type must define its icon or image');
|
||||
}
|
||||
if (!opts.visualization) {
|
||||
throw('vis_type must define visualization controller');
|
||||
}
|
||||
|
||||
const _defaults = {
|
||||
// name, title, description, icon, image
|
||||
category: CATEGORY.OTHER,
|
||||
visualization: null, // must be a class with render/resize/destroy methods
|
||||
visConfig: {
|
||||
defaults: {}, // default configuration
|
||||
},
|
||||
requestHandler: 'courier', // select one from registry or pass a function
|
||||
responseHandler: 'none',
|
||||
editor: 'default',
|
||||
editorConfig: {
|
||||
collections: {}, // collections used for configuration (list of positions, ...)
|
||||
},
|
||||
options: { // controls the visualize editor
|
||||
showTimePicker: true,
|
||||
showQueryBar: true,
|
||||
showFilterBar: true,
|
||||
showIndexSelection: true,
|
||||
hierarchicalData: false // we should get rid of this i guess ?
|
||||
},
|
||||
events: {
|
||||
filterBucket: {
|
||||
defaultAction: visFilters.addFilter,
|
||||
}
|
||||
},
|
||||
stage: 'production',
|
||||
feedbackMessage: ''
|
||||
};
|
||||
|
||||
_.defaultsDeep(this, opts, _defaults);
|
||||
|
||||
this.requiresSearch = this.requestHandler !== 'none';
|
||||
}
|
||||
|
||||
const _defaults = {
|
||||
// name, title, description, icon, image
|
||||
category: CATEGORY.OTHER,
|
||||
visualization: null, // must be a class with render/resize/destroy methods
|
||||
visConfig: {
|
||||
defaults: {}, // default configuration
|
||||
},
|
||||
requestHandler: 'courier', // select one from registry or pass a function
|
||||
responseHandler: 'none',
|
||||
editor: 'default',
|
||||
editorConfig: {
|
||||
collections: {}, // collections used for configuration (list of positions, ...)
|
||||
},
|
||||
options: { // controls the visualize editor
|
||||
showTimePicker: true,
|
||||
showQueryBar: true,
|
||||
showFilterBar: true,
|
||||
showIndexSelection: true,
|
||||
hierarchicalData: false // we should get rid of this i guess ?
|
||||
},
|
||||
stage: 'production',
|
||||
feedbackMessage: ''
|
||||
};
|
||||
shouldMarkAsExperimentalInUI() {
|
||||
//we are not making a distinction in the UI if a plugin is experimental and/or labs.
|
||||
//we just want to indicate it is special. the current flask icon is sufficient for that.
|
||||
return this.stage === 'experimental' || this.stage === 'lab';
|
||||
}
|
||||
|
||||
_.defaultsDeep(this, opts, _defaults);
|
||||
|
||||
this.requiresSearch = this.requestHandler !== 'none';
|
||||
get schemas() {
|
||||
if (this.editorConfig && this.editorConfig.schemas) {
|
||||
return this.editorConfig.schemas;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
shouldMarkAsExperimentalInUI() {
|
||||
//we are not making a distinction in the UI if a plugin is experimental and/or labs.
|
||||
//we just want to indicate it is special. the current flask icon is sufficient for that.
|
||||
return this.stage === 'experimental' || this.stage === 'lab';
|
||||
}
|
||||
|
||||
get schemas() {
|
||||
if (this.editorConfig && this.editorConfig.schemas) {
|
||||
return this.editorConfig.schemas;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return BaseVisType;
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { BaseVisType } from './base_vis_type';
|
||||
import { BaseVisTypeProvider } from './base_vis_type';
|
||||
import { AngularVisTypeProvider } from './angular_vis_type';
|
||||
import { VislibVisTypeProvider } from './vislib_vis_type';
|
||||
import { ReactVisType } from './react_vis_type';
|
||||
import { ReactVisTypeProvider } from './react_vis_type';
|
||||
|
||||
export { BaseVisType, AngularVisTypeProvider, VislibVisTypeProvider, ReactVisType };
|
||||
export { BaseVisTypeProvider, AngularVisTypeProvider, VislibVisTypeProvider, ReactVisTypeProvider };
|
||||
|
|
|
@ -20,44 +20,50 @@
|
|||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import chrome from '../../chrome';
|
||||
import { BaseVisType } from './base_vis_type';
|
||||
import { BaseVisTypeProvider } from './base_vis_type';
|
||||
|
||||
class ReactVisController {
|
||||
constructor(element, vis) {
|
||||
this.el = element;
|
||||
this.vis = vis;
|
||||
}
|
||||
export function ReactVisTypeProvider(Private) {
|
||||
const BaseVisType = Private(BaseVisTypeProvider);
|
||||
|
||||
render(visData, updateStatus) {
|
||||
this.visData = visData;
|
||||
class ReactVisController {
|
||||
constructor(element, vis) {
|
||||
this.el = element;
|
||||
this.vis = vis;
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const Component = this.vis.type.visConfig.component;
|
||||
const config = chrome.getUiSettingsClient();
|
||||
render(<Component
|
||||
config={config}
|
||||
vis={this.vis}
|
||||
visData={visData}
|
||||
renderComplete={resolve}
|
||||
updateStatus={updateStatus}
|
||||
/>, this.el);
|
||||
});
|
||||
}
|
||||
render(visData, updateStatus) {
|
||||
this.visData = visData;
|
||||
|
||||
destroy() {
|
||||
unmountComponentAtNode(this.el);
|
||||
}
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
const Component = this.vis.type.visConfig.component;
|
||||
const config = chrome.getUiSettingsClient();
|
||||
render(<Component
|
||||
config={config}
|
||||
vis={this.vis}
|
||||
visData={visData}
|
||||
renderComplete={resolve}
|
||||
updateStatus={updateStatus}
|
||||
/>, this.el);
|
||||
});
|
||||
}
|
||||
|
||||
export class ReactVisType extends BaseVisType {
|
||||
constructor(opts) {
|
||||
super({
|
||||
...opts,
|
||||
visualization: ReactVisController
|
||||
});
|
||||
|
||||
if (!this.visConfig.component) {
|
||||
throw new Error('Missing component for ReactVisType');
|
||||
destroy() {
|
||||
unmountComponentAtNode(this.el);
|
||||
}
|
||||
}
|
||||
|
||||
class ReactVisType extends BaseVisType {
|
||||
constructor(opts) {
|
||||
super({
|
||||
...opts,
|
||||
visualization: ReactVisController
|
||||
});
|
||||
|
||||
if (!this.visConfig.component) {
|
||||
throw new Error('Missing component for ReactVisType');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ReactVisType;
|
||||
}
|
||||
|
|
|
@ -21,12 +21,14 @@ import _ from 'lodash';
|
|||
import html from './vislib_vis_legend.html';
|
||||
import { VislibLibDataProvider } from '../../vislib/lib/data';
|
||||
import { uiModules } from '../../modules';
|
||||
import { VisFiltersProvider } from '../vis_filters';
|
||||
import { htmlIdGenerator, keyCodes } from '@elastic/eui';
|
||||
|
||||
|
||||
uiModules.get('kibana')
|
||||
.directive('vislibLegend', function (Private, $timeout, i18n) {
|
||||
const Data = Private(VislibLibDataProvider);
|
||||
const visFilters = Private(VisFiltersProvider);
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
@ -104,7 +106,7 @@ uiModules.get('kibana')
|
|||
};
|
||||
|
||||
$scope.canFilter = function (legendData) {
|
||||
const filters = $scope.vis.API.events.filter({ datum: legendData.values }, { simulate: true });
|
||||
const filters = visFilters.filter({ datum: legendData.values }, { simulate: true });
|
||||
return filters.length;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,14 +24,18 @@ import 'plugins/kbn_vislib_vis_types/controls/heatmap_options';
|
|||
import 'plugins/kbn_vislib_vis_types/controls/gauge_options';
|
||||
import 'plugins/kbn_vislib_vis_types/controls/point_series';
|
||||
import './vislib_vis_legend';
|
||||
import { BaseVisType } from './base_vis_type';
|
||||
import { BaseVisTypeProvider } from './base_vis_type';
|
||||
import { AggResponsePointSeriesProvider } from '../../agg_response/point_series/point_series';
|
||||
import VislibProvider from '../../vislib';
|
||||
import { VisFiltersProvider } from '../vis_filters';
|
||||
import $ from 'jquery';
|
||||
import { defaultsDeep } from 'lodash';
|
||||
|
||||
export function VislibVisTypeProvider(Private, $rootScope, $timeout, $compile) {
|
||||
const pointSeries = Private(AggResponsePointSeriesProvider);
|
||||
const vislib = Private(VislibProvider);
|
||||
const visFilters = Private(VisFiltersProvider);
|
||||
const BaseVisType = Private(BaseVisTypeProvider);
|
||||
|
||||
const legendClassName = {
|
||||
top: 'vislib-container--legend-top',
|
||||
|
@ -118,6 +122,14 @@ export function VislibVisTypeProvider(Private, $rootScope, $timeout, $compile) {
|
|||
if (!opts.responseConverter) {
|
||||
opts.responseConverter = pointSeries;
|
||||
}
|
||||
opts.events = defaultsDeep({}, opts.events, {
|
||||
filterBucket: {
|
||||
defaultAction: visFilters.filter,
|
||||
},
|
||||
brush: {
|
||||
defaultAction: visFilters.brush,
|
||||
}
|
||||
});
|
||||
opts.visualization = VislibVisController;
|
||||
super(opts);
|
||||
this.refreshLegend = 0;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import { EventEmitter } from 'events';
|
||||
import { debounce } from 'lodash';
|
||||
import { debounce, forEach } from 'lodash';
|
||||
import * as Rx from 'rxjs';
|
||||
import { share } from 'rxjs/operators';
|
||||
import { Inspector } from '../../inspector';
|
||||
|
@ -80,7 +80,9 @@ export class EmbeddedVisualizeHandler {
|
|||
private uiState: PersistedState;
|
||||
private dataLoader: VisualizeDataLoader;
|
||||
private dataSubject: Rx.Subject<any>;
|
||||
private inspectorAdapters: Adapters = {};
|
||||
private readonly inspectorAdapters: Adapters = {};
|
||||
private actions: any = {};
|
||||
private events$: Rx.Observable<any>;
|
||||
|
||||
constructor(
|
||||
private readonly element: HTMLElement,
|
||||
|
@ -128,6 +130,23 @@ export class EmbeddedVisualizeHandler {
|
|||
this.vis.openInspector = this.openInspector;
|
||||
this.vis.hasInspector = this.hasInspector;
|
||||
|
||||
// init default actions
|
||||
forEach(this.vis.type.events, (event, eventName) => {
|
||||
if (event.disabled || !eventName) {
|
||||
return;
|
||||
} else {
|
||||
this.actions[eventName] = event.defaultAction;
|
||||
}
|
||||
});
|
||||
|
||||
this.vis.eventsSubject = new Rx.Subject();
|
||||
this.events$ = this.vis.eventsSubject.asObservable().pipe(share());
|
||||
this.events$.subscribe(event => {
|
||||
if (this.actions[event.name]) {
|
||||
this.actions[event.name](event.data);
|
||||
}
|
||||
});
|
||||
|
||||
this.dataSubject = new Rx.Subject();
|
||||
this.data$ = this.dataSubject.asObservable().pipe(share());
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue