I'm struggling to get my chart elements in the right Z order, in particular where I have dataLabels with useHTML enabled, and where I also add a rectangle via chart.renderer.rect(). This is illustrated in the following jsfiddle:
https://jsfiddle.net/fk7b3cnz/
I want the rectangle to be above the main chart features (lines, labels), and for the tooltip to be above the rectangle (i.e. above everything). I managed to get the tooltip to sit on top (except for the margin around it... how do I fix that?), but the data labels are sitting above the rectangle... the zIndex I set for the rectangle doesn't seem to have any effect.
JAVASCRIPT:
Highcharts.chart('container', {
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
tooltip: {
useHTML: true,
formatter: function () {
return '<div class="tooltip">value: ' + this.y + '</div>';
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
useHTML: true // need this to achieve the text formatting I want via appropriate html (not shown here)
}
}
},
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]
}]
}, function (chart) { // on complete
chart.renderer.rect(100, 100, 100, 100, 5)
.attr({
'stroke-width': 2,
stroke: 'red',
fill: 'yellow',
zIndex: 9998 // want this to be above chart features but below tooltip
})
.add();
});
CSS:
.highcharts-tooltip span {
background-color: white;
border: 1px solid green;
opacity: 1;
z-index: 9999;
}
.tooltip {
padding: 5px;
}
HTML:
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
Instead of adding zIndex manually you can use Highcharts.SVGElement.toFront method. The rectangle will be plotted above lines and other svg elements. However, data labels that are created using HTML will be always above other SVG elements (Since Highcharts v6.1.1 tooltip can be plotted above HTML content) as you can read in the Highcharts documentation:
"It will always be laid out on top of all other SVG content.
Specifically the tooltip may be rendered below the useHTML label.
Since Highcharts v6.1.1 this can be avoided by setting tooltip.outside
to true."
chart.renderer.rect(100, 100, 100, 100, 5)
.attr({
'stroke-width': 2,
stroke: 'red',
fill: 'yellow'
})
.add()
.toFront();
Demo:
jsfiddle
Related
Is it possible to create a Highcharts plot background like the picture below? It's important it will adjust when the plot is zoomed in/out.
E.g. Using radialGradient, but without the "gradient" between the colors.
The example below is only a starting point using SVGrenderer:
Highcharts.chart('container', {
chart: {
type: 'scatter'
},
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, 216.4, 194.1, 95.6, 54.4]
}]
}, function(chart) {
var yAxis = chart.yAxis[0],
y = yAxis.top+yAxis.height,
x = chart.plotLeft,
h = yAxis.height;
svg = chart.renderer;
svg.arc(x,y,h/3,0,1.5*Math.PI,0)
.attr({
fill: '#dce6f2',
'stroke-width': 0,
zIndex: -1
}).add();
svg.arc(x,y,2*h/3,0,1.5*Math.PI,0)
.attr({
fill: '#c5d8f1',
'stroke-width': 0,
zIndex: -2
}).add();
svg.arc(x,y,h,0,1.5*Math.PI,0)
.attr({
fill: '#95b3d7',
'stroke-width': 0,
zIndex: -3
}).add();
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
If you don't need it to be x/y symmetrical, then it's easy:
chart: {
backgroundColor: {
radialGradient: {
cx: 0,
cy: 1,
r: 1
},
stops: [
[0, '#dce6f2'],
[.25, '#dce6f2'],
[.25, '#c5d8f1'],
[.50, '#c5d8f1'],
[.50, '#95b3d7'],
[.75, '#95b3d7'],
[.75, '#fff'],
[1, '#fff']
]
},
type: 'line'
},
http://jsfiddle.net/ndjnx2eh/9/
This will scale with the size of the chart.
If you need it to always be a quarter circle, it's not so easy.
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 am trying to create a custom button next to legend as per below use-case:
1) button right of horizontal legend
2) button below vertical legend
JS Fiddle Link
Using chart renderer, I can add the button on chart but its coordinates are fixed. It is rendered as rectangle on chart (got to know after inspecting button using developer tools). Is there any way I can always keep this custom button next to any element inside chart, in my case, next to legend.
chart.renderer.button(...); // code inside jsfiddle link
Use lagend labelFormatter with useHTML:true to add button next to It.If You are using vertical legend you can add line break in legend labelFormatter
var chart;
chart=new Highcharts.chart('container', {
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
legend: {
useHTML:true,
labelFormatter: function () {
return this.name + ' (click to hide) <button onclick="buttonAction()">Button Action</button>';
}
},
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]
}]
});
function buttonAction(){
if(chart.series[0].visible==true){ //button click will interfere with legend text click
chart.series[0].visible=false
}else{
chart.series[0].visible=true
}
console.log('button clicked')
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
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 am curious to know why button 2 is not working in this example
In this jsfiddle example 'update' method attached to button 1 is working, but in my original code 'update' is also not working. It shows error: "object# has no method 'update'"
$(function () {
var options= {
chart: {
renderTo: 'container',
height: 400
},
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, 216.4, 194.1, 95.6, 54.4]
}]
};
var chart = new Highcharts.Chart(options);
buttonhandle1();
buttonhandle2()
});
function buttonhandle1(){
$("#b1").click(function(){
var chart = $('#container').highcharts();
chart.yAxis[0].update({
min:0,
max: 5,
tickInterval : 1,
});
});
}
function buttonhandle2(){
var chart = $('#container').highcharts();
$("#b2").click(function(){
chart.yAxis[0].min= 0;
chart.yAxis[0].max= 5;
chart.yAxis[0].tickInterval = 1;
chart.redraw();
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
<button id="b1"> button 1</button>
<button id="b2"> button 2</button>
Because when you use chart.redraw() you should also set isDirty flag as true
http://jsfiddle.net/uKWQ9/3/
chart.yAxis[0].isDirty = true;
Update works for me on button 2 as well, chart property can be accessed by closure.
function buttonhandle2(){
var chart = $('#container').highcharts();
$("#b2").click(function(){
chart.yAxis[0].update({
min:0,
max: 5,
tickInterval : 1
});
});
}
another option is to set isDirty on axis.
function buttonhandle3(){
var chart = $('#container').highcharts();
$("#b3").click(function(){
chart.yAxis[0].min= 0;
chart.yAxis[0].max= 5;
chart.yAxis[0].tickInterval = 1;
chart.yAxis[0].isDirty = true;
chart.redraw();
});
}
Code in fiddle.
http://jsfiddle.net/MrHunt/uKWQ9/5/
Better to pass chart as argument to handlers instead of creating separate vars. Updated fiddle here: http://jsfiddle.net/MrHunt/uKWQ9/6/