[Vis: Default editor] EUIficate gauge/goal options tab (#43265)

* Euificate gauge options

* Changes params places

* Add ranges validation

* Get rid of legacy translates

* Fix functional tests

* Split gauge to panel components

* Disable alignment option
This commit is contained in:
Daniil Suleiman 2019-08-22 16:01:55 +03:00 committed by GitHub
parent 7602710bdc
commit e568c3dfde
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 2123 additions and 1688 deletions

View file

@ -1,383 +0,0 @@
<div class="visEditorSidebar__section">
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="gaugeType"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.gaugeTypeLabel"
i18n-default-message="Gauge Type"
></label>
<div class="visEditorSidebar__formControl">
<select
id="gaugeType"
class="kuiSelect visEditorSidebar__select"
ng-model="editorState.params.gauge.gaugeType"
ng-options="mode for mode in collections.gaugeTypes"
></select>
</div>
</div>
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="percentageMode"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.percentageModeLabel"
i18n-default-message="Percentage Mode"
></label>
<div class="visEditorSidebar__formControl">
<input class="kuiCheckBox" id="percentageMode" type="checkbox" ng-model="editorState.params.gauge.percentageMode">
</div>
</div>
<div class="visEditorSidebar__formRow" ng-hide="editorState.params.gauge.type === 'simple'">
<label
class="visEditorSidebar__formLabel"
for="alignment"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.alignmentLabel"
i18n-default-message="Alignment"
></label>
<div class="visEditorSidebar__formControl">
<select
id="alignment"
class="kuiSelect visEditorSidebar__select"
ng-model="editorState.params.gauge.alignment"
ng-options="alignment.id as alignment.label for alignment in collections.alignments"
></select>
</div>
</div>
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="displayWarnings"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.displayWarningsLabel"
i18n-default-message="Display warnings"
></label>
<div class="visEditorSidebar__formControl">
<input class="kuiCheckBox" id="displayWarnings" type="checkbox" ng-model="editorState.params.isDisplayWarning">
&nbsp;
<icon-tip
content="'Turns on/off warnings. When turned on, a warning will be shown if not all labels could be displayed.'"
position="'right'"
></icon-tip>
</div>
</div>
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="addLegend"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.showLegendLabel"
i18n-default-message="Show Legend"
></label>
<div class="visEditorSidebar__formControl">
<input class="kuiCheckBox" id="addLegend" type="checkbox" ng-model="editorState.params.addLegend">
</div>
</div>
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="showLabels"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.showLabelsLabel"
i18n-default-message="Show Labels"
></label>
<div class="visEditorSidebar__formControl">
<input class="kuiCheckBox" id="showLabels" type="checkbox" ng-model="editorState.params.gauge.labels.show">
</div>
</div>
<div class="visEditorSidebar__formRow" ng-show="editorState.params.gauge.labels.show">
<label
class="visEditorSidebar__formLabel"
for="subText"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.subTextLabel"
i18n-default-message="Sub Text"
></label>
<div class="visEditorSidebar__formControl">
<input
id="subText"
class="kuiInput visEditorSidebar__input"
ng-model="editorState.params.gauge.style.subText"
type="text"
>
</div>
</div>
<div
class="visEditorSidebar__formRow"
ng-hide="editorState.params.gauge.type === 'simple'"
ng-show="editorState.params.gauge.colorsRange.length > 1"
>
<label
class="visEditorSidebar__formLabel"
for="extendRange"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.autoExtendRangeLabel"
i18n-default-message="Auto Extend Range"
></label>
<div class="visEditorSidebar__formControl">
<input class="kuiCheckBox" id="extendRange" type="checkbox" ng-model="editorState.params.gauge.extendRange">
&nbsp;
<icon-tip
content="'Extends range to the maximum value in your data'"
position="'right'"
></icon-tip>
</div>
</div>
<div class="visEditorSidebar__collapsible--margin">
<div class="visEditorSidebar__collapsibleTitle">
<div
kbn-accessible-click
aria-expanded="{{!!showColorRange}}"
aria-controls="gaugeOptionsRanges"
aria-label="Toggle range options"
class="visEditorSidebar__collapsibleTitleLabel"
ng-click="showColorRange = !showColorRange"
>
<icon color="'primary'" aria-hidden="true" ng-if="showColorRange" type="'arrowDown'" size="'s'"></icon>
<icon color="'primary'" aria-hidden="true" ng-if="!showColorRange" type="'arrowRight'" size="'s'"></icon>
<span
class="visEditorSidebar__collapsibleTitleText"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.rangesTitle"
i18n-default-message="Ranges"
></span>
</div>
</div>
<div id="gaugeOptionsRanges" ng-show="showColorRange">
<table class="visEditorAgg__rangesTable form-group" ng-show="editorState.params.gauge.colorsRange.length">
<tr>
<th scope="col">
<label
id="gaugeOptionsCustomRangeFrom"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.fromTitle"
i18n-default-message="From"
></label>
</th>
<th scope="col" colspan="2">
<label
id="gaugeOptionsCustomRangeTo"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.toTitle"
i18n-default-message="To"
></label>
</th>
</tr>
<tr ng-repeat="range in editorState.params.gauge.colorsRange track by $index">
<td>
<input
aria-labelledby="gaugeOptionsCustomRangeFrom"
ng-model="range.from"
type="number"
class="form-control"
name="range.from"
greater-or-equal-than="getGreaterThan($index)"
required
step="any" />
</td>
<td>
<input
aria-labelledby="gaugeOptionsCustomRangeTo"
ng-model="range.to"
type="number"
class="form-control"
name="range.to"
greater-or-equal-than="range.from"
required
step="any" />
</td>
<td>
<button
type="button"
ng-click="removeRange($index)"
ng-show="editorState.params.gauge.colorsRange.length > 1"
class="kuiButton kuiButton--danger kuiButton--small">
<i class="fa fa-times"></i>
</button>
</td>
</tr>
</table>
<div class="hintbox" ng-show="!editorState.params.gauge.colorsRange.length">
<p>
<i class="fa fa-danger text-danger"></i>
<span
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.specifiedRangeNumberWarningMessage"
i18n-default-message="{required} You must specify at least one range."
i18n-values="{ html_required: '<strong>' + requiredText + '</strong>' }"
></span>
</p>
</div>
<div
ng-click="addRange()"
class="kuiButton kuiButton--primary kuiButton--fullWidth"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.addRangeTitle"
i18n-default-message="Add Range"
></div>
<div
class="euiFormHelpText"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.howToChangeColorsDescription"
i18n-default-message="Note: colors can be changed in the legend"
></div>
</div>
</div>
<div class="visEditorSidebar__collapsible--margin" ng-show="editorState.params.gauge.colorsRange.length > 1">
<div class="visEditorSidebar__collapsibleTitle">
<div
kbn-accessible-click
aria-expanded="{{!!showColorOptions}}"
aria-controls="gaugeOptionsColors"
aria-label="Toggle color options"
class="visEditorSidebar__collapsibleTitleLabel"
ng-click="showColorOptions = !showColorOptions"
>
<icon color="'primary'" aria-hidden="true" ng-if="showColorOptions" type="'arrowDown'" size="'s'"></icon>
<icon color="'primary'" aria-hidden="true" ng-if="!showColorOptions" type="'arrowRight'" size="'s'"></icon>
<span
class="visEditorSidebar__collapsibleTitleText"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.colorOptionsTitle"
i18n-default-message="Color Options"
></span>
</div>
</div>
<div id="gaugeOptionsColors" ng-if="showColorOptions">
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="colorSchema"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.colorSchemaLabel"
i18n-default-message="Color Schema"
></label>
<div class="visEditorSidebar__formControl">
<select
id="colorSchema"
class="kuiSelect visEditorSidebar__select"
ng-model="editorState.params.gauge.colorSchema"
ng-options="mode.id as mode.label for mode in collections.colorSchemas"
></select>
</div>
<div
class="text-info text-center"
ng-show="customColors"
ng-click="resetColors()"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.resetColorsTitle"
i18n-default-message="reset colors"
></div>
</div>
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="invertColors"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.reverseColorSchemaLabel"
i18n-default-message="Reverse Color Schema"
></label>
<div class="visEditorSidebar__formControl">
<input class="kuiCheckBox" id="invertColors" type="checkbox" ng-model="editorState.params.gauge.invertColors">
</div>
</div>
</div>
</div>
<div class="visEditorSidebar__collapsible--margin">
<div class="visEditorSidebar__collapsibleTitle">
<div
kbn-accessible-click
aria-expanded="{{!!showStyle}}"
aria-controls="gaugeOptionsStyle"
aria-label="Toggle style options"
class="visEditorSidebar__collapsibleTitleLabel"
ng-click="showStyle = !showStyle"
>
<icon color="'primary'" aria-hidden="true" ng-if="showStyle" type="'arrowDown'" size="'s'"></icon>
<icon color="'primary'" aria-hidden="true" ng-if="!showStyle" type="'arrowRight'" size="'s'"></icon>
<span
class="visEditorSidebar__collapsibleTitleText"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.styleTitle"
i18n-default-message="Style"
></span>
</div>
</div>
<div id="gaugeOptionsStyle" ng-if="showStyle">
<div ng-hide="editorState.params.gauge.type === 'simple'">
<div class="visEditorSidebar__formRow" ng-show="editorState.params.gauge.colorsRange.length > 1">
<label
class="visEditorSidebar__formLabel"
for="labelColor"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.colorLabelsLabel"
i18n-default-message="Color Labels"
></label>
<div class="visEditorSidebar__formControl">
<input class="kuiCheckBox" id="labelColor" type="checkbox" ng-model="editorState.params.gauge.style.labelColor">
</div>
</div>
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="showScale"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.showScaleLabel"
i18n-default-message="Show Scale"
></label>
<div class="visEditorSidebar__formControl">
<input class="kuiCheckBox" id="showScale" type="checkbox" ng-model="editorState.params.gauge.scale.show">
</div>
</div>
</div>
<div ng-show="editorState.params.gauge.type === 'simple'">
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="gaugeColorMode"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.colorLabel"
i18n-default-message="Color"
></label>
<div class="visEditorSidebar__formControl">
<select
id="gaugeColorMode"
class="kuiSelect visEditorSidebar__select"
ng-model="editorState.params.gauge.gaugeColorMode"
ng-options="mode for mode in collections.gaugeColorMode"
></select>
</div>
</div>
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="backColor"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.backTextColorLabel"
i18n-default-message="Back/Text Color"
></label>
<div class="visEditorSidebar__formControl">
<input
id="backTextColor"
class="kuiInput visEditorSidebar__input"
ng-model="editorState.params.gauge.style.bgFill"
>
</div>
</div>
<div class="visEditorSidebar__formRow">
<label
class="visEditorSidebar__formLabel"
for="showScale"
i18n-id="kbnVislibVisTypes.controls.gaugeOptions.fontSizeLabel"
i18n-default-message="Font Size ({fontSize}pt)"
i18n-values="{ fontSize: editorState.params.gauge.style.fontSize }"
></label>
<div class="visEditorSidebar__formControl">
<input type="range" ng-model="editorState.params.gauge.style.fontSize" class="form-control" min="12" max="120" />
</div>
</div>
</div>
</div>
</div>
</div>

View file

@ -1,117 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { uiModules } from 'ui/modules';
import { i18n } from '@kbn/i18n';
import gaugeOptionsTemplate from './gauge_options.html';
import _ from 'lodash';
const module = uiModules.get('kibana');
module.directive('gaugeOptions', function () {
return {
restrict: 'E',
template: gaugeOptionsTemplate,
replace: true,
link: function ($scope) {
$scope.collections = $scope.vis.type.editorConfig.collections;
$scope.showColorRange = true;
$scope.$watch('editorState.params.gauge.gaugeType', type => {
switch (type) {
case 'Arc':
$scope.editorState.params.gauge.type = 'meter';
$scope.editorState.params.gauge.minAngle = undefined;
$scope.editorState.params.gauge.maxAngle = undefined;
break;
case 'Circle':
$scope.editorState.params.gauge.type = 'meter';
$scope.editorState.params.gauge.minAngle = 0;
$scope.editorState.params.gauge.maxAngle = 2 * Math.PI;
break;
case 'Metric':
$scope.editorState.params.gauge.type = 'simple';
}
});
const updateLegend = () => {
if (!$scope.editorState.params.gauge.style.bgColor && !$scope.editorState.params.gauge.style.labelColor) {
$scope.editorState.params.addLegend = false;
} else {
$scope.editorState.params.addLegend = true;
}
};
$scope.$watch('editorState.params.gauge.gaugeColorMode', newValue => {
switch (newValue) {
case 'Labels':
$scope.editorState.params.gauge.style.labelColor = true;
$scope.editorState.params.gauge.style.bgColor = false;
break;
case 'Background':
$scope.editorState.params.gauge.style.labelColor = false;
$scope.editorState.params.gauge.style.bgColor = true;
break;
case 'None':
$scope.editorState.params.gauge.style.labelColor = false;
$scope.editorState.params.gauge.style.bgColor = false;
break;
}
updateLegend();
});
$scope.resetColors = function () {
$scope.uiState.set('vis.colors', null);
$scope.customColors = false;
};
$scope.getGreaterThan = function (index) {
if (index === 0) return -Infinity;
return $scope.editorState.params.gauge.colorsRange[index - 1].to;
};
$scope.addRange = function () {
const previousRange = _.last($scope.editorState.params.gauge.colorsRange);
const from = previousRange ? previousRange.to : 0;
const to = previousRange ? from + (previousRange.to - previousRange.from) : 100;
$scope.editorState.params.gauge.colorsRange.push({ from: from, to: to });
};
$scope.removeRange = function (index) {
$scope.editorState.params.gauge.colorsRange.splice(index, 1);
};
$scope.getColor = function (index) {
const defaultColors = this.uiState.get('vis.defaultColors');
const overwriteColors = this.uiState.get('vis.colors');
const colors = defaultColors ? _.defaults({}, overwriteColors, defaultColors) : overwriteColors;
return colors ? Object.values(colors)[index] : 'transparent';
};
$scope.uiState.on('colorChanged', () => {
$scope.customColors = true;
});
$scope.requiredText = i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.requiredText', {
defaultMessage: 'Required:'
});
}
};
});

View file

@ -21,6 +21,8 @@ import React from 'react';
import { EuiFormRow, EuiSelect } from '@elastic/eui';
interface SelectOptionProps<ParamName extends string, ValidParamValues extends string> {
disabled?: boolean;
helpText?: React.ReactNode;
id?: string;
label: string;
labelAppend?: React.ReactNode;
@ -33,6 +35,8 @@ interface SelectOptionProps<ParamName extends string, ValidParamValues extends s
const emptyValue = { text: '', value: 'EMPTY_VALUE', disabled: true, hidden: true };
function SelectOption<ParamName extends string, ValidParamValues extends string>({
disabled,
helpText,
id,
label,
labelAppend,
@ -42,8 +46,16 @@ function SelectOption<ParamName extends string, ValidParamValues extends string>
setValue,
}: SelectOptionProps<ParamName, ValidParamValues>) {
return (
<EuiFormRow id={id} label={label} fullWidth={true} compressed labelAppend={labelAppend}>
<EuiFormRow
compressed
fullWidth
helpText={helpText}
id={id}
label={label}
labelAppend={labelAppend}
>
<EuiSelect
disabled={disabled}
options={[emptyValue, ...options]}
value={value || emptyValue.value}
onChange={ev => setValue(paramName, ev.target.value as ValidParamValues)}

View file

@ -21,6 +21,7 @@ import React from 'react';
import { EuiFormRow, EuiFieldText } from '@elastic/eui';
interface TextInputOptionProps<ParamName extends string> {
disabled?: boolean;
helpText?: React.ReactNode;
label?: React.ReactNode;
paramName: ParamName;
@ -29,6 +30,7 @@ interface TextInputOptionProps<ParamName extends string> {
}
function TextInputOption<ParamName extends string>({
disabled,
helpText,
label,
paramName,
@ -37,7 +39,12 @@ function TextInputOption<ParamName extends string>({
}: TextInputOptionProps<ParamName>) {
return (
<EuiFormRow helpText={helpText} label={label} fullWidth compressed>
<EuiFieldText fullWidth value={value} onChange={ev => setValue(paramName, ev.target.value)} />
<EuiFieldText
fullWidth
disabled={disabled}
value={value}
onChange={ev => setValue(paramName, ev.target.value)}
/>
</EuiFormRow>
);
}

View file

@ -1,2 +0,0 @@
<!-- vis type specific options -->
<gauge-options></gauge-options>

View file

@ -0,0 +1,63 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { useCallback } from 'react';
import { EuiSpacer } from '@elastic/eui';
import { VisOptionsProps } from 'ui/vis/editors/default';
import { GaugeVisParams } from '../../gauge';
import { RangesPanel } from './ranges_panel';
import { StylePanel } from './style_panel';
import { LabelsPanel } from './labels_panel';
export type GaugeOptionsInternalProps = VisOptionsProps<GaugeVisParams> & {
setGaugeValue: <T extends keyof GaugeVisParams['gauge']>(
paramName: T,
value: GaugeVisParams['gauge'][T]
) => void;
};
function GaugeOptions(props: VisOptionsProps<GaugeVisParams>) {
const { stateParams, setValue } = props;
const setGaugeValue: GaugeOptionsInternalProps['setGaugeValue'] = useCallback(
(paramName, value) =>
setValue('gauge', {
...stateParams.gauge,
[paramName]: value,
}),
[setValue, stateParams.gauge]
);
return (
<>
<StylePanel {...props} setGaugeValue={setGaugeValue} />
<EuiSpacer size="s" />
<RangesPanel {...props} setGaugeValue={setGaugeValue} />
<EuiSpacer size="s" />
<LabelsPanel {...props} setGaugeValue={setGaugeValue} />
</>
);
}
export { GaugeOptions };

View file

@ -0,0 +1,83 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { SwitchOption } from '../../controls/switch';
import { TextInputOption } from '../../controls/text_input';
import { GaugeOptionsInternalProps } from '.';
function LabelsPanel({ stateParams, setValue, setGaugeValue }: GaugeOptionsInternalProps) {
return (
<EuiPanel paddingSize="s">
<EuiTitle size="xs">
<h2>
<FormattedMessage
id="kbnVislibVisTypes.controls.gaugeOptions.labelsTitle"
defaultMessage="Labels"
/>
</h2>
</EuiTitle>
<EuiSpacer size="s" />
<SwitchOption
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.showLabelsLabel', {
defaultMessage: 'Show labels',
})}
paramName="show"
value={stateParams.gauge.labels.show}
setValue={(paramName, value) =>
setGaugeValue('labels', { ...stateParams.gauge.labels, [paramName]: value })
}
/>
<EuiSpacer size="s" />
<TextInputOption
disabled={!stateParams.gauge.labels.show}
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.subTextLabel', {
defaultMessage: 'Sub label',
})}
paramName="subText"
value={stateParams.gauge.style.subText}
setValue={(paramName, value) =>
setGaugeValue('style', { ...stateParams.gauge.style, [paramName]: value })
}
/>
<SwitchOption
disabled={!stateParams.gauge.labels.show}
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.displayWarningsLabel', {
defaultMessage: 'Display warnings',
})}
tooltip={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.switchWarningsTooltip', {
defaultMessage:
'Turns on/off warnings. When turned on, a warning will be shown if not all labels could be displayed.',
})}
paramName="isDisplayWarning"
value={stateParams.isDisplayWarning}
setValue={setValue}
/>
</EuiPanel>
);
}
export { LabelsPanel };

