highchart chart redraw method is not refreshing the chart - highcharts

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/

Related

How can I apply different background color to entire tooltip for different series in highcharts

I would to give different backgroundcolor to entire tooltip for different series. I checked highcharts api document but their is no background color option in series.tooltip = {}.
Can you please suggest some way or alternative for this?
I checked this question - Changing backgroundcolor of tooltip for a specific data point in Highcharts
My question is similar to this one.
ex. I want to apply red color to a series through formatter and not want to honor yellow background color given in tooltip options.
please check this fiddle - http://jsfiddle.net/eoqdcxn4/1/
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
tooltip: {
useHTML:true,
backgroundColor:"yellow",
formatter: function() {
console.log(this);
if(this.point.customBck)
return '<div style="background-color:red;">The value for <b>'+ this.x + '</b> is <b>'+ this.y +'</b></div>';
else
return '<div>The value for <b>'+ this.x + '</b> is <b>'+ this.y +'</b></div>';
}
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [{
y:29.9,
customBck: true
}, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
});
Thanks in advance.
You can change tooltip background color in the refresh event depending on the hovered series, for example:
(function(H) {
H.addEvent(H.Tooltip, 'refresh', function(e) {
var series = this.chart.series.find(function(s) {
return s.isHovered;
});
this.label.attr({
fill: series.options.tooltipColor
});
});
}(Highcharts));
$(function() {
var chart = new Highcharts.Chart({
...,
plotOptions: {
series: {
events: {
mouseOver: function() {
this.isHovered = true;
},
mouseOut: function() {
this.isHovered = false;
}
}
}
},
series: [{
tooltipColor: 'red',
...
}, {
tooltipColor: 'yellow',
...
}]
});
});
Live demo: http://jsfiddle.net/BlackLabel/ojqews35/
API Reference: https://api.highcharts.com/highcharts/plotOptions.series.events
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts

how to show cross hair in highchart always by default

I want to show cross hair by default in high chart not any event but it should always be there. How to show crosshair at every x-axis point in highchart?
Using highcharts api
The mouse course will change to crosshair when over a point on the chart
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
Highcharts.chart('container', {
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
series: {
cursor: 'crosshair',
events: {
click: function () {
alert('You just clicked the graph');
}
}
}
},
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]
}]
});
using api jsfiddle
Using jquery
This will make the mouse cursor be a cross hair whenever its on the graph.
$("#container").css( 'cursor', 'crosshair' );
using jquery jsfiddle

show/hide series vanishes styling of datalable

In my chart I am combining a class together with datalables of each series.
At some point I am hiding datalables of one series. But If now I show/hide any other series, the hided datalables appears.
I made a jsfiddle example. Do the following steps to see my meaning:
1. click on button 1 to hide datalables on series1
2. Hide series 2
Now the datalables on series 1 shows up. How can I stop this behavior?
jsfiddle link: http://jsfiddle.net/jmogexfj/2/
$(function () {
button1();
$('#container').highcharts({
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
useHTML: true,
formatter: function () {
return '<div class="label_'+this.series._i+'">' + this.y + '</div>';
}
}
}
},
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]
},
{
data: [10.9, 50.5, 60.4, 100.2, 104.0, 106.0, 120.6, 108.5, 106.4, 104.1, 90.6, 50.4]
}]
});
});
function button1(){
$("#b1").click(function(){
$(".label_0").toggle();
});
}
That's how Highcharts library works. When you update chart (like hiding by legend, resizing window browser etc.), elements are redrawn.
To hide dataLabels, use series.update():
$('#container').highcharts().series[0].update({
dataLabels: {
enabled: false
}
});
Demo: http://jsfiddle.net/jmogexfj/4/
If you really need to use classes, then use chart.events.redraw to show/hide dataLabel on each redraw: http://jsfiddle.net/jmogexfj/5/
Highcharts example:
chart: {
events: {
redraw: function () {
var showOrHide = display ? 'show' : 'hide';
$(".label_0")[showOrHide]();
}
}
},
Click button:
function button1() {
$("#b1").click(function () {
display = !display;
$(".label_0").toggle();
});
}

Highcharts: how display tooltip, when point = null?

