Vega visualization renderer (#81606)

* Create vega to_ast function

* Create a custom vega renderer

* Fix sass error

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Daniil Suleiman 2020-10-29 14:51:09 +03:00 committed by GitHub
parent db92edff1f
commit 28a726fe7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 354 additions and 106 deletions

View file

@ -1,3 +1,11 @@
.vgaVis__wrapper {
@include euiScrollBar;
display: flex;
flex: 1 1 0;
overflow: auto;
}
.vgaVis {
display: flex;
flex: 1 1 100%;

View file

@ -0,0 +1,85 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { useEffect, useMemo, useRef } from 'react';
import { EuiResizeObserver } from '@elastic/eui';
import { throttle } from 'lodash';
import { IInterpreterRenderHandlers } from 'src/plugins/expressions';
import { createVegaVisualization } from '../vega_visualization';
import { VegaVisualizationDependencies } from '../plugin';
import { VegaParser } from '../data_model/vega_parser';
import './vega_vis.scss';
interface VegaVisComponentProps {
deps: VegaVisualizationDependencies;
fireEvent: IInterpreterRenderHandlers['event'];
renderComplete: () => void;
visData: VegaParser;
}
type VegaVisController = InstanceType<ReturnType<typeof createVegaVisualization>>;
const VegaVisComponent = ({ visData, fireEvent, renderComplete, deps }: VegaVisComponentProps) => {
const chartDiv = useRef<HTMLDivElement>(null);
const visController = useRef<VegaVisController | null>(null);
useEffect(() => {
if (chartDiv.current) {
const VegaVis = createVegaVisualization(deps);
visController.current = new VegaVis(chartDiv.current, fireEvent);
}
return () => {
visController.current?.destroy();
visController.current = null;
};
}, [deps, fireEvent]);
useEffect(() => {
if (visController.current) {
visController.current.render(visData).then(renderComplete);
}
}, [visData, renderComplete]);
const updateChartSize = useMemo(
() =>
throttle(() => {
if (visController.current) {
visController.current.render(visData).then(renderComplete);
}
}, 300),
[renderComplete, visData]
);
return (
<EuiResizeObserver onResize={updateChartSize}>
{(resizeRef) => (
<div className="vgaVis__wrapper" ref={resizeRef}>
<div ref={chartDiv} />
</div>
)}
</EuiResizeObserver>
);
};
// default export required for React.Lazy
// eslint-disable-next-line import/no-default-export
export { VegaVisComponent as default };

View file

@ -30,6 +30,8 @@ import { VisParams } from '../vega_fn';
import { VegaHelpMenu } from './vega_help_menu';
import { VegaActionsMenu } from './vega_actions_menu';
import './vega_editor.scss';
const aceOptions = {
maxLines: Infinity,
highlightActiveLine: false,
@ -102,4 +104,6 @@ function VegaVisEditor({ stateParams, setValue }: VisOptionsProps<VisParams>) {
);
}
export { VegaVisEditor };
// default export required for React.Lazy
// eslint-disable-next-line import/no-default-export
export { VegaVisEditor as default };

View file

@ -0,0 +1,29 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { lazy } from 'react';
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
import { VisParams } from '../vega_fn';
const VegaVisEditor = lazy(() => import('./vega_vis_editor'));
export const VegaVisEditorComponent = (props: VisOptionsProps<VisParams>) => (
<VegaVisEditor {...props} />
);

View file

@ -1,9 +0,0 @@
// Prefix all styles with "vga" to avoid conflicts.
// Examples
// vgaChart
// vgaChart__legend
// vgaChart__legend--small
// vgaChart__legend-isLoading
@import './vega_vis';
@import './vega_editor';

View file

@ -35,10 +35,10 @@ import {
import { createVegaFn } from './vega_fn';
import { createVegaTypeDefinition } from './vega_type';
import { IServiceSettings } from '../../maps_legacy/public';
import './index.scss';
import { ConfigSchema } from '../config';
import { getVegaInspectorView } from './vega_inspector';
import { getVegaVisRenderer } from './vega_vis_renderer';
/** @internal */
export interface VegaVisualizationDependencies {
@ -93,6 +93,7 @@ export class VegaPlugin implements Plugin<Promise<void>, void> {
inspector.registerView(getVegaInspectorView({ uiSettings: core.uiSettings }));
expressions.registerFunction(() => createVegaFn(visualizationDependencies));
expressions.registerRenderer(getVegaVisRenderer(visualizationDependencies));
visualizations.createBaseVisualization(createVegaTypeDefinition(visualizationDependencies));
}

View file

@ -0,0 +1,32 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { buildExpression, buildExpressionFunction } from '../../expressions/public';
import { Vis } from '../../visualizations/public';
import { VegaExpressionFunctionDefinition, VisParams } from './vega_fn';
export const toExpressionAst = (vis: Vis<VisParams>) => {
const vega = buildExpressionFunction<VegaExpressionFunctionDefinition>('vega', {
spec: vis.params.spec,
});
const ast = buildExpression([vega]);
return ast.toAst();
};

View file

@ -40,21 +40,23 @@ interface Arguments {
export type VisParams = Required<Arguments>;
interface RenderValue {
export interface RenderValue {
visData: VegaParser;
visType: 'vega';
visConfig: VisParams;
}
export const createVegaFn = (
dependencies: VegaVisualizationDependencies
): ExpressionFunctionDefinition<
export type VegaExpressionFunctionDefinition = ExpressionFunctionDefinition<
'vega',
Input,
Arguments,
Output,
ExecutionContext<VegaInspectorAdapters>
> => ({
>;
export const createVegaFn = (
dependencies: VegaVisualizationDependencies
): VegaExpressionFunctionDefinition => ({
name: 'vega',
type: 'render',
inputTypes: ['kibana_context', 'null'],
@ -80,7 +82,7 @@ export const createVegaFn = (
return {
type: 'render',
as: 'visualization',
as: 'vega_vis',
value: {
visData: response,
visType: 'vega',

View file

@ -41,7 +41,7 @@ const specLabel = i18n.translate('visTypeVega.inspector.specLabel', {
defaultMessage: 'Spec',
});
export const VegaDataInspector = ({ adapters }: VegaDataInspectorProps) => {
const VegaDataInspector = ({ adapters }: VegaDataInspectorProps) => {
const tabs = [
{
id: 'data-viewer--id',
@ -75,3 +75,7 @@ export const VegaDataInspector = ({ adapters }: VegaDataInspectorProps) => {
/>
);
};
// default export required for React.Lazy
// eslint-disable-next-line import/no-default-export
export { VegaDataInspector as default };

View file

@ -16,14 +16,17 @@
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import React, { lazy, Suspense } from 'react';
import { EuiLoadingSpinner } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { IUiSettingsClient } from 'kibana/public';
import { VegaAdapter } from './vega_adapter';
import { VegaDataInspector, VegaDataInspectorProps } from './vega_data_inspector';
import { KibanaContextProvider } from '../../../kibana_react/public';
import { Adapters, RequestAdapter, InspectorViewDescription } from '../../../inspector/public';
import { VegaAdapter } from './vega_adapter';
import type { VegaDataInspectorProps } from './vega_data_inspector';
const VegaDataInspector = lazy(() => import('./vega_data_inspector'));
export interface VegaInspectorAdapters extends Adapters {
requests: RequestAdapter;
@ -46,7 +49,9 @@ export const getVegaInspectorView = (dependencies: VegaInspectorViewDependencies
},
component: (props) => (
<KibanaContextProvider services={dependencies}>
<VegaDataInspector {...(props as VegaDataInspectorProps)}> </VegaDataInspector>
<Suspense fallback={<EuiLoadingSpinner />}>
<VegaDataInspector {...(props as VegaDataInspectorProps)} />
</Suspense>
</KibanaContextProvider>
),
} as InspectorViewDescription);

View file

@ -21,22 +21,20 @@ import { i18n } from '@kbn/i18n';
import { BaseVisTypeOptions } from 'src/plugins/visualizations/public';
import { DefaultEditorSize } from '../../vis_default_editor/public';
import { VegaVisualizationDependencies } from './plugin';
import { VegaVisEditor } from './components';
import { createVegaRequestHandler } from './vega_request_handler';
// @ts-expect-error
import { createVegaVisualization } from './vega_visualization';
import { getDefaultSpec } from './default_spec';
import { createInspectorAdapters } from './vega_inspector';
import { VIS_EVENT_TO_TRIGGER } from '../../visualizations/public';
import { toExpressionAst } from './to_ast';
import { VisParams } from './vega_fn';
import { getInfoMessage } from './components/experimental_map_vis_info';
import { VegaVisEditorComponent } from './components/vega_vis_editor_lazy';
export const createVegaTypeDefinition = (
dependencies: VegaVisualizationDependencies
): BaseVisTypeOptions => {
): BaseVisTypeOptions<VisParams> => {
const requestHandler = createVegaRequestHandler(dependencies);
const visualization = createVegaVisualization(dependencies);
return {
name: 'vega',
@ -49,13 +47,12 @@ export const createVegaTypeDefinition = (
icon: 'visVega',
visConfig: { defaults: { spec: getDefaultSpec() } },
editorConfig: {
optionsTemplate: VegaVisEditor,
optionsTemplate: VegaVisEditorComponent,
enableAutoApply: true,
defaultSize: DefaultEditorSize.MEDIUM,
},
visualization,
requestHandler,
responseHandler: 'none',
toExpressionAst,
options: {
showIndexSelection: false,
showQueryBar: true,

View file

@ -0,0 +1,40 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { DataPublicPluginStart } from 'src/plugins/data/public';
import { IInterpreterRenderHandlers } from 'src/plugins/expressions';
import { IServiceSettings } from 'src/plugins/maps_legacy/public';
import { VegaParser } from '../data_model/vega_parser';
interface VegaViewParams {
parentEl: HTMLDivElement;
fireEvent: IInterpreterRenderHandlers['event'];
vegaParser: VegaParser;
serviceSettings: IServiceSettings;
filterManager: DataPublicPluginStart['query']['filterManager'];
timefilter: DataPublicPluginStart['query']['timefilter']['timefilter'];
// findIndex: (index: string) => Promise<...>;
}
export class VegaBaseView {
constructor(params: VegaViewParams);
init(): Promise<void>;
onError(error: any): void;
destroy(): Promise<void>;
}

View file

@ -63,7 +63,7 @@ export class VegaBaseView {
this._parser = opts.vegaParser;
this._serviceSettings = opts.serviceSettings;
this._filterManager = opts.filterManager;
this._applyFilter = opts.applyFilter;
this._fireEvent = opts.fireEvent;
this._timefilter = opts.timefilter;
this._findIndex = opts.findIndex;
this._view = null;
@ -264,7 +264,7 @@ export class VegaBaseView {
const indexId = await this._findIndex(index);
const filter = esFilters.buildQueryFilter(query, indexId);
this._applyFilter({ filters: [filter] });
this._fireEvent({ name: 'applyFilter', data: { filters: [filter] } });
}
/**
@ -301,19 +301,22 @@ export class VegaBaseView {
setTimeFilterHandler(start, end) {
const { from, to, mode } = VegaBaseView._parseTimeRange(start, end);
this._applyFilter({
timeFieldName: '*',
filters: [
{
range: {
'*': {
mode,
gte: from,
lte: to,
this._fireEvent({
name: 'applyFilter',
data: {
timeFieldName: '*',
filters: [
{
range: {
'*': {
mode,
gte: from,
lte: to,
},
},
},
},
],
],
},
});
}

View file

@ -0,0 +1,22 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { VegaBaseView } from './vega_base_view';
export class VegaMapView extends VegaBaseView {}

View file

@ -17,4 +17,6 @@
* under the License.
*/
export { VegaVisEditor } from './vega_vis_editor';
import { VegaBaseView } from './vega_base_view';
export class VegaView extends VegaBaseView {}

View file

@ -0,0 +1,51 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { lazy } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { ExpressionRenderDefinition } from 'src/plugins/expressions';
import { VisualizationContainer } from '../../visualizations/public';
import { VegaVisualizationDependencies } from './plugin';
import { RenderValue } from './vega_fn';
const VegaVisComponent = lazy(() => import('./components/vega_vis_component'));
export const getVegaVisRenderer: (
deps: VegaVisualizationDependencies
) => ExpressionRenderDefinition<RenderValue> = (deps) => ({
name: 'vega_vis',
reuseDomNode: true,
render: (domNode, { visData }, handlers) => {
handlers.onDestroy(() => {
unmountComponentAtNode(domNode);
});
render(
<VisualizationContainer handlers={handlers}>
<VegaVisComponent
deps={deps}
fireEvent={handlers.event}
renderComplete={handlers.done}
visData={visData}
/>
</VisualizationContainer>,
domNode
);
},
});

View file

@ -30,8 +30,6 @@ import vegaMapGraph from './test_utils/vega_map_test.json';
import { VegaParser } from './data_model/vega_parser';
import { SearchAPI } from './data_model/search_api';
import { createVegaTypeDefinition } from './vega_type';
import { setInjectedVars, setData, setSavedObjects, setNotifications } from './services';
import { coreMock } from '../../../core/public/mocks';
import { dataPluginMock } from '../../data/public/mocks';
@ -49,9 +47,7 @@ jest.mock('./lib/vega', () => ({
describe('VegaVisualizations', () => {
let domNode;
let VegaVisualization;
let vis;
let vegaVisualizationDependencies;
let vegaVisType;
let mockWidth;
let mockedWidthValue;
@ -91,22 +87,12 @@ describe('VegaVisualizations', () => {
getServiceSettings: mockGetServiceSettings,
};
vegaVisType = createVegaTypeDefinition(vegaVisualizationDependencies);
VegaVisualization = createVegaVisualization(vegaVisualizationDependencies);
});
describe('VegaVisualization - basics', () => {
beforeEach(async () => {
setupDOM();
vis = {
type: vegaVisType,
API: {
events: {
applyFilter: jest.fn(),
},
},
};
});
afterEach(() => {
@ -117,7 +103,7 @@ describe('VegaVisualizations', () => {
test('should show vegalite graph and update on resize (may fail in dev env)', async () => {
let vegaVis;
try {
vegaVis = new VegaVisualization(domNode, vis);
vegaVis = new VegaVisualization(domNode, jest.fn());
const vegaParser = new VegaParser(
JSON.stringify(vegaliteGraph),
@ -137,7 +123,7 @@ describe('VegaVisualizations', () => {
mockedWidthValue = 256;
mockedHeightValue = 256;
await vegaVis._vegaView.resize();
await vegaVis.vegaView.resize();
expect(domNode.innerHTML).toMatchSnapshot();
} finally {
@ -148,7 +134,7 @@ describe('VegaVisualizations', () => {
test('should show vega graph (may fail in dev env)', async () => {
let vegaVis;
try {
vegaVis = new VegaVisualization(domNode, vis);
vegaVis = new VegaVisualization(domNode, jest.fn());
const vegaParser = new VegaParser(
JSON.stringify(vegaGraph),
new SearchAPI({
@ -172,7 +158,7 @@ describe('VegaVisualizations', () => {
test('should show vega blank rectangle on top of a map (vegamap)', async () => {
let vegaVis;
try {
vegaVis = new VegaVisualization(domNode, vis);
vegaVis = new VegaVisualization(domNode, jest.fn());
const vegaParser = new VegaParser(
JSON.stringify(vegaMapGraph),
new SearchAPI({

View file

@ -17,28 +17,34 @@
* under the License.
*/
import { i18n } from '@kbn/i18n';
import { IInterpreterRenderHandlers } from 'src/plugins/expressions';
import { VegaParser } from './data_model/vega_parser';
import { VegaVisualizationDependencies } from './plugin';
import { getNotifications, getData, getSavedObjects } from './services';
import type { VegaView } from './vega_view/vega_view';
export const createVegaVisualization = ({ getServiceSettings }) =>
export const createVegaVisualization = ({ getServiceSettings }: VegaVisualizationDependencies) =>
class VegaVisualization {
constructor(el, vis) {
this._el = el;
this._vis = vis;
private readonly dataPlugin = getData();
private readonly savedObjectsClient = getSavedObjects();
private vegaView: InstanceType<typeof VegaView> | null = null;
this.savedObjectsClient = getSavedObjects();
this.dataPlugin = getData();
}
constructor(
private el: HTMLDivElement,
private fireEvent: IInterpreterRenderHandlers['event']
) {}
/**
* Find index pattern by its title, of if not given, gets default
* @param {string} [index]
* @returns {Promise<string>} index id
*/
async findIndex(index) {
async findIndex(index: string) {
const { indexPatterns } = this.dataPlugin;
let idxObj;
if (index) {
// @ts-expect-error
idxObj = indexPatterns.findByTitle(this.savedObjectsClient, index);
if (!idxObj) {
throw new Error(
@ -61,16 +67,10 @@ export const createVegaVisualization = ({ getServiceSettings }) =>
return idxObj.id;
}
/**
*
* @param {VegaParser} visData
* @param {*} status
* @returns {Promise<void>}
*/
async render(visData) {
async render(visData: VegaParser) {
const { toasts } = getNotifications();
if (!visData && !this._vegaView) {
if (!visData && !this.vegaView) {
toasts.addWarning(
i18n.translate('visTypeVega.visualization.unableToRenderWithoutDataWarningMessage', {
defaultMessage: 'Unable to render without data',
@ -82,8 +82,8 @@ export const createVegaVisualization = ({ getServiceSettings }) =>
try {
await this._render(visData);
} catch (error) {
if (this._vegaView) {
this._vegaView.onError(error);
if (this.vegaView) {
this.vegaView.onError(error);
} else {
toasts.addError(error, {
title: i18n.translate('visTypeVega.visualization.renderErrorTitle', {
@ -94,20 +94,20 @@ export const createVegaVisualization = ({ getServiceSettings }) =>
}
}
async _render(vegaParser) {
async _render(vegaParser: VegaParser) {
if (vegaParser) {
// New data received, rebuild the graph
if (this._vegaView) {
await this._vegaView.destroy();
this._vegaView = null;
if (this.vegaView) {
await this.vegaView.destroy();
this.vegaView = null;
}
const serviceSettings = await getServiceSettings();
const { filterManager } = this.dataPlugin.query;
const { timefilter } = this.dataPlugin.query.timefilter;
const vegaViewParams = {
parentEl: this._el,
applyFilter: this._vis.API.events.applyFilter,
parentEl: this.el,
fireEvent: this.fireEvent,
vegaParser,
serviceSettings,
filterManager,
@ -116,18 +116,17 @@ export const createVegaVisualization = ({ getServiceSettings }) =>
};
if (vegaParser.useMap) {
const services = { toastService: getNotifications().toasts };
const { VegaMapView } = await import('./vega_view/vega_map_view');
this._vegaView = new VegaMapView(vegaViewParams, services);
this.vegaView = new VegaMapView(vegaViewParams);
} else {
const { VegaView } = await import('./vega_view/vega_view');
this._vegaView = new VegaView(vegaViewParams);
const { VegaView: VegaViewClass } = await import('./vega_view/vega_view');
this.vegaView = new VegaViewClass(vegaViewParams);
}
await this._vegaView.init();
await this.vegaView?.init();
}
}
destroy() {
return this._vegaView && this._vegaView.destroy();
this.vegaView?.destroy();
}
};

View file

@ -13,5 +13,3 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunct
exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function without buckets 1`] = `"regionmap visConfig='{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}}' "`;
exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles tile_map function 1`] = `"tilemap visConfig='{\\"metric\\":{},\\"dimensions\\":{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},\\"geohash\\":1,\\"geocentroid\\":3}}' "`;
exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles vega function 1`] = `"vega spec='this is a test' "`;

View file

@ -94,14 +94,6 @@ describe('visualize loader pipeline helpers: build pipeline', () => {
uiState = {};
});
it('handles vega function', () => {
const vis = {
params: { spec: 'this is a test' },
};
const actual = buildPipelineVisFunction.vega(vis.params, schemasDef, uiState);
expect(actual).toMatchSnapshot();
});
it('handles input_control_vis function', () => {
const params = {
some: 'nested',

View file

@ -254,9 +254,6 @@ const adjustVislibDimensionFormmaters = (vis: Vis, dimensions: { y: any[] }): vo
};
export const buildPipelineVisFunction: BuildPipelineVisFunction = {
vega: (params) => {
return `vega ${prepareString('spec', params.spec)}`;
},
input_control_vis: (params) => {
return `input_control_vis ${prepareJson('visConfig', params)}`;
},