diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md
index 9d5f7609ee6cd2..a957ecd63f0430 100644
--- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md
+++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md
@@ -9,5 +9,5 @@ A user friendly name of the renderer as will be displayed to user in UI.
Signature:
```typescript
-displayName: string;
+displayName?: string;
```
diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.displayname.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.displayname.md
index e936e25cee6cad..8ae5aa2f1790ec 100644
--- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.displayname.md
+++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.displayname.md
@@ -9,5 +9,5 @@ A user friendly name of the renderer as will be displayed to user in UI.
Signature:
```typescript
-displayName: string;
+displayName?: string;
```
diff --git a/src/plugins/expressions/common/expression_renderers/types.ts b/src/plugins/expressions/common/expression_renderers/types.ts
index 7b3e812eafedd4..b760e7b32a7d2b 100644
--- a/src/plugins/expressions/common/expression_renderers/types.ts
+++ b/src/plugins/expressions/common/expression_renderers/types.ts
@@ -28,7 +28,7 @@ export interface ExpressionRenderDefinition {
/**
* A user friendly name of the renderer as will be displayed to user in UI.
*/
- displayName: string;
+ displayName?: string;
/**
* Help text as will be displayed to user. A sentence or few about what this
diff --git a/src/plugins/expressions/public/public.api.md b/src/plugins/expressions/public/public.api.md
index 162f0ef6824f5b..5c0fd8ab1a5729 100644
--- a/src/plugins/expressions/public/public.api.md
+++ b/src/plugins/expressions/public/public.api.md
@@ -429,7 +429,7 @@ export interface ExpressionImage {
//
// @public (undocumented)
export interface ExpressionRenderDefinition {
- displayName: string;
+ displayName?: string;
help?: string;
name: string;
render: (domNode: HTMLElement, config: Config, handlers: IInterpreterRenderHandlers) => void | Promise;
diff --git a/src/plugins/expressions/server/server.api.md b/src/plugins/expressions/server/server.api.md
index 6ac251ea005b44..d8872ee4160174 100644
--- a/src/plugins/expressions/server/server.api.md
+++ b/src/plugins/expressions/server/server.api.md
@@ -401,7 +401,7 @@ export interface ExpressionImage {
//
// @public (undocumented)
export interface ExpressionRenderDefinition {
- displayName: string;
+ displayName?: string;
help?: string;
name: string;
render: (domNode: HTMLElement, config: Config, handlers: IInterpreterRenderHandlers) => void | Promise;
diff --git a/src/plugins/timelion/public/index.scss b/src/plugins/timelion/public/index.scss
index 6bf7133287c51c..f39e0c18a28706 100644
--- a/src/plugins/timelion/public/index.scss
+++ b/src/plugins/timelion/public/index.scss
@@ -10,3 +10,9 @@
@import './app';
@import './base';
@import './directives/index';
+
+// these styles is needed to be loaded here explicitly if the timelion visualization was not opened in browser
+// styles for timelion visualization are lazy loaded only while a vis is opened
+// this will duplicate styles only if both Timelion app and timelion visualization are loaded
+// could be left here as it is since the Timelion app is deprecated
+@import '../../vis_type_timelion/public/components/index.scss';
diff --git a/src/plugins/vis_type_tagcloud/public/tag_cloud_vis_renderer.tsx b/src/plugins/vis_type_tagcloud/public/tag_cloud_vis_renderer.tsx
index d37aa5f6fe409a..b433ed9cbed218 100644
--- a/src/plugins/vis_type_tagcloud/public/tag_cloud_vis_renderer.tsx
+++ b/src/plugins/vis_type_tagcloud/public/tag_cloud_vis_renderer.tsx
@@ -25,7 +25,6 @@ import { ExpressionRenderDefinition } from '../../expressions/common/expression_
import { TagCloudVisDependencies } from './plugin';
import { TagCloudVisRenderValue } from './tag_cloud_fn';
-// @ts-ignore
const TagCloudChart = lazy(() => import('./components/tag_cloud_chart'));
export const getTagCloudVisRenderer: (
diff --git a/src/plugins/vis_type_timelion/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_type_timelion/public/__snapshots__/to_ast.test.ts.snap
new file mode 100644
index 00000000000000..9e32a6c4ae17cb
--- /dev/null
+++ b/src/plugins/vis_type_timelion/public/__snapshots__/to_ast.test.ts.snap
@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`timelion vis toExpressionAst function should match basic snapshot 1`] = `
+Object {
+ "chain": Array [
+ Object {
+ "arguments": Object {
+ "expression": Array [
+ ".es(*)",
+ ],
+ "interval": Array [
+ "auto",
+ ],
+ },
+ "function": "timelion_vis",
+ "type": "function",
+ },
+ ],
+ "type": "expression",
+}
+`;
diff --git a/src/plugins/vis_type_timelion/public/_timelion_editor.scss b/src/plugins/vis_type_timelion/public/_timelion_editor.scss
deleted file mode 100644
index a9331930a86ffa..00000000000000
--- a/src/plugins/vis_type_timelion/public/_timelion_editor.scss
+++ /dev/null
@@ -1,15 +0,0 @@
-.visEditor--timelion {
- vis-options-react-wrapper,
- .visEditorSidebar__options,
- .visEditorSidebar__timelionOptions {
- flex: 1 1 auto;
- display: flex;
- flex-direction: column;
- }
-
- .visEditor__sidebar {
- @include euiBreakpoint('xs', 's', 'm') {
- width: 100%;
- }
- }
-}
diff --git a/src/plugins/vis_type_timelion/public/_timelion_vis.scss b/src/plugins/vis_type_timelion/public/_timelion_vis.scss
deleted file mode 100644
index e7175bf3c0c2aa..00000000000000
--- a/src/plugins/vis_type_timelion/public/_timelion_vis.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-.timVis {
- min-width: 100%;
- display: flex;
- flex-direction: column;
-
- .timChart {
- min-width: 100%;
- flex: 1;
- display: flex;
- flex-direction: column;
- }
-}
diff --git a/src/plugins/vis_type_timelion/public/components/_panel.scss b/src/plugins/vis_type_timelion/public/components/_timelion_vis.scss
similarity index 88%
rename from src/plugins/vis_type_timelion/public/components/_panel.scss
rename to src/plugins/vis_type_timelion/public/components/_timelion_vis.scss
index c4d591bc82cad9..6729d400523cd8 100644
--- a/src/plugins/vis_type_timelion/public/components/_panel.scss
+++ b/src/plugins/vis_type_timelion/public/components/_timelion_vis.scss
@@ -58,3 +58,11 @@
white-space: nowrap;
font-weight: $euiFontWeightBold;
}
+
+.visEditor--timelion {
+ .visEditorSidebar__timelionOptions {
+ flex: 1 1 auto;
+ display: flex;
+ flex-direction: column;
+ }
+}
diff --git a/src/plugins/vis_type_timelion/public/components/_index.scss b/src/plugins/vis_type_timelion/public/components/index.scss
similarity index 60%
rename from src/plugins/vis_type_timelion/public/components/_index.scss
rename to src/plugins/vis_type_timelion/public/components/index.scss
index 707c9dafebe2b7..a541c66e6e9139 100644
--- a/src/plugins/vis_type_timelion/public/components/_index.scss
+++ b/src/plugins/vis_type_timelion/public/components/index.scss
@@ -1,2 +1,2 @@
-@import 'panel';
+@import 'timelion_vis';
@import 'timelion_expression_input';
diff --git a/src/plugins/vis_type_timelion/public/components/index.ts b/src/plugins/vis_type_timelion/public/components/index.ts
index c70caab8dd70cf..8d7d32a3ba2627 100644
--- a/src/plugins/vis_type_timelion/public/components/index.ts
+++ b/src/plugins/vis_type_timelion/public/components/index.ts
@@ -19,4 +19,3 @@
export * from './timelion_expression_input';
export * from './timelion_interval';
-export * from './timelion_vis';
diff --git a/src/plugins/vis_type_timelion/public/components/timelion_vis.tsx b/src/plugins/vis_type_timelion/public/components/timelion_vis.tsx
deleted file mode 100644
index aa594c749b600e..00000000000000
--- a/src/plugins/vis_type_timelion/public/components/timelion_vis.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 from 'react';
-
-import { IUiSettingsClient } from 'kibana/public';
-import { ChartComponent } from './chart';
-import { VisParams } from '../timelion_vis_fn';
-import { TimelionSuccessResponse } from '../helpers/timelion_request_handler';
-import { ExprVis } from '../../../visualizations/public';
-
-export interface TimelionVisComponentProp {
- config: IUiSettingsClient;
- renderComplete(): void;
- updateStatus: object;
- vis: ExprVis;
- visData: TimelionSuccessResponse;
- visParams: VisParams;
-}
-
-function TimelionVisComponent(props: TimelionVisComponentProp) {
- return (
-
-
-
- );
-}
-
-export { TimelionVisComponent };
diff --git a/src/plugins/vis_type_timelion/public/components/panel.tsx b/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx
similarity index 90%
rename from src/plugins/vis_type_timelion/public/components/panel.tsx
rename to src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx
index 9c30a6b75d6dbc..a7b623ac8680c6 100644
--- a/src/plugins/vis_type_timelion/public/components/panel.tsx
+++ b/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx
@@ -21,7 +21,9 @@ import React, { useState, useEffect, useMemo, useCallback } from 'react';
import $ from 'jquery';
import moment from 'moment-timezone';
import { debounce, compact, get, each, cloneDeep, last, map } from 'lodash';
+import { useResizeObserver } from '@elastic/eui';
+import { IInterpreterRenderHandlers } from 'src/plugins/expressions';
import { useKibana } from '../../../kibana_react/public';
import '../flot';
import { DEFAULT_TIME_FORMAT } from '../../common/lib';
@@ -38,18 +40,19 @@ import { Series, Sheet } from '../helpers/timelion_request_handler';
import { tickFormatters } from '../helpers/tick_formatters';
import { generateTicksProvider } from '../helpers/tick_generator';
import { TimelionVisDependencies } from '../plugin';
-import { ExprVisAPIEvents } from '../../../visualizations/public';
+
+import './index.scss';
interface CrosshairPlot extends jquery.flot.plot {
setCrosshair: (pos: Position) => void;
clearCrosshair: () => void;
}
-interface PanelProps {
- applyFilter: ExprVisAPIEvents['applyFilter'];
+interface TimelionVisComponentProps {
+ fireEvent: IInterpreterRenderHandlers['event'];
interval: string;
seriesList: Sheet;
- renderComplete(): void;
+ renderComplete: IInterpreterRenderHandlers['done'];
}
interface Position {
@@ -75,11 +78,16 @@ const DEBOUNCE_DELAY = 50;
// ensure legend is the same height with or without a caption so legend items do not move around
const emptyCaption = '
';
-function Panel({ interval, seriesList, renderComplete, applyFilter }: PanelProps) {
+function TimelionVisComponent({
+ interval,
+ seriesList,
+ renderComplete,
+ fireEvent,
+}: TimelionVisComponentProps) {
const kibana = useKibana();
const [chart, setChart] = useState(() => cloneDeep(seriesList.list));
const [canvasElem, setCanvasElem] = useState();
- const [chartElem, setChartElem] = useState();
+ const [chartElem, setChartElem] = useState(null);
const [originalColorMap, setOriginalColorMap] = useState(() => new Map());
@@ -191,7 +199,7 @@ function Panel({ interval, seriesList, renderComplete, applyFilter }: PanelProps
interval,
kibana.services.timefilter,
kibana.services.uiSettings,
- chartElem && chartElem.clientWidth,
+ chartElem?.clientWidth,
grid
);
const updatedSeries = buildSeriesData(chartValue, options);
@@ -216,12 +224,14 @@ function Panel({ interval, seriesList, renderComplete, applyFilter }: PanelProps
updateCaption(newPlot.getData());
}
},
- [canvasElem, chartElem, renderComplete, kibana.services, interval, updateCaption]
+ [canvasElem, chartElem?.clientWidth, renderComplete, kibana.services, interval, updateCaption]
);
+ const dimensions = useResizeObserver(chartElem);
+
useEffect(() => {
updatePlot(chart, seriesList.render && seriesList.render.grid);
- }, [chart, updatePlot, seriesList.render]);
+ }, [chart, updatePlot, seriesList.render, dimensions]);
useEffect(() => {
const colorsSet: Array<[Series, string]> = [];
@@ -349,21 +359,24 @@ function Panel({ interval, seriesList, renderComplete, applyFilter }: PanelProps
const plotSelectedHandler = useCallback(
(event: JQuery.TriggeredEvent, ranges: Ranges) => {
- applyFilter({
- timeFieldName: '*',
- filters: [
- {
- range: {
- '*': {
- gte: ranges.xaxis.from,
- lte: ranges.xaxis.to,
+ fireEvent({
+ name: 'applyFilter',
+ data: {
+ timeFieldName: '*',
+ filters: [
+ {
+ range: {
+ '*': {
+ gte: ranges.xaxis.from,
+ lte: ranges.xaxis.to,
+ },
},
},
- },
- ],
+ ],
+ },
});
},
- [applyFilter]
+ [fireEvent]
);
useEffect(() => {
@@ -396,4 +409,6 @@ function Panel({ interval, seriesList, renderComplete, applyFilter }: PanelProps
);
}
-export { Panel };
+// default export required for React.Lazy
+// eslint-disable-next-line import/no-default-export
+export { TimelionVisComponent as default };
diff --git a/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts b/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts
index 3442f84599fb82..975d12a152d89d 100644
--- a/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts
+++ b/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts
@@ -19,10 +19,10 @@
import { i18n } from '@kbn/i18n';
import { KIBANA_CONTEXT_NAME } from 'src/plugins/expressions/public';
-import { VisParams } from '../../../visualizations/public';
import { TimeRange, Filter, esQuery, Query } from '../../../data/public';
import { TimelionVisDependencies } from '../plugin';
import { getTimezone } from './get_timezone';
+import { TimelionVisParams } from '../timelion_vis_fn';
interface Stats {
cacheCount: number;
@@ -77,7 +77,7 @@ export function getTimelionRequestHandler({
timeRange: TimeRange;
filters: Filter[];
query: Query;
- visParams: VisParams;
+ visParams: TimelionVisParams;
}): Promise {
const expression = visParams.expression;
diff --git a/src/plugins/vis_type_timelion/public/index.scss b/src/plugins/vis_type_timelion/public/index.scss
deleted file mode 100644
index 00e9a885209610..00000000000000
--- a/src/plugins/vis_type_timelion/public/index.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-@import './timelion_vis';
-@import './timelion_editor';
-@import './components/index';
diff --git a/src/plugins/vis_type_timelion/public/plugin.ts b/src/plugins/vis_type_timelion/public/plugin.ts
index e2c7efec34c7f3..bb8fb6b298a077 100644
--- a/src/plugins/vis_type_timelion/public/plugin.ts
+++ b/src/plugins/vis_type_timelion/public/plugin.ts
@@ -39,8 +39,8 @@ import { getTimelionVisDefinition } from './timelion_vis_type';
import { setIndexPatterns, setSavedObjectsClient } from './helpers/plugin_services';
import { ConfigSchema } from '../config';
-import './index.scss';
import { getArgValueSuggestions } from './helpers/arg_value_suggestions';
+import { getTimelionVisRenderer } from './timelion_vis_renderer';
/** @internal */
export interface TimelionVisDependencies extends Partial {
@@ -93,7 +93,8 @@ export class TimelionVisPlugin
};
expressions.registerFunction(() => getTimelionVisualizationConfig(dependencies));
- visualizations.createReactVisualization(getTimelionVisDefinition(dependencies));
+ expressions.registerRenderer(getTimelionVisRenderer(dependencies));
+ visualizations.createBaseVisualization(getTimelionVisDefinition(dependencies));
return {
isUiEnabled: this.initializerContext.config.get().ui.enabled,
diff --git a/src/plugins/vis_type_timelion/public/timelion_options.tsx b/src/plugins/vis_type_timelion/public/timelion_options.tsx
index dfe017d3a273f5..1ef8088c7a7143 100644
--- a/src/plugins/vis_type_timelion/public/timelion_options.tsx
+++ b/src/plugins/vis_type_timelion/public/timelion_options.tsx
@@ -21,30 +21,45 @@ import React, { useCallback } from 'react';
import { EuiPanel } from '@elastic/eui';
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
-import { VisParams } from './timelion_vis_fn';
+import { KibanaContextProvider } from '../../kibana_react/public';
+
+import { TimelionVisParams } from './timelion_vis_fn';
import { TimelionInterval, TimelionExpressionInput } from './components';
+import { TimelionVisDependencies } from './plugin';
-export type TimelionOptionsProps = VisOptionsProps;
+export type TimelionOptionsProps = VisOptionsProps;
-function TimelionOptions({ stateParams, setValue, setValidity }: TimelionOptionsProps) {
- const setInterval = useCallback((value: VisParams['interval']) => setValue('interval', value), [
- setValue,
- ]);
+function TimelionOptions({
+ services,
+ stateParams,
+ setValue,
+ setValidity,
+}: TimelionOptionsProps & {
+ services: TimelionVisDependencies;
+}) {
+ const setInterval = useCallback(
+ (value: TimelionVisParams['interval']) => setValue('interval', value),
+ [setValue]
+ );
const setExpressionInput = useCallback(
- (value: VisParams['expression']) => setValue('expression', value),
+ (value: TimelionVisParams['expression']) => setValue('expression', value),
[setValue]
);
return (
-
-
-
-
+
+
+
+
+
+
);
}
-export { TimelionOptions };
+// default export required for React.Lazy
+// eslint-disable-next-line import/no-default-export
+export { TimelionOptions as default };
diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts b/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts
index d3c6ca5d90371d..a0cd410e197ff0 100644
--- a/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts
+++ b/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts
@@ -24,29 +24,39 @@ import {
KibanaContext,
Render,
} from 'src/plugins/expressions/public';
-import { getTimelionRequestHandler } from './helpers/timelion_request_handler';
+import {
+ getTimelionRequestHandler,
+ TimelionSuccessResponse,
+} from './helpers/timelion_request_handler';
import { TIMELION_VIS_NAME } from './timelion_vis_type';
import { TimelionVisDependencies } from './plugin';
import { Filter, Query, TimeRange } from '../../data/common';
type Input = KibanaContext | null;
-type Output = Promise>;
+type Output = Promise>;
interface Arguments {
expression: string;
interval: string;
}
-interface RenderValue {
- visData: Input;
+export interface TimelionRenderValue {
+ visData: TimelionSuccessResponse;
visType: 'timelion';
- visParams: VisParams;
+ visParams: TimelionVisParams;
}
-export type VisParams = Arguments;
+export type TimelionVisParams = Arguments;
+
+export type TimelionExpressionFunctionDefinition = ExpressionFunctionDefinition<
+ 'timelion_vis',
+ Input,
+ Arguments,
+ Output
+>;
export const getTimelionVisualizationConfig = (
dependencies: TimelionVisDependencies
-): ExpressionFunctionDefinition<'timelion_vis', Input, Arguments, Output> => ({
+): TimelionExpressionFunctionDefinition => ({
name: 'timelion_vis',
type: 'render',
inputTypes: ['kibana_context', 'null'],
@@ -82,7 +92,7 @@ export const getTimelionVisualizationConfig = (
return {
type: 'render',
- as: 'visualization',
+ as: 'timelion_vis',
value: {
visParams,
visType: TIMELION_VIS_NAME,
diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx b/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx
new file mode 100644
index 00000000000000..13a279138a8e4b
--- /dev/null
+++ b/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx
@@ -0,0 +1,65 @@
+/*
+ * 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 { KibanaContextProvider } from '../../kibana_react/public';
+import { VisualizationContainer } from '../../visualizations/public';
+import { TimelionVisDependencies } from './plugin';
+import { TimelionRenderValue } from './timelion_vis_fn';
+// @ts-ignore
+const TimelionVisComponent = lazy(() => import('./components/timelion_vis_component'));
+
+export const getTimelionVisRenderer: (
+ deps: TimelionVisDependencies
+) => ExpressionRenderDefinition = (deps) => ({
+ name: 'timelion_vis',
+ displayName: 'Timelion visualization',
+ reuseDomNode: true,
+ render: (domNode, { visData, visParams }, handlers) => {
+ handlers.onDestroy(() => {
+ unmountComponentAtNode(domNode);
+ });
+
+ const [seriesList] = visData.sheet;
+ const showNoResult = !seriesList || !seriesList.list.length;
+
+ if (showNoResult) {
+ // send the render complete event when there is no data to show
+ // to notify that a chart is updated
+ handlers.done();
+ }
+
+ render(
+
+
+
+
+ ,
+ domNode
+ );
+ },
+});
diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx b/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx
index 8fdde175708e0e..a5425478e46acf 100644
--- a/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx
+++ b/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx
@@ -17,18 +17,19 @@
* under the License.
*/
-import React from 'react';
+import React, { lazy } from 'react';
import { i18n } from '@kbn/i18n';
-import { KibanaContextProvider } from '../../kibana_react/public';
import { DefaultEditorSize } from '../../vis_default_editor/public';
import { getTimelionRequestHandler } from './helpers/timelion_request_handler';
-import { TimelionVisComponent, TimelionVisComponentProp } from './components';
-import { TimelionOptions, TimelionOptionsProps } from './timelion_options';
+import { TimelionOptionsProps } from './timelion_options';
import { TimelionVisDependencies } from './plugin';
+import { toExpressionAst } from './to_ast';
import { VIS_EVENT_TO_TRIGGER } from '../../visualizations/public';
+const TimelionOptions = lazy(() => import('./timelion_options'));
+
export const TIMELION_VIS_NAME = 'timelion';
export function getTimelionVisDefinition(dependencies: TimelionVisDependencies) {
@@ -48,21 +49,15 @@ export function getTimelionVisDefinition(dependencies: TimelionVisDependencies)
expression: '.es(*)',
interval: 'auto',
},
- component: (props: TimelionVisComponentProp) => (
-
-
-
- ),
},
editorConfig: {
optionsTemplate: (props: TimelionOptionsProps) => (
-
-
-
+
),
defaultSize: DefaultEditorSize.MEDIUM,
},
requestHandler: timelionRequestHandler,
+ toExpressionAst,
responseHandler: 'none',
inspectorAdapters: {},
getSupportedTriggers: () => {
diff --git a/src/plugins/vis_type_timelion/public/components/chart.tsx b/src/plugins/vis_type_timelion/public/to_ast.test.ts
similarity index 60%
rename from src/plugins/vis_type_timelion/public/components/chart.tsx
rename to src/plugins/vis_type_timelion/public/to_ast.test.ts
index 15a376d4e96386..8a9d4b83f94d20 100644
--- a/src/plugins/vis_type_timelion/public/components/chart.tsx
+++ b/src/plugins/vis_type_timelion/public/to_ast.test.ts
@@ -17,25 +17,24 @@
* under the License.
*/
-import React from 'react';
+import { Vis } from 'src/plugins/visualizations/public';
+import { TimelionVisParams } from './timelion_vis_fn';
+import { toExpressionAst } from './to_ast';
-import { Sheet } from '../helpers/timelion_request_handler';
-import { Panel } from './panel';
-import { ExprVisAPIEvents } from '../../../visualizations/public';
+describe('timelion vis toExpressionAst function', () => {
+ let vis: Vis;
-interface ChartComponentProp {
- applyFilter: ExprVisAPIEvents['applyFilter'];
- interval: string;
- renderComplete(): void;
- seriesList: Sheet;
-}
+ beforeEach(() => {
+ vis = {
+ params: {
+ expression: '.es(*)',
+ interval: 'auto',
+ },
+ } as any;
+ });
-function ChartComponent(props: ChartComponentProp) {
- if (!props.seriesList) {
- return null;
- }
-
- return ;
-}
-
-export { ChartComponent };
+ it('should match basic snapshot', () => {
+ const actual = toExpressionAst(vis);
+ expect(actual).toMatchSnapshot();
+ });
+});
diff --git a/src/plugins/vis_type_timelion/public/to_ast.ts b/src/plugins/vis_type_timelion/public/to_ast.ts
new file mode 100644
index 00000000000000..7044bbf4e58318
--- /dev/null
+++ b/src/plugins/vis_type_timelion/public/to_ast.ts
@@ -0,0 +1,37 @@
+/*
+ * 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 { TimelionExpressionFunctionDefinition, TimelionVisParams } from './timelion_vis_fn';
+
+const escapeString = (data: string): string => {
+ return data.replace(/\\/g, `\\\\`).replace(/'/g, `\\'`);
+};
+
+export const toExpressionAst = (vis: Vis) => {
+ const timelion = buildExpressionFunction('timelion_vis', {
+ expression: escapeString(vis.params.expression),
+ interval: escapeString(vis.params.interval),
+ });
+
+ const ast = buildExpression([timelion]);
+
+ return ast.toAst();
+};
diff --git a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap
index 654ac78cdaa022..c0c37e2262f9c6 100644
--- a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap
+++ b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap
@@ -24,6 +24,4 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunct
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 timelion function 1`] = `"timelion_vis expression='foo' interval='bar' "`;
-
exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles vega function 1`] = `"vega spec='this is a test' "`;
diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts
index 8cac76726b13b0..a1fea45f517816 100644
--- a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts
+++ b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts
@@ -117,12 +117,6 @@ describe('visualize loader pipeline helpers: build pipeline', () => {
expect(actual).toMatchSnapshot();
});
- it('handles timelion function', () => {
- const params = { expression: 'foo', interval: 'bar' };
- const actual = buildPipelineVisFunction.timelion(params, schemasDef, uiState);
- expect(actual).toMatchSnapshot();
- });
-
describe('handles table function', () => {
it('without splits or buckets', () => {
const params = { foo: 'bar' };
diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.ts b/src/plugins/visualizations/public/legacy/build_pipeline.ts
index dcc384a191858f..79e1c1cca2155a 100644
--- a/src/plugins/visualizations/public/legacy/build_pipeline.ts
+++ b/src/plugins/visualizations/public/legacy/build_pipeline.ts
@@ -263,11 +263,6 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = {
const paramsArray = [paramsJson, uiStateJson].filter((param) => Boolean(param));
return `tsvb ${paramsArray.join(' ')}`;
},
- timelion: (params) => {
- const expression = prepareString('expression', params.expression);
- const interval = prepareString('interval', params.interval);
- return `timelion_vis ${expression}${interval}`;
- },
table: (params, schemas) => {
const visConfig = {
...params,