When we hover on may In example, we don't see tooltip for this month, because data is null. Can I set the settings to see the tooltip when data is null?
Well as far as I know there is no generic option for that since highcharts ignores null values from showing.
On the other hand, we can replace the null points with "fake" ones, that have an average value between the 2 closest points (this will cause the chart flow remain the same), and with a custom property isNull which can be used as a flag later.
After doing that, we can use a formatter function for the tooltip, and manipulate the tooltip the way we want, for example displaying only the series name when a point isNull.
$(function () {
$('#container').highcharts({
title: {
text: 'The line is connected from April to Juni, despite the null value in May'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
series: {
connectNulls: true
}
},
tooltip: {
formatter: function(){
if(this.point.isNull == undefined)
return this.series.name+"<br>"+"<b>value:</b>"+this.y;
return this.series.name;
}
},
series: [{
data: [null, 71.5, 106.4, 129.2, null, 176.0, 135.6, null, 216.4, 194.1, 95.6, 54.4]
}]
}, function(chart){
var series = chart.series[0];
var data = series.data;
$.each(data,function(i){
var point = data[i];
var prevPoint = data[i-1] != undefined ? data[i-1].y : 0;
var nextPoint = data[i+1] != undefined ? data[i+1].y : 0;
if(point.y == null){
series.addPoint({x:point.x,y:(prevPoint+nextPoint)/2, isNull:true});
}
});
});
});
http://jsfiddle.net/zb5ksxtc/1/
I hope this is what you meant.
UPDATE
We can also do something not less hacky... (I guess a little hacking could work fine in this unusuall case)
What I did here was creating a "fake" scatter series, with points located where null values from the real series (used same average logic).
The series has hidden markers, and has a unique name.
After that, I used a shared tooltip and a formatter to display the right tooltip.
I used the name attribute to determine what series is focused:
$(function () {
$('#container').highcharts({
title: {
text: 'The line is connected from April to Juni, despite the null value in May'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
series: {
connectNulls: true,
},
},
tooltip: {
shared:true,
formatter: function(){
var points = this.points;
var seriesName = points[0].series.name;
if(seriesName == 'fake')
return "Null tooltip";
return seriesName+"<br>value: <b>"+this.y+"</b>";
}
},
series: [{
type:'areaspline',
data: [null, 71.5, 106.4, 129.2, null, 176.0, 135.6, null, 216.4, 194.1, 95.6, 54.4]
},
{
type:'spline',
lineWidth:0,
name:'fake',
showInLegend:false,
marker:{
symbol:'circle',
radius:0,
}
}
]
}, function(chart){
var series = chart.series[0];
var fake_series = chart.series[1];
$.each(series.data, function(i){
var point = this;
var nextPoint = series.data[i+1] != undefined ? series.data[i+1].y : 0;
var prevPoint = series.data[i-1] != undefined ? series.data[i-1].y : 0;
if(series.data[i].y == null)
fake_series.addPoint([series.data[i].x, (nextPoint+prevPoint)/2]);
});
});
});
and the fiddle ofcourse: http://jsfiddle.net/zb5ksxtc/8/

Can not exporting renderer shapes added in callback function in highcharts / highstock

I want to dynamically added several primitive shapes like text and images into highcharts / highstock.
Please see this fiddle.
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
spacingBottom: 50
},
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) { // on complete
$("#add").click(function(){
chart.renderer.image('http://highcharts.com/demo/gfx/sun.png', 100, 100, 30, 30)
.add();
});
});
});
After click button "Add Image", there is a image will be added to chart. Unfortunately, those dynamically added elements can not be exported to images.
Is there any possible solution to fix this?
You can use chart.exportChart() function to achieve that: http://jsfiddle.net/B6s7V/38/
The same solution as here.
$("#export").click(function () {
chart.exportChart(null, {
chart: {
events: {
load: function () {
this.renderer.image('http://highcharts.com/demo/gfx/sun.png', 100, 100, 30, 30).add();
}
}
}
});
});
When you export a chart, the chart SVG is regenerated from the original .Chart call. If you want to add things after the chart has drawn, do it in the charts:events:load callback.
chart: {
renderTo: 'container',
spacingBottom: 50,
events: {
load: function(){
this.renderer.image('http://highcharts.com/demo/gfx/sun.png', 100, 100, 30, 30).add();
}
}
},
See updated fiddle here.

Resources