mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
Control round and decimal places in Gauge Visualization when using aggregate functions like average (#91293) (#93014)
* Add field for providing format in percentage mode * Fix CI * Add tests * Fix ci * Fix some remarks * Fix ci * Fix some remarks * Fix ci * Fix width * Fix some remarks * Fix text * Fix i18n * Remove unneeded import * Remove unneeded code Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
9a9739453c
commit
0772e207a2
27 changed files with 280 additions and 52 deletions
|
@ -15,3 +15,4 @@ export { NumberInputOption } from './number_input';
|
|||
export { RangeOption } from './range';
|
||||
export { RequiredNumberInputOption } from './required_number_input';
|
||||
export { TextInputOption } from './text_input';
|
||||
export { PercentageModeOption } from './percentage_mode';
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 { mountWithIntl } from '@kbn/test/jest';
|
||||
import { PercentageModeOption, PercentageModeOptionProps } from './percentage_mode';
|
||||
import { EuiFieldText } from '@elastic/eui';
|
||||
|
||||
describe('PercentageModeOption', () => {
|
||||
let props: PercentageModeOptionProps;
|
||||
let component;
|
||||
beforeAll(() => {
|
||||
props = {
|
||||
percentageMode: true,
|
||||
setValue: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
it('renders the EuiFieldText', () => {
|
||||
component = mountWithIntl(<PercentageModeOption {...props} />);
|
||||
expect(component.find(EuiFieldText).length).toBe(1);
|
||||
});
|
||||
|
||||
it('should call setValue when value was putted in fieldText', () => {
|
||||
component = mountWithIntl(<PercentageModeOption {...props} />);
|
||||
const fieldText = component.find(EuiFieldText);
|
||||
fieldText.props().onChange!({
|
||||
target: {
|
||||
value: '0.0%',
|
||||
},
|
||||
} as React.ChangeEvent<HTMLInputElement>);
|
||||
|
||||
expect(props.setValue).toHaveBeenCalledWith('percentageFormatPattern', '0.0%');
|
||||
});
|
||||
|
||||
it('fieldText should be disabled when percentageMode is false', () => {
|
||||
props.percentageMode = false;
|
||||
component = mountWithIntl(<PercentageModeOption {...props} />);
|
||||
const fieldText = component.find(EuiFieldText);
|
||||
|
||||
expect(fieldText.props().disabled).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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 { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiFieldText, EuiFormRow, EuiLink } from '@elastic/eui';
|
||||
import { SwitchOption } from './switch';
|
||||
import { useKibana } from '../../../../kibana_react/public';
|
||||
import { UI_SETTINGS } from '../../../../data/public';
|
||||
|
||||
export interface PercentageModeOptionProps {
|
||||
setValue: (
|
||||
paramName: 'percentageMode' | 'percentageFormatPattern',
|
||||
value: boolean | string | undefined
|
||||
) => void;
|
||||
percentageMode: boolean;
|
||||
formatPattern?: string;
|
||||
'data-test-subj'?: string;
|
||||
}
|
||||
|
||||
function PercentageModeOption({
|
||||
'data-test-subj': dataTestSubj,
|
||||
setValue,
|
||||
percentageMode,
|
||||
formatPattern,
|
||||
}: PercentageModeOptionProps) {
|
||||
const { services } = useKibana();
|
||||
const defaultPattern = services.uiSettings?.get(UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SwitchOption
|
||||
data-test-subj={dataTestSubj}
|
||||
label={i18n.translate('visDefaultEditor.options.percentageMode.percentageModeLabel', {
|
||||
defaultMessage: 'Percentage mode',
|
||||
})}
|
||||
paramName="percentageMode"
|
||||
value={percentageMode}
|
||||
setValue={setValue}
|
||||
/>
|
||||
<EuiFormRow
|
||||
fullWidth
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="visDefaultEditor.options.percentageMode.numeralLabel"
|
||||
defaultMessage="Format pattern"
|
||||
/>
|
||||
}
|
||||
helpText={
|
||||
<EuiLink target="_blank" href="https://adamwdraper.github.io/Numeral-js/">
|
||||
<FormattedMessage
|
||||
id="visDefaultEditor.options.percentageMode.documentationLabel"
|
||||
defaultMessage="Numeral.js documentation"
|
||||
/>
|
||||
</EuiLink>
|
||||
}
|
||||
>
|
||||
<EuiFieldText
|
||||
fullWidth
|
||||
compressed
|
||||
data-test-subj={`${dataTestSubj}FormatPattern`}
|
||||
value={formatPattern || ''}
|
||||
placeholder={defaultPattern}
|
||||
onChange={(e) => {
|
||||
setValue('percentageFormatPattern', e.target.value ? e.target.value : undefined);
|
||||
}}
|
||||
disabled={!percentageMode}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export { PercentageModeOption };
|
|
@ -26,6 +26,7 @@ import {
|
|||
SetColorSchemaOptionsValue,
|
||||
ColorSchemaOptions,
|
||||
RangeOption,
|
||||
PercentageModeOption,
|
||||
} from '../../../vis_default_editor/public';
|
||||
import { ColorMode, colorSchemas } from '../../../charts/public';
|
||||
import { MetricVisParam, VisParams } from '../types';
|
||||
|
@ -113,12 +114,10 @@ function MetricVisOptions({
|
|||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
<SwitchOption
|
||||
label={i18n.translate('visTypeMetric.params.percentageModeLabel', {
|
||||
defaultMessage: 'Percentage mode',
|
||||
})}
|
||||
paramName="percentageMode"
|
||||
value={stateParams.metric.percentageMode}
|
||||
<PercentageModeOption
|
||||
data-test-subj="metricPercentageMode"
|
||||
percentageMode={stateParams.metric.percentageMode}
|
||||
formatPattern={stateParams.metric.percentageFormatPattern}
|
||||
setValue={setMetricValue}
|
||||
/>
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ export const toExpressionAst: VisToExpressionAst<VisParams> = (vis, params) => {
|
|||
|
||||
const {
|
||||
percentageMode,
|
||||
percentageFormatPattern,
|
||||
useRanges,
|
||||
colorSchema,
|
||||
metricColorMode,
|
||||
|
@ -55,7 +56,10 @@ export const toExpressionAst: VisToExpressionAst<VisParams> = (vis, params) => {
|
|||
// fix formatter for percentage mode
|
||||
if (get(vis.params, 'metric.percentageMode') === true) {
|
||||
schemas.metric.forEach((metric: SchemaConfig) => {
|
||||
metric.format = { id: 'percent' };
|
||||
metric.format = {
|
||||
id: 'percent',
|
||||
params: { pattern: percentageFormatPattern },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ export interface DimensionsVisParam {
|
|||
|
||||
export interface MetricVisParam {
|
||||
percentageMode: boolean;
|
||||
percentageFormatPattern?: string;
|
||||
useRanges: boolean;
|
||||
colorSchema: ColorSchemas;
|
||||
metricColorMode: ColorMode;
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
SetColorRangeValue,
|
||||
SwitchOption,
|
||||
ColorSchemaOptions,
|
||||
PercentageModeOption,
|
||||
} from '../../../../../vis_default_editor/public';
|
||||
import { ColorSchemaParams, ColorSchemas, colorSchemas } from '../../../../../charts/public';
|
||||
import { GaugeOptionsInternalProps } from '../gauge';
|
||||
|
@ -77,13 +78,10 @@ function RangesPanel({
|
|||
setValue={setGaugeValue}
|
||||
/>
|
||||
|
||||
<SwitchOption
|
||||
<PercentageModeOption
|
||||
data-test-subj="gaugePercentageMode"
|
||||
label={i18n.translate('visTypeVislib.controls.gaugeOptions.percentageModeLabel', {
|
||||
defaultMessage: 'Percentage mode',
|
||||
})}
|
||||
paramName="percentageMode"
|
||||
value={stateParams.gauge.percentageMode}
|
||||
percentageMode={stateParams.gauge.percentageMode}
|
||||
formatPattern={stateParams.gauge.percentageFormatPattern}
|
||||
setValue={setGaugeValue}
|
||||
/>
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
SetColorSchemaOptionsValue,
|
||||
ColorSchemaOptions,
|
||||
NumberInputOption,
|
||||
PercentageModeOption,
|
||||
} from '../../../../../vis_default_editor/public';
|
||||
|
||||
import { HeatmapVisParams } from '../../../heatmap';
|
||||
|
@ -125,13 +126,10 @@ function HeatmapOptions(props: VisEditorOptionsProps<HeatmapVisParams>) {
|
|||
setValue={setValueAxisScale}
|
||||
/>
|
||||
|
||||
<SwitchOption
|
||||
disabled={stateParams.setColorRange}
|
||||
label={i18n.translate('visTypeVislib.controls.heatmapOptions.percentageModeLabel', {
|
||||
defaultMessage: 'Percentage mode',
|
||||
})}
|
||||
paramName="percentageMode"
|
||||
value={stateParams.setColorRange ? false : stateParams.percentageMode}
|
||||
<PercentageModeOption
|
||||
data-test-subj="metricPercentageMode"
|
||||
percentageMode={stateParams.setColorRange ? false : stateParams.percentageMode}
|
||||
formatPattern={stateParams.percentageFormatPattern}
|
||||
setValue={setValue}
|
||||
/>
|
||||
<EuiSpacer size="s" />
|
||||
|
|
|
@ -12,6 +12,9 @@ setFormatService({
|
|||
deserialize: () => ({
|
||||
convert: (v) => v,
|
||||
}),
|
||||
getInstance: () => ({
|
||||
convert: (v) => v,
|
||||
}),
|
||||
});
|
||||
|
||||
export const getMockUiState = () => {
|
||||
|
|
|
@ -28,6 +28,7 @@ export interface Gauge extends ColorSchemaParams {
|
|||
gaugeType: GaugeType;
|
||||
labels: Labels;
|
||||
percentageMode: boolean;
|
||||
percentageFormatPattern?: string;
|
||||
outline?: boolean;
|
||||
scale: {
|
||||
show: boolean;
|
||||
|
|
|
@ -29,6 +29,7 @@ export interface HeatmapVisParams extends CommonVislibParams, ColorSchemaParams
|
|||
valueAxes: ValueAxis[];
|
||||
setColorRange: boolean;
|
||||
percentageMode: boolean;
|
||||
percentageFormatPattern?: string;
|
||||
times: TimeMarker[];
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,10 @@ export const toExpressionAst = async <TVisParams extends VisParams>(
|
|||
}
|
||||
}
|
||||
if (visConfig?.gauge?.percentageMode === true) {
|
||||
yDimension.format = { id: 'percent' };
|
||||
yDimension.format = {
|
||||
id: 'percent',
|
||||
params: { pattern: visConfig?.gauge?.percentageFormatPattern },
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -6,14 +6,33 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { last } from 'lodash';
|
||||
import React from 'react';
|
||||
import { renderToStaticMarkup } from 'react-dom/server';
|
||||
import { UI_SETTINGS } from '../../../../../../plugins/data/public';
|
||||
import { getValueForPercentageMode } from '../../percentage_mode_transform';
|
||||
|
||||
function getMax(handler, config, isGauge) {
|
||||
let max;
|
||||
if (handler.pointSeries) {
|
||||
const series = handler.pointSeries.getSeries();
|
||||
const scale = series.getValueAxis().getScale();
|
||||
max = scale.domain()[1];
|
||||
} else {
|
||||
max = last(config.get(isGauge ? 'gauge.colorsRange' : 'colorsRange', [{}])).to;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
export function pointSeriesTooltipFormatter() {
|
||||
return function tooltipFormatter({ datum, data }) {
|
||||
return function tooltipFormatter({ datum, data, config, handler }, uiSettings) {
|
||||
if (!datum) return '';
|
||||
|
||||
const details = [];
|
||||
const isGauge = config.get('gauge', false);
|
||||
const isPercentageMode = config.get(isGauge ? 'gauge.percentageMode' : 'percentageMode', false);
|
||||
const isSetColorRange = config.get('setColorRange', false);
|
||||
|
||||
const currentSeries =
|
||||
data.series && data.series.find((serie) => serie.rawId === datum.seriesId);
|
||||
|
@ -30,8 +49,20 @@ export function pointSeriesTooltipFormatter() {
|
|||
}
|
||||
|
||||
if (datum.y !== null && datum.y !== undefined) {
|
||||
const value = datum.yScale ? datum.yScale * datum.y : datum.y;
|
||||
addDetail(currentSeries.label, currentSeries.yAxisFormatter(value));
|
||||
let value = datum.yScale ? datum.yScale * datum.y : datum.y;
|
||||
if (isPercentageMode && !isSetColorRange) {
|
||||
const percentageFormatPattern = config.get(
|
||||
isGauge ? 'gauge.percentageFormatPattern' : 'percentageFormatPattern',
|
||||
uiSettings.get(UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN)
|
||||
);
|
||||
value = getValueForPercentageMode(
|
||||
value / getMax(handler, config, isGauge),
|
||||
percentageFormatPattern
|
||||
);
|
||||
addDetail(currentSeries.label, value);
|
||||
} else {
|
||||
addDetail(currentSeries.label, currentSeries.yAxisFormatter(value));
|
||||
}
|
||||
}
|
||||
|
||||
if (datum.z !== null && datum.z !== undefined) {
|
||||
|
|
|
@ -43,11 +43,36 @@ describe('tooltipFormatter', function () {
|
|||
extraMetrics: [],
|
||||
seriesId: '1',
|
||||
},
|
||||
config: {
|
||||
get: (name) => {
|
||||
const config = {
|
||||
setColorRange: false,
|
||||
gauge: false,
|
||||
percentageMode: false,
|
||||
};
|
||||
return config[name];
|
||||
},
|
||||
},
|
||||
handler: {
|
||||
pointSeries: {
|
||||
getSeries: () => ({
|
||||
getValueAxis: () => ({
|
||||
getScale: () => ({
|
||||
domain: () => [0, 10],
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const uiSettings = {
|
||||
get: () => '',
|
||||
};
|
||||
|
||||
it('returns html based on the mouse event', function () {
|
||||
const event = _.cloneDeep(baseEvent);
|
||||
const $el = $(tooltipFormatter(event));
|
||||
const $el = $(tooltipFormatter(event, uiSettings));
|
||||
const $rows = $el.find('tr');
|
||||
expect($rows.length).toBe(3);
|
||||
|
||||
|
@ -67,7 +92,7 @@ describe('tooltipFormatter', function () {
|
|||
it('renders correctly on missing extraMetrics in datum', function () {
|
||||
const event = _.cloneDeep(baseEvent);
|
||||
delete event.datum.extraMetrics;
|
||||
const $el = $(tooltipFormatter(event));
|
||||
const $el = $(tooltipFormatter(event, uiSettings));
|
||||
const $rows = $el.find('tr');
|
||||
expect($rows.length).toBe(3);
|
||||
});
|
||||
|
|
|
@ -29,9 +29,9 @@ const tooltipMaxWidth = parseInt(theme.euiSizeXL || 0, 10) * 10;
|
|||
* @param formatter {Function} Tooltip formatter
|
||||
* @param events {Constructor} Allows tooltip to return event response data
|
||||
*/
|
||||
export function Tooltip(id, el, formatter, events) {
|
||||
export function Tooltip(id, el, formatter, events, uiSettings) {
|
||||
if (!(this instanceof Tooltip)) {
|
||||
return new Tooltip(id, el, formatter, events);
|
||||
return new Tooltip(id, el, formatter, events, uiSettings);
|
||||
}
|
||||
|
||||
this.id = id; // unique id for this tooltip type
|
||||
|
@ -39,6 +39,7 @@ export function Tooltip(id, el, formatter, events) {
|
|||
this.order = 100; // higher ordered contents are rendered below the others
|
||||
this.formatter = formatter;
|
||||
this.events = events;
|
||||
this.uiSettings = uiSettings;
|
||||
this.containerClass = 'visWrapper';
|
||||
this.tooltipClass = 'visTooltip';
|
||||
this.tooltipSizerClass = 'visTooltip__sizingClone';
|
||||
|
@ -223,7 +224,7 @@ Tooltip.prototype.render = function () {
|
|||
}
|
||||
|
||||
const events = self.events ? self.events.eventResponse(d, i) : d;
|
||||
return render(self.formatter(events));
|
||||
return render(self.formatter(events, self.uiSettings));
|
||||
});
|
||||
|
||||
self.binder.fakeD3Bind(this, 'mouseleave', function () {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// @ts-ignore
|
||||
import numeral from '@elastic/numeral';
|
||||
import { getFormatService } from '../services';
|
||||
|
||||
export function getValueForPercentageMode(value: string | number, percentageFormatPattern: string) {
|
||||
const formatServices = getFormatService();
|
||||
const percentFormatter = formatServices.getInstance('percent', {
|
||||
pattern: percentageFormatPattern,
|
||||
});
|
||||
|
||||
return percentFormatter.convert(value);
|
||||
}
|
|
@ -49,7 +49,7 @@ export class Chart {
|
|||
const element = this.handler.el;
|
||||
|
||||
// Add tooltip
|
||||
this.tooltip = new Tooltip('chart', element, tooltipFormatter, events);
|
||||
this.tooltip = new Tooltip('chart', element, tooltipFormatter, events, uiSettings);
|
||||
this.tooltips.push(this.tooltip);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ export class GaugeChart extends Chart {
|
|||
constructor(handler, chartEl, chartData, uiSettings) {
|
||||
super(handler, chartEl, chartData, uiSettings);
|
||||
this.gaugeConfig = handler.visConfig.get('gauge', {});
|
||||
this.gauge = new gaugeTypes[this.gaugeConfig.type](this);
|
||||
this.gauge = new gaugeTypes[this.gaugeConfig.type](this, uiSettings);
|
||||
}
|
||||
|
||||
addEvents(element) {
|
||||
|
|
|
@ -10,6 +10,8 @@ import d3 from 'd3';
|
|||
import _ from 'lodash';
|
||||
|
||||
import { getHeatmapColors } from '../../../../../charts/public';
|
||||
import { UI_SETTINGS } from '../../../../../data/public';
|
||||
import { getValueForPercentageMode } from '../../percentage_mode_transform';
|
||||
|
||||
const arcAngles = {
|
||||
angleFactor: 0.75,
|
||||
|
@ -47,9 +49,10 @@ const defaultConfig = {
|
|||
};
|
||||
|
||||
export class MeterGauge {
|
||||
constructor(gaugeChart) {
|
||||
constructor(gaugeChart, uiSettings) {
|
||||
this.gaugeChart = gaugeChart;
|
||||
this.gaugeConfig = gaugeChart.gaugeConfig;
|
||||
this.uiSettings = uiSettings;
|
||||
this.gaugeConfig = _.defaultsDeep(this.gaugeConfig, defaultConfig);
|
||||
|
||||
this.gaugeChart.handler.visConfig.set('legend', {
|
||||
|
@ -68,12 +71,19 @@ export class MeterGauge {
|
|||
|
||||
getLabels() {
|
||||
const isPercentageMode = this.gaugeConfig.percentageMode;
|
||||
const percentageFormatPattern =
|
||||
this.gaugeConfig.percentageFormatPattern ||
|
||||
this.uiSettings.get(UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN);
|
||||
const colorsRange = this.gaugeConfig.colorsRange;
|
||||
const max = _.last(colorsRange).to;
|
||||
const labels = [];
|
||||
colorsRange.forEach((range) => {
|
||||
const from = isPercentageMode ? Math.round((100 * range.from) / max) : range.from;
|
||||
const to = isPercentageMode ? Math.round((100 * range.to) / max) : range.to;
|
||||
const from = isPercentageMode
|
||||
? getValueForPercentageMode(range.from / max, percentageFormatPattern)
|
||||
: range.from;
|
||||
const to = isPercentageMode
|
||||
? getValueForPercentageMode(range.to / max, percentageFormatPattern)
|
||||
: range.to;
|
||||
labels.push(`${from} - ${to}`);
|
||||
});
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ const defaults = {
|
|||
* chart
|
||||
*/
|
||||
export class AreaChart extends PointSeries {
|
||||
constructor(handler, chartEl, chartData, seriesConfigArgs, core) {
|
||||
super(handler, chartEl, chartData, seriesConfigArgs, core);
|
||||
constructor(handler, chartEl, chartData, seriesConfigArgs, uiSettings) {
|
||||
super(handler, chartEl, chartData, seriesConfigArgs, uiSettings);
|
||||
|
||||
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
|
||||
this.isOverlapping = this.seriesConfig.mode !== 'stacked';
|
||||
|
|
|
@ -46,8 +46,8 @@ function datumWidth(defaultWidth, datum, nextDatum, scale, gutterWidth, groupCou
|
|||
* @param chartData {Object} Elasticsearch query results for this specific chart
|
||||
*/
|
||||
export class ColumnChart extends PointSeries {
|
||||
constructor(handler, chartEl, chartData, seriesConfigArgs, core) {
|
||||
super(handler, chartEl, chartData, seriesConfigArgs, core);
|
||||
constructor(handler, chartEl, chartData, seriesConfigArgs, uiSettings) {
|
||||
super(handler, chartEl, chartData, seriesConfigArgs, uiSettings);
|
||||
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
|
||||
this.labelOptions = _.defaults(handler.visConfig.get('labels', {}), defaults.showLabel);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import { isColorDark } from '@elastic/eui';
|
|||
|
||||
import { PointSeries } from './_point_series';
|
||||
import { getHeatmapColors } from '../../../../../../plugins/charts/public';
|
||||
import { UI_SETTINGS } from '../../../../../../plugins/data/public';
|
||||
import { getValueForPercentageMode } from '../../percentage_mode_transform';
|
||||
|
||||
const defaults = {
|
||||
color: undefined, // todo
|
||||
|
@ -29,8 +31,10 @@ const defaults = {
|
|||
* @param chartData {Object} Elasticsearch query results for this specific chart
|
||||
*/
|
||||
export class HeatmapChart extends PointSeries {
|
||||
constructor(handler, chartEl, chartData, seriesConfigArgs, core) {
|
||||
super(handler, chartEl, chartData, seriesConfigArgs, core);
|
||||
constructor(handler, chartEl, chartData, seriesConfigArgs, uiSettings) {
|
||||
super(handler, chartEl, chartData, seriesConfigArgs, uiSettings);
|
||||
|
||||
this.uiSettings = uiSettings;
|
||||
|
||||
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
|
||||
|
||||
|
@ -48,6 +52,10 @@ export class HeatmapChart extends PointSeries {
|
|||
|
||||
getHeatmapLabels(cfg) {
|
||||
const percentageMode = cfg.get('percentageMode');
|
||||
const percentageFormatPattern = cfg.get(
|
||||
'percentageFormatPattern',
|
||||
this.uiSettings.get(UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN)
|
||||
);
|
||||
const colorsNumber = cfg.get('colorsNumber');
|
||||
const colorsRange = cfg.get('colorsRange');
|
||||
const zAxisConfig = this.getValueAxis().axisConfig;
|
||||
|
@ -71,9 +79,9 @@ export class HeatmapChart extends PointSeries {
|
|||
let val = i / colorsNumber;
|
||||
let nextVal = (i + 1) / colorsNumber;
|
||||
if (percentageMode) {
|
||||
val = Math.ceil(val * 100);
|
||||
nextVal = Math.ceil(nextVal * 100);
|
||||
label = `${val}% - ${nextVal}%`;
|
||||
val = getValueForPercentageMode(val, percentageFormatPattern);
|
||||
nextVal = getValueForPercentageMode(nextVal, percentageFormatPattern);
|
||||
label = `${val} - ${nextVal}`;
|
||||
} else {
|
||||
val = val * (max - min) + min;
|
||||
nextVal = nextVal * (max - min) + min;
|
||||
|
|
|
@ -68,6 +68,7 @@ describe('Vislib Heatmap Chart Test Suite', function () {
|
|||
colorSchema: 'Greens',
|
||||
setColorRange: false,
|
||||
percentageMode: true,
|
||||
percentageFormatPattern: '0.0%',
|
||||
invertColors: false,
|
||||
colorsRange: [],
|
||||
};
|
||||
|
|
|
@ -31,8 +31,8 @@ const defaults = {
|
|||
* @param chartData {Object} Elasticsearch query results for this specific chart
|
||||
*/
|
||||
export class LineChart extends PointSeries {
|
||||
constructor(handler, chartEl, chartData, seriesConfigArgs, core) {
|
||||
super(handler, chartEl, chartData, seriesConfigArgs, core);
|
||||
constructor(handler, chartEl, chartData, seriesConfigArgs, uiSettings) {
|
||||
super(handler, chartEl, chartData, seriesConfigArgs, uiSettings);
|
||||
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,11 +51,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.visEditor.clickOptionsTab();
|
||||
await testSubjects.setValue('gaugeColorRange2__to', '10000');
|
||||
await testSubjects.click('gaugePercentageMode');
|
||||
await testSubjects.setValue('gaugePercentageModeFormatPattern', '0.0%');
|
||||
await PageObjects.visChart.waitForVisualizationRenderingStabilized();
|
||||
await PageObjects.visEditor.clickGo();
|
||||
|
||||
await retry.try(async function tryingForTime() {
|
||||
const expectedTexts = ['57.273%', 'Average bytes'];
|
||||
const expectedTexts = ['57.3%', 'Average bytes'];
|
||||
const metricValue = await PageObjects.visChart.getGaugeValue();
|
||||
expect(expectedTexts).to.eql(metricValue);
|
||||
});
|
||||
|
|
|
@ -3885,7 +3885,6 @@
|
|||
"visTypeMetric.metricDescription": "計算結果を単独の数字として表示します。",
|
||||
"visTypeMetric.metricTitle": "メトリック",
|
||||
"visTypeMetric.params.color.useForLabel": "使用する色",
|
||||
"visTypeMetric.params.percentageModeLabel": "百分率モード",
|
||||
"visTypeMetric.params.rangesTitle": "範囲",
|
||||
"visTypeMetric.params.settingsTitle": "設定",
|
||||
"visTypeMetric.params.showTitleLabel": "タイトルを表示",
|
||||
|
@ -4570,7 +4569,6 @@
|
|||
"visTypeVislib.controls.gaugeOptions.extendRangeTooltip": "範囲をデータの最高値に広げます。",
|
||||
"visTypeVislib.controls.gaugeOptions.gaugeTypeLabel": "ゲージタイプ",
|
||||
"visTypeVislib.controls.gaugeOptions.labelsTitle": "ラベル",
|
||||
"visTypeVislib.controls.gaugeOptions.percentageModeLabel": "百分率モード",
|
||||
"visTypeVislib.controls.gaugeOptions.rangesTitle": "範囲",
|
||||
"visTypeVislib.controls.gaugeOptions.showLabelsLabel": "ラベルを表示",
|
||||
"visTypeVislib.controls.gaugeOptions.showLegendLabel": "凡例を表示",
|
||||
|
@ -4584,7 +4582,6 @@
|
|||
"visTypeVislib.controls.heatmapOptions.colorsNumberLabel": "色の数",
|
||||
"visTypeVislib.controls.heatmapOptions.labelsTitle": "ラベル",
|
||||
"visTypeVislib.controls.heatmapOptions.overwriteAutomaticColorLabel": "自動からーを上書きする",
|
||||
"visTypeVislib.controls.heatmapOptions.percentageModeLabel": "百分率モード",
|
||||
"visTypeVislib.controls.heatmapOptions.rotateLabel": "回転",
|
||||
"visTypeVislib.controls.heatmapOptions.scaleToDataBoundsLabel": "データバウンドに合わせる",
|
||||
"visTypeVislib.controls.heatmapOptions.showLabelsTitle": "ラベルを表示",
|
||||
|
|
|
@ -3889,7 +3889,6 @@
|
|||
"visTypeMetric.metricDescription": "将计算结果显示为单个数字。",
|
||||
"visTypeMetric.metricTitle": "指标",
|
||||
"visTypeMetric.params.color.useForLabel": "将颜色用于",
|
||||
"visTypeMetric.params.percentageModeLabel": "百分比模式",
|
||||
"visTypeMetric.params.rangesTitle": "范围",
|
||||
"visTypeMetric.params.settingsTitle": "设置",
|
||||
"visTypeMetric.params.showTitleLabel": "显示标题",
|
||||
|
@ -4575,7 +4574,6 @@
|
|||
"visTypeVislib.controls.gaugeOptions.extendRangeTooltip": "将数据范围扩展到数据中的最大值。",
|
||||
"visTypeVislib.controls.gaugeOptions.gaugeTypeLabel": "仪表类型",
|
||||
"visTypeVislib.controls.gaugeOptions.labelsTitle": "标签",
|
||||
"visTypeVislib.controls.gaugeOptions.percentageModeLabel": "百分比模式",
|
||||
"visTypeVislib.controls.gaugeOptions.rangesTitle": "范围",
|
||||
"visTypeVislib.controls.gaugeOptions.showLabelsLabel": "显示标签",
|
||||
"visTypeVislib.controls.gaugeOptions.showLegendLabel": "显示图例",
|
||||
|
@ -4589,7 +4587,6 @@
|
|||
"visTypeVislib.controls.heatmapOptions.colorsNumberLabel": "颜色个数",
|
||||
"visTypeVislib.controls.heatmapOptions.labelsTitle": "标签",
|
||||
"visTypeVislib.controls.heatmapOptions.overwriteAutomaticColorLabel": "覆盖自动配色",
|
||||
"visTypeVislib.controls.heatmapOptions.percentageModeLabel": "百分比模式",
|
||||
"visTypeVislib.controls.heatmapOptions.rotateLabel": "旋转",
|
||||
"visTypeVislib.controls.heatmapOptions.scaleToDataBoundsLabel": "缩放到数据边界",
|
||||
"visTypeVislib.controls.heatmapOptions.showLabelsTitle": "显示标签",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue