diff --git a/src/legacy/ui/public/vislib/visualizations/gauges/meter.js b/src/legacy/ui/public/vislib/visualizations/gauges/meter.js index d77f72342b0f..5642c6e76c4d 100644 --- a/src/legacy/ui/public/vislib/visualizations/gauges/meter.js +++ b/src/legacy/ui/public/vislib/visualizations/gauges/meter.js @@ -189,6 +189,22 @@ export function MeterGaugeProvider() { const totalWidth = Math.abs(radius(0) - radius(1)); const bgPadding = totalWidth * (1 - this.gaugeConfig.style.bgWidth) / 2; const gaugePadding = totalWidth * (1 - this.gaugeConfig.style.width) / 2; + + /** + * Function to calculate the free space in the center of the gauge. This takes into account + * whether ticks are enabled or not. + * + * This is calculated using the inner diameter (radius(1) * 2) of the gauge. + * If ticks/scale are enabled we need to still subtract the tick length * 2 to make space for a tick + * on every side. If ticks/scale are disabled, the radius(1) function actually leaves space for the scale, + * so we add that free space (which is expressed via the paddings, we just use the larger of those) to the diameter. + */ + const getInnerFreeSpace = () => (radius(1) * 2) - + (this.gaugeConfig.scale.show + ? this.gaugeConfig.scale.tickLength * 2 + : -Math.max(bgPadding, gaugePadding) * 2 + ); + const arc = d3.svg.arc() .startAngle(minAngle) .endAngle(function (d) { @@ -201,7 +217,6 @@ export function MeterGaugeProvider() { return Math.max(0, radius(j) - gaugePadding); }); - const bgArc = d3.svg.arc() .startAngle(minAngle) .endAngle(maxAngle) @@ -241,6 +256,35 @@ export function MeterGaugeProvider() { const smallContainer = svg.node().getBBox().height < 70; let hiddenLabels = smallContainer; + // If the value label is hidden we later want to hide also all other labels + // since they don't make sense as long as the actual value is hidden. + let valueLabelHidden = false; + + gauges + .append('text') + .attr('class', 'chart-label') + .attr('y', -5) + .text(d => { + if (this.gaugeConfig.percentageMode) { + const percentage = Math.round(100 * (d.y - min) / (max - min)); + return `${percentage}%`; + } + return data.yAxisFormatter(d.y); + }) + .attr('style', 'dominant-baseline: central;') + .style('text-anchor', 'middle') + .style('font-size', '2em') + .style('display', function () { + const textLength = this.getBBox().width; + // The text is too long if it's larger than the inner free space minus a couple of random pixels for padding. + const textTooLong = textLength >= getInnerFreeSpace() - 6; + if (textTooLong) { + hiddenLabels = true; + valueLabelHidden = true; + } + return textTooLong ? 'none' : 'initial'; + }); + if (this.gaugeConfig.labels.show) { svg .append('text') @@ -269,33 +313,10 @@ export function MeterGaugeProvider() { if (textTooLong) { hiddenLabels = true; } - return smallContainer || textTooLong ? 'none' : 'initial'; + return valueLabelHidden || smallContainer || textTooLong ? 'none' : 'initial'; }); } - gauges - .append('text') - .attr('class', 'chart-label') - .attr('y', -5) - .text(d => { - if (this.gaugeConfig.percentageMode) { - const percentage = Math.round(100 * (d.y - min) / (max - min)); - return `${percentage}%`; - } - return data.yAxisFormatter(d.y); - }) - .attr('style', 'dominant-baseline: central;') - .style('text-anchor', 'middle') - .style('font-size', '2em') - .style('display', function () { - const textLength = this.getBBox().width; - const textTooLong = textLength > maxRadius; - if (textTooLong) { - hiddenLabels = true; - } - return textTooLong ? 'none' : 'initial'; - }); - if (this.gaugeConfig.scale.show) { this.drawScale(svg, radius(1), angle); } diff --git a/test/functional/apps/visualize/_gauge_chart.js b/test/functional/apps/visualize/_gauge_chart.js index d58a2cab872b..55f0d4eaac61 100644 --- a/test/functional/apps/visualize/_gauge_chart.js +++ b/test/functional/apps/visualize/_gauge_chart.js @@ -49,7 +49,7 @@ export default function ({ getService, getPageObjects }) { // initial metric of "Count" is selected by default return retry.try(async function tryingForTime() { const metricValue = await PageObjects.visualize.getGaugeValue(); - expect(expectedCount).to.eql(metricValue[0].split('\n')); + expect(expectedCount).to.eql(metricValue); }); }); @@ -67,16 +67,16 @@ export default function ({ getService, getPageObjects }) { await retry.try(async () => { expect(await PageObjects.visualize.getGaugeValue()).to.eql([ - 'win 8', - 'win xp', - 'win 7', - 'ios' + '2,904', 'win 8', + '2,858', 'win xp', + '2,814', 'win 7', + '2,784', 'ios', ]); }); }); it('should show correct values for fields with fieldFormatters', async function () { - const expectedTexts = [ '2,904\nwin 8: Count', '0B\nwin 8: Min bytes' ]; + const expectedTexts = [ '2,904', 'win 8: Count', '0B', 'win 8: Min bytes' ]; await PageObjects.visualize.clickMetricEditor(); await PageObjects.visualize.selectAggregation('Terms'); diff --git a/test/functional/page_objects/visualize_page.js b/test/functional/page_objects/visualize_page.js index 94f951bd793c..8e7f0bf9bc6d 100644 --- a/test/functional/page_objects/visualize_page.js +++ b/test/functional/page_objects/visualize_page.js @@ -386,7 +386,12 @@ export function VisualizePageProvider({ getService, getPageObjects, updateBaseli async getGaugeValue() { const elements = await find.allByCssSelector('[data-test-subj="visualizationLoader"] .chart svg'); - return await Promise.all(elements.map(async element => await element.getVisibleText())); + const values = await Promise.all(elements.map(async element => { + const text = await element.getVisibleText(); + return text.split('\n'); + })); + // .flat() replacement + return values.reduce((acc, val) => [...acc, ...val], []); } async clickMetricEditor() {