parent
25df364e05
commit
6c1a1e888d
|
@ -1,463 +0,0 @@
|
|||
[[development-create-visualization]]
|
||||
=== Developing Visualizations
|
||||
|
||||
This is a short description of functions and interfaces provided. For more information you should check the kibana
|
||||
source code and the existing visualizations provided with it.
|
||||
|
||||
- <<development-visualization-factory>>
|
||||
* <<development-base-visualization-type>>
|
||||
* <<development-react-visualization-type>>
|
||||
- <<development-vis-editors>>
|
||||
* <<development-default-editor>>
|
||||
* <<development-custom-editor>>
|
||||
- <<development-visualization-request-handlers>>
|
||||
* <<development-default-request-handler>>
|
||||
* <<development-none-request-handler>>
|
||||
* <<development-custom-request-handler>>
|
||||
- <<development-visualization-response-handlers>>
|
||||
* <<development-default-response-handler>>
|
||||
* <<development-none-response-handler>>
|
||||
* <<development-custom-response-handler>>
|
||||
- <<development-vis-object>>
|
||||
* <<development-vis-timefilter>>
|
||||
- <<development-aggconfig>>
|
||||
|
||||
[[development-visualization-factory]]
|
||||
=== Visualization Factory
|
||||
|
||||
Use the `VisualizationFactory` to create a new visualization.
|
||||
The creation-methods create a new visualization tied to the underlying rendering technology.
|
||||
You should also register the visualization with `VisTypesRegistryProvider`.
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
import { VisFactoryProvider } from 'ui/vis/vis_factory';
|
||||
import { VisTypesRegistryProvider } from 'ui/registry/vis_types';
|
||||
|
||||
const MyNewVisType = (Private) => {
|
||||
const VisFactory = Private(VisFactoryProvider);
|
||||
|
||||
return VisFactory.createBaseVisualization({
|
||||
name: 'my_new_vis',
|
||||
title: 'My New Vis',
|
||||
icon: 'my_icon',
|
||||
description: 'Cool new chart',
|
||||
...
|
||||
});
|
||||
}
|
||||
|
||||
VisTypesRegistryProvider.register(MyNewVisType);
|
||||
-----------
|
||||
|
||||
The list of common parameters:
|
||||
|
||||
- *name*: unique visualization name, only lowercase letters and underscore
|
||||
- *title*: title of your visualization as displayed in kibana
|
||||
- *icon*: <string> the https://elastic.github.io/eui/#/display/icons[EUI icon] type to use for this visualization
|
||||
- *image*: instead of an icon you can provide a SVG image (imported)
|
||||
- *description*: description of your visualization as shown in kibana
|
||||
- *hidden*: <bool> if set to true, will hide the type from showing up in the visualization wizard
|
||||
- *visConfig*: object holding visualization parameters
|
||||
- *visConfig.defaults*: object holding default visualization configuration
|
||||
- *visualization*: A constructor function for a Visualization.
|
||||
- *requestHandler*: <string> one of the available request handlers or a <function> for a custom request handler
|
||||
- *responseHandler*: <string> one of the available response handlers or a <function> for a custom response handler
|
||||
- *editor*: Editor class for custom one
|
||||
- *editorConfig*: object holding editor parameters
|
||||
- *options.showTimePicker*: <bool> show or hide time filter (defaults to true)
|
||||
- *options.showQueryBar*: <bool> show or hide query bar (defaults to true)
|
||||
- *options.showFilterBar*: <bool> show or hide filter bar (defaults to true)
|
||||
- *options.showIndexSelection*: <bool> show or hide index selection (defaults to true)
|
||||
- *stage*: <string> Set this to "experimental" to mark your visualization as experimental.
|
||||
Experimental visualizations can also be disabled from the advanced settings. (defaults to "production")
|
||||
- *feedbackMessage*: <string> You can provide a message (which can contain HTML), that will be appended
|
||||
to the experimental notification in visualize, if your visualization is experimental or in lab mode.
|
||||
|
||||
|
||||
Each of the factories have some of the custom parameters, which will be described below.
|
||||
|
||||
[[development-base-visualization-type]]
|
||||
==== Base Visualization Type
|
||||
The base visualization type does not make any assumptions about the rendering technology you are going to use and
|
||||
works with pure JavaScript. It is the visualization type we recommend to use.
|
||||
|
||||
You need to provide a type with a constructor function, a render method which will be called every time
|
||||
options or data change, and a destroy method which will be called to cleanup.
|
||||
|
||||
The render function receives the data object and status object which tells what actually changed.
|
||||
Render function needs to return a promise, which should be resolved once the visualization is done rendering.
|
||||
|
||||
The status object provides information about changes since the previous render call.
|
||||
Due to performance reasons you need to opt-in for each status change, that you want
|
||||
to be informed about by Kibana. This is done by using the `requiresUpdateStatus` key
|
||||
in your visualization registration object. You pass it an array, that contains all
|
||||
the status updates you want to receive. By default none of it will be calculated.
|
||||
|
||||
The following snippet shows explain all available status updates. You should only
|
||||
activate those changes, that you actually use in your `render` method.
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
import { Status } from 'ui/vis/update_status';
|
||||
|
||||
// ...
|
||||
return VisFactory.createBaseVisualization({
|
||||
// ...
|
||||
requiresUpdateStatus: [
|
||||
// Check for changes in the aggregation configuration for the visualization
|
||||
Status.AGGS,
|
||||
// Check for changes in the actual data returned from Elasticsearch
|
||||
Status.DATA,
|
||||
// Check for changes in the parameters (configuration) for the visualization
|
||||
Status.PARAMS,
|
||||
// Check if the visualization has changes its size
|
||||
Status.RESIZE,
|
||||
// Check if the time range for the visualization has been changed
|
||||
Status.TIME,
|
||||
// Check if the UI state of the visualization has been changed
|
||||
Status.UI_STATE
|
||||
]
|
||||
});
|
||||
-----------
|
||||
|
||||
If you activate any of these status updates, the `status` object passed as second
|
||||
parameter to the `render` method will contain a key for that status (e.g. `status[Status.DATA]`),
|
||||
that is either `true` if a change has been detected or `false` otherwise.
|
||||
|
||||
|
||||
image::images/visualize-flow.png[Main Flow]
|
||||
|
||||
- Your visualizations constructor will get called with `vis` object and the DOM-element to which it should render.
|
||||
At this point you should prepare everything for rendering, but not render yet
|
||||
- `<visualize>` component monitors `appState`, `uiState` and `vis` for changes
|
||||
- on changes the `<visualize>`-directive will call your `requestHandler`.
|
||||
Implementing a request handler is optional, as you might use one of the provided ones.
|
||||
- response from `requestHandler` will get passed to `responseHandler`. It should convert raw data to something that
|
||||
can be consumed by visualization. Implementing `responseHandler` is optional, as you might use of of the provided ones.
|
||||
- On new data from the `responseHandler` or on when the size of the surrounding DOM-element has changed,
|
||||
your visualization `render`-method gets called. It needs to return a promise which resolves once the visualization
|
||||
is done rendering.
|
||||
- the visualization should call `vis.updateState()` any time something has changed that requires to
|
||||
re-render or fetch new data.
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
import { VisFactoryProvider } from 'ui/vis/vis_factory';
|
||||
import { VisTypesRegistryProvider } from 'ui/registry/vis_types';
|
||||
|
||||
class MyVisualization {
|
||||
constructor(el, vis) {
|
||||
this.el = el;
|
||||
this.vis = vis;
|
||||
}
|
||||
async render(visData, status) {
|
||||
...
|
||||
return 'done rendering';
|
||||
}
|
||||
destroy() {
|
||||
console.log('destroying');
|
||||
}
|
||||
}
|
||||
|
||||
const MyNewVisType = (Private) => {
|
||||
const VisFactory = Private(VisFactoryProvider);
|
||||
|
||||
return VisFactory.createBaseVisualization({
|
||||
name: 'my_new_vis',
|
||||
title: 'My New Vis',
|
||||
icon: 'my_icon',
|
||||
description: 'Cool new chart',
|
||||
visualization: MyVisualization
|
||||
});
|
||||
}
|
||||
|
||||
VisTypesRegistryProvider.register(MyNewVisType);
|
||||
-----------
|
||||
|
||||
[[development-react-visualization-type]]
|
||||
==== React Visualization Type
|
||||
React visualization type assumes you are using React as your rendering technology.
|
||||
Just pass in a React component to `visConfig.component`.
|
||||
|
||||
The visualization will receive `vis`, `appState`, `updateStatus` and `visData` as props.
|
||||
It also has a `renderComplete` property, which needs to be called once the rendering has completed.
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
import { ReactComponent } from './my_react_component';
|
||||
|
||||
const MyNewVisType = (Private) => {
|
||||
const VisFactory = Private(VisFactoryProvider);
|
||||
|
||||
return VisFactory.createReactVisualization({
|
||||
name: 'my_new_vis',
|
||||
title: 'My New Vis',
|
||||
icon: 'my_icon',
|
||||
description: 'Cool new chart',
|
||||
visConfig: {
|
||||
component: ReactComponent
|
||||
}
|
||||
});
|
||||
}
|
||||
-----------
|
||||
|
||||
[[development-vis-editors]]
|
||||
=== Visualization Editors
|
||||
By default, visualizations will use the `default` editor.
|
||||
This is the sidebar editor you see in many of the Kibana visualizations. You can also write your own editor.
|
||||
|
||||
[[development-default-editor]]
|
||||
==== `default` editor controller
|
||||
The default editor controller receives an `optionsTemplate` or `optionTabs` parameter.
|
||||
These tabs should be React components.
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
{
|
||||
name: 'my_new_vis',
|
||||
title: 'My New Vis',
|
||||
icon: 'my_icon',
|
||||
description: 'Cool new chart',
|
||||
editorConfig: {
|
||||
optionsTemplate: MyReactComponent // or if multiple tabs are required:
|
||||
optionTabs: [
|
||||
{ title: 'tab 3', editor: MyReactComponent }
|
||||
]
|
||||
}
|
||||
}
|
||||
-----------
|
||||
|
||||
[[development-custom-editor]]
|
||||
==== custom editor controller
|
||||
You can create a custom editor controller. To do so pass an Editor object (the same format as VisController class).
|
||||
You can make your controller take extra configuration which is passed to the editorConfig property.
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
import { VisFactoryProvider } from 'ui/vis/vis_factory';
|
||||
|
||||
class MyEditorController {
|
||||
constructor(el, vis) {
|
||||
this.el = el;
|
||||
this.vis = vis;
|
||||
this.config = vis.type.editorConfig;
|
||||
}
|
||||
async render(visData) {
|
||||
console.log(this.config.my);
|
||||
...
|
||||
return 'done rendering';
|
||||
}
|
||||
destroy() {
|
||||
console.log('destroying');
|
||||
}
|
||||
}
|
||||
|
||||
const MyNewVisType = (Private) => {
|
||||
const VisFactory = Private(VisFactoryProvider);
|
||||
|
||||
return VisFactory.createAngularVisualization({
|
||||
name: 'my_new_vis',
|
||||
title: 'My New Vis',
|
||||
icon: 'my_icon',
|
||||
description: 'Cool new chart',
|
||||
editor: MyEditorController,
|
||||
editorConfig: { my: 'custom config' }
|
||||
});
|
||||
}
|
||||
|
||||
VisTypesRegistryProvider.register(MyNewVisType);
|
||||
-----------
|
||||
|
||||
[[development-visualization-request-handlers]]
|
||||
=== Visualization Request Handlers
|
||||
Request handler gets called when one of the following keys on AppState change:
|
||||
`vis`, `query`, `filters` or `uiState` and when the time filter is updated. On top
|
||||
of that it will also get called on force refresh.
|
||||
|
||||
By default visualizations will use the `courier` request handler. They can also choose to use any of the other provided
|
||||
request handlers. It is also possible to define your own request handler
|
||||
(which you can then register to be used by other visualizations).
|
||||
|
||||
[[development-default-request-handler]]
|
||||
==== courier request handler
|
||||
'courier' is the default request handler which works with the 'default' side bar editor.
|
||||
|
||||
[[development-none-request-handler]]
|
||||
==== `none` request handler
|
||||
Using 'none' as your request handles means your visualization does not require any data to be requested.
|
||||
|
||||
[[development-custom-request-handler]]
|
||||
==== custom request handler
|
||||
You can define your custom request handler by providing a function with the following signature:
|
||||
`function (vis, { uiState, appState, timeRange }) { ... }`
|
||||
|
||||
The `timeRange` will be an object with a `from` and `to` key, that can contain
|
||||
datemath expressions, like `now-7d`. You can use the `datemath` library to parse
|
||||
them.
|
||||
|
||||
This function must return a promise, which should get resolved with new data that will be passed to responseHandler.
|
||||
|
||||
It's up to function to decide when it wants to issue a new request or return previous data
|
||||
(if none of the objects relevant to the request handler changed).
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
import { VisFactoryProvider } from 'ui/vis/vis_factory';
|
||||
|
||||
const myRequestHandler = async (vis, { appState, uiState, timeRange }) => {
|
||||
const data = ... parse ...
|
||||
return data;
|
||||
};
|
||||
|
||||
const MyNewVisType = (Private) => {
|
||||
const VisFactory = Private(VisFactoryProvider);
|
||||
|
||||
return VisFactory.createAngularVisualization({
|
||||
name: 'my_new_vis',
|
||||
title: 'My New Vis',
|
||||
icon: 'my_icon',
|
||||
description: 'Cool new chart',
|
||||
requestHandler: myRequestHandler
|
||||
});
|
||||
}
|
||||
|
||||
VisTypesRegistryProvider.register(MyNewVisType);
|
||||
-----------
|
||||
|
||||
[[development-visualization-response-handlers]]
|
||||
=== Visualization Response Handlers
|
||||
The response handler is a function that receives the data from a request handler, as well as an instance of Vis object.
|
||||
Its job is to convert the data to a format visualization can use. By default 'default' request handler is used
|
||||
which produces a table representation of the data. The data object will then be passed to visualization.
|
||||
This response matches the visData property of the <visualization> directive.
|
||||
|
||||
[[development-default-response-handler]]
|
||||
==== default response handler
|
||||
The default response handler converts pure elasticsearch responses into a tabular format.
|
||||
It is the recommended responseHandler. The response object contains a table property,
|
||||
which is an array of all the tables in the response. Each of the table objects has two properties:
|
||||
|
||||
- `columns`: array of column objects, where each column object has a title property and an aggConfig property
|
||||
- `rows`: array of rows, where each row is an array of non formatted cell values
|
||||
|
||||
Here is an example of a response with 1 table, 3 columns and 2 rows:
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
{
|
||||
tables: [{
|
||||
columns: [{
|
||||
title: 'column1',
|
||||
aggConfig: ...
|
||||
},{
|
||||
title: 'column2',
|
||||
aggConfig: ...
|
||||
},{
|
||||
title: 'column3',
|
||||
aggConfig: ...
|
||||
}],
|
||||
rows: [
|
||||
[ '404', 1262, 12.5 ]
|
||||
[ '200', 343546, 60.1 ]
|
||||
]
|
||||
}];
|
||||
}
|
||||
-----------
|
||||
|
||||
[[development-none-response-handler]]
|
||||
==== none response handler
|
||||
None response handler is an identity function, which will return the same data it receives.
|
||||
|
||||
[[development-custom-response-handler]]
|
||||
==== custom response handler
|
||||
You can define your custom response handler by providing a function with the following definition:
|
||||
'function (vis, response) { ... }'.
|
||||
|
||||
Function should return the transformed data object that visualization can consume.
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
import { VisFactoryProvider } from 'ui/vis/vis_factory';
|
||||
|
||||
const myResponseHandler = (vis, response) => {
|
||||
// transform the response (based on vis object?)
|
||||
const response = ... transform data ...;
|
||||
return response;
|
||||
};
|
||||
|
||||
const MyNewVisType(Private) => {
|
||||
const VisFactory = Private(VisFactoryProvider);
|
||||
|
||||
return VisFactory.createAngularVisualization({
|
||||
name: 'my_new_vis',
|
||||
title: 'My New Vis',
|
||||
icon: 'my_icon',
|
||||
description: 'Cool new chart',
|
||||
responseHandler: myResponseHandler
|
||||
});
|
||||
}
|
||||
|
||||
VisTypesRegistryProvider.register(MyNewVisType);
|
||||
-----------
|
||||
|
||||
[[development-vis-object]]
|
||||
=== Vis object
|
||||
The `vis` object holds the visualization state and is the window into kibana:
|
||||
|
||||
- *vis.params*: holds the visualization parameters
|
||||
- *vis.indexPattern*: selected index pattern object
|
||||
- *vis.getState()*: gets current visualization state
|
||||
- *vis.updateState()*: updates current state with values from `vis.params`
|
||||
- *vis.resetState()*: resets `vis.params` to the values in the current state
|
||||
- *vis.forceReload()*: forces whole cycle (request handler gets called)
|
||||
- *vis.getUiState()*: gets UI state of visualization
|
||||
- *vis.uiStateVal(name, val)*: updates a property in UI state
|
||||
- *vis.isEditorMode()*: returns true if in editor mode
|
||||
- *vis.API.timeFilter*: allows you to access time filter
|
||||
- *vis.API.queryFilter*: gives you access to queryFilter
|
||||
- *vis.API.events.click*: default click handler
|
||||
- *vis.API.events.brush*: default brush handler
|
||||
|
||||
The visualization gets all its parameters in `vis.params`, which are default values merged with the current state.
|
||||
If the visualization needs to update the current state, it should update the `vis.params` and call `vis.updateState()`
|
||||
which will inform <visualize> about the change, which will call request and response handler and then your
|
||||
visualization's render method.
|
||||
|
||||
For the parameters that should not be saved with the visualization you should use the UI state.
|
||||
These hold viewer-specific state, such as popup open/closed, custom colors applied to the series etc.
|
||||
|
||||
You can access the filter bar and time filter through the objects defined on `vis.API`
|
||||
|
||||
[[development-vis-timefilter]]
|
||||
==== timeFilter
|
||||
|
||||
Update the timefilter time values and call update() method on it to update the time filter
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
timefilter.time.from = moment(ranges.xaxis.from);
|
||||
timefilter.time.to = moment(ranges.xaxis.to);
|
||||
timefilter.time.mode = 'absolute';
|
||||
timefilter.update();
|
||||
-----------
|
||||
|
||||
|
||||
[[development-aggconfig]]
|
||||
=== AggConfig object
|
||||
|
||||
The AggConfig object represents an aggregation search to Elasticsearch,
|
||||
plus some additional functionality to manage data-values that belong to this aggregation.
|
||||
This is primarily used internally in Kibana, but you may find you have a need for it
|
||||
when writing your own visualization. Here we provide short description of some of the methods on it,
|
||||
however the best reference would be to actually check the source code.
|
||||
|
||||
|
||||
- *fieldFormatter(<type>)* : returns a function which will format your value according to field formatters defined on
|
||||
the field. The type can be either 'text' or 'html'.
|
||||
- *makeLabel()* : gets the label for the aggregation
|
||||
- *isFilterable()* : return true if aggregation is filterable (you can then call createFilter)
|
||||
- *createFilter(bucketKey)* : creates a filter for specific bucket key
|
||||
- *getValue(bucket)* : gets value for a specific bucket
|
||||
- *getField()* : gets the field used for this aggregation
|
||||
- *getFieldDisplayName()* : gets field display name
|
||||
- *getAggParams()* : gets the arguments to the aggregation
|
|
@ -1,58 +0,0 @@
|
|||
[[development-embedding-visualizations]]
|
||||
=== Embedding Visualizations
|
||||
|
||||
To embed visualization use the `VisualizeLoader`.
|
||||
|
||||
==== VisualizeLoader
|
||||
|
||||
The `VisualizeLoader` class is the easiest way to embed a visualization into your plugin.
|
||||
It will take care of loading the data and rendering the visualization.
|
||||
|
||||
To get an instance of the loader, do the following:
|
||||
|
||||
["source","js"]
|
||||
-----------
|
||||
import { getVisualizeLoader } from 'ui/visualize/loader';
|
||||
|
||||
getVisualizeLoader().then((loader) => {
|
||||
// You now have access to the loader
|
||||
});
|
||||
-----------
|
||||
|
||||
The loader exposes the following methods:
|
||||
|
||||
- `getVisualizationList()`: which returns promise which gets resolved with a list of saved visualizations
|
||||
- `embedVisualizationWithId(container, savedId, params)`: which embeds visualization by id
|
||||
- `embedVisualizationWithSavedObject(container, savedObject, params)`: which embeds visualization from saved object
|
||||
|
||||
Depending on which embed method you are using, you either pass in the id of the
|
||||
saved object for the visualization, or a `savedObject`, that you can retrieve via
|
||||
the `savedVisualizations` Angular service by its id. The `savedObject` give you access
|
||||
to the filter and query logic and allows you to attach listeners to the visualizations.
|
||||
For a more complex use-case you usually want to use that method.
|
||||
|
||||
`container` should be a DOM element (jQuery wrapped or regular DOM element) into which the visualization should be embedded
|
||||
`params` is a parameter object specifying several parameters, that influence rendering.
|
||||
|
||||
You will find a detailed description of all the parameters in the inline docs
|
||||
in the {repo}blob/{branch}/src/legacy/ui/public/visualize/loader/types.ts[loader source code].
|
||||
|
||||
Both methods return an `EmbeddedVisualizeHandler`, that gives you some access
|
||||
to the visualization. The `embedVisualizationWithSavedObject` method will return
|
||||
the handler immediately from the method call, whereas the `embedVisualizationWithId`
|
||||
will return a promise, that resolves with the handler, as soon as the `id` could be
|
||||
found. It will reject, if the `id` is invalid.
|
||||
|
||||
The returned `EmbeddedVisualizeHandler` itself has the following methods and properties:
|
||||
|
||||
- `destroy()`: destroys the embedded visualization. You MUST call that method when navigating away
|
||||
or destroying the DOM node you have embedded into.
|
||||
- `getElement()`: a reference to the jQuery wrapped DOM element, that renders the visualization
|
||||
- `whenFirstRenderComplete()`: will return a promise, that resolves as soon as the visualization has
|
||||
finished rendering for the first time
|
||||
- `addRenderCompleteListener(listener)`: will register a listener to be called whenever
|
||||
a rendering of this visualization finished (not just the first one)
|
||||
- `removeRenderCompleteListener(listener)`: removes an event listener from the handler again
|
||||
|
||||
You can find the detailed `EmbeddedVisualizeHandler` documentation in its
|
||||
{repo}blob/{branch}/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.ts[source code].
|
|
@ -1,21 +1,26 @@
|
|||
[[development-visualize-index]]
|
||||
== Developing Visualizations
|
||||
|
||||
Kibana Visualizations are the easiest way to add additional functionality to Kibana.
|
||||
This part of documentation is split into two parts.
|
||||
The first part tells you all you need to know on how to embed existing Kibana Visualizations in your plugin.
|
||||
The second step explains how to create your own custom visualization.
|
||||
|
||||
[IMPORTANT]
|
||||
==============================================
|
||||
These pages document internal APIs and are not guaranteed to be supported across future versions of Kibana.
|
||||
However, these docs will be kept up-to-date to reflect the current implementation of Visualization plugins in Kibana.
|
||||
These pages document internal APIs and are not guaranteed to be supported across future versions of Kibana.
|
||||
==============================================
|
||||
|
||||
* <<development-embedding-visualizations>>
|
||||
* <<development-create-visualization>>
|
||||
The internal APIs for creating custom visualizations are in a state of heavy churn as
|
||||
they are being migrated to the new Kibana platform, and large refactorings have been
|
||||
happening across minor releases in the `7.x` series. In particular, in `7.5` and later
|
||||
we have made significant changes to the legacy APIs as we work to gradually replace them.
|
||||
|
||||
As a result, starting in `7.5` we have removed the documentation for the legacy APIs
|
||||
to prevent confusion. We expect to be able to create new documentation later in `7.x`
|
||||
when the visualizations plugin has been completed.
|
||||
|
||||
include::development-embedding-visualizations.asciidoc[]
|
||||
We would recommend waiting until later in `7.x` to upgrade your plugins if possible.
|
||||
If you would like to keep up with progress on the visualizations plugin in the meantime,
|
||||
here are a few resources:
|
||||
|
||||
include::development-create-visualization.asciidoc[]
|
||||
* The <<breaking-changes,breaking changes>> documentation, where we try to capture any changes to the APIs as they occur across minors.
|
||||
* link:https://github.com/elastic/kibana/issues/44121[Meta issue] which is tracking the move of the plugin to the new Kibana platform
|
||||
* Our link:https://www.elastic.co/blog/join-our-elastic-stack-workspace-on-slack[Elastic Stack workspace on Slack].
|
||||
* The {repo}blob/{branch}/src/plugins/visualizations[source code], which will continue to be
|
||||
the most accurate source of information.
|
||||
|
|
|
@ -58,8 +58,6 @@ You can also nest these aggregations. For example, if you want to produce a thir
|
|||
|
||||
{ref}/search-aggregations-pipeline-serialdiff-aggregation.html[Serial diff]:: Values in a time series are subtracted from itself at different time lags or periods.
|
||||
|
||||
Custom {kib} plugins can <<development-visualize-index, add more capabilities to the default editor>>, which includes support for adding more aggregations.
|
||||
|
||||
[float]
|
||||
[[visualize-sibling-pipeline-aggregations]]
|
||||
=== Sibling pipeline aggregations
|
||||
|
|
Loading…
Reference in a new issue