I am trying to add a click event on a Highchart annotation but it doesn't work ..
I tried to set the events property on the annotation object like described here :
https://www.highcharts.com/products/plugin-registry/single/17/Annotations
events
mouseup, click, dblclick. this in a callback refers to the annotation
object.
And I don't find anything about annotation events here : https://api.highcharts.com/highcharts/annotations
What I am doing wrong ?
// Data generated from http://www.bikeforums.net/professional-cycling-fans/1113087-2017-tour-de-france-gpx-tcx-files.html
var elevationData = [
[0.0, 225],
[0.1, 226],
[0.2, 228],
[0.3, 228],
[0.4, 229],
[0.5, 229],
[0.6, 230],
[0.7, 234],
[0.8, 235],
[0.9, 236],
[1.0, 235],
];
// Now create the chart
Highcharts.chart('container', {
chart: {
type: 'area',
zoomType: 'x',
panning: true,
panKey: 'shift',
scrollablePlotArea: {
minWidth: 600
}
},
title: {
text: '2017 Tour de France Stage 8: Dole - Station des Rousses'
},
subtitle: {
text: 'An annotated chart in Highcharts'
},
annotations: [{
labelOptions: {
backgroundColor: 'rgba(255,255,255,0.5)',
verticalAlign: 'top',
y: 15
},
labels: [{
point: {
xAxis: 0,
yAxis: 0,
x: 0.9,
y: 235,
},
text: 'Arbois',
}],
events:{
click: function(e){alert('test');}
}
}],
xAxis: {
labels: {
format: '{value} km'
},
minRange: 5,
title: {
text: 'Distance'
}
},
yAxis: {
startOnTick: true,
endOnTick: false,
maxPadding: 0.35,
title: {
text: null
},
labels: {
format: '{value} m'
}
},
tooltip: {
headerFormat: 'Distance: {point.x:.1f} km<br>',
pointFormat: '{point.y} m a. s. l.',
shared: true
},
legend: {
enabled: false
},
series: [{
data: elevationData,
lineColor: Highcharts.getOptions().colors[1],
color: Highcharts.getOptions().colors[2],
fillOpacity: 0.5,
name: 'Elevation',
marker: {
enabled: false
},
threshold: null
}]
});
#container {
max-width: 800px;
min-width: 380px;
height: 400px;
margin: 1em auto;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/annotations.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<div id="container" style="height: 400px; min-width: 380px"></div>
EDIT :
I resolved my problem by getting the annotation.group element and assign it a event handler.
for(var annotation in chart.annotations){
var element = chart.annotations[annotation].group.element;
element.addEventListener("click",function(e){alert('here I am');});
}
It not supported, but very simple and quick in implementation. You need to do the wrap on the initLabel function, and after calling proceed, just assign the events defined in your Annotation / label object. Here is the example code with handling click event:
(function(H) {
H.wrap(H.Annotation.prototype, 'initLabel', function(proceed, shapeOptions) {
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
var label = this.labels[this.labels.length - 1]
var annotation = label.annotation
if (label && annotation) {
label.element.onclick = label.options.events.click || annotation.options.events.click
}
})
})(Highcharts)
It assigns the event defined in your label object, but if it's undefined, it takes the function definition directly from Annotation object for all labels.
Additionally, you can read more about Highcharts.wrap() function here: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts
Here is the example of using it: http://jsfiddle.net/ew7ufnjb/
[EDIT]
Wrap method is no longer necessary since v7.0. Just delete the wrap method and keep the event definition from general Annotation object.
Live example: http://jsfiddle.net/rgm3puL8/
Related
I need to create a div container for a highcharts graphic. This should be done by means of code, but I can not make it work.
The reason to create divs by code is because I have to show many graphics.
Currently I first create the div, then the id and finally the properties.
Error on graphic:
Example :
http://jsfiddle.net/povyq7em/1/
My code is:
var nombre="container-speed";
var div = document.createElement('div');
div.setAttribute("style", "width: 580px; height: 400px; float: left");
div.setAttribute("id", nombre);
var gaugeOptions = {
chart: {
type: 'solidgauge'
},
title: null,
pane: {
center: ['50%', '85%'],
size: '140%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor: (Highcharts.theme &&
Highcharts.theme.background2) || '#EEE',
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc'
}
},
tooltip: {
enabled: false
},
yAxis: {
stops: [
[0.1, '#55BF3B'], // green
[0.5, '#DDDF0D'], // yellow
[0.9, '#DF5353'] // red
],
lineWidth: 0,
minorTickInterval: null,
tickAmount: 2,
title: {
y: -70
},
labels: {
y: 16
}
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true
}
}
}
};
var chartSpeed = Highcharts.chart(nombre, Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: 200,
title: {
text: 'Speed'
}
},
credits: {
enabled: false
},
series: [{
name: 'Speed',
data: [80],
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:25px;color:' +
((Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black') + '">{y}</span><br/>' +
'<span style="font-size:12px;color:silver">km/h</span></div>'
},
tooltip: {
valueSuffix: ' km/h'
}
}]
}));
.highcharts-yaxis-grid .highcharts-grid-line {
display: none;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/solid-gauge.js"></script>
<!--<div id="container-speed" style="width: 300px; height: 200px; float: left"></div>-->
Thank you very much for your help.
You're just missing one step. You need to append the element after you create it. Here's the beginning of your code:
var nombre="container-speed";
var div = document.createElement('div');
div.setAttribute("style", "width: 580px; height: 400px; float: left");
div.setAttribute("id", nombre);
// APPEND ELEMENT TO document.body
document.body.appendChild(div);
Also, I updated your fiddle
Per your request, I updated the fiddle once more. I made 3 changes. Only one of which were really important.
declare and value name to be used as element id and as argument for grafica()
var name = "chart-" + i;
alter setAttribute to div.setAttribute("id", name);
***MOST IMPORTANTLY, you changed the variable nombre to name in every place but here var chartSpeed = Highcharts.chart(name, Highcharts.merge(gaugeOptions, {... which you can tell, I've updated.
There's too much padding on either side of the area chart and minPadding/maxPadding doesn't work with categories.
I want the area chart to start and end without any padding.
My code is below:
http://jsfiddle.net/nx4xeb4k/1/
$('#container').highcharts({
chart: {
type: 'area',
inverted: false
},
title: {
text: 'Too Much Padding On Either Side'
},
plotOptions: {
series: {
fillOpacity: 0.1
}
},
xAxis: {
type: 'category'
},
yAxis: {
title: {
text: 'Data Point'
}
},
legend: {
enabled: false
},
tooltip: {
pointFormat: '<b>{point.y}</b> points'
},
series: [{
name: 'Visits',
data: [
["Monday", 58],
["Tuesday", 65],
["Wednesday", 55],
["Thursday", 44],
["Friday", 56],
["Saturday", 65],
["Sunday", 69]
],
dataLabels: {
enabled: false,
rotation: -90,
color: '#FFFFFF',
align: 'right',
format: '{point.y:.1f}',
y: 10,
style: {
fontSize: '14px',
fontFamily: 'Verdana, sans-serif'
}
}
}]
});
A colleague of mine solved this very situation for some of my charts. Their solution was to remove the type: 'category' from the x-axis (making it a linear type instead) and instead replace the axis labels from an array.
Here's what's been changed:
First, I added an array of your x-axis labels.
var categoryLabels = ["Monday","Tuesday","Wednesday","Thursday","Friday",
"Saturday","Sunday"];
Next, I updated your series values to hold only the y-axis values.
series: [{
name: 'Visits',
data: [58, 65, 55, 44, 56, 65, 69],
Then, for your x-axis, I included a formatter function to pull in the labels from the array as substitutes for the default linear values.
xAxis: {
labels: {
formatter: function(){
return categoryLabels[this.value];
}
}
},
Lastly, I updated the tooltip options to show the values from the labels array.
tooltip: {
formatter: function () {
return categoryLabels[this.x] + ': ' + Highcharts.numberFormat(this.y,0);
}
},
I updated your fiddle with this tweaks: http://jsfiddle.net/brightmatrix/nx4xeb4k/4/
I hope you'll find this solution as useful as I have!
According to API, the default value of highcharts.xAxis.tickmarkPlacement is between and this is why the point of each category drops between two ticks on xAxis in your chart.
By setting highcharts.xAxis.tickmarkPlacement to on and playing around the value of highcharts.xAxis.min and highcharts.xAxis.max like this, you should be able to achieve what you want.
You can declare the min / max values to fix the problem.
var categoryLabels = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];
//....
xAxis: {
min: 0.49,
max: categoryLabels.length - 1.49,
categories: categoryLabels,
type: 'category'
},
Example:
http://jsfiddle.net/fo04m7k7/
I am creating highchart graph using the following code in a HTML file using JQuery 1.8 and Highcharts 4.1.9.
<div id="JSGraphContainer" class="GraphContainerJS" "></div>
<script>
$(function() {
var line;
var plotList= [];
data = {"vals": [['1244246400000', 11],
['1244332800000', 22],
['1244419200000', 11],
['1244505600000', 22],
['1244592000000', 33],
['1244678400000', 11],
['1244764800000', 22]
]};
$("#JSGraphContainer").highcharts({
chart: {
type: 'line',
zoomType: "x",
plotBorderWidth: 1,
plotBorderColor: 'black',
},
title: {text: null},
xAxis: {
crosshair: true,
type: 'datetime',
opposite: true,
tickmarkPlacement: "on",
gridLineDashStyle: "Dash",
gridLineWidth: 1,
tickWidth : 0,
plotLines: plotList,
},
yAxis: {
title: { text: null },
tickAmount: 5,
gridLineDashStyle: "Dash",
opposite: false
},
series: [{ data: data.vals }],
plotOptions: {
series: {
marker: {
enabled: true
}
}
},
legend: {enabled : false},
tooltip: {
formatterdd: function() {
return ((new Date(this.x)).toDateString()) + ", " + this.y;
},
pointFormat: '<span style="color:{point.color}">\u25CF</span><b>{point.y}</b><br/>',
crosshairs: {
color: 'green',
dashStyle: 'solid'
}
}
});
});
</script>
My test code which is meant to extract generated SVG out for comparison purpose is
WebElement elem = driver.findElement(By.className("GraphContainerJS"));
String contents = (String)((JavascriptExecutor)driver).executeScript("return arguments[0].innerHTML;", elem);
System.out.println(contents);
When I use FirefoxDriver then I get the correct SVG printed out to sysout but when I use JavaScript enabled HTMLUnitDriver, then I get the different SVG output which doesn't match firefox and doesn't render anything when copied on an html file. I tried to use firefox capabilities as
new HtmlLUnitDriver(DesiredCapabilities.firefox());
but it doesn't help. I am hoping there must be a way to configure HtmlUnitDriver, if at all, to get the right output.
Appreciate any pointers.
there is already a method called getSVG in highcharts which can be used.
svg = chart.getSVG()
.replace(/</g, '\n<')
.replace(/>/g, '>');
http://jsfiddle.net/Nishith/g10j2ymc/
I've been asked to do this kind of graph (40,9% and 16,4% are examples, they should indicate something like -6% and 9%):
Any idea on how I can get that kind of result, using a javascript library, if possible (but it is not a must) Highcharts?
Thanks
It's possible with HighCharts, Documentation
e.g.
$(function () {
data = [{
valSecond: 25,
valFirst: 62.5
}];
// Build the data arrays
var secondData = [];
var firstData = [];
for (var i = 0; i < data.length; i++) {
// add second data
secondData.push({
name: "Second",
y: data[i].valSecond,
color: "#00FF00"
});
// add first data
firstData.push({
name: "First",
y: data[i].valFirst,
color:'#FF0000'
});
}
// Create the chart
$('#container').highcharts({
chart: {
type: 'pie'
},
title: {
text: ''
},
plotOptions: {
pie: {
animation: false,
shadow: false,
center: ['50%', '50%']
}
},
tooltip: {
valueSuffix: '%'
},
series: [{
name: 'second',
data: secondData,
size: '30%',
startAngle: 270,
endAngle: 360,
innerSize: '20%'
}, {
name: 'first',
color:'#FFFFFF',
data: firstData,
size: '80%',
startAngle: 0,
endAngle: 225,
innerSize: '60%',
}]
});
});
<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>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="width: 600px; height: 400px; margin: 0 auto"></div>
Jsfiddle
In the highcharts you can adapt donut chart http://www.highcharts.com/demo/pie-donut, remove connectors, set useHTML for dataLabels and rotate by css / rotation SVG element. Missing elements can by added by renderer.
I am using highcharts to draw a column chart as following:
var chart;
var count = 0;
$(function () {
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'graph',
type: 'column',
margin: [ 50, 50, 100, 80]
},
title: {
text: 'Random Data'
},
xAxis: {
categories: [
'T1',
'T2'
],
startOnTick: true,
endOnTick: true,
labels: {
rotation: -45,
align: 'right',
style: {
fontSize: '13px',
fontFamily: 'Verdana, sans-serif'
}
}
},
yAxis: {
min: 0,
title: {
text: 'Y-Axis'
}
},
legend: {
enabled: false
},
tooltip: {
formatter: function() {
return '<b>'+ this.x +'</b><br/>'+
'Tip is: '+ Highcharts.numberFormat(this.y, 1);
}
},
series: [{
name: 'Population',
data: [34.4, 21.8],
dataLabels: {
enabled: true,
rotation: -90,
color: '#FFFFFF',
align: 'right',
x: 4,
y: 10,
style: {
fontSize: '13px',
fontFamily: 'Verdana, sans-serif'
}
}
}]
});
});
});
I added the following function in order to add new points to the chart
function addPoints(name,acc)
{
var series = chart.series[0];
series.addPoint(acc, false, true);
categories = chart.xAxis[0].categories;
categories.push(name+count);
count++;
chart.xAxis[0].setCategories(categories, false);
chart.redraw();
}
The problem is that everytime I add a new point, one column shifts out of the chart. I would like to keep all columns in the chart view, so when I add a new point the chart just zooms out.
Check it on JSFiddle
Thanks in Advance ....
addPoint (Object options, [Boolean redraw], [Boolean shift], [Mixed animation])
Add a point to the series after render time.
Parameters
options: Number|Array|Object
The point options. If options isa single number, a point with that y value is appended to the series.If it is an array, it will be interpreted as x and y values respectively, or inthe case of OHLC or candlestick, as [x, open, high, low, close]. If it is an object, advanced options as outlined under series.data are applied.
redraw: Boolean
Defaults to true. Whether to redraw the chart after the point is added. When adding more thanone point, it is highly recommended that the redraw option beset to false, and instead chart.redraw() is explicitly calledafter the adding of points is finished.
shift: Boolean
Defaults to false. When shift is true, one point is shifted off the start of the series as one is appended to the end. Use this option for live charts monitoring a value over time.
animation: Mixed
Defaults to true. When true, the graph will be animated with default animationoptions. The animation can also be a configuration object with properties durationand easing.
series.addPoint(acc, false, true);
/\ here's the problem, it should be false
Reference
http://api.highcharts.com/highstock#Series
Updated demo