NOTE: the below code is for Highcharts in R, but obviously any solution in 'normal' Highcharts code is also more than welcome!
I'm trying to print the mean (indicated by the diamond symbol in the example, below), and a difference to benchmark (not included in the sample data below) to a horizontal stacked bar chart.
At first I thought to plot a second graph, and combine them with hw_grid, but aligning them is really tricky. Hence I thought I'd add the numbers as the labels on a second x-axis.
I know it's possible to add multiple y-axes (Two y Axis in Highcharter in R, and https://www.highcharts.com/demo/combo-dual-axes), but because this is a horizontal chart, it needs to be the x-axis, and there doesn't seem to be an equivalent?
Here's the dummy data to reproduce in R:
library(dplyr)
library(highcharter)
df1 = data.frame("label"= paste0("Label", c(1,1,1,2,2,2,3,3,3,4,4,4)),
"value" = c(-100,231,110, -189,299,198, -199,150,298, -90,180,155),
"grade" = rep(c("Disagree","Neutral","Agree"), 4))
df2 = data.frame("x" = c(0,1,2,3),
"y" = c(200,100,250,280))
highchart() %>%
hc_add_series(df1, type="bar", hcaes(x=label,y=value,group=grade)) %>%
hc_add_series(df2, type="scatter", marker=list(symbol='diamond', radius=8)) %>%
hc_plotOptions(bar = list(stacking="normal")) %>%
hc_xAxis(type = "category") %>%
hc_yAxis(visible=FALSE)
Works just the same as with the y-axis: simply add another axis object to the xAxis array (being sure to set opposite = true for it) and then for the series you want to leverage it, specify xAxis = 1.
Here is an example (which is using categorical x-axis values but that need not be the case):
xAxis: [{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
crosshair: true
},
{
categories: ['1', '2', '3', '4', '5', '6',
'7', '8', '9', '10', '11', '12'],
opposite: true
}]
...
series: [{
name: 'Rainfall',
type: 'column',
xAxis: 1, // this applies this data to the alternate (2nd axis) specified above
data: [49.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4],
tooltip: {
valueSuffix: ' mm'
}
}, {
name: 'Temperature',
type: 'spline',
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6],
tooltip: {
valueSuffix: '°C'
}
}]
In this example, you can even have 2 x-axes and 2 y-axes:
https://jsfiddle.net/mzhukovs/8v167bcf/2/
Related
I was adding some padding to my chart because I want to control the space between the actual chart and the container, and I encountered a problem.
Look at mi first fiddle, all seems legal but the padding isn't being applied:
https://jsfiddle.net/9r2Lqmpj/
Highcharts.chart('container', {
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
minPadding: 0.4,
maxPadding: 0.4
},
yAxis: {
startOnTick: false,
minPadding: 0.2
},
series: [{
data: [129.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
But if I duplicate the "xAxis" key, this time without the categories array, which seems highly wrong, for no reason it works:
https://jsfiddle.net/v0rj1xkg/
Highcharts.chart('container', {
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
minPadding: 0.4,
maxPadding: 0.4
},
xAxis: {
minPadding: 0.4,
maxPadding: 0.4
},
yAxis: {
startOnTick: false,
minPadding: 0.2
},
series: [{
data: [129.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
I wasn't expecting at all that this worked, in fact, I discovered it by mistake. Why is it working only when I repeat the xAxis key definition?
Properties minPadding and maxPadding don't work with category axis type. Use min and max options instead.
Highcharts.chart('container', {
xAxis: {...},
...
}, function() {
var xAxis = this.xAxis[0];
this.update({
xAxis: [{
min: xAxis.min + 0.2,
max: xAxis.max - 0.2
}]
}, true, true, false);
});
Live demo: https://jsfiddle.net/BlackLabel/96s30khd/
Well Agustin, not much of a discovery rather than a common logic there in your second scenario. I am not really sure what you're trying to achieve, but having xAxis defined twice is not necessary. Just remove the first one to get the same result, so it looks like your second one is overwriting the first one. Have a look at your fiddle here https://jsfiddle.net/xcmq869s/ which looks the same to me. Also it might be the case that the padding doesn't work with categorical data, so it works fine when no categories are specified. U can certainly alter the padding with removed categories.
On the other note, if you want to keep your x-axis labels and add only outer spacing, try using the chart.spacing config option as in the fiddle here https://jsfiddle.net/xcmq869s/1/.
I'm checking through the documentation and don't really see a way to do this.
What I'd like to do is position the chart title to the right of the chart, rotated 90 degrees and centered vertically.
So something like this (used Photoshop to represent rotation):
I know I can set the x, and y position like this:
title: {
text: 'Chart title',
align: 'right',
y: 140,
x: 50,
rotation: 90 //this does not work
}
But that doesn't really give me what I want. Is there a setting that I'm not finding to position the title on the right, and rotate it 90 degrees?
Here is a fiddle I was messing with for the x, y axis positioning:
http://jsfiddle.net/c2tb1p5b/1/
You can do this using a combination of x, y placement on the title along with CSS - you will need to mess around with the exact values but something like this should work:
Highcharts.chart('container', {
chart: {
type: 'bar'
},
title: {
text: 'Chart title',
align: 'right',
y:-480,
x:-280
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
labels: {
step: 1
}
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
CSS:
.highcharts-title {
transform: rotate(90deg);
}
http://jsfiddle.net/c2tb1p5b/2/
I try to use a horizontal crosshair as some kind of auxiliary line to compare the upper and lower endpoints of the errorbars.
From a statistical point of view it is some kind of virtual significance test by comparing the confidence intervals.
My problem is that given a column chart I am not able to reach the lower endpoint of the errorbars with the crosshair.
Here is a fiddle (simplified demo from Highcharts).
var chart;
$(function () {
$('#container').highcharts({
chart: {
zoomType: 'xy'
},
title: {
text: 'Temperature vs Rainfall'
},
xAxis: [{
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
}],
yAxis: [{
title: {
text: 'Rainfall',
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: '{value} mm',
style: {
color: Highcharts.getOptions().colors[0]
}
}
}],
tooltip:{
crosshairs: [false, {color: 'red'}],
formatter: function(){
return false;
}
},
series: [{
name: 'Rainfall',
type: 'column',
yAxis: 0,
data: [49.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4],
}, {
name: 'Rainfall error',
type: 'errorbar',
yAxis: 0,
data: [[42, 51], [66, 73], [90, 110], [128, 136], [140, 150], [171, 179], [135, 143], [142, 149], [204, 220], [189, 199], [90, 110], [52, 56]],
}]
});
});
Any suggestions are welcome!
Error bars are paths in SVG, so there's no such thing like lower/higher part of it. If you check highcharts.src.js file and search for drawCrosshair, you will find method responsible for rendering crosshair. As you can see, there is line:
pos = (this.chart.inverted != this.horiz) ? point.plotX : this.len - point.plotY;
Which takes point.plotY to get position of the crosshair. In error bars plotY is top of the point. If you replace point.plotY with point.lowPlot (only for error bars!) then you will render crosshair on the bottom part of the error bar.
I'm trying to put Y-Axis title on top right of the Y-Axis, right below the chart title. However, when I insert the axis title, the whole graph moves to the right. I tried to used spacingLeft to set the position of the chart, but nothing changes. Is there a way to keep the position of the chart even if I add the axis title?
Here is my code:
$(function () {
$('#container').highcharts({
chart: {
marginBottom: 80,
spacingTop: 20
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
title: {
text: 'Chart title',
y: -10
},
yAxis: {
title: {
text: 'aaaaaaaaaaaaaaaaaaa',
align: 'high',
rotation: 0,
x: 100,
y:-20
},
labels: {
align: 'high',
x: 0,
y: -5
}
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
});
jsfiddle: http://jsfiddle.net/8m7rc/1/
Min Sun Song, you can use offset property to reduce that gap.
offset: -120,
I've updated you fiddle here
Hope this is what you are looking for.
You can set marginLeft property for a chart. See demo.
I've spent some time poking around the API documentation, and I don't see a simple solution to my problem. This is what I'm looking for:
In a chart, I can set each line to be a different color I choose like
colors: [ 'red', 'green', 'blue ]
But what if I want the points to be different colors than the line?
I know I can set the
plotOptions: {
series: {
marker: {
fillColor: 'yellow',
lineColor: 'yellow'
}
}
},
But what if I want each point marker to be a different color? (For instance, I want the blue line to have dark blue points, the red line the have dark red points, and the green line to have dark green points.
I think I want to do something along the lines of
borderColors: [ 'darkBlue', 'darkGreen', 'darkRed' ]
or whatever and the same with fillColors...
Is there any way I can do this easily that I've missed.
Thanks!
Define the marker in the series...
I found this in the api:Highchart symbol api
Which links to this fiddle:
High char jsfiddle
changed the code to work with colour:
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 316.4, 294.1, 195.6, 154.4],
marker: {
fillColor: '#f11',
lineWidth: 2,
lineColor: '999'
}
}, {
data: [216.4, 194.1, 95.6, 54.4, 29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5],
marker: {
fillColor: '#999',
lineWidth: 2,
lineColor: '#111'
}
}]
});
});
You can specify the line color and the marker color for each series explicitly.
Series Color Sets the color to the series.
Markers Color sets the color to every point in the series.
Demo .