From 2b6885a74cd86b36553a21d3c49c0309e7e6bf9e Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 4 Mar 2022 11:06:06 +0200 Subject: [PATCH] [Gauge] Vis Type (#126048) * Added transparent background * Added gauge/goal visType. * Fixed palette, scale, and types. * Set legacy chart as default. * Removed deprecation message. * Added percent format params, coming from visdimensions. * Added support of labels/sublabels. * Updated i18n label. * Added support of showElasticChartsOptions * Added autoextend ranges elastic charts tooltip. * The outline elastic-charts message added. * outline renaming and metric/buckets limitations * reverted mistaken change of sample_vis.test.mocks. * Warning message added to gauge split chart. * Added warning message to the splitChart button at goal/gauge. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .i18nrc.json | 1 + docs/developer/plugin-list.asciidoc | 4 + packages/kbn-optimizer/limits.yml | 1 + .../expression_gauge/common/index.ts | 1 + .../public/components/gauge_component.tsx | 22 +-- src/plugins/vis_types/gauge/common/index.ts | 9 ++ .../config.ts} | 13 +- src/plugins/vis_types/gauge/jest.config.js | 18 +++ src/plugins/vis_types/gauge/kibana.json | 16 +++ .../public/__snapshots__/to_ast.test.ts.snap | 63 +++++++++ .../public/editor/collections.ts | 19 +-- .../public/editor/components/gauge/index.tsx | 12 +- .../editor/components/gauge/labels_panel.tsx | 6 +- .../editor/components/gauge/ranges_panel.tsx | 49 +++++-- .../editor/components/gauge/style_panel.tsx | 57 +++++--- .../public/editor/components/index.tsx | 9 +- .../{vislib => gauge}/public/editor/index.ts | 0 src/plugins/vis_types/gauge/public/index.ts | 17 +++ src/plugins/vis_types/gauge/public/plugin.ts | 41 ++++++ .../vis_types/gauge/public/to_ast.test.ts | 53 +++++++ src/plugins/vis_types/gauge/public/to_ast.ts | 93 +++++++++++++ .../vis_types/gauge/public/to_ast_esaggs.ts | 33 +++++ src/plugins/vis_types/gauge/public/types.ts | 68 +++++++++ .../vis_types/gauge/public/utils/index.ts | 9 ++ .../vis_types/gauge/public/utils/palette.ts | 49 +++++++ .../vis_types/gauge/public/vis_type/gauge.tsx | 130 +++++++++++++++++ .../vis_types/gauge/public/vis_type/goal.tsx | 122 ++++++++++++++++ .../vis_types/gauge/public/vis_type/index.ts | 19 +++ .../gauge/public/vis_type/split_tooltip.tsx | 19 +++ src/plugins/vis_types/gauge/server/index.ts | 17 +++ src/plugins/vis_types/gauge/server/plugin.ts | 47 +++++++ src/plugins/vis_types/gauge/tsconfig.json | 27 ++++ src/plugins/vis_types/vislib/kibana.json | 2 +- src/plugins/vis_types/vislib/public/gauge.ts | 114 +-------------- src/plugins/vis_types/vislib/public/goal.ts | 103 +------------- src/plugins/vis_types/vislib/public/plugin.ts | 15 +- src/plugins/vis_types/vislib/tsconfig.json | 2 +- .../visualizations/common/utils/accessors.ts | 12 +- .../visualizations/common/utils/index.ts | 2 +- .../components/split_chart_warning.tsx | 131 +++++++++++++----- .../components/visualize_editor_common.tsx | 29 +++- .../public/visualize_app/constants.ts | 10 ++ .../utils/split_chart_warning_helpers.ts | 34 +++++ .../translations/translations/ja-JP.json | 54 ++++---- .../translations/translations/zh-CN.json | 54 ++++---- 45 files changed, 1228 insertions(+), 378 deletions(-) create mode 100755 src/plugins/vis_types/gauge/common/index.ts rename src/plugins/vis_types/{vislib/public/vis_type_vislib_vis_types.ts => gauge/config.ts} (51%) create mode 100644 src/plugins/vis_types/gauge/jest.config.js create mode 100755 src/plugins/vis_types/gauge/kibana.json create mode 100644 src/plugins/vis_types/gauge/public/__snapshots__/to_ast.test.ts.snap rename src/plugins/vis_types/{vislib => gauge}/public/editor/collections.ts (67%) rename src/plugins/vis_types/{vislib => gauge}/public/editor/components/gauge/index.tsx (84%) rename src/plugins/vis_types/{vislib => gauge}/public/editor/components/gauge/labels_panel.tsx (87%) rename src/plugins/vis_types/{vislib => gauge}/public/editor/components/gauge/ranges_panel.tsx (63%) rename src/plugins/vis_types/{vislib => gauge}/public/editor/components/gauge/style_panel.tsx (50%) rename src/plugins/vis_types/{vislib => gauge}/public/editor/components/index.tsx (64%) rename src/plugins/vis_types/{vislib => gauge}/public/editor/index.ts (100%) create mode 100755 src/plugins/vis_types/gauge/public/index.ts create mode 100755 src/plugins/vis_types/gauge/public/plugin.ts create mode 100644 src/plugins/vis_types/gauge/public/to_ast.test.ts create mode 100644 src/plugins/vis_types/gauge/public/to_ast.ts create mode 100644 src/plugins/vis_types/gauge/public/to_ast_esaggs.ts create mode 100755 src/plugins/vis_types/gauge/public/types.ts create mode 100644 src/plugins/vis_types/gauge/public/utils/index.ts create mode 100644 src/plugins/vis_types/gauge/public/utils/palette.ts create mode 100644 src/plugins/vis_types/gauge/public/vis_type/gauge.tsx create mode 100644 src/plugins/vis_types/gauge/public/vis_type/goal.tsx create mode 100644 src/plugins/vis_types/gauge/public/vis_type/index.ts create mode 100644 src/plugins/vis_types/gauge/public/vis_type/split_tooltip.tsx create mode 100755 src/plugins/vis_types/gauge/server/index.ts create mode 100755 src/plugins/vis_types/gauge/server/plugin.ts create mode 100644 src/plugins/vis_types/gauge/tsconfig.json create mode 100644 src/plugins/visualizations/public/visualize_app/constants.ts create mode 100644 src/plugins/visualizations/public/visualize_app/utils/split_chart_warning_helpers.ts diff --git a/.i18nrc.json b/.i18nrc.json index 7ec704aab3a7a..eeb2578ef3472 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -68,6 +68,7 @@ "usageCollection": "src/plugins/usage_collection", "utils": "packages/kbn-securitysolution-utils/src", "visDefaultEditor": "src/plugins/vis_default_editor", + "visTypeGauge": "src/plugins/vis_types/gauge", "visTypeHeatmap": "src/plugins/vis_types/heatmap", "visTypeMarkdown": "src/plugins/vis_type_markdown", "visTypeMetric": "src/plugins/vis_types/metric", diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 2dd78be3c1012..2de3fc3000ac5 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -297,6 +297,10 @@ It acts as a container for a particular visualization and options tabs. Contains The plugin exposes the static DefaultEditorController class to consume. +|{kib-repo}blob/{branch}/src/plugins/vis_types/gauge[visTypeGauge] +|WARNING: Missing README. + + |{kib-repo}blob/{branch}/src/plugins/vis_types/heatmap[visTypeHeatmap] |WARNING: Missing README. diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 3a999272c3a4d..f9f0bfc4fd29e 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -121,4 +121,5 @@ pageLoadAssetSize: expressionPartitionVis: 26338 sharedUX: 16225 ux: 20784 + visTypeGauge: 24113 cloudSecurityPosture: 19109 diff --git a/src/plugins/chart_expressions/expression_gauge/common/index.ts b/src/plugins/chart_expressions/expression_gauge/common/index.ts index afd8f6105d8f6..395aa3ed60861 100755 --- a/src/plugins/chart_expressions/expression_gauge/common/index.ts +++ b/src/plugins/chart_expressions/expression_gauge/common/index.ts @@ -10,6 +10,7 @@ export const PLUGIN_ID = 'expressionGauge'; export const PLUGIN_NAME = 'expressionGauge'; export type { + GaugeExpressionFunctionDefinition, GaugeExpressionProps, FormatFactory, GaugeRenderProps, diff --git a/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx b/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx index 99342edbdbc64..22601ae409f62 100644 --- a/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx +++ b/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx @@ -10,6 +10,7 @@ import { Chart, Goal, Settings } from '@elastic/charts'; import { FormattedMessage } from '@kbn/i18n-react'; import type { CustomPaletteState } from '../../../../charts/public'; import { EmptyPlaceholder } from '../../../../charts/public'; +import { isVisDimension } from '../../../../visualizations/common/utils'; import { GaugeRenderProps, GaugeLabelMajorMode, @@ -234,17 +235,22 @@ export const GaugeComponent: FC = memo( /> ); } + const customMetricFormatParams = isVisDimension(args.metric) ? args.metric.format : undefined; + const tableMetricFormatParams = metricColumn?.meta?.params?.params + ? metricColumn?.meta?.params + : undefined; + + const defaultMetricFormatParams = { + id: 'number', + params: { + pattern: max - min > 5 ? `0,0` : `0,0.0`, + }, + }; const tickFormatter = formatFactory( - metricColumn?.meta?.params?.params - ? metricColumn?.meta?.params - : { - id: 'number', - params: { - pattern: max - min > 5 ? `0,0` : `0,0.0`, - }, - } + customMetricFormatParams ?? tableMetricFormatParams ?? defaultMetricFormatParams ); + const colors = palette?.params?.colors ? normalizeColors(palette.params, min, max) : undefined; const bands: number[] = (palette?.params as CustomPaletteState) ? normalizeBands(args.palette?.params as CustomPaletteState, { min, max }) diff --git a/src/plugins/vis_types/gauge/common/index.ts b/src/plugins/vis_types/gauge/common/index.ts new file mode 100755 index 0000000000000..e27c302c53c16 --- /dev/null +++ b/src/plugins/vis_types/gauge/common/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export const LEGACY_GAUGE_CHARTS_LIBRARY = 'visualization:visualize:legacyGaugeChartsLibrary'; diff --git a/src/plugins/vis_types/vislib/public/vis_type_vislib_vis_types.ts b/src/plugins/vis_types/gauge/config.ts similarity index 51% rename from src/plugins/vis_types/vislib/public/vis_type_vislib_vis_types.ts rename to src/plugins/vis_types/gauge/config.ts index 220c69afb21d2..b831d26854c30 100644 --- a/src/plugins/vis_types/vislib/public/vis_type_vislib_vis_types.ts +++ b/src/plugins/vis_types/gauge/config.ts @@ -6,13 +6,10 @@ * Side Public License, v 1. */ -import { VisTypeDefinition } from 'src/plugins/visualizations/public'; -import { gaugeVisTypeDefinition } from './gauge'; -import { goalVisTypeDefinition } from './goal'; +import { schema, TypeOf } from '@kbn/config-schema'; -export { pieVisTypeDefinition } from './pie'; +export const configSchema = schema.object({ + enabled: schema.boolean({ defaultValue: true }), +}); -export const visLibVisTypeDefinitions: Array> = [ - gaugeVisTypeDefinition, - goalVisTypeDefinition, -]; +export type ConfigSchema = TypeOf; diff --git a/src/plugins/vis_types/gauge/jest.config.js b/src/plugins/vis_types/gauge/jest.config.js new file mode 100644 index 0000000000000..87fd58fd42dbc --- /dev/null +++ b/src/plugins/vis_types/gauge/jest.config.js @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + roots: ['/src/plugins/vis_types/gauge'], + coverageDirectory: '/target/kibana-coverage/jest/src/plugins/vis_types/gauge', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/src/plugins/vis_types/gauge/{common,public,server}/**/*.{ts,tsx}', + ], +}; diff --git a/src/plugins/vis_types/gauge/kibana.json b/src/plugins/vis_types/gauge/kibana.json new file mode 100755 index 0000000000000..5eb2794452de9 --- /dev/null +++ b/src/plugins/vis_types/gauge/kibana.json @@ -0,0 +1,16 @@ +{ + "id": "visTypeGauge", + "version": "1.0.0", + "kibanaVersion": "kibana", + "server": true, + "ui": true, + "requiredPlugins": ["charts", "data", "expressions", "visualizations"], + "requiredBundles": ["visDefaultEditor"], + "optionalPlugins": ["expressionGauge"], + "extraPublicDirs": ["common/index"], + "owner": { + "name": "Vis Editors", + "githubTeam": "kibana-vis-editors" + }, + "description": "Contains the gauge chart implementation using the elastic-charts library. The goal is to eventually deprecate the old implementation and keep only this. Until then, the library used is defined by the Legacy charts library advanced setting." +} diff --git a/src/plugins/vis_types/gauge/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_types/gauge/public/__snapshots__/to_ast.test.ts.snap new file mode 100644 index 0000000000000..dbc909f9ede22 --- /dev/null +++ b/src/plugins/vis_types/gauge/public/__snapshots__/to_ast.test.ts.snap @@ -0,0 +1,63 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`gauge vis toExpressionAst function with minimal params 1`] = ` +Object { + "chain": Array [ + Object { + "arguments": Object { + "aggs": Array [], + "index": Array [ + Object { + "chain": Array [ + Object { + "arguments": Object { + "id": Array [ + "123", + ], + }, + "function": "indexPatternLoad", + "type": "function", + }, + ], + "type": "expression", + }, + ], + "metricsAtAllLevels": Array [ + false, + ], + "partialRows": Array [ + false, + ], + }, + "function": "esaggs", + "type": "function", + }, + Object { + "arguments": Object { + "centralMajorMode": Array [ + "custom", + ], + "colorMode": Array [ + "palette", + ], + "labelMajorMode": Array [ + "auto", + ], + "labelMinor": Array [ + "some custom sublabel", + ], + "metric": Array [], + "shape": Array [ + "circle", + ], + "ticksPosition": Array [ + "hidden", + ], + }, + "function": "gauge", + "type": "function", + }, + ], + "type": "expression", +} +`; diff --git a/src/plugins/vis_types/vislib/public/editor/collections.ts b/src/plugins/vis_types/gauge/public/editor/collections.ts similarity index 67% rename from src/plugins/vis_types/vislib/public/editor/collections.ts rename to src/plugins/vis_types/gauge/public/editor/collections.ts index e7905ccaf1c29..3f52ffbead01c 100644 --- a/src/plugins/vis_types/vislib/public/editor/collections.ts +++ b/src/plugins/vis_types/gauge/public/editor/collections.ts @@ -7,21 +7,18 @@ */ import { i18n } from '@kbn/i18n'; - import { colorSchemas } from '../../../../charts/public'; -import { getPositions, getScaleTypes } from '../../../xy/public'; - import { Alignment, GaugeType } from '../types'; export const getGaugeTypes = () => [ { - text: i18n.translate('visTypeVislib.gauge.gaugeTypes.arcText', { + text: i18n.translate('visTypeGauge.gauge.gaugeTypes.arcText', { defaultMessage: 'Arc', }), value: GaugeType.Arc, }, { - text: i18n.translate('visTypeVislib.gauge.gaugeTypes.circleText', { + text: i18n.translate('visTypeGauge.gauge.gaugeTypes.circleText', { defaultMessage: 'Circle', }), value: GaugeType.Circle, @@ -30,19 +27,19 @@ export const getGaugeTypes = () => [ export const getAlignments = () => [ { - text: i18n.translate('visTypeVislib.gauge.alignmentAutomaticTitle', { + text: i18n.translate('visTypeGauge.gauge.alignmentAutomaticTitle', { defaultMessage: 'Automatic', }), value: Alignment.Automatic, }, { - text: i18n.translate('visTypeVislib.gauge.alignmentHorizontalTitle', { + text: i18n.translate('visTypeGauge.gauge.alignmentHorizontalTitle', { defaultMessage: 'Horizontal', }), value: Alignment.Horizontal, }, { - text: i18n.translate('visTypeVislib.gauge.alignmentVerticalTitle', { + text: i18n.translate('visTypeGauge.gauge.alignmentVerticalTitle', { defaultMessage: 'Vertical', }), value: Alignment.Vertical, @@ -54,9 +51,3 @@ export const getGaugeCollections = () => ({ alignments: getAlignments(), colorSchemas, }); - -export const getHeatmapCollections = () => ({ - legendPositions: getPositions(), - scales: getScaleTypes(), - colorSchemas, -}); diff --git a/src/plugins/vis_types/vislib/public/editor/components/gauge/index.tsx b/src/plugins/vis_types/gauge/public/editor/components/gauge/index.tsx similarity index 84% rename from src/plugins/vis_types/vislib/public/editor/components/gauge/index.tsx rename to src/plugins/vis_types/gauge/public/editor/components/gauge/index.tsx index 5a741ffbadd83..8fbe8b1567ae3 100644 --- a/src/plugins/vis_types/vislib/public/editor/components/gauge/index.tsx +++ b/src/plugins/vis_types/gauge/public/editor/components/gauge/index.tsx @@ -10,19 +10,21 @@ import React, { useCallback } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { VisEditorOptionsProps } from 'src/plugins/visualizations/public'; -import { GaugeVisParams } from '../../../gauge'; +import { GaugeTypeProps, GaugeVisParams } from '../../../types'; import { RangesPanel } from './ranges_panel'; import { StylePanel } from './style_panel'; import { LabelsPanel } from './labels_panel'; -export type GaugeOptionsInternalProps = VisEditorOptionsProps & { +export interface GaugeOptionsProps extends VisEditorOptionsProps, GaugeTypeProps {} + +export type GaugeOptionsInternalProps = GaugeOptionsProps & { setGaugeValue: ( paramName: T, value: GaugeVisParams['gauge'][T] ) => void; }; -function GaugeOptions(props: VisEditorOptionsProps) { +function GaugeOptions(props: GaugeOptionsProps) { const { stateParams, setValue } = props; const setGaugeValue: GaugeOptionsInternalProps['setGaugeValue'] = useCallback( @@ -37,13 +39,9 @@ function GaugeOptions(props: VisEditorOptionsProps) { return ( <> - - - - ); diff --git a/src/plugins/vis_types/vislib/public/editor/components/gauge/labels_panel.tsx b/src/plugins/vis_types/gauge/public/editor/components/gauge/labels_panel.tsx similarity index 87% rename from src/plugins/vis_types/vislib/public/editor/components/gauge/labels_panel.tsx rename to src/plugins/vis_types/gauge/public/editor/components/gauge/labels_panel.tsx index fb5c1594e601a..087a43c5dd005 100644 --- a/src/plugins/vis_types/vislib/public/editor/components/gauge/labels_panel.tsx +++ b/src/plugins/vis_types/gauge/public/editor/components/gauge/labels_panel.tsx @@ -19,7 +19,7 @@ function LabelsPanel({ stateParams, setValue, setGaugeValue }: GaugeOptionsInter

@@ -27,7 +27,7 @@ function LabelsPanel({ stateParams, setValue, setGaugeValue }: GaugeOptionsInter

@@ -66,13 +67,20 @@ function RangesPanel({ /> + ); + return (

@@ -35,7 +53,7 @@ function StylePanel({ aggs, setGaugeValue, stateParams }: GaugeOptionsInternalPr - - + {showElasticChartsOptions ? ( + <> + + + {alignmentSelect} + + + + ) : ( + alignmentSelect + )}
); } diff --git a/src/plugins/vis_types/vislib/public/editor/components/index.tsx b/src/plugins/vis_types/gauge/public/editor/components/index.tsx similarity index 64% rename from src/plugins/vis_types/vislib/public/editor/components/index.tsx rename to src/plugins/vis_types/gauge/public/editor/components/index.tsx index ab7e34b576e87..7cb1ca9a26c69 100644 --- a/src/plugins/vis_types/vislib/public/editor/components/index.tsx +++ b/src/plugins/vis_types/gauge/public/editor/components/index.tsx @@ -9,10 +9,11 @@ import React, { lazy } from 'react'; import { VisEditorOptionsProps } from 'src/plugins/visualizations/public'; -import { GaugeVisParams } from '../../gauge'; +import { GaugeTypeProps, GaugeVisParams } from '../../types'; const GaugeOptionsLazy = lazy(() => import('./gauge')); -export const GaugeOptions = (props: VisEditorOptionsProps) => ( - -); +export const getGaugeOptions = + ({ showElasticChartsOptions }: GaugeTypeProps) => + (props: VisEditorOptionsProps) => + ; diff --git a/src/plugins/vis_types/vislib/public/editor/index.ts b/src/plugins/vis_types/gauge/public/editor/index.ts similarity index 100% rename from src/plugins/vis_types/vislib/public/editor/index.ts rename to src/plugins/vis_types/gauge/public/editor/index.ts diff --git a/src/plugins/vis_types/gauge/public/index.ts b/src/plugins/vis_types/gauge/public/index.ts new file mode 100755 index 0000000000000..78aa55f59486f --- /dev/null +++ b/src/plugins/vis_types/gauge/public/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { VisTypeGaugePlugin } from './plugin'; + +export function plugin() { + return new VisTypeGaugePlugin(); +} + +export type { VisTypeGaugePluginSetup, VisTypeGaugePluginStart } from './types'; + +export { gaugeVisType, goalVisType } from './vis_type'; diff --git a/src/plugins/vis_types/gauge/public/plugin.ts b/src/plugins/vis_types/gauge/public/plugin.ts new file mode 100755 index 0000000000000..8c11892192766 --- /dev/null +++ b/src/plugins/vis_types/gauge/public/plugin.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { VisualizationsSetup } from '../../../../plugins/visualizations/public'; +import { DataPublicPluginStart } from '../../../../plugins/data/public'; +import { CoreSetup } from '../../../../core/public'; +import { LEGACY_GAUGE_CHARTS_LIBRARY } from '../common'; +import { VisTypeGaugePluginSetup } from './types'; +import { gaugeVisType, goalVisType } from './vis_type'; + +/** @internal */ +export interface VisTypeGaugeSetupDependencies { + visualizations: VisualizationsSetup; +} + +/** @internal */ +export interface VisTypePiePluginStartDependencies { + data: DataPublicPluginStart; +} + +export class VisTypeGaugePlugin { + public setup( + core: CoreSetup, + { visualizations }: VisTypeGaugeSetupDependencies + ): VisTypeGaugePluginSetup { + if (!core.uiSettings.get(LEGACY_GAUGE_CHARTS_LIBRARY)) { + const visTypeProps = { showElasticChartsOptions: true }; + visualizations.createBaseVisualization(gaugeVisType(visTypeProps)); + visualizations.createBaseVisualization(goalVisType(visTypeProps)); + } + + return {}; + } + + public start() {} +} diff --git a/src/plugins/vis_types/gauge/public/to_ast.test.ts b/src/plugins/vis_types/gauge/public/to_ast.test.ts new file mode 100644 index 0000000000000..4f76e8e5f727e --- /dev/null +++ b/src/plugins/vis_types/gauge/public/to_ast.test.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { TimefilterContract } from 'src/plugins/data/public'; +import { Vis } from 'src/plugins/visualizations/public'; +import { toExpressionAst } from './to_ast'; +import { GaugeVisParams } from './types'; + +describe('gauge vis toExpressionAst function', () => { + let vis: Vis; + + beforeEach(() => { + vis = { + isHierarchical: () => false, + type: {}, + params: { + gauge: { + gaugeType: 'Circle', + scale: { + show: false, + labels: false, + color: 'rgba(105,112,125,0.2)', + }, + labels: { + show: true, + }, + style: { + subText: 'some custom sublabel', + }, + }, + }, + data: { + indexPattern: { id: '123' } as any, + aggs: { + getResponseAggs: () => [], + aggs: [], + } as any, + }, + } as unknown as Vis; + }); + + it('with minimal params', () => { + const actual = toExpressionAst(vis, { + timefilter: {} as TimefilterContract, + }); + expect(actual).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/vis_types/gauge/public/to_ast.ts b/src/plugins/vis_types/gauge/public/to_ast.ts new file mode 100644 index 0000000000000..041ae765b7696 --- /dev/null +++ b/src/plugins/vis_types/gauge/public/to_ast.ts @@ -0,0 +1,93 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { getVisSchemas, SchemaConfig, VisToExpressionAst } from '../../../visualizations/public'; +import { buildExpression, buildExpressionFunction } from '../../../expressions/public'; +import type { + GaugeExpressionFunctionDefinition, + GaugeShape, +} from '../../../chart_expressions/expression_gauge/common'; +import { GaugeType, GaugeVisParams } from './types'; +import { getStopsWithColorsFromRanges } from './utils'; +import { getEsaggsFn } from './to_ast_esaggs'; + +const prepareDimension = (params: SchemaConfig) => { + const visdimension = buildExpressionFunction('visdimension', { accessor: params.accessor }); + + if (params.format) { + visdimension.addArgument('format', params.format.id); + visdimension.addArgument('formatParams', JSON.stringify(params.format.params)); + } + + return buildExpression([visdimension]); +}; + +const gaugeTypeToShape = (type: GaugeType): GaugeShape => { + const arc: GaugeShape = 'arc'; + const circle: GaugeShape = 'circle'; + + return { + [GaugeType.Arc]: arc, + [GaugeType.Circle]: circle, + }[type]; +}; + +export const toExpressionAst: VisToExpressionAst = (vis, params) => { + const schemas = getVisSchemas(vis, params); + + const { + gaugeType, + percentageMode, + percentageFormatPattern, + colorSchema, + colorsRange, + invertColors, + scale, + style, + labels, + } = vis.params.gauge; + + // fix formatter for percentage mode + if (percentageMode === true) { + schemas.metric.forEach((metric: SchemaConfig) => { + metric.format = { + id: 'percent', + params: { pattern: percentageFormatPattern }, + }; + }); + } + + const centralMajorMode = labels.show ? (style.subText ? 'custom' : 'auto') : 'none'; + const gauge = buildExpressionFunction('gauge', { + shape: gaugeTypeToShape(gaugeType), + metric: schemas.metric.map(prepareDimension), + ticksPosition: scale.show ? 'auto' : 'hidden', + labelMajorMode: 'auto', + colorMode: 'palette', + centralMajorMode, + ...(centralMajorMode === 'custom' ? { labelMinor: style.subText } : {}), + }); + + if (colorsRange && colorsRange.length) { + const stopsWithColors = getStopsWithColorsFromRanges(colorsRange, colorSchema, invertColors); + const palette = buildExpressionFunction('palette', { + ...stopsWithColors, + range: percentageMode ? 'percent' : 'number', + continuity: 'none', + gradient: true, + rangeMax: percentageMode ? 100 : Infinity, + rangeMin: 0, + }); + + gauge.addArgument('palette', buildExpression([palette])); + } + + const ast = buildExpression([getEsaggsFn(vis), gauge]); + + return ast.toAst(); +}; diff --git a/src/plugins/vis_types/gauge/public/to_ast_esaggs.ts b/src/plugins/vis_types/gauge/public/to_ast_esaggs.ts new file mode 100644 index 0000000000000..ecf3f3e637177 --- /dev/null +++ b/src/plugins/vis_types/gauge/public/to_ast_esaggs.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Vis } from '../../../visualizations/public'; +import { buildExpression, buildExpressionFunction } from '../../../expressions/public'; +import { + EsaggsExpressionFunctionDefinition, + IndexPatternLoadExpressionFunctionDefinition, +} from '../../../data/public'; + +import { GaugeVisParams } from './types'; + +/** + * Get esaggs expressions function + * @param vis + */ +export function getEsaggsFn(vis: Vis) { + return buildExpressionFunction('esaggs', { + index: buildExpression([ + buildExpressionFunction('indexPatternLoad', { + id: vis.data.indexPattern!.id!, + }), + ]), + metricsAtAllLevels: vis.isHierarchical(), + partialRows: false, + aggs: vis.data.aggs!.aggs.map((agg) => buildExpression(agg.toExpressionAst())), + }); +} diff --git a/src/plugins/vis_types/gauge/public/types.ts b/src/plugins/vis_types/gauge/public/types.ts new file mode 100755 index 0000000000000..c160b2ccf2f3f --- /dev/null +++ b/src/plugins/vis_types/gauge/public/types.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { $Values } from '@kbn/utility-types'; +import { Range } from '../../../expressions/public'; +import { ColorSchemaParams, Labels, Style } from '../../../charts/public'; + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface VisTypeGaugePluginSetup {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface VisTypeGaugePluginStart {} + +/** + * Gauge title alignment + */ +export const Alignment = { + Automatic: 'automatic', + Horizontal: 'horizontal', + Vertical: 'vertical', +} as const; + +export type Alignment = $Values; + +export const GaugeType = { + Arc: 'Arc', + Circle: 'Circle', +} as const; + +export type GaugeType = $Values; + +export interface Gauge extends ColorSchemaParams { + backStyle: 'Full'; + gaugeStyle: 'Full'; + orientation: 'vertical'; + type: 'meter'; + alignment: Alignment; + colorsRange: Range[]; + extendRange: boolean; + gaugeType: GaugeType; + labels: Labels; + percentageMode: boolean; + percentageFormatPattern?: string; + outline?: boolean; + scale: { + show: boolean; + labels: false; + color: 'rgba(105,112,125,0.2)'; + }; + style: Style; +} + +export interface GaugeVisParams { + type: 'gauge'; + addTooltip: boolean; + addLegend: boolean; + isDisplayWarning: boolean; + gauge: Gauge; +} + +export interface GaugeTypeProps { + showElasticChartsOptions?: boolean; +} diff --git a/src/plugins/vis_types/gauge/public/utils/index.ts b/src/plugins/vis_types/gauge/public/utils/index.ts new file mode 100644 index 0000000000000..fb23c97d835fe --- /dev/null +++ b/src/plugins/vis_types/gauge/public/utils/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { getStopsWithColorsFromRanges } from './palette'; diff --git a/src/plugins/vis_types/gauge/public/utils/palette.ts b/src/plugins/vis_types/gauge/public/utils/palette.ts new file mode 100644 index 0000000000000..a236a0daa6d53 --- /dev/null +++ b/src/plugins/vis_types/gauge/public/utils/palette.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ColorSchemas, getHeatmapColors } from '../../../../charts/common'; +import { Range } from '../../../../expressions'; + +export interface PaletteConfig { + color: Array; + stop: number[]; +} + +const TRANSPARENT = 'rgb(0, 0, 0, 0)'; + +const getColor = ( + index: number, + elementsCount: number, + colorSchema: ColorSchemas, + invertColors: boolean = false +) => { + const divider = Math.max(elementsCount - 1, 1); + const value = invertColors ? 1 - index / divider : index / divider; + return getHeatmapColors(value, colorSchema); +}; + +export const getStopsWithColorsFromRanges = ( + ranges: Range[], + colorSchema: ColorSchemas, + invertColors: boolean = false +) => { + return ranges.reduce( + (acc, range, index, rangesArr) => { + if (index && range.from !== rangesArr[index - 1].to) { + acc.color.push(TRANSPARENT); + acc.stop.push(range.from); + } + + acc.color.push(getColor(index, rangesArr.length, colorSchema, invertColors)); + acc.stop.push(range.to); + + return acc; + }, + { color: [], stop: [] } + ); +}; diff --git a/src/plugins/vis_types/gauge/public/vis_type/gauge.tsx b/src/plugins/vis_types/gauge/public/vis_type/gauge.tsx new file mode 100644 index 0000000000000..648d34cdee7bd --- /dev/null +++ b/src/plugins/vis_types/gauge/public/vis_type/gauge.tsx @@ -0,0 +1,130 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; + +import { ColorMode, ColorSchemas } from '../../../../charts/public'; +import { AggGroupNames } from '../../../../data/public'; +import { VisTypeDefinition, VIS_EVENT_TO_TRIGGER } from '../../../../visualizations/public'; + +import { Alignment, GaugeType, GaugeTypeProps } from '../types'; +import { toExpressionAst } from '../to_ast'; +import { getGaugeOptions } from '../editor/components'; +import { GaugeVisParams } from '../types'; +import { SplitTooltip } from './split_tooltip'; + +export const getGaugeVisTypeDefinition = ( + props: GaugeTypeProps +): VisTypeDefinition => ({ + name: 'gauge', + title: i18n.translate('visTypeGauge.gauge.gaugeTitle', { defaultMessage: 'Gauge' }), + icon: 'visGauge', + description: i18n.translate('visTypeGauge.gauge.gaugeDescription', { + defaultMessage: 'Show the status of a metric.', + }), + getSupportedTriggers: () => [VIS_EVENT_TO_TRIGGER.filter], + toExpressionAst, + visConfig: { + defaults: { + type: 'gauge', + addTooltip: true, + addLegend: true, + isDisplayWarning: false, + gauge: { + alignment: Alignment.Automatic, + extendRange: true, + percentageMode: false, + gaugeType: GaugeType.Arc, + gaugeStyle: 'Full', + backStyle: 'Full', + orientation: 'vertical', + colorSchema: ColorSchemas.GreenToRed, + gaugeColorMode: ColorMode.Labels, + colorsRange: [ + { from: 0, to: 50 }, + { from: 50, to: 75 }, + { from: 75, to: 100 }, + ], + invertColors: false, + labels: { + show: true, + color: 'black', + }, + scale: { + show: true, + labels: false, + color: 'rgba(105,112,125,0.2)', + }, + type: 'meter', + style: { + bgWidth: 0.9, + width: 0.9, + mask: false, + bgMask: false, + maskBars: 50, + bgFill: 'rgba(105,112,125,0.2)', + bgColor: true, + subText: '', + fontSize: 60, + }, + }, + }, + }, + editorConfig: { + optionsTemplate: getGaugeOptions(props), + schemas: [ + { + group: AggGroupNames.Metrics, + name: 'metric', + title: i18n.translate('visTypeGauge.gauge.metricTitle', { defaultMessage: 'Metric' }), + min: 1, + ...(props.showElasticChartsOptions ? { max: 1 } : {}), + aggFilter: [ + '!std_dev', + '!geo_centroid', + '!percentiles', + '!percentile_ranks', + '!derivative', + '!serial_diff', + '!moving_avg', + '!cumulative_sum', + '!geo_bounds', + '!filtered_metric', + '!single_percentile', + ], + defaults: [{ schema: 'metric', type: 'count' }], + }, + { + group: AggGroupNames.Buckets, + name: 'group', + // TODO: Remove when split chart aggs are supported + ...(props.showElasticChartsOptions && { + disabled: true, + tooltip: , + }), + title: i18n.translate('visTypeGauge.gauge.groupTitle', { + defaultMessage: 'Split group', + }), + min: 0, + max: 1, + aggFilter: [ + '!geohash_grid', + '!geotile_grid', + '!filter', + '!sampler', + '!diversified_sampler', + '!rare_terms', + '!multi_terms', + '!significant_text', + ], + }, + ], + }, + requiresSearch: true, +}); diff --git a/src/plugins/vis_types/gauge/public/vis_type/goal.tsx b/src/plugins/vis_types/gauge/public/vis_type/goal.tsx new file mode 100644 index 0000000000000..e56e87ee70dff --- /dev/null +++ b/src/plugins/vis_types/gauge/public/vis_type/goal.tsx @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; + +import { AggGroupNames } from '../../../../data/public'; +import { ColorMode, ColorSchemas } from '../../../../charts/public'; +import { VisTypeDefinition } from '../../../../visualizations/public'; + +import { getGaugeOptions } from '../editor/components'; +import { toExpressionAst } from '../to_ast'; +import { GaugeVisParams, GaugeType, GaugeTypeProps } from '../types'; +import { SplitTooltip } from './split_tooltip'; + +export const getGoalVisTypeDefinition = ( + props: GaugeTypeProps +): VisTypeDefinition => ({ + name: 'goal', + title: i18n.translate('visTypeGauge.goal.goalTitle', { defaultMessage: 'Goal' }), + icon: 'visGoal', + description: i18n.translate('visTypeGauge.goal.goalDescription', { + defaultMessage: 'Track how a metric progresses to a goal.', + }), + toExpressionAst, + visConfig: { + defaults: { + addTooltip: true, + addLegend: false, + isDisplayWarning: false, + type: 'gauge', + gauge: { + verticalSplit: false, + autoExtend: false, + percentageMode: true, + gaugeType: GaugeType.Arc, + gaugeStyle: 'Full', + backStyle: 'Full', + orientation: 'vertical', + useRanges: false, + colorSchema: ColorSchemas.GreenToRed, + gaugeColorMode: ColorMode.None, + colorsRange: [{ from: 0, to: 10000 }], + invertColors: false, + labels: { + show: true, + color: 'black', + }, + scale: { + show: false, + labels: false, + color: 'rgba(105,112,125,0.2)', + width: 2, + }, + type: 'meter', + style: { + bgFill: 'rgba(105,112,125,0.2)', + bgColor: false, + labelColor: false, + subText: '', + fontSize: 60, + }, + }, + }, + }, + editorConfig: { + optionsTemplate: getGaugeOptions(props), + schemas: [ + { + group: AggGroupNames.Metrics, + name: 'metric', + title: i18n.translate('visTypeGauge.goal.metricTitle', { defaultMessage: 'Metric' }), + min: 1, + ...(props.showElasticChartsOptions ? { max: 1 } : {}), + aggFilter: [ + '!std_dev', + '!geo_centroid', + '!percentiles', + '!percentile_ranks', + '!derivative', + '!serial_diff', + '!moving_avg', + '!cumulative_sum', + '!geo_bounds', + '!filtered_metric', + '!single_percentile', + ], + defaults: [{ schema: 'metric', type: 'count' }], + }, + { + group: AggGroupNames.Buckets, + name: 'group', + // TODO: Remove when split chart aggs are supported + ...(props.showElasticChartsOptions && { + disabled: true, + tooltip: , + }), + title: i18n.translate('visTypeGauge.goal.groupTitle', { + defaultMessage: 'Split group', + }), + min: 0, + max: 1, + aggFilter: [ + '!geohash_grid', + '!geotile_grid', + '!filter', + '!sampler', + '!diversified_sampler', + '!rare_terms', + '!multi_terms', + '!significant_text', + ], + }, + ], + }, + requiresSearch: true, +}); diff --git a/src/plugins/vis_types/gauge/public/vis_type/index.ts b/src/plugins/vis_types/gauge/public/vis_type/index.ts new file mode 100644 index 0000000000000..cc78afedc02bd --- /dev/null +++ b/src/plugins/vis_types/gauge/public/vis_type/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { GaugeTypeProps } from '../types'; +import { getGaugeVisTypeDefinition } from './gauge'; +import { getGoalVisTypeDefinition } from './goal'; + +export const gaugeVisType = (props: GaugeTypeProps) => { + return getGaugeVisTypeDefinition(props); +}; + +export const goalVisType = (props: GaugeTypeProps) => { + return getGoalVisTypeDefinition(props); +}; diff --git a/src/plugins/vis_types/gauge/public/vis_type/split_tooltip.tsx b/src/plugins/vis_types/gauge/public/vis_type/split_tooltip.tsx new file mode 100644 index 0000000000000..8c92b6d65ff77 --- /dev/null +++ b/src/plugins/vis_types/gauge/public/vis_type/split_tooltip.tsx @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import React from 'react'; + +import { FormattedMessage } from '@kbn/i18n-react'; + +export function SplitTooltip() { + return ( + + ); +} diff --git a/src/plugins/vis_types/gauge/server/index.ts b/src/plugins/vis_types/gauge/server/index.ts new file mode 100755 index 0000000000000..8d958e63356e2 --- /dev/null +++ b/src/plugins/vis_types/gauge/server/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { PluginConfigDescriptor } from 'src/core/server'; +import { configSchema, ConfigSchema } from '../config'; +import { VisTypeGaugeServerPlugin } from './plugin'; + +export const config: PluginConfigDescriptor = { + schema: configSchema, +}; + +export const plugin = () => new VisTypeGaugeServerPlugin(); diff --git a/src/plugins/vis_types/gauge/server/plugin.ts b/src/plugins/vis_types/gauge/server/plugin.ts new file mode 100755 index 0000000000000..0334f963c720c --- /dev/null +++ b/src/plugins/vis_types/gauge/server/plugin.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { i18n } from '@kbn/i18n'; +import { schema } from '@kbn/config-schema'; + +import { CoreSetup, Plugin, UiSettingsParams } from 'kibana/server'; + +import { LEGACY_GAUGE_CHARTS_LIBRARY } from '../common'; + +export const getUiSettingsConfig: () => Record> = () => ({ + [LEGACY_GAUGE_CHARTS_LIBRARY]: { + name: i18n.translate( + 'visTypeGauge.advancedSettings.visualization.legacyGaugeChartsLibrary.name', + { + defaultMessage: 'Gauge legacy charts library', + } + ), + requiresPageReload: true, + value: true, + description: i18n.translate( + 'visTypeGauge.advancedSettings.visualization.legacyGaugeChartsLibrary.description', + { + defaultMessage: 'Enables legacy charts library for gauge charts in visualize.', + } + ), + category: ['visualization'], + schema: schema.boolean(), + }, +}); + +export class VisTypeGaugeServerPlugin implements Plugin { + public setup(core: CoreSetup) { + core.uiSettings.register(getUiSettingsConfig()); + + return {}; + } + + public start() { + return {}; + } +} diff --git a/src/plugins/vis_types/gauge/tsconfig.json b/src/plugins/vis_types/gauge/tsconfig.json new file mode 100644 index 0000000000000..b1717173757e7 --- /dev/null +++ b/src/plugins/vis_types/gauge/tsconfig.json @@ -0,0 +1,27 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "common/**/*", + "public/**/*", + "server/**/*", + "*.ts" + ], + "references": [ + { "path": "../../../core/tsconfig.json" }, + { "path": "../../charts/tsconfig.json" }, + { "path": "../../data/tsconfig.json" }, + { "path": "../../expressions/tsconfig.json" }, + { "path": "../../chart_expressions/expression_gauge/tsconfig.json" }, + { "path": "../../visualizations/tsconfig.json" }, + { "path": "../../usage_collection/tsconfig.json" }, + { "path": "../../vis_default_editor/tsconfig.json" }, + { "path": "../../field_formats/tsconfig.json" }, + { "path": "../../chart_expressions/expression_partition_vis/tsconfig.json" } + ] + } \ No newline at end of file diff --git a/src/plugins/vis_types/vislib/kibana.json b/src/plugins/vis_types/vislib/kibana.json index feb252f1bb0f5..7c55aba21e7e4 100644 --- a/src/plugins/vis_types/vislib/kibana.json +++ b/src/plugins/vis_types/vislib/kibana.json @@ -4,7 +4,7 @@ "server": true, "ui": true, "requiredPlugins": ["charts", "data", "expressions", "visualizations"], - "requiredBundles": ["kibanaUtils", "visDefaultEditor", "visTypeXy", "visTypePie", "visTypeHeatmap", "fieldFormats", "kibanaReact"], + "requiredBundles": ["kibanaUtils", "visTypeXy", "visTypePie", "visTypeHeatmap", "visTypeGauge", "fieldFormats", "kibanaReact"], "owner": { "name": "Vis Editors", "githubTeam": "kibana-vis-editors" diff --git a/src/plugins/vis_types/vislib/public/gauge.ts b/src/plugins/vis_types/vislib/public/gauge.ts index 128c0758bfd03..5edc33edb84fa 100644 --- a/src/plugins/vis_types/vislib/public/gauge.ts +++ b/src/plugins/vis_types/vislib/public/gauge.ts @@ -6,16 +6,13 @@ * Side Public License, v 1. */ -import { i18n } from '@kbn/i18n'; - -import { ColorMode, ColorSchemas, ColorSchemaParams, Labels, Style } from '../../../charts/public'; +import { ColorSchemaParams, Labels, Style } from '../../../charts/public'; import { RangeValues } from '../../../vis_default_editor/public'; -import { AggGroupNames } from '../../../data/public'; -import { VisTypeDefinition, VIS_EVENT_TO_TRIGGER } from '../../../visualizations/public'; +import { gaugeVisType } from '../../gauge/public'; +import { VisTypeDefinition } from '../../../visualizations/public'; -import { Alignment, GaugeType, VislibChartType } from './types'; +import { Alignment, GaugeType } from './types'; import { toExpressionAst } from './to_ast'; -import { GaugeOptions } from './editor/components'; export interface Gauge extends ColorSchemaParams { backStyle: 'Full'; @@ -46,104 +43,7 @@ export interface GaugeVisParams { gauge: Gauge; } -export const gaugeVisTypeDefinition: VisTypeDefinition = { - name: 'gauge', - title: i18n.translate('visTypeVislib.gauge.gaugeTitle', { defaultMessage: 'Gauge' }), - icon: 'visGauge', - description: i18n.translate('visTypeVislib.gauge.gaugeDescription', { - defaultMessage: 'Show the status of a metric.', - }), - getSupportedTriggers: () => [VIS_EVENT_TO_TRIGGER.filter], +export const gaugeVisTypeDefinition = { + ...gaugeVisType({}), toExpressionAst, - visConfig: { - defaults: { - type: VislibChartType.Gauge, - addTooltip: true, - addLegend: true, - isDisplayWarning: false, - gauge: { - alignment: Alignment.Automatic, - extendRange: true, - percentageMode: false, - gaugeType: GaugeType.Arc, - gaugeStyle: 'Full', - backStyle: 'Full', - orientation: 'vertical', - colorSchema: ColorSchemas.GreenToRed, - gaugeColorMode: ColorMode.Labels, - colorsRange: [ - { from: 0, to: 50 }, - { from: 50, to: 75 }, - { from: 75, to: 100 }, - ], - invertColors: false, - labels: { - show: true, - color: 'black', - }, - scale: { - show: true, - labels: false, - color: 'rgba(105,112,125,0.2)', - }, - type: 'meter', - style: { - bgWidth: 0.9, - width: 0.9, - mask: false, - bgMask: false, - maskBars: 50, - bgFill: 'rgba(105,112,125,0.2)', - bgColor: true, - subText: '', - fontSize: 60, - }, - }, - }, - }, - editorConfig: { - optionsTemplate: GaugeOptions, - schemas: [ - { - group: AggGroupNames.Metrics, - name: 'metric', - title: i18n.translate('visTypeVislib.gauge.metricTitle', { defaultMessage: 'Metric' }), - min: 1, - aggFilter: [ - '!std_dev', - '!geo_centroid', - '!percentiles', - '!percentile_ranks', - '!derivative', - '!serial_diff', - '!moving_avg', - '!cumulative_sum', - '!geo_bounds', - '!filtered_metric', - '!single_percentile', - ], - defaults: [{ schema: 'metric', type: 'count' }], - }, - { - group: AggGroupNames.Buckets, - name: 'group', - title: i18n.translate('visTypeVislib.gauge.groupTitle', { - defaultMessage: 'Split group', - }), - min: 0, - max: 1, - aggFilter: [ - '!geohash_grid', - '!geotile_grid', - '!filter', - '!sampler', - '!diversified_sampler', - '!rare_terms', - '!multi_terms', - '!significant_text', - ], - }, - ], - }, - requiresSearch: true, -}; +} as VisTypeDefinition; diff --git a/src/plugins/vis_types/vislib/public/goal.ts b/src/plugins/vis_types/vislib/public/goal.ts index 9dd5fdbc92b5f..205b3a7a4280a 100644 --- a/src/plugins/vis_types/vislib/public/goal.ts +++ b/src/plugins/vis_types/vislib/public/goal.ts @@ -6,108 +6,13 @@ * Side Public License, v 1. */ -import { i18n } from '@kbn/i18n'; - -import { AggGroupNames } from '../../../data/public'; -import { ColorMode, ColorSchemas } from '../../../charts/public'; import { VisTypeDefinition } from '../../../visualizations/public'; +import { goalVisType } from '../../gauge/public'; -import { GaugeOptions } from './editor'; import { toExpressionAst } from './to_ast'; -import { GaugeType } from './types'; import { GaugeVisParams } from './gauge'; -export const goalVisTypeDefinition: VisTypeDefinition = { - name: 'goal', - title: i18n.translate('visTypeVislib.goal.goalTitle', { defaultMessage: 'Goal' }), - icon: 'visGoal', - description: i18n.translate('visTypeVislib.goal.goalDescription', { - defaultMessage: 'Track how a metric progresses to a goal.', - }), +export const goalVisTypeDefinition = { + ...goalVisType({}), toExpressionAst, - visConfig: { - defaults: { - addTooltip: true, - addLegend: false, - isDisplayWarning: false, - type: 'gauge', - gauge: { - verticalSplit: false, - autoExtend: false, - percentageMode: true, - gaugeType: GaugeType.Arc, - gaugeStyle: 'Full', - backStyle: 'Full', - orientation: 'vertical', - useRanges: false, - colorSchema: ColorSchemas.GreenToRed, - gaugeColorMode: ColorMode.None, - colorsRange: [{ from: 0, to: 10000 }], - invertColors: false, - labels: { - show: true, - color: 'black', - }, - scale: { - show: false, - labels: false, - color: 'rgba(105,112,125,0.2)', - width: 2, - }, - type: 'meter', - style: { - bgFill: 'rgba(105,112,125,0.2)', - bgColor: false, - labelColor: false, - subText: '', - fontSize: 60, - }, - }, - }, - }, - editorConfig: { - optionsTemplate: GaugeOptions, - schemas: [ - { - group: AggGroupNames.Metrics, - name: 'metric', - title: i18n.translate('visTypeVislib.goal.metricTitle', { defaultMessage: 'Metric' }), - min: 1, - aggFilter: [ - '!std_dev', - '!geo_centroid', - '!percentiles', - '!percentile_ranks', - '!derivative', - '!serial_diff', - '!moving_avg', - '!cumulative_sum', - '!geo_bounds', - '!filtered_metric', - '!single_percentile', - ], - defaults: [{ schema: 'metric', type: 'count' }], - }, - { - group: AggGroupNames.Buckets, - name: 'group', - title: i18n.translate('visTypeVislib.goal.groupTitle', { - defaultMessage: 'Split group', - }), - min: 0, - max: 1, - aggFilter: [ - '!geohash_grid', - '!geotile_grid', - '!filter', - '!sampler', - '!diversified_sampler', - '!rare_terms', - '!multi_terms', - '!significant_text', - ], - }, - ], - }, - requiresSearch: true, -}; +} as VisTypeDefinition; diff --git a/src/plugins/vis_types/vislib/public/plugin.ts b/src/plugins/vis_types/vislib/public/plugin.ts index 8c54df99bb988..23013bc582387 100644 --- a/src/plugins/vis_types/vislib/public/plugin.ts +++ b/src/plugins/vis_types/vislib/public/plugin.ts @@ -14,13 +14,16 @@ import { ChartsPluginSetup } from '../../../charts/public'; import { DataPublicPluginStart } from '../../../data/public'; import { LEGACY_PIE_CHARTS_LIBRARY } from '../../pie/common/index'; import { LEGACY_HEATMAP_CHARTS_LIBRARY } from '../../heatmap/common/index'; +import { LEGACY_GAUGE_CHARTS_LIBRARY } from '../../gauge/common/index'; import { heatmapVisTypeDefinition } from './heatmap'; import { createVisTypeVislibVisFn } from './vis_type_vislib_vis_fn'; import { createPieVisFn } from './pie_fn'; -import { visLibVisTypeDefinitions, pieVisTypeDefinition } from './vis_type_vislib_vis_types'; +import { pieVisTypeDefinition } from './pie'; import { setFormatService, setDataActions, setTheme } from './services'; import { getVislibVisRenderer } from './vis_renderer'; +import { gaugeVisTypeDefinition } from './gauge'; +import { goalVisTypeDefinition } from './goal'; /** @internal */ export interface VisTypeVislibPluginSetupDependencies { @@ -48,7 +51,7 @@ export class VisTypeVislibPlugin { expressions, visualizations, charts }: VisTypeVislibPluginSetupDependencies ) { // register vislib XY axis charts - visLibVisTypeDefinitions.forEach(visualizations.createBaseVisualization); + expressions.registerRenderer(getVislibVisRenderer(core, charts)); expressions.registerFunction(createVisTypeVislibVisFn()); @@ -57,10 +60,16 @@ export class VisTypeVislibPlugin visualizations.createBaseVisualization(pieVisTypeDefinition); expressions.registerFunction(createPieVisFn()); } + if (core.uiSettings.get(LEGACY_HEATMAP_CHARTS_LIBRARY)) { // register vislib heatmap chart visualizations.createBaseVisualization(heatmapVisTypeDefinition); - expressions.registerFunction(createVisTypeVislibVisFn()); + } + + if (core.uiSettings.get(LEGACY_GAUGE_CHARTS_LIBRARY)) { + // register vislib gauge and goal charts + visualizations.createBaseVisualization(gaugeVisTypeDefinition); + visualizations.createBaseVisualization(goalVisTypeDefinition); } } diff --git a/src/plugins/vis_types/vislib/tsconfig.json b/src/plugins/vis_types/vislib/tsconfig.json index 6c0b13e36a619..ef4d0a97fd2a4 100644 --- a/src/plugins/vis_types/vislib/tsconfig.json +++ b/src/plugins/vis_types/vislib/tsconfig.json @@ -18,7 +18,7 @@ { "path": "../../expressions/tsconfig.json" }, { "path": "../../visualizations/tsconfig.json" }, { "path": "../../kibana_utils/tsconfig.json" }, - { "path": "../../vis_default_editor/tsconfig.json" }, + { "path": "../../vis_types/gauge/tsconfig.json" }, { "path": "../../vis_types/xy/tsconfig.json" }, { "path": "../../vis_types/pie/tsconfig.json" }, { "path": "../../vis_types/heatmap/tsconfig.json" }, diff --git a/src/plugins/visualizations/common/utils/accessors.ts b/src/plugins/visualizations/common/utils/accessors.ts index 57a2d434dfd76..27940e1fb6890 100644 --- a/src/plugins/visualizations/common/utils/accessors.ts +++ b/src/plugins/visualizations/common/utils/accessors.ts @@ -37,7 +37,7 @@ export const getAccessorByDimension = ( dimension: string | ExpressionValueVisDimension, columns: DatatableColumn[] ) => { - if (typeof dimension === 'string') { + if (!isVisDimension(dimension)) { return dimension; } @@ -48,3 +48,13 @@ export const getAccessorByDimension = ( return accessor.id; }; + +export function isVisDimension( + accessor: string | ExpressionValueVisDimension | undefined +): accessor is ExpressionValueVisDimension { + if (typeof accessor === 'string' || accessor === undefined) { + return false; + } + + return true; +} diff --git a/src/plugins/visualizations/common/utils/index.ts b/src/plugins/visualizations/common/utils/index.ts index 59833b3e54e46..3e92e878bb5cf 100644 --- a/src/plugins/visualizations/common/utils/index.ts +++ b/src/plugins/visualizations/common/utils/index.ts @@ -8,4 +8,4 @@ export { prepareLogTable } from './prepare_log_table'; export type { Dimension } from './prepare_log_table'; -export { findAccessorOrFail, getAccessorByDimension } from './accessors'; +export { findAccessorOrFail, getAccessorByDimension, isVisDimension } from './accessors'; diff --git a/src/plugins/visualizations/public/visualize_app/components/split_chart_warning.tsx b/src/plugins/visualizations/public/visualize_app/components/split_chart_warning.tsx index 942c6269f15f8..679aa6aa2fbe1 100644 --- a/src/plugins/visualizations/public/visualize_app/components/split_chart_warning.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/split_chart_warning.tsx @@ -6,56 +6,117 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { FC } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiCallOut, EuiLink } from '@elastic/eui'; import { useKibana } from '../../../../kibana_react/public'; import { VisualizeServices } from '../types'; +import { CHARTS_WITHOUT_SMALL_MULTIPLES } from '../utils/split_chart_warning_helpers'; +import type { CHARTS_WITHOUT_SMALL_MULTIPLES as CHART_WITHOUT_SMALL_MULTIPLES } from '../utils/split_chart_warning_helpers'; -export const NEW_HEATMAP_CHARTS_LIBRARY = 'visualization:visualize:legacyHeatmapChartsLibrary'; +interface Props { + chartType: CHART_WITHOUT_SMALL_MULTIPLES; + chartConfigToken: string; +} -export const SplitChartWarning = () => { +interface WarningMessageProps { + canEditAdvancedSettings: boolean | Readonly<{ [x: string]: boolean }>; + advancedSettingsLink: string; +} + +const SwitchToOldLibraryMessage: FC = ({ + canEditAdvancedSettings, + advancedSettingsLink, +}) => { + return ( + <> + {canEditAdvancedSettings && ( + + + + ), + }} + /> + )} + + ); +}; + +const ContactAdminMessage: FC = ({ canEditAdvancedSettings }) => { + return ( + <> + {!canEditAdvancedSettings && ( + + )} + + ); +}; + +const GaugeWarningFormatMessage: FC = (props) => { + return ( + + + + + ), + }} + /> + ); +}; + +const HeatmapWarningFormatMessage: FC = (props) => { + return ( + + + + + ), + }} + /> + ); +}; + +const warningMessages = { + [CHARTS_WITHOUT_SMALL_MULTIPLES.heatmap]: HeatmapWarningFormatMessage, + [CHARTS_WITHOUT_SMALL_MULTIPLES.gauge]: GaugeWarningFormatMessage, +}; + +export const SplitChartWarning: FC = ({ chartType, chartConfigToken }) => { const { services } = useKibana(); const canEditAdvancedSettings = services.application.capabilities.advancedSettings.save; const advancedSettingsLink = services.application.getUrlForApp('management', { - path: `/kibana/settings?query=${NEW_HEATMAP_CHARTS_LIBRARY}`, + path: `/kibana/settings?query=${chartConfigToken}`, }); + const WarningMessage = warningMessages[chartType]; return ( - {canEditAdvancedSettings && ( - - - - ), - }} - /> - )} - {!canEditAdvancedSettings && ( - - )} - - ), - }} + } iconType="alert" diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx index 7d6594e05ae18..c76515072a1e2 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx @@ -17,7 +17,7 @@ import { ExperimentalVisInfo } from './experimental_vis_info'; import { useKibana } from '../../../../kibana_react/public'; import { urlFor } from '../../../../visualizations/public'; import { getUISettings } from '../../services'; -import { SplitChartWarning, NEW_HEATMAP_CHARTS_LIBRARY } from './split_chart_warning'; +import { SplitChartWarning } from './split_chart_warning'; import { SavedVisInstance, VisualizeAppState, @@ -25,6 +25,11 @@ import { VisualizeAppStateContainer, VisualizeEditorVisInstance, } from '../types'; +import { + CHARTS_CONFIG_TOKENS, + CHARTS_WITHOUT_SMALL_MULTIPLES, + isSplitChart as isSplitChartFn, +} from '../utils/split_chart_warning_helpers'; interface VisualizeEditorCommonProps { visInstance?: VisualizeEditorVisInstance; @@ -110,8 +115,17 @@ export const VisualizeEditorCommon = ({ return null; }, [visInstance?.savedVis, services, visInstance?.vis?.type.title]); // Adds a notification for split chart on the new implementation as it is not supported yet - const isSplitChart = visInstance?.vis?.data?.aggs?.aggs.some((agg) => agg.schema === 'split'); - const hasHeatmapLegacyhartsEnabled = getUISettings().get(NEW_HEATMAP_CHARTS_LIBRARY); + const chartName = visInstance?.vis.type.name; + const isSplitChart = isSplitChartFn(chartName, visInstance?.vis?.data?.aggs); + + const chartsWithoutSmallMultiples: string[] = Object.values(CHARTS_WITHOUT_SMALL_MULTIPLES); + const chartNeedsWarning = chartName ? chartsWithoutSmallMultiples.includes(chartName) : false; + const chartToken = + chartName && chartNeedsWarning + ? CHARTS_CONFIG_TOKENS[chartName as CHARTS_WITHOUT_SMALL_MULTIPLES] + : undefined; + + const hasLegacyChartsEnabled = chartToken ? getUISettings().get(chartToken) : true; return (
@@ -134,9 +148,12 @@ export const VisualizeEditorCommon = ({ /> )} {visInstance?.vis?.type?.stage === 'experimental' && } - {!hasHeatmapLegacyhartsEnabled && - isSplitChart && - visInstance?.vis.type.name === 'heatmap' && } + {!hasLegacyChartsEnabled && isSplitChart && chartNeedsWarning && chartToken && chartName && ( + + )} {visInstance?.vis?.type?.getInfoMessage?.(visInstance.vis)} {getLegacyUrlConflictCallout()} {visInstance && ( diff --git a/src/plugins/visualizations/public/visualize_app/constants.ts b/src/plugins/visualizations/public/visualize_app/constants.ts new file mode 100644 index 0000000000000..fd256cb5bbb86 --- /dev/null +++ b/src/plugins/visualizations/public/visualize_app/constants.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export const NEW_HEATMAP_CHARTS_LIBRARY = 'visualization:visualize:legacyHeatmapChartsLibrary'; +export const NEW_GAUGE_CHARTS_LIBRARY = 'visualization:visualize:legacyGaugeChartsLibrary'; diff --git a/src/plugins/visualizations/public/visualize_app/utils/split_chart_warning_helpers.ts b/src/plugins/visualizations/public/visualize_app/utils/split_chart_warning_helpers.ts new file mode 100644 index 0000000000000..d40f15aa08657 --- /dev/null +++ b/src/plugins/visualizations/public/visualize_app/utils/split_chart_warning_helpers.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { $Values } from '@kbn/utility-types'; +import { AggConfigs } from '../../../../data/common'; +import { NEW_HEATMAP_CHARTS_LIBRARY, NEW_GAUGE_CHARTS_LIBRARY } from '../constants'; + +export const CHARTS_WITHOUT_SMALL_MULTIPLES = { + heatmap: 'heatmap', + gauge: 'gauge', +} as const; + +export type CHARTS_WITHOUT_SMALL_MULTIPLES = $Values; + +export const CHARTS_CONFIG_TOKENS = { + [CHARTS_WITHOUT_SMALL_MULTIPLES.heatmap]: NEW_HEATMAP_CHARTS_LIBRARY, + [CHARTS_WITHOUT_SMALL_MULTIPLES.gauge]: NEW_GAUGE_CHARTS_LIBRARY, +} as const; + +export const isSplitChart = (chartType: string | undefined, aggs?: AggConfigs) => { + const defaultIsSplitChart = () => aggs?.aggs.some((agg) => agg.schema === 'split'); + + const knownCheckers = { + [CHARTS_WITHOUT_SMALL_MULTIPLES.heatmap]: defaultIsSplitChart, + [CHARTS_WITHOUT_SMALL_MULTIPLES.gauge]: () => aggs?.aggs.some((agg) => agg.schema === 'group'), + }; + + return (knownCheckers[chartType as CHARTS_WITHOUT_SMALL_MULTIPLES] ?? defaultIsSplitChart)(); +}; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 565dba89ffd32..d47ff1ed31496 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -6285,33 +6285,33 @@ "visTypeVislib.advancedSettings.visualization.heatmap.maxBucketsText": "1つのデータソースが返せるバケットの最大数です。値が大きいとブラウザのレンダリング速度が下がる可能性があります。", "visTypeVislib.advancedSettings.visualization.heatmap.maxBucketsTitle": "ヒートマップの最大バケット数", "visTypeVislib.aggResponse.allDocsTitle": "すべてのドキュメント", - "visTypeVislib.controls.gaugeOptions.alignmentLabel": "アラインメント", - "visTypeVislib.controls.gaugeOptions.autoExtendRangeLabel": "範囲を自動拡張", - "visTypeVislib.controls.gaugeOptions.extendRangeTooltip": "範囲をデータの最高値に広げます。", - "visTypeVislib.controls.gaugeOptions.gaugeTypeLabel": "ゲージタイプ", - "visTypeVislib.controls.gaugeOptions.labelsTitle": "ラベル", - "visTypeVislib.controls.gaugeOptions.rangesTitle": "範囲", - "visTypeVislib.controls.gaugeOptions.showLabelsLabel": "ラベルを表示", - "visTypeVislib.controls.gaugeOptions.showLegendLabel": "凡例を表示", - "visTypeVislib.controls.gaugeOptions.showOutline": "アウトラインを表示", - "visTypeVislib.controls.gaugeOptions.showScaleLabel": "縮尺を表示", - "visTypeVislib.controls.gaugeOptions.styleTitle": "スタイル", - "visTypeVislib.controls.gaugeOptions.subTextLabel": "サブラベル", + "visTypeGauge.controls.gaugeOptions.alignmentLabel": "アラインメント", + "visTypeGauge.controls.gaugeOptions.autoExtendRangeLabel": "範囲を自動拡張", + "visTypeGauge.controls.gaugeOptions.extendRangeTooltip": "範囲をデータの最高値に広げます。", + "visTypeGauge.controls.gaugeOptions.gaugeTypeLabel": "ゲージタイプ", + "visTypeGauge.controls.gaugeOptions.labelsTitle": "ラベル", + "visTypeGauge.controls.gaugeOptions.rangesTitle": "範囲", + "visTypeGauge.controls.gaugeOptions.showLabelsLabel": "ラベルを表示", + "visTypeGauge.controls.gaugeOptions.showLegendLabel": "凡例を表示", + "visTypeGauge.controls.gaugeOptions.showOutline": "アウトラインを表示", + "visTypeGauge.controls.gaugeOptions.showScaleLabel": "縮尺を表示", + "visTypeGauge.controls.gaugeOptions.styleTitle": "スタイル", + "visTypeGauge.controls.gaugeOptions.subTextLabel": "サブラベル", "visTypeVislib.functions.pie.help": "パイビジュアライゼーション", "visTypeVislib.functions.vislib.help": "Vislib ビジュアライゼーション", - "visTypeVislib.gauge.alignmentAutomaticTitle": "自動", - "visTypeVislib.gauge.alignmentHorizontalTitle": "横", - "visTypeVislib.gauge.alignmentVerticalTitle": "縦", - "visTypeVislib.gauge.gaugeDescription": "メトリックのステータスを示します。", - "visTypeVislib.gauge.gaugeTitle": "ゲージ", - "visTypeVislib.gauge.gaugeTypes.arcText": "弧形", - "visTypeVislib.gauge.gaugeTypes.circleText": "円", - "visTypeVislib.gauge.groupTitle": "グループを分割", - "visTypeVislib.gauge.metricTitle": "メトリック", - "visTypeVislib.goal.goalDescription": "メトリックがどのように目標まで進むのかを追跡します。", - "visTypeVislib.goal.goalTitle": "ゴール", - "visTypeVislib.goal.groupTitle": "グループを分割", - "visTypeVislib.goal.metricTitle": "メトリック", + "visTypeGauge.gauge.alignmentAutomaticTitle": "自動", + "visTypeGauge.gauge.alignmentHorizontalTitle": "横", + "visTypeGauge.gauge.alignmentVerticalTitle": "縦", + "visTypeGauge.gauge.gaugeDescription": "メトリックのステータスを示します。", + "visTypeGauge.gauge.gaugeTitle": "ゲージ", + "visTypeGauge.gauge.gaugeTypes.arcText": "弧形", + "visTypeGauge.gauge.gaugeTypes.circleText": "円", + "visTypeGauge.gauge.groupTitle": "グループを分割", + "visTypeGauge.gauge.metricTitle": "メトリック", + "visTypeGauge.goal.goalDescription": "メトリックがどのように目標まで進むのかを追跡します。", + "visTypeGauge.goal.goalTitle": "ゴール", + "visTypeGauge.goal.groupTitle": "グループを分割", + "visTypeGauge.goal.metricTitle": "メトリック", "visTypeVislib.vislib.errors.noResultsFoundTitle": "結果が見つかりませんでした", "visTypeVislib.vislib.heatmap.maxBucketsText": "定義された数列が多すぎます({nr})。構成されている最大値は {max} です。", "visTypeVislib.vislib.legend.filterForValueButtonAriaLabel": "値 {legendDataLabel} でフィルタリング", @@ -6587,8 +6587,8 @@ "visualizations.listing.table.titleColumnName": "タイトル", "visualizations.listing.table.typeColumnName": "型", "visualizations.listingPageTitle": "Visualizeライブラリ", - "visualizations.newHeatmapChart.conditionalMessage.advancedSettingsLink": "高度な設定", - "visualizations.newHeatmapChart.conditionalMessage.newLibrary": "{link}で古いライブラリに切り替える", + "visualizations.newChart.conditionalMessage.advancedSettingsLink": "高度な設定", + "visualizations.newChart.conditionalMessage.newLibrary": "{link}で古いライブラリに切り替える", "visualizations.newHeatmapChart.notificationMessage": "新しいヒートマップグラフライブラリはまだ分割グラフアグリゲーションをサポートしていません。{conditionalMessage}", "visualizations.newVisWizard.aggBasedGroupDescription": "クラシック Visualize ライブラリを使用して、アグリゲーションに基づいてグラフを作成します。", "visualizations.newVisWizard.aggBasedGroupTitle": "アグリゲーションに基づく", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index a230de1237174..96f9e892ba0b9 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -6296,33 +6296,33 @@ "visTypeVislib.advancedSettings.visualization.heatmap.maxBucketsText": "单个数据源可以返回的最大存储桶数目。较高的数目可能对浏览器呈现性能有负面影响", "visTypeVislib.advancedSettings.visualization.heatmap.maxBucketsTitle": "热图最大存储桶数", "visTypeVislib.aggResponse.allDocsTitle": "所有文档", - "visTypeVislib.controls.gaugeOptions.alignmentLabel": "对齐方式", - "visTypeVislib.controls.gaugeOptions.autoExtendRangeLabel": "自动扩展范围", - "visTypeVislib.controls.gaugeOptions.extendRangeTooltip": "将数据范围扩展到数据中的最大值。", - "visTypeVislib.controls.gaugeOptions.gaugeTypeLabel": "仪表类型", - "visTypeVislib.controls.gaugeOptions.labelsTitle": "标签", - "visTypeVislib.controls.gaugeOptions.rangesTitle": "范围", - "visTypeVislib.controls.gaugeOptions.showLabelsLabel": "显示标签", - "visTypeVislib.controls.gaugeOptions.showLegendLabel": "显示图例", - "visTypeVislib.controls.gaugeOptions.showOutline": "显示轮廓", - "visTypeVislib.controls.gaugeOptions.showScaleLabel": "显示比例", - "visTypeVislib.controls.gaugeOptions.styleTitle": "样式", - "visTypeVislib.controls.gaugeOptions.subTextLabel": "子标签", + "visTypeGauge.controls.gaugeOptions.alignmentLabel": "对齐方式", + "visTypeGauge.controls.gaugeOptions.autoExtendRangeLabel": "自动扩展范围", + "visTypeGauge.controls.gaugeOptions.extendRangeTooltip": "将数据范围扩展到数据中的最大值。", + "visTypeGauge.controls.gaugeOptions.gaugeTypeLabel": "仪表类型", + "visTypeGauge.controls.gaugeOptions.labelsTitle": "标签", + "visTypeGauge.controls.gaugeOptions.rangesTitle": "范围", + "visTypeGauge.controls.gaugeOptions.showLabelsLabel": "显示标签", + "visTypeGauge.controls.gaugeOptions.showLegendLabel": "显示图例", + "visTypeGauge.controls.gaugeOptions.showOutline": "显示轮廓", + "visTypeGauge.controls.gaugeOptions.showScaleLabel": "显示比例", + "visTypeGauge.controls.gaugeOptions.styleTitle": "样式", + "visTypeGauge.controls.gaugeOptions.subTextLabel": "子标签", "visTypeVislib.functions.pie.help": "饼图可视化", "visTypeVislib.functions.vislib.help": "Vislib 可视化", - "visTypeVislib.gauge.alignmentAutomaticTitle": "自动", - "visTypeVislib.gauge.alignmentHorizontalTitle": "水平", - "visTypeVislib.gauge.alignmentVerticalTitle": "垂直", - "visTypeVislib.gauge.gaugeDescription": "显示指标的状态。", - "visTypeVislib.gauge.gaugeTitle": "仪表盘", - "visTypeVislib.gauge.gaugeTypes.arcText": "弧形", - "visTypeVislib.gauge.gaugeTypes.circleText": "圆形", - "visTypeVislib.gauge.groupTitle": "拆分组", - "visTypeVislib.gauge.metricTitle": "指标", - "visTypeVislib.goal.goalDescription": "跟踪指标如何达到目标。", - "visTypeVislib.goal.goalTitle": "目标图", - "visTypeVislib.goal.groupTitle": "拆分组", - "visTypeVislib.goal.metricTitle": "指标", + "visTypeGauge.gauge.alignmentAutomaticTitle": "自动", + "visTypeGauge.gauge.alignmentHorizontalTitle": "水平", + "visTypeGauge.gauge.alignmentVerticalTitle": "垂直", + "visTypeGauge.gauge.gaugeDescription": "显示指标的状态。", + "visTypeGauge.gauge.gaugeTitle": "仪表盘", + "visTypeGauge.gauge.gaugeTypes.arcText": "弧形", + "visTypeGauge.gauge.gaugeTypes.circleText": "圆形", + "visTypeGauge.gauge.groupTitle": "拆分组", + "visTypeGauge.gauge.metricTitle": "指标", + "visTypeGauge.goal.goalDescription": "跟踪指标如何达到目标。", + "visTypeGauge.goal.goalTitle": "目标图", + "visTypeGauge.goal.groupTitle": "拆分组", + "visTypeGauge.goal.metricTitle": "指标", "visTypeVislib.vislib.errors.noResultsFoundTitle": "找不到结果", "visTypeVislib.vislib.heatmap.maxBucketsText": "定义了过多的序列 ({nr})。配置的最大值为 {max}。", "visTypeVislib.vislib.legend.filterForValueButtonAriaLabel": "筛留值 {legendDataLabel}", @@ -6598,8 +6598,8 @@ "visualizations.listing.table.titleColumnName": "标题", "visualizations.listing.table.typeColumnName": "类型", "visualizations.listingPageTitle": "Visualize 库", - "visualizations.newHeatmapChart.conditionalMessage.advancedSettingsLink": "免费的 API 密钥。", - "visualizations.newHeatmapChart.conditionalMessage.newLibrary": "切换到{link}中的旧库", + "visualizations.newChart.conditionalMessage.advancedSettingsLink": "免费的 API 密钥。", + "visualizations.newChart.conditionalMessage.newLibrary": "切换到{link}中的旧库", "visualizations.newHeatmapChart.notificationMessage": "新的热图图表库尚不支持拆分图表聚合。{conditionalMessage}", "visualizations.newVisWizard.aggBasedGroupDescription": "使用我们的经典可视化库,基于聚合创建图表。", "visualizations.newVisWizard.aggBasedGroupTitle": "基于聚合",