I'm doing some highcharts and I use 40×40 images as the legend labels. However, the legend symbols are vertically top-aligned. (fiddle)
legend: {
align: 'right',
verticalAlign: 'middle',
layout: 'vertical',
labelFormatter: function () {
return $('<div>').append($('<img>').attr('src', 'http://doc.jsfiddle.net/_downloads/jsfiddle-logo.png').css({
height: 40,
width: 40
})).html();
},
useHTML: true
}
Is there some easy way to vertically center-align the legend symbols?
You can wrap positionItem function, to post-translate items to be in the middle: http://jsfiddle.net/6fgMp/3/
(function(H){
H.wrap(H.Legend.prototype, 'positionItem', function(proceed, item){
proceed.call(this, item);
if(item.legendSymbol) {
item.legendSymbol.translate(0, 10);
}
if(item.legendLine){
item.legendLine.translate(0, 10);
}
});
})(Highcharts);
Related
I want to create charts with fixed height, depending on user interaction, some chart can be empty, so there are no legend.
My problem is I want all of them with the same height, and then, if there is legend it's above the chart, this height should be increased by the legend.
I can't get it, it's my try.
options = {
chart: {
zoomType: 'x',
height: 300
},
legend: {
enabled: 'true',
align: 'center',
verticalAlign: 'bottom',
layout: 'horizontal',
maxHeight: 50
}
};
As result, what I have is, if there is legend, a 250px chart and if it's not a 300px chart. What I want is always a 300px chart, and if legend, 50px more to contain it.
how can I solve it?
In the chart load event you can use the chart.setSize method to increase the height of the chart by the height of the legend.
function addLegendHeight(chart) {
var legendSpace = chart.legend.legendHeight -
chart.legend.padding;
if (legendSpace) {
chart.setSize(null, chart.chartHeight + legendSpace);
}
}
Highcharts.chart('container', {
chart: {
...,
events: {
load: function() {
addLegendHeight(this);
}
}
},
...
});
Live demo: http://jsfiddle.net/BlackLabel/seqah1by/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Chart#setSize
i try edit in legend to have result same the picture below but not sucess
This my jsfiddle.net/hoanghoang3009/9wXvr/44.
I also try edit with labelFormat with code and can't show chart.
labelFormat: '<div><div style="float: left; width: 80%;">{name}</div><div style="margin-left: 80%">({percentage:.2f}%)</div></div>'
so I change labelFormat to first value:
labelFormat: '{name} ({percentage:.1f}%)'
Anybody can give me solution to have result same the picture.
Thanks!
Your legend in code will be like this
Fiddle
legend: {
useHTML: true,
//labelFormat: '{name} ({percentage:.1f}%)',
labelFormatter: function() {
return '<div style="width:30vh;"><span style="float:left;color:#ccc">' + this.name + '</span><span style="float:right">' + this.percentage.toFixed(0) + '%</span></div>';
},
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
symbolRadius: 0, //for changing to square
padding: 3,
itemMarginTop: 5,
itemMarginBottom: 5,
},
As useHTML: true in code so you can try as many possibilities with CSS and HTML
I am trying to use HighCharts in Angular2 using typescripts.
I am trying to format my legend text, with image to show up next to it. HighChart legend has labelFormatter property to provide callback function.
http://api.highcharts.com/highcharts#legend.labelFormatter
Callback function to format each of the series' labels. The this
keyword refers to the series object, or the point object in case of
pie charts. By default the series or point name is printed.
But I dont know how to pass callback function in typescripts to labelFormatter property.
updateChart(): void {
let newOptions = {
legend: {
useHTML: true,
itemMarginBottom: 10,
enabled: true,
floating: true,
align: 'center',
verticalAlign: 'top',
labelFormatter: (s) => this.getLegendLabel(s),
y: 35
}
}
}
getLegendLabel(seriesDetails) {
console.log(seriesDetails);
}
But I am getting undefined for seriesDetails object.
and if I used this keyword anywhere it refers to that component rather than series information.
According to the documentation:
Callback function to format each of the series' labels. The this
keyword refers to the series object, or the point object in case of
pie charts. By default the series or point name is printed.
I guess you've got wrong "this" in the fat arrow function. IMHO the simpliest way just follow documentation syntax (jsfiddle):
labelFormatter: function () {
return this.name + ' (click to hide)';
}
You should write your code like this:
updateChart(): void {
let newOptions = {
legend: {
useHTML: true,
itemMarginBottom: 10,
enabled: true,
floating: true,
align: 'center',
verticalAlign: 'top',
labelFormatter: this.getLegendLabel,
y: 35
}
}
}
getLegendLabel() {
console.log(this);
}
It will produce the following JS code and will work as you expect (Test is my classname):
Test.prototype.updateChart = function () {
var newOptions = {
legend: {
useHTML: true,
itemMarginBottom: 10,
enabled: true,
floating: true,
align: 'center',
verticalAlign: 'top',
labelFormatter: this.getLegendLabel,
y: 35
}
};
};
Test.prototype.getLegendLabel = function () {
console.log(this);
};
How do I include the events text to the left of chart when exporting in HighCharts.
The text disappears on export.
ref: http://jsfiddle.net/no1uknow/4PU9j/
events: {
load: function () {
var label = this.renderer.html("36 Aircraft delivered to Air 1<UL><li>13 in 2013</li><li>23 in 2014</li></UL>52 Aircraft remaining on Air 2 certificate")
.css({
width: '180px'
})
.attr({
'stroke': 'silver',
'stroke-width': 1,
'r': 5,
'padding': 10
})
.add();
label.align(Highcharts.extend(label.getBBox(), {
align: 'left',
x: 0, // offset
verticalAlign: 'top',
y: 40 // offset
}), null, 'spacingBox');
}
},
marginLeft: 300
},
The exporting function in Highcharts renders the original chart as it was passed in first, not after it's been modified by further actions, such as using the renderer to add text. Fortunately, you can manually call the exportChart function and pass in additional chart settings, including functions for adding the renderer text. This will let you do what you want.
See here for details: Can not exporting renderer shapes added in callback function in highcharts / highstock
You need to use a renderer text instead of html (which is not exported).
events: {
load: function () {
var label = this.renderer.text("36 Aircraft delivered to Air 1<UL><li>13 in 2013</li><li>23 in 2014</li></UL>52 Aircraft remaining on Air 2 certificate",100,100)
.css({
width: '180px'
})
.attr({
'stroke': 'silver',
'stroke-width': 1,
'r': 5,
'padding': 10
})
.add();
label.align(Highcharts.extend(label.getBBox(), {
align: 'left',
x: 0, // offset
verticalAlign: 'top',
y: 40 // offset
}), null, 'spacingBox');
}
},
Example: http://jsfiddle.net/4PU9j/1/
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.