Skip to content

Commit

Permalink
Hide gauge labels when value is hidden (elastic#34171)
Browse files Browse the repository at this point in the history
* Hide gauge labels when value is hidden

* Only hide subtext when value is hidden

* Use better free space calculation

* Fix tests
  • Loading branch information
timroes committed Apr 1, 2019
1 parent 614046f commit 39663b6
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 32 deletions.
71 changes: 46 additions & 25 deletions src/legacy/ui/public/vislib/visualizations/gauges/meter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -201,7 +217,6 @@ export function MeterGaugeProvider() {
return Math.max(0, radius(j) - gaugePadding);
});


const bgArc = d3.svg.arc()
.startAngle(minAngle)
.endAngle(maxAngle)
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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);
}
Expand Down
12 changes: 6 additions & 6 deletions test/functional/apps/visualize/_gauge_chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});

Expand All @@ -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');
Expand Down
7 changes: 6 additions & 1 deletion test/functional/page_objects/visualize_page.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,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() {
Expand Down

0 comments on commit 39663b6

Please sign in to comment.