View file

@ -0,0 +1,184 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { useCallback, useEffect, useState } from 'react';
import { last } from 'lodash';
import { EuiLink, EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { RangesParamEditor } from 'ui/agg_types/controls/ranges';
import { SelectOption } from '../../controls/select';
import { SwitchOption } from '../../controls/switch';
import { GaugeOptionsInternalProps } from '.';
function RangesPanel({
setGaugeValue,
setTouched,
setValidity,
setValue,
stateParams,
uiState,
vis,
}: GaugeOptionsInternalProps) {
const [isCustomColors, setIsCustomColors] = useState(false);
useEffect(() => {
uiState.on('colorChanged', () => {
setIsCustomColors(true);
});
}, [uiState]);
const addRangeValues = useCallback(() => {
const previousRange = last(stateParams.gauge.colorsRange);
const from = previousRange.to ? previousRange.to : 0;
const to = previousRange.to ? from + (previousRange.to - (previousRange.from || 0)) : 100;
return { from, to };
}, [stateParams.gauge.colorsRange]);
const validateRange = useCallback(
({ from, to }, index) => {
const leftBound = index === 0 ? -Infinity : stateParams.gauge.colorsRange[index - 1].to || 0;
const isFromValid = from >= leftBound;
const isToValid = to >= from;
return [isFromValid, isToValid];
},
[stateParams.gauge.colorsRange]
);
const resetColorsButton = (
<EuiText size="xs">
<EuiLink
onClick={() => {
uiState.set('vis.colors', null);
setIsCustomColors(false);
}}
>
<FormattedMessage
id="kbnVislibVisTypes.controls.gaugeOptions.resetColorsButtonLabel"
defaultMessage="Reset colors"
/>
</EuiLink>
</EuiText>
);
return (
<EuiPanel paddingSize="s">
<EuiTitle size="xs">
<h2>
<FormattedMessage
id="kbnVislibVisTypes.controls.gaugeOptions.rangesTitle"
defaultMessage="Ranges"
/>
</h2>
</EuiTitle>
<EuiSpacer size="s" />
<RangesParamEditor
dataTestSubj="gaugeColorRange"
error={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.errorText', {
defaultMessage: 'Each range should be greater than previous.',
})}
hidePlaceholders={true}
value={stateParams.gauge.colorsRange}
setValue={value => setGaugeValue('colorsRange', value)}
setTouched={setTouched}
setValidity={setValidity}
addRangeValues={addRangeValues}
validateRange={validateRange}
/>
<SwitchOption
disabled={stateParams.gauge.colorsRange.length < 2}
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.autoExtendRangeLabel', {
defaultMessage: 'Auto extend range',
})}
tooltip={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.extendRangeTooltip', {
defaultMessage: 'Extends range to the maximum value in your data.',
})}
paramName="extendRange"
value={stateParams.gauge.extendRange}
setValue={setGaugeValue}
/>
<SwitchOption
dataTestSubj="gaugePercentageMode"
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.percentageModeLabel', {
defaultMessage: 'Percentage mode',
})}
paramName="percentageMode"
value={stateParams.gauge.percentageMode}
setValue={setGaugeValue}
/>
<EuiSpacer size="s" />
<SelectOption
disabled={stateParams.gauge.colorsRange.length < 2}
helpText={i18n.translate(
'kbnVislibVisTypes.controls.gaugeOptions.howToChangeColorsDescription',
{
defaultMessage: 'Note: colors can be changed in the legend.',
}
)}
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.colorSchemaLabel', {
defaultMessage: 'Color schema',
})}
labelAppend={isCustomColors && resetColorsButton}
options={vis.type.editorConfig.collections.colorSchemas}
paramName="colorSchema"
value={stateParams.gauge.colorSchema}
setValue={setGaugeValue}
/>
<SwitchOption
disabled={stateParams.gauge.colorsRange.length < 2}
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.reverseColorSchemaLabel', {
defaultMessage: 'Reverse schema',
})}
paramName="invertColors"
value={stateParams.gauge.invertColors}
setValue={setGaugeValue}
/>
<SwitchOption
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.showLegendLabel', {
defaultMessage: 'Show legend',
})}
paramName="addLegend"
value={stateParams.addLegend}
setValue={setValue}
/>
<SwitchOption
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.showScaleLabel', {
defaultMessage: 'Show scale',
})}
paramName="show"
value={stateParams.gauge.scale.show}
setValue={(paramName, value) =>
setGaugeValue('scale', { ...stateParams.gauge.scale, [paramName]: value })
}
/>
</EuiPanel>
);
}
export { RangesPanel };

View file

@ -0,0 +1,92 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { useCallback } from 'react';
import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { AggGroupNames } from 'ui/vis/editors/default';
import { SelectOption } from '../../controls/select';
import { GaugeVisParams } from '../../gauge';
import { GaugeOptionsInternalProps } from '.';
function StylePanel({
aggs,
setGaugeValue,
stateParams,
setValue,
vis,
}: GaugeOptionsInternalProps) {
const diasableAlignment =
aggs.bySchemaGroup[AggGroupNames.Metrics].length === 1 &&
!aggs.bySchemaGroup[AggGroupNames.Buckets];
const setGaugeType = useCallback(
(paramName: 'gaugeType', value: GaugeVisParams['gauge']['gaugeType']) => {
const minAngle = value === 'Arc' ? undefined : 0;
const maxAngle = value === 'Arc' ? undefined : 2 * Math.PI;
setValue('gauge', {
...stateParams.gauge,
[paramName]: value,
minAngle,
maxAngle,
});
},
[setValue, stateParams.gauge]
);
return (
<EuiPanel paddingSize="s">
<EuiTitle size="xs">
<h2>
<FormattedMessage
id="kbnVislibVisTypes.controls.gaugeOptions.styleTitle"
defaultMessage="Style"
/>
</h2>
</EuiTitle>
<EuiSpacer size="s" />
<SelectOption
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.gaugeTypeLabel', {
defaultMessage: 'Gauge type',
})}
options={vis.type.editorConfig.collections.gaugeTypes}
paramName="gaugeType"
value={stateParams.gauge.gaugeType}
setValue={setGaugeType}
/>
<SelectOption
disabled={diasableAlignment}
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.alignmentLabel', {
defaultMessage: 'Alignment',
})}
options={vis.type.editorConfig.collections.alignments}
paramName="alignment"
value={stateParams.gauge.alignment}
setValue={setGaugeValue}
/>
</EuiPanel>
);
}
export { StylePanel };

