cancel
Showing results for 
Search instead for 
Did you mean: 

Bar Chart - Prevent bars from hiding the value label text

Ophir_Buchman
Sisense Team Member
Sisense Team Member

When creating a bar chart and formatting it to include "Values",  you might find out that the bars cover their values. The following (widget) code manipulates the bars' width and label position:

const labelWidth = 25 + 5 // 5 is the space between the label and the bar

widget.on('domready', function(widget) {
try {
console.log('DOM Ready script starting (wid=' + widget.oid + ')');

// Get plot width
plotWidth = parseInt(widget.chart[0].getElementsByClassName('highcharts-plot-border')[0].getAttribute('width'));

// Find Widest bar
maxBarWidth = -1;
widget.chart[0].getElementsByClassName('highcharts-series','highcharts-bar-series').forEach(bar => {
bar.childNodes.forEach(rect => {
if (parseInt(rect.getAttribute('height')) > maxBarWidth)
maxBarWidth = parseInt(rect.getAttribute('height'))
})
})

if (maxBarWidth == -1) return;

// Check if we require adjustment
if (plotWidth - maxBarWidth > labelWidth) return;

ratio = (maxBarWidth - labelWidth) / maxBarWidth;

// Adjust Bar height and location
barsArray = widget.chart[0].getElementsByClassName('highcharts-series','highcharts-bar-series');
labelsArray = widget.chart[0].getElementsByClassName('highcharts-data-labels');

for (let seriesNum = 0; seriesNum < barsArray.length; seriesNum++) {
for (let barNum = 0; barNum < barsArray[seriesNum].childNodes.length; barNum++) {
currentWidth = parseInt(barsArray[seriesNum].childNodes[barNum].getAttribute('height'));
currentY = parseInt(barsArray[seriesNum].childNodes[barNum].getAttribute('y'));
transformLabel = labelsArray[seriesNum].childNodes[barNum].getAttribute('transform')

// Calculate offset
offset = Math.round(currentWidth * (1-ratio))

// Adjust bars
barsArray[seriesNum].childNodes[barNum].setAttribute('height',currentWidth-offset)
barsArray[seriesNum].childNodes[barNum].setAttribute('y',currentY+offset)

// Adjust labels
newLabel = 'translate(' + (currentWidth - offset) + ',' + transformLabel.split(',')[1]
labelsArray[seriesNum].childNodes[barNum].setAttribute('transform',newLabel)
}
}
}
catch (error) {
console.error(error);
}
finally {
console.log('DOM Ready script complete (wid=' + widget.oid + ')');
}
});
Before After
Ophir_Buchman_0-1648199914908.png Ophir_Buchman_1-1648199963769.png
5 REPLIES 5

cartercjb
10 - ETL
10 - ETL

@Ophir_Buchman how do you apply fill-opacity to the bars only so that it does not apply to the data labels as well?

Hi @cartercjb 

In 'domready' - Perform the following:

$('.highcharts-series.highcharts-series-1')[0].childNodes.forEach(item => item.setAttribute('opacity',0.3))

 

Ophir_Buchman_0-1651047362377.png

 

BIQ
8 - Cloud Apps
8 - Cloud Apps

How can we get this code to work on column charts as well? 

fabricio_fta
7 - Data Storage
7 - Data Storage

How this code could also work for negative bar charts? For us, it's working fine for positive values, but for negative values, it does not.

Example:

fabricio_fta_0-1692131088960.png

We would like that the numbers once inside the bar would be white as the third bar is and once they out they would be gray the first bar is.