mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
parent
7fff53fcb8
commit
45bd78ca38
5 changed files with 97 additions and 19 deletions
|
@ -22,7 +22,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="kuiSideBarFormRow">
|
||||
<div class="kuiSideBarFormRow" ng-hide="vis.params.gauge.type === 'simple'">
|
||||
<label class="kuiSideBarFormRow__label" for="verticalSplit">
|
||||
Vertical Split
|
||||
<kbn-info
|
||||
|
@ -35,6 +35,15 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="kuiSideBarFormRow">
|
||||
<label class="kuiSideBarFormRow__label" for="addLegend">
|
||||
Show Legend
|
||||
</label>
|
||||
<div class="kuiSideBarFormRow__control">
|
||||
<input class="kuiCheckBox" id="addLegend" type="checkbox" ng-model="vis.params.addLegend">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="kuiSideBarFormRow">
|
||||
<label class="kuiSideBarFormRow__label" for="showLabels">
|
||||
Show Labels
|
||||
|
|
|
@ -32,7 +32,7 @@ module.exports = {
|
|||
'series': 'win 8'
|
||||
}]
|
||||
}, {
|
||||
'label': 'win xp',
|
||||
'label': 'windows xp service pack 2 version 20123452',
|
||||
'aggLabel': 'Count',
|
||||
'aggId': '1',
|
||||
'values': [{
|
||||
|
|
|
@ -49,6 +49,7 @@ describe('Vislib Gauge Chart Test Suite', function () {
|
|||
maskBars: 50,
|
||||
bgFill: '#eee',
|
||||
subText: '',
|
||||
fontSize: 32
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -141,4 +142,11 @@ describe('Vislib Gauge Chart Test Suite', function () {
|
|||
'rgb(247, 251, 255)'
|
||||
]);
|
||||
});
|
||||
|
||||
it('label can split into multiple lines', function () {
|
||||
generateVis({
|
||||
gauge: { type: 'simple' }
|
||||
});
|
||||
expect($(chartEl).find('svg:nth-child(4) > g > text > tspan').length).to.be.above(0);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -31,27 +31,48 @@ export function GaugeChartProvider(Private) {
|
|||
return function (selection) {
|
||||
selection.each(function (data) {
|
||||
const div = d3.select(this);
|
||||
const containerMargin = 5;
|
||||
const containerMargin = 20;
|
||||
const containerWidth = $(this).width() - containerMargin;
|
||||
const containerHeight = $(this).height() - containerMargin;
|
||||
const width = Math.floor(verticalSplit ? $(this).width() : containerWidth / data.series.length);
|
||||
const height = Math.floor((verticalSplit ? containerHeight / data.series.length : $(this).height()) - 25);
|
||||
const transformX = width / 2;
|
||||
const transformY = self.gaugeConfig.gaugeType === 'Meter' ? height / 1.5 : height / 2;
|
||||
|
||||
|
||||
div
|
||||
.style('text-align', 'center')
|
||||
.style('overflow-y', 'auto');
|
||||
|
||||
data.series.forEach(series => {
|
||||
const svg = div.append('svg')
|
||||
.attr('width', width)
|
||||
.attr('height', height)
|
||||
.style('display', 'inline-block')
|
||||
.style('overflow', 'hidden');
|
||||
.style('overflow', 'hidden')
|
||||
.attr('width', width);
|
||||
|
||||
const g = svg.append('g')
|
||||
.attr('transform', `translate(${transformX}, ${transformY})`);
|
||||
const g = svg.append('g');
|
||||
|
||||
const gauges = self.gauge.drawGauge(g, series, width, height);
|
||||
|
||||
if (self.gaugeConfig.type === 'simple') {
|
||||
const bbox = svg.node().children[0].getBBox();
|
||||
const finalWidth = bbox.width + containerMargin * 2;
|
||||
const finalHeight = bbox.height + containerMargin * 2;
|
||||
svg
|
||||
.attr('width', () => {
|
||||
return finalWidth;
|
||||
})
|
||||
.attr('height', () => {
|
||||
return finalHeight;
|
||||
});
|
||||
|
||||
const transformX = finalWidth / 2;
|
||||
const transformY = finalHeight / 2;
|
||||
g.attr('transform', `translate(${transformX}, ${transformY})`);
|
||||
} else {
|
||||
svg.attr('height', height);
|
||||
const transformX = width / 2;
|
||||
const transformY = height / 2;
|
||||
g.attr('transform', `translate(${transformX}, ${transformY})`);
|
||||
}
|
||||
|
||||
self.addEvents(gauges);
|
||||
});
|
||||
|
||||
|
|
|
@ -100,6 +100,37 @@ export function SimpleGaugeProvider() {
|
|||
return this.colorFunc(labels[bucket]);
|
||||
}
|
||||
|
||||
wrapText(texts, width) {
|
||||
texts.each(function () {
|
||||
const text = d3.select(this);
|
||||
const words = text.text().split(/\s+/).reverse();
|
||||
const lineHeight = 1.1;
|
||||
const y = text.attr('y');
|
||||
const dy = parseFloat(text.attr('dy'));
|
||||
let word;
|
||||
let lineNumber = 0;
|
||||
let line = [];
|
||||
let tspan = text.text(null).append('tspan')
|
||||
.attr('x', 0)
|
||||
.attr('y', y)
|
||||
.attr('dy', dy + 'em');
|
||||
while (word = words.pop()) {
|
||||
line.push(word);
|
||||
tspan.text(line.join(' '));
|
||||
if (tspan.node().getComputedTextLength() > width) {
|
||||
line.pop();
|
||||
tspan.text(line.join(' '));
|
||||
line = [ word ];
|
||||
tspan = text.append('tspan')
|
||||
.attr('x', 0)
|
||||
.attr('y', y)
|
||||
.attr('dy', ++lineNumber * lineHeight + dy + 'em')
|
||||
.text(word);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
drawGauge(svg, data, width) {
|
||||
const tooltip = this.gaugeChart.tooltip;
|
||||
const isTooltip = this.gaugeChart.handler.visConfig.get('addTooltip');
|
||||
|
@ -128,10 +159,10 @@ export function SimpleGaugeProvider() {
|
|||
const self = this;
|
||||
const series = gauges
|
||||
.append('rect')
|
||||
.attr('x', '-50%')
|
||||
.attr('y', '-50%')
|
||||
.attr('width', '99%')
|
||||
.attr('height', '99%')
|
||||
.attr('x', '-45%')
|
||||
.attr('y', '-45%')
|
||||
.attr('width', '90%')
|
||||
.attr('height', '90%')
|
||||
.style('fill', function (d) {
|
||||
return bgColor ? self.getColorBucket(d.y) : 'transparent';
|
||||
});
|
||||
|
@ -154,8 +185,14 @@ export function SimpleGaugeProvider() {
|
|||
.append('text')
|
||||
.attr('class', 'chart-label')
|
||||
.text(data.label)
|
||||
.attr('y', Math.min(-25, -fontSize))
|
||||
.attr('style', 'dominant-baseline: central; text-anchor: middle;')
|
||||
.attr('dy', 0)
|
||||
.attr('style', 'dominant-baseline: central; text-anchor: middle; pointer-events: none;')
|
||||
.call(this.wrapText, width)
|
||||
.attr('y', function () {
|
||||
const textMargin = 10;
|
||||
const height = this.getBBox().height;
|
||||
return (-fontSize / 2) - height - textMargin;
|
||||
})
|
||||
.style('display', isTextTooLong)
|
||||
.style('fill', bgFill);
|
||||
|
||||
|
@ -164,7 +201,9 @@ export function SimpleGaugeProvider() {
|
|||
.attr('class', 'chart-label')
|
||||
.text(this.gaugeConfig.style.subText)
|
||||
.attr('y', Math.max(15, fontSize))
|
||||
.attr('style', 'dominant-baseline: central; text-anchor: middle;')
|
||||
.attr('dy', 0)
|
||||
.attr('style', 'dominant-baseline: central; text-anchor: middle; pointer-events: none;')
|
||||
.call(this.wrapText, width)
|
||||
.style('display', isTextTooLong)
|
||||
.style('fill', bgFill);
|
||||
}
|
||||
|
@ -183,7 +222,8 @@ export function SimpleGaugeProvider() {
|
|||
}
|
||||
return d.y;
|
||||
})
|
||||
.attr('style', 'dominant-baseline: central; font-weight: bold; white-space: nowrap;text-overflow: ellipsis;overflow: hidden;')
|
||||
.attr('style', `dominant-baseline: central; font-weight: bold; white-space: nowrap;
|
||||
text-overflow: ellipsis;overflow: hidden; pointer-events: none;`)
|
||||
.style('text-anchor', 'middle')
|
||||
.style('font-size', fontSize + 'pt')
|
||||
.style('fill', function () {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue