Is there way to set the label of an Bar Chart to 50% of the charts width? I've tried this but it does not work:
xAxis: {
categories: [],
labels: {
formatter: function() {
var text = this.value;
return '<div class="js-ellipse" style="width:100%; overflow:hidden; text-overflow: ellipsis" title="' + text + '">' + text + '</div>';
},
style: {
width: '50%'
},
useHTML: true
}
},
So goal is to have labels on the left side of the bar chart that are 50% of the width of the whole chart container.
You have an option for that in the plotOptions :
plotOptions: {
bar: {
dataLabels: {
enabled: true,
inside: true
// ^^^^^^^^^^^^
}
}
},
The property inside :
For points with an extent, like columns, whether to align the data label inside the box or to the actual value point. Defaults to false in most cases, true in stacked columns.
And an example forked from the official documentation : http://jsfiddle.net/XXB9k/
EDIT :
There is another option to center the x labels (I don't know witch labels your are talking about), but there is a solution not far away from your code :
xAxis: {
...
labels: {
enabled: true,
x: this.width / 2,
}
}
An example : http://jsfiddle.net/QMPkh/
FINAL EDIT :
In fact you can simply use the width of the chart in the label formatter :
labels: {
enabled: true,
formatter: function() {
return '<div style="width:' + (this.axis.width/2) +'px">'+this.value+'</div>';
},
useHTML: true
}
An example to show the result : http://jsfiddle.net/QMPkh/2/
Unfortunately width in percent is not supported, only in pixels.
Related
Found a couple of posts that came close to solving this. I'm loading a chart into a widget and it's not filling it, instead it's centered and extended past the widget - about only 1/3 of the pie chart shows for example.
I found the resize options for gridster and it gets me almost there... the same problem exists when I load the page, but when I resize the widget the chart fills it in perfectly.
I've tried aligning the chart, removing width and height settings, addeing resize and stop elements to gridsters..
var gridster = null;
$(document).ready(function () {
gridster = $(".gridster ul").gridster({
widget_base_dimensions: ['auto', 140],
autogenerate_stylesheet: true,
min_cols: 1,
max_cols: 6,
widget_margins: [5, 5],
resize: {
enabled: true,
resize: function (e, ui, $widget) {
Highcharts.charts[0].reflow(); // reflow the first chart...
},
stop: function(e, ui, $widget) {
Highcharts.charts[0].reflow(); // reflow the first chart...
}
}
}).data('gridster');
$('.gridster ul').css({'padding': '0'});
});
Highcharts.chart('container', {
chart: {
type: 'pie'
},
title: {
text: 'User data',
style: {"fontSize": "15px" , "color":"red"},
},
subtitle: {
text: 'Source: Click the slices to view categories.'
},
plotOptions: {
pie: {
showInLegend: false,
dataLabels: {
formatter: function(){
console.log(this);
if (this.percentage > 5)
return this.key + ': ' + this.y;
else
this.point.visible = false;
return '';
}
}
},
series: {
dataLabels: {
enabled: true,
}
}
},
tooltip: {
headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
when page loads the pie chart is sized to fit into the gridster widget.
Add one div wrapper around widget and add class which having height and width of that widget. It will render your highchart graph in that wrapper only.
<div class="size-1x1">
Render your graph code here
</div>
CSS:
.size-1x1 {
height:100px;
width: 120px;
}
How can I hide a stackLabel (a label above the column) in highCharts when the text in the label is bigger than the column (As you can see in the image below).
I want to show empty string when my data exceeds the column width.
This is part of the code which is responsible for showing the data:
yAxis: {
stackLabels: {
style: {
color: 'black'
},
enabled: true
formatter: function () {
return this.total + " mm ";
}
}
}
Create a function which loop through the stack labels and compare their width with the point's width - according to the comparison hide or show the label.
Function can look like this:
function hideLabel() {
const axis = this.yAxis[0];
const stacks = axis.stacks.column;
const pointWidth = this.series[0].points[0].shapeArgs.width;
Object.keys(stacks).forEach(key => {
const label = stacks[key].label;
label.attr({
visibility: label.getBBox().width > pointWidth ? 'hidden' : 'visible'
});
})
}
Set this function on load and redraw events:
chart: {
type: 'column',
events: {
load: hideLabel,
redraw: hideLabel
}
},
example: http://jsfiddle.net/nq5ke47z/
I would like to make tooltip in Highstock styled differently(not just style of content, but style for tooltip itself. For example, different padding, shadow, border radious etc) when hovering over flag series and line serieses. However, it looks like these properties needs to be configured in the tooltip configuration object. Not sure if it can be dynamically changed.
Like in this jsbin:
http://jsbin.com/cixowuloxa/1/edit?js,output
What's the better way to give 'Summer arrives' tooltip different style than other shared tooltips?
Your approach is correct. In the formatter callback wrap the text in the html tags and style it using css, inline or by class name, depending if it is a flag or line series. Make sure you set useHTML to true.
tooltip: {
useHTML:true,
borderWidth: 0,
headerFormat: '',
shared: true,
formatter: function(){
if (!!this.points) {
return this.points
.reduce(
function(prev, cur) {
return prev +
'<br>' + cur.series.name + ': '+ cur.y;
}, '');
}
return "<div style='border:5px solid black; padding: 20px'>Summer arrives!</div>";
},
padding: 0
}
example: https://jsfiddle.net/hpeq7Lbe/1/
Actually, you can set different options for flag's and line's tooltip, but not all the options are supported, e.g. padding or border width will not work - they have to be set in the tooltip's global options.
plotOptions: {
line: {
tooltip: {
pointFormat: 'line',
borderWidth: 10, // not supported
padding: 10 // not supported
}
},
flags: {
tooltip: {
pointFormat: 'flags',
borderWidth: 1, //not supported
padding: 1 // not supported
}
}
}
example: https://jsfiddle.net/hpeq7Lbe/3/
I want to make some tooltips visible in my d3 map. The tooltips are column charts generated by Highcharts regarding the chosen city. The trick is that everything is displaying correctly (axis, labels ...) except that the columns are not visible!
Here my d3 code (only the relevant parts):
var tooltip = d3.select("body")
.append("div")
.attr("id","tooltip")
.style("position", "absolute")
.style("visibility", "hidden");
cities.on("mouseover", function(d, i) {
d3.select(this).style('fill', '#95a5a6');
tooltip.html(zoomCityComm(d))
return tooltip.style("visibility", "visible")})
.on("mousemove", function(d, i){
return tooltip.style("top", (d3.event.pageY - 130) + "px").style("left",(d3.event.pageX - 120) + "px");
})
}
The function zoomCityComm is HighCharts (example of data: [5,10]):
function zoomCityComm(d) {
chart = new Highcharts.Chart({
chart : {
renderTo: 'tooltip',
type: 'column',
width:200,
height:200,
plotBackgroundColor: '#FCFFC5',
zoomType: 'xy'
},
title: {
text: "TOTO"
},
legend: {
enabled: false
},
xAxis: {
categories: ['In','Out']
},
yAxis: {
title: {
text: 'Sum',
style: {
color: '#4572A7'
}
},
labels: {
style: {
color: '#4572A7'
}
},
},
series:[{color: '#4572A7',data: res}]
});
return document.getElementById("tooltip").innerHTML;
}
When the graph is displayed in a "normal" div within the document, it appears correctly.
Sorry if my explanations are not clear but ask me for some details if needed.
Thanks
Cyril
You're setting the HTML content of the div twice, as highcharts renders it itself. In your mouseover handler function, it is enough to do
zoomCityComm(d);
instead of
tooltip.html(zoomCityComm(d));
For the interested, here's what's happening. Setting the HTML of the tooltip div from the return value of the function captures the first animation frame that highchart uses to grow the bars. As it is the first frame, the height of the bars is still 0 -- that is, the bars are there, but not visible because they have essentially no height. Replacing the HTML of the div means that the animation won't work anymore, as the elements that would be animated have been replaced.
I took a sample jsfiddle and modified it here just to show a sample of what I experienced:
http://jsfiddle.net/pMwuv/
Here is what my actual datalabel code looks like:
dataLabels: {
enabled: true,
align: 'left',
verticalAlign: 'top',
style: {
color: 'black'
},
formatter: function () {
if (this.x == 19) {
return this.y + '<br>units left';
};
}
}
What I am having on my area chart is that the last data label is cut off. Is there a way to increase the width of the container or add some type of padding so that the full label shows?
Just changing the x and y position of the label will not work for my area chart. I have my chart customized so that only the last point of the chart has a data label and i want it aligned to the right of the last point and not within the chart.
But if we can get the above sample fiddle to work then the same solution should work for me.
You can add marginRight to chart like this:
chart: {
renderTo: container,
width: 550,
marginRight: 35
}
jsFiddle.
This is not a direct solution, but I suggest you to put the label at the yAxis:
yAxis: {
title: {
text: 'Units left'
}
},
And remove the other attributes, leaving just enabled: true:
plotOptions: {
series: {
dataLabels: {
enabled: true
}
}
},
See the fiddle
You can set spacingRight and add correct value.