I am going round in circles a bit with highcharts trying to make a chart as follows:
And here is a jsbin of the above example:
http://jsbin.com/pezufeweki/1/
My main issue is I have to use a fake segment (and make it white) for the values to be correct (which in turn means the 'hidden' section still has a tooltip.
Is there a way in highcharts to make a segment 'hidden' from the pie chart?
Alternatively, I can get away with making it white but then I would need to hide the tool tip just for that segment as I need it everywhere else.
An added bonus would be for the inner (red) area to start anti-clockwise.
Any pointers much appreciated.
Cheers.
Fixed hiding the tooltip per item
formatter: function() {
if (this.key === "hide") {
return false;
}
else return this.y;
}
{
name: 'hide',
y: 12,
color:'red'
},
Related
I have made a highcharts graph which is intended to mirror the following:
I am using a triangle image as a marker for the graph, but by default, the marker is being situated in the center of the bar. I have tried to use the translation function
chart.series[1].data.graphic.translate(0, 20);
but this does not seem to be helping.
Here is my full code:
barchartFiddle
I was also wondering how I would add the percentage to the top of as it would move along with the bar.
Furthermore, I have tried using (multiple versions with different css properties + high zIndex - I will be listing the basic)
chart.renderer.text('blah',50,50).add();
to add the bottom 3 criteria, but for some odd reason, no text shows up.
Finally, I was wondering what logic to add in order to change the appearance of the text, depending on the data, to mirror the one shown in the image (Note difference between acceptable and healthy)
In your jsFiddle you have added your callback function in wrong place, when you will add it correctly it should work fine.
function(chart) {
var marker = chart.series[1].data[0];
marker.graphic.translate(-20, 0);
}
You can use dataLabels for showing the percent value near your marker.
dataLabels: {
enabled: true,
x: -5,
y: 10,
style: {
fontSize: 20
},
formatter: function() {
return this.y + '%'
}
}
Here you can find an example how it can work: http://jsfiddle.net/2TuCW/341/
I made a small fiddle based on the highcharts demos at http://jsfiddle.net/w53woene/1/
The issue I have boils down to four things:
1) I need to rotate the labels (this is based on a feature request so I can't ignore it).
labels: {
rotation: -45
}
2) The fact that the last label is really really long. This is based on data which is given for each chart so it's not always the case but it's the case around 30%-40% of the time so quite often.
3) Labels shouldn't be wrapped or shortened with an ellipsis.
4) I need to add spacing between the chart and the legend to adapt to the labels size but only when the label is going to be too long and colliding with the legend.
This only seems to happen when the chart: { inverted: true } and if it's not inverted the legend behaves normally, increasing the distance from the chart as needed.
Ideally I'd like to know if there's a specific option I'm missing that achieves this natively, i.e., I would have expected floating: false to achieve this the same way it does when the chart is not inverted, but it doesn't seem to. If this isn't possible I'd like to know how I can adjust the chart size (excluding the legend) in order to achieve this via JavaScript.
The problem is that vertical axis add space on the left size, but doesn't add on the bottom. I would wrap labels for a better readability: http://jsfiddle.net/w53woene/2/ - otherwise it may happen that you will have so long label that chart will get 0 pixels for plotting area.
If you really need non-wrapped text, then I would wrap Axis.prototype. getOffset to add extra space:
(function(H) {
H.wrap(H.Axis.prototype, 'getOffset', function(p) {
p.call(this);
if (this.isXAxis) {
var lastTick = this.tickPositions[this.tickPositions.length - 1],
lastLabel = this.ticks[lastTick].label,
height = lastLabel.getBBox(true).height;
this.labelDiff = height - this.chart.marginBottom;
if (this.labelDiff > this.chart.axisOffset[2]) {
this.chart.axisOffset[2] = this.labelDiff;
} else {
this.labelDiff = 0;
}
} else {
this.offset -= this.chart.xAxis[0].labelDiff;
}
});
})(Highcharts)
And live demo: http://jsfiddle.net/vwegeuvy/
I am working with highcharts and having some problems with stackLabels configuration of highcharts. I was asked to display a bar chart with "score/full score" format, e.g. 6 out of 10 should be like
⬛︎⬛︎⬛︎⬛︎⬛︎⬛︎⬜︎⬜︎⬜︎⬜︎ 6/10
And I faked it with stacked bar chart with 6 for the first part of the bar and 4 for the second part.
[Solved] However, I don't know how to display 6/10 in stackLabels (It seems that I can only use {total} in it, while I can use {point.y}/{point.fullscore} in dataLabels).
[Unsolved] And also, when I use the basic bar chart, dataLabels automatically adjust its position (In my case, dataLabels will show on the left of the right edge of the bar). However, how should I force the stackLabels to display?
This answer points out that there is no enough space for stackLabels to display, and the solution is to make max value bigger and leave some space for it. However, the solution is not that elegant to me, and also since my bar chart is horizontal and the label should be long.
Any help will be appreciated! Thanks in advance!
To answer second question:
You can set yAxis.stackLabels.crop to false, so labels will be rendered always. Those labels won't show up inside the plotting area, but will be rendered somewhere outside. stackLabels are not dataLabels - dataLabels have option justify, which forces labels to be rendered inside the plotting area.
However, in Highcharts you can get access to those labels, and move them (that's why crop needs to be set to false - to render labels anyway), here is simple POC:
function updateStacks() {
var chart = this,
H = Highcharts,
padding = 15,
item,
bbox;
for (var stackName in chart.yAxis[0].stacks) {
for (var itemName in chart.yAxis[0].stacks[stackName]) {
item = chart.yAxis[0].stacks[stackName][itemName]; // get stack item
bbox = item.label.getBBox(true); // get label's bounding box
// if label is outside, translate it:
if (bbox.width + bbox.x > chart.plotWidth) {
// add some poding, for a better look&feel:
item.label.translate(-bbox.width - padding);
}
}
}
}
Now simply use that method in load and redraw events, here you are:
chart: {
type: 'bar',
events: {
redraw: updateStacks,
load: updateStacks
}
},
And live demo: http://jsfiddle.net/awe4abwk/ - let me know if something is not clear.
PS: Your answer with formatter for stackLabels is good!
Use formatter to change default stack label. You can access axis label with this.axis.
stackLabels: {
enabled: true,
formatter: function() {
return (this.axis.series[1].yData[this.x] / this.total * 100).toPrecision(2) + '%';
//Make your changes here to reflect your output. This is just a sample code
}
}
Now to always show stack labels you have two options which are described here.
Link
Okay, I've found the solution for the first question: How to show the specific series values in stackLabels? from this answer.
In my case, the code should be:
yAxis: {
stackLabels: {
formatter: function() {
return [this.axis.series[1].yData[this.x], '/', this.total].join('');
},
enabled: true,
}
}
If you have better solution, post it! And I still have no idea about how to find it in the docs, maybe I should dig more...
I would like my chart area to be extended on the top so I've added a negative margin to the chart. However, this causes series at times to be drawn over the contextButtons and can make them impossible to click. I'd like to just increase the z-index or do something that makes them appear above the series without having to make my own buttons that live outside the chart. Does anyone have a way to do this?
Example: http://jsfiddle.net/tu67e1ce/1/
chart: {
marginTop: -25,
events: {
load: function() {
this.exportSVGElements[0].toFront();
this.exportSVGElements[1].toFront();
}
}
},
So method toFront() will bring items on top of the SVG container. this.exportSVGElements[0]/[1] are button/symbol. Of course both of them are inner object of the Highcharts core.
Please see the Highcharts related jsfiddle here
http://jsfiddle.net/gh/get/jquery/1.7.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/combo-dual-axes/
This is my Y axis
{
// Secondary yAxis
title: {
text: 'Rainfall',
style: {
color: '#4572A7'
}
},
labels: {
formatter: function() {
return this.value +' mm';
},
style: {
color: '#4572A7'
}
},
opposite: true
}
Typically what i want is that , under the Y axis Secondary Axis label (that is below 250 mm here in this case ) , i need to display the Temparature series Symbol
Could anybody please help me ?
I'm not quite sure why you want a symbol for temperature on the rainfall side, but let me see if I can help.
Well, if you just want to display a picture in the same place on your chart, then use the highcharts renderer. Highcharts drawing API. In this case, just use the image(...) function.
I'm not finding simple ways of doing more dynamic bits. There are some enforcements of the css for the axis's that prevent anything but text to show up. You may be able to dig into the axis (in the formatter; this.axis) and find something useful. But you may have more luck running jQuery code to find the location of the text you want, then using offset(), find where in the page to slap your image onto. Either using a div or the highchart.Renderer.
Good luck!