View file

@ -0,0 +1,53 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ColorSchemas } from 'ui/vislib/components/color/colormaps';
export interface GaugeVisParams {
readonly type: 'gauge';
addTooltip: boolean;
addLegend: boolean;
isDisplayWarning: boolean;
gauge: {
readonly backStyle: 'Full';
readonly gaugeStyle: 'Full';
readonly orientation: 'vertical';
readonly type: 'meter';
alignment: 'automatic' | 'horizontal' | 'vertical';
colorsRange: Array<{ from?: number; to?: number }>;
colorSchema: ColorSchemas;
extendRange: boolean;
invertColors: boolean;
gaugeType: 'Arc' | 'Circle';
labels: {
show: boolean;
};
minAngle?: number;
maxAngle?: number;
percentageMode: boolean;
scale: {
show: boolean;
readonly labels: false;
readonly color: 'rgba(105,112,125,0.2)';
};
style: {
subText: string;
};
};
}

View file

@ -17,11 +17,11 @@
* under the License.
*/
import { VisFactoryProvider } from 'ui/vis/vis_factory';
import { i18n } from '@kbn/i18n';
import { VisFactoryProvider } from 'ui/vis/vis_factory';
import { Schemas } from 'ui/vis/editors/default/schemas';
import gaugeTemplate from './editors/gauge.html';
import { vislibColorMaps } from 'ui/vislib/components/color/colormaps';
import { colorSchemas } from 'ui/vislib/components/color/colormaps';
import { GaugeOptions } from './editors/gauge';
export default function GaugeVisType(Private) {
const VisFactory = Private(VisFactoryProvider);
@ -84,25 +84,36 @@ export default function GaugeVisType(Private) {
},
editorConfig: {
collections: {
gaugeTypes: ['Arc', 'Circle'],
gaugeColorMode: ['None', 'Labels', 'Background'],
gaugeTypes: [
{
text: i18n.translate('kbnVislibVisTypes.gauge.gaugeTypes.arcText', {
defaultMessage: 'Arc',
}),
value: 'Arc',
},
{
text: i18n.translate('kbnVislibVisTypes.gauge.gaugeTypes.circleText', {
defaultMessage: 'Circle',
}),
value: 'Circle',
},
],
alignments: [
{
id: 'automatic',
label: i18n.translate('kbnVislibVisTypes.gauge.alignmentAutomaticTitle', { defaultMessage: 'Automatic' })
value: 'automatic',
text: i18n.translate('kbnVislibVisTypes.gauge.alignmentAutomaticTitle', { defaultMessage: 'Automatic' })
},
{
id: 'horizontal',
label: i18n.translate('kbnVislibVisTypes.gauge.alignmentHorizontalTitle', { defaultMessage: 'Horizontal' })
value: 'horizontal',
text: i18n.translate('kbnVislibVisTypes.gauge.alignmentHorizontalTitle', { defaultMessage: 'Horizontal' })
},
{
id: 'vertical',
label: i18n.translate('kbnVislibVisTypes.gauge.alignmentVerticalTitle', { defaultMessage: 'Vertical' }) },
value: 'vertical',
text: i18n.translate('kbnVislibVisTypes.gauge.alignmentVerticalTitle', { defaultMessage: 'Vertical' }) },
],
scales: ['linear', 'log', 'square root'],
colorSchemas: Object.values(vislibColorMaps).map(value => ({ id: value.id, label: value.label })),
colorSchemas,
},
optionsTemplate: gaugeTemplate,
optionsTemplate: GaugeOptions,
schemas: new Schemas([
{
group: 'metrics',

View file

@ -20,8 +20,8 @@
import { VisFactoryProvider } from 'ui/vis/vis_factory';
import { i18n } from '@kbn/i18n';
import { Schemas } from 'ui/vis/editors/default/schemas';
import gaugeTemplate from './editors/gauge.html';
import { vislibColorMaps } from 'ui/vislib/components/color/colormaps';
import { colorSchemas } from 'ui/vislib/components/color/colormaps';
import { GaugeOptions } from './editors/gauge';
export default function GoalVisType(Private) {
const VisFactory = Private(VisFactoryProvider);
@ -80,12 +80,36 @@ export default function GoalVisType(Private) {
},
editorConfig: {
collections: {
gaugeTypes: ['Arc', 'Circle'],
gaugeColorMode: ['None', 'Labels', 'Background'],
scales: ['linear', 'log', 'square root'],
colorSchemas: Object.values(vislibColorMaps).map(value => ({ id: value.id, label: value.label })),
gaugeTypes: [
{
text: i18n.translate('kbnVislibVisTypes.gauge.gaugeTypes.arcText', {
defaultMessage: 'Arc',
}),
value: 'Arc',
},
{
text: i18n.translate('kbnVislibVisTypes.gauge.gaugeTypes.circleText', {
defaultMessage: 'Circle',
}),
value: 'Circle',
},
],
alignments: [
{
value: 'automatic',
text: i18n.translate('kbnVislibVisTypes.gauge.alignmentAutomaticTitle', { defaultMessage: 'Automatic' })
},
{
value: 'horizontal',
text: i18n.translate('kbnVislibVisTypes.gauge.alignmentHorizontalTitle', { defaultMessage: 'Horizontal' })
},
{
value: 'vertical',
text: i18n.translate('kbnVislibVisTypes.gauge.alignmentVerticalTitle', { defaultMessage: 'Vertical' }) },
],
colorSchemas,
},
optionsTemplate: gaugeTemplate,
optionsTemplate: GaugeOptions,
schemas: new Schemas([
{
group: 'metrics',

View file

@ -17,6 +17,7 @@
* under the License.
*/
import React from 'react';
import { BucketAggType } from './_bucket_agg_type';
import { createFilterRange } from './create_filter/range';
import { FieldFormat } from '../../../field_formats/field_format';
@ -91,7 +92,7 @@ export const rangeBucketAgg = new BucketAggType({
{ from: 0, to: 1000 },
{ from: 1000, to: 2000 }
],
editorComponent: RangesParamEditor,
editorComponent: ({ value, setValue }) => <RangesParamEditor value={value} setValue={setValue}/>,
write: function (aggConfig, output) {
output.params.ranges = aggConfig.params.ranges;
output.params.keyed = true;

View file

@ -111,7 +111,7 @@ function DateRangesParamEditor({
);
return (
<EuiFormRow compressed>
<EuiFormRow compressed fullWidth>
<>
<EuiText size="xs">
<EuiLink href={getDocLink('date.dateMath')} target="_blank" rel="noopener">

View file

@ -24,6 +24,7 @@ import {
EuiFieldNumber,
EuiFlexItem,
EuiFlexGroup,
EuiFormErrorText,
EuiIcon,
EuiSpacer,
EuiButtonEmpty,
@ -32,7 +33,6 @@ import {
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { isEqual, omit } from 'lodash';
import { AggParamEditorProps } from 'ui/vis/editors/default';
const FROM_PLACEHOLDER = '\u2212\u221E';
const TO_PLACEHOLDER = '+\u221E';
@ -49,7 +49,29 @@ interface RangeValuesModel extends RangeValues {
id: string;
}
function RangesParamEditor({ agg, value = [], setValue }: AggParamEditorProps<RangeValues[]>) {
interface RangesParamEditorProps {
dataTestSubj?: string;
error?: React.ReactNode;
value?: RangeValues[];
hidePlaceholders?: boolean;
setValue(value: RangeValues[]): void;
setValidity?(isValid: boolean): void;
setTouched?(isTouched: boolean): void;
addRangeValues?(): RangeValues;
validateRange?(range: RangeValues, index: number): boolean[];
}
function RangesParamEditor({
addRangeValues,
dataTestSubj = 'range',
error,
value = [],
hidePlaceholders,
setValue,
setTouched,
setValidity,
validateRange,
}: RangesParamEditorProps) {
const [ranges, setRanges] = useState(() => value.map(range => ({ ...range, id: generateId() })));
// set up an initial range when there is no default range
@ -73,8 +95,15 @@ function RangesParamEditor({ agg, value = [], setValue }: AggParamEditorProps<Ra
// do not set internal id parameter into saved object
setValue(rangeValues.map(range => omit(range, 'id')));
setRanges(rangeValues);
if (setTouched) {
setTouched(true);
}
};
const onAddRange = () => updateRanges([...ranges, { id: generateId() }]);
const onAddRange = () =>
addRangeValues
? updateRanges([...ranges, { ...addRangeValues(), id: generateId() }])
: updateRanges([...ranges, { id: generateId() }]);
const onRemoveRange = (id: string) => updateRanges(ranges.filter(range => range.id !== id));
const onChangeRange = (id: string, key: string, newValue: string) =>
updateRanges(
@ -88,10 +117,24 @@ function RangesParamEditor({ agg, value = [], setValue }: AggParamEditorProps<Ra
)
);
const hasInvalidRange =
validateRange &&
ranges.some(({ from, to, id }, index) => {
const [isFromValid, isToValid] = validateRange({ from, to }, index);
return !isFromValid || !isToValid;
});
useEffect(() => {
if (setValidity) {
setValidity(!hasInvalidRange);
}
}, [hasInvalidRange, setValidity]);
return (
<EuiFormRow compressed>
<EuiFormRow compressed fullWidth>
<>
{ranges.map(({ from, to, id }) => {
{ranges.map(({ from, to, id }, index) => {
const deleteBtnTitle = i18n.translate(
'common.ui.aggTypes.ranges.removeRangeButtonAriaLabel',
{
@ -103,19 +146,28 @@ function RangesParamEditor({ agg, value = [], setValue }: AggParamEditorProps<Ra
}
);
let isFromValid = true;
let isToValid = true;
if (validateRange) {
[isFromValid, isToValid] = validateRange({ from, to }, index);
}
return (
<Fragment key={id}>
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexGroup gutterSize="s" alignItems="center" responsive={false}>
<EuiFlexItem>
<EuiFieldNumber
aria-label={i18n.translate('common.ui.aggTypes.ranges.fromLabel', {
defaultMessage: 'From',
})}
data-test-subj={`${dataTestSubj}${index}__from`}
value={isEmpty(from) ? '' : from}
placeholder={FROM_PLACEHOLDER}
placeholder={hidePlaceholders ? undefined : FROM_PLACEHOLDER}
onChange={ev => onChangeRange(id, 'from', ev.target.value)}
fullWidth={true}
compressed={true}
isInvalid={!isFromValid}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
@ -126,11 +178,13 @@ function RangesParamEditor({ agg, value = [], setValue }: AggParamEditorProps<Ra
aria-label={i18n.translate('common.ui.aggTypes.ranges.toLabel', {
defaultMessage: 'To',
})}
data-test-subj={`${dataTestSubj}${index}__to`}
value={isEmpty(to) ? '' : to}
placeholder={TO_PLACEHOLDER}
placeholder={hidePlaceholders ? undefined : TO_PLACEHOLDER}
onChange={ev => onChangeRange(id, 'to', ev.target.value)}
fullWidth={true}
compressed={true}
isInvalid={!isToValid}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
@ -149,6 +203,8 @@ function RangesParamEditor({ agg, value = [], setValue }: AggParamEditorProps<Ra
);
})}
{hasInvalidRange && error && <EuiFormErrorText>{error}</EuiFormErrorText>}
<EuiSpacer size="s" />
<EuiFlexItem>
<EuiButtonEmpty iconType="plusInCircleFilled" onClick={onAddRange} size="xs">

View file

@ -174,6 +174,7 @@
<div class="visEditorSidebar__config" ng-repeat="tab in vis.type.editorConfig.optionTabs" ng-show="sidebar.section == tab.name">
<vis-editor-vis-options
class="visEditorSidebar__options"
ng-model="_internalNgModelState"
editor-state="state"
has-histogram-agg="hasHistogramAgg"
vis="vis"

View file

@ -31,14 +31,19 @@ uiModules
.get('app/visualize')
.directive('visOptionsReactWrapper', reactDirective => reactDirective(wrapInI18nContext(VisOptionsReactWrapper), [
['component', { wrapApply: false }],
['aggs', { watchDepth: 'collection' }],
['stateParams', { watchDepth: 'collection' }],
['vis', { watchDepth: 'collection' }],
['uiState', { watchDepth: 'collection' }],
['setValue', { watchDepth: 'reference' }],
['setValidity', { watchDepth: 'reference' }],
['setTouched', { watchDepth: 'reference' }],
'hasHistogramAgg',
]))
.directive('visEditorVisOptions', function ($compile) {
return {
restrict: 'E',
require: '?^ngModel',
scope: {
vis: '=',
visData: '=',
@ -49,18 +54,34 @@ uiModules
onAggParamsChange: '=',
hasHistogramAgg: '=',
},
link: function ($scope, $el) {
link: function ($scope, $el, attrs, ngModelCtrl) {
$scope.setValue = (paramName, value) =>
$scope.onAggParamsChange($scope.editorState.params, paramName, value);
$scope.setValidity = isValid => {
ngModelCtrl.$setValidity(`visOptions`, isValid);
};
$scope.setTouched = isTouched => {
if (isTouched) {
ngModelCtrl.$setTouched();
} else {
ngModelCtrl.$setUntouched();
}
};
const comp = typeof $scope.editor === 'string' ?
$scope.editor :
`<vis-options-react-wrapper
component="editor"
aggs="editorState.aggs"
has-histogram-agg="hasHistogramAgg"
state-params="editorState.params"
vis="vis"
set-value="setValue">
ui-state="uiState"
set-value="setValue"
set-validity="setValidity"
set-touched="setTouched">
</vis-options-react-wrapper>`;
const $editor = $compile(comp)($scope);
$el.append($editor);

View file

@ -17,11 +17,17 @@
* under the License.
*/
import { PersistedState } from 'ui/persisted_state';
import { AggConfigs } from 'ui/vis/agg_configs';
import { Vis } from './../..';
export interface VisOptionsProps<VisParamType = unknown> {
aggs: AggConfigs;
hasHistogramAgg: boolean;
stateParams: VisParamType;
vis: Vis;
uiState: PersistedState;
setValue<T extends keyof VisParamType>(paramName: T, value: VisParamType[T]): void;
setValidity(isValid: boolean): void;
setTouched(isTouched: boolean): void;
}

View file

@ -20,7 +20,6 @@
import 'plugins/kbn_vislib_vis_types/controls/point_series_options';
import 'plugins/kbn_vislib_vis_types/controls/line_interpolation_option';
import 'plugins/kbn_vislib_vis_types/controls/heatmap_options';
import 'plugins/kbn_vislib_vis_types/controls/gauge_options';
import 'plugins/kbn_vislib_vis_types/controls/point_series';
import { CUSTOM_LEGEND_VIS_TYPES } from './vislib_vis_legend';
import { BaseVisType } from './base_vis_type';

View file

@ -23,7 +23,7 @@ export default function ({ getService, getPageObjects }) {
const log = getService('log');
const retry = getService('retry');
const inspector = getService('inspector');
const find = getService('find');
const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['common', 'visualize', 'timePicker']);
describe('gauge chart', function indexPatternCreation() {
@ -100,12 +100,8 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.visualize.selectAggregation('Average', 'metrics');
await PageObjects.visualize.selectField('bytes', 'metrics');
await PageObjects.visualize.clickOptionsTab();
const table = await find.byClassName('visEditorAgg__rangesTable');
const lastRow = await table.findByCssSelector('tr:last-child');
const toCell = await lastRow.findByCssSelector('td:nth-child(2) input');
await toCell.clearValue();
await toCell.type('10000', { charByChar: true });
await find.clickByCssSelector('#percentageMode');
await testSubjects.setValue('gaugeColorRange2__to', '10000');
await testSubjects.click('gaugePercentageMode');
await PageObjects.visualize.waitForVisualizationRenderingStabilized();
await PageObjects.visualize.clickGo();

View file

@ -2459,31 +2459,12 @@
"kbnVislibVisTypes.area.radiusTitle": "点のサイズ",
"kbnVislibVisTypes.area.segmentTitle": "X 軸",
"kbnVislibVisTypes.area.splitTitle": "チャートを分割",
"kbnVislibVisTypes.controls.gaugeOptions.addRangeTitle": "範囲を追加",
"kbnVislibVisTypes.controls.gaugeOptions.alignmentLabel": "アラインメント",
"kbnVislibVisTypes.controls.gaugeOptions.autoExtendRangeLabel": "範囲を自動拡張",
"kbnVislibVisTypes.controls.gaugeOptions.backTextColorLabel": "背景/文字の色",
"kbnVislibVisTypes.controls.gaugeOptions.colorLabel": "色",
"kbnVislibVisTypes.controls.gaugeOptions.colorLabelsLabel": "カラーラベル",
"kbnVislibVisTypes.controls.gaugeOptions.colorOptionsTitle": "カラーオプション",
"kbnVislibVisTypes.controls.gaugeOptions.colorSchemaLabel": "カラースキーム",
"kbnVislibVisTypes.controls.gaugeOptions.displayWarningsLabel": "警告を表示",
"kbnVislibVisTypes.controls.gaugeOptions.fontSizeLabel": "フォントサイズ ({fontSize} pt)",
"kbnVislibVisTypes.controls.gaugeOptions.fromTitle": "開始:",
"kbnVislibVisTypes.controls.gaugeOptions.gaugeTypeLabel": "ゲージタイプ",
"kbnVislibVisTypes.controls.gaugeOptions.howToChangeColorsDescription": "注: 色は凡例で変更できます",
"kbnVislibVisTypes.controls.gaugeOptions.percentageModeLabel": "パーセンテージモード",
"kbnVislibVisTypes.controls.gaugeOptions.rangesTitle": "範囲",
"kbnVislibVisTypes.controls.gaugeOptions.requiredText": "必須:",
"kbnVislibVisTypes.controls.gaugeOptions.resetColorsTitle": "色のリセット",
"kbnVislibVisTypes.controls.gaugeOptions.reverseColorSchemaLabel": "カラースキームを反転",
"kbnVislibVisTypes.controls.gaugeOptions.showLabelsLabel": "ラベルを表示",
"kbnVislibVisTypes.controls.gaugeOptions.showLegendLabel": "凡例を表示",
"kbnVislibVisTypes.controls.gaugeOptions.showScaleLabel": "スケールを表示",
"kbnVislibVisTypes.controls.gaugeOptions.specifiedRangeNumberWarningMessage": "{required} 範囲を最低 1 つ指定する必要があります。",
"kbnVislibVisTypes.controls.gaugeOptions.styleTitle": "スタイル",
"kbnVislibVisTypes.controls.gaugeOptions.subTextLabel": "サブテキスト",
"kbnVislibVisTypes.controls.gaugeOptions.toTitle": "To",
"kbnVislibVisTypes.controls.heatmapOptions.addRangeButtonLabel": "範囲を追加",
"kbnVislibVisTypes.controls.heatmapOptions.colorLabel": "色",
"kbnVislibVisTypes.controls.heatmapOptions.colorScaleLabel": "カラースケール",

View file

@ -2459,31 +2459,12 @@
"kbnVislibVisTypes.area.radiusTitle": "点大小",
"kbnVislibVisTypes.area.segmentTitle": "X 轴",
"kbnVislibVisTypes.area.splitTitle": "拆分图表",
"kbnVislibVisTypes.controls.gaugeOptions.addRangeTitle": "添加范围",
"kbnVislibVisTypes.controls.gaugeOptions.alignmentLabel": "对齐方式",
"kbnVislibVisTypes.controls.gaugeOptions.autoExtendRangeLabel": "自动扩展范围",
"kbnVislibVisTypes.controls.gaugeOptions.backTextColorLabel": "背景/文本颜色",
"kbnVislibVisTypes.controls.gaugeOptions.colorLabel": "颜色",
"kbnVislibVisTypes.controls.gaugeOptions.colorLabelsLabel": "颜色标签",
"kbnVislibVisTypes.controls.gaugeOptions.colorOptionsTitle": "颜色选项",
"kbnVislibVisTypes.controls.gaugeOptions.colorSchemaLabel": "颜色模式",
"kbnVislibVisTypes.controls.gaugeOptions.displayWarningsLabel": "显示警告",
"kbnVislibVisTypes.controls.gaugeOptions.fontSizeLabel": "字体大小({fontSize} 磅)",
"kbnVislibVisTypes.controls.gaugeOptions.fromTitle": "从",
"kbnVislibVisTypes.controls.gaugeOptions.gaugeTypeLabel": "仪表类型",
"kbnVislibVisTypes.controls.gaugeOptions.howToChangeColorsDescription": "注意:可以更改图例颜色",
"kbnVislibVisTypes.controls.gaugeOptions.percentageModeLabel": "百分比模式",
"kbnVislibVisTypes.controls.gaugeOptions.rangesTitle": "范围",
"kbnVislibVisTypes.controls.gaugeOptions.requiredText": "必需:",
"kbnVislibVisTypes.controls.gaugeOptions.resetColorsTitle": "重置颜色",
"kbnVislibVisTypes.controls.gaugeOptions.reverseColorSchemaLabel": "反色模式",
"kbnVislibVisTypes.controls.gaugeOptions.showLabelsLabel": "显示标签",
"kbnVislibVisTypes.controls.gaugeOptions.showLegendLabel": "显示图例",
"kbnVislibVisTypes.controls.gaugeOptions.showScaleLabel": "显示比例",
"kbnVislibVisTypes.controls.gaugeOptions.specifiedRangeNumberWarningMessage": "{required}您必须指定至少一个范围。",
"kbnVislibVisTypes.controls.gaugeOptions.styleTitle": "样式",
"kbnVislibVisTypes.controls.gaugeOptions.subTextLabel": "子文本",
"kbnVislibVisTypes.controls.gaugeOptions.toTitle": "到",
"kbnVislibVisTypes.controls.heatmapOptions.addRangeButtonLabel": "添加范围",
"kbnVislibVisTypes.controls.heatmapOptions.colorLabel": "颜色",
"kbnVislibVisTypes.controls.heatmapOptions.colorScaleLabel": "颜色比例",
@ -10629,4 +10610,4 @@
"xpack.watcher.watchActions.logging.logTextIsRequiredValidationMessage": "“日志文本”必填。",
"xpack.watcher.watcherDescription": "通过创建、管理和监测警报来检测数据中的更改。"
}
}
}