Difference in rendered SVG fetched from FirefoxDriver and HtmlUnitDriver - javascript

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/

Related

Highchart annotation click event doesn't work

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/

redraw method is not refreshing polar chart

I have a similar problem like posted on highchart chart redraw method is not refreshing the chart but I am working with polar chart, so the solution given there is not solving my issue.
So, the code below is showing the highchart correctly, but doesn't refreshing data. Now I'm asking for advice/help how to solve it.
$(function() {
$.getJSON('wind_graph.php?callback=?', function(dataWind) {
var direction = Wind_direction;
var polarOptions = {
chart: {
polar: true,
events : {
load : function () {
setInterval(function(){
RefreshDataWind();
}, 1000);
}
}
},
title: {
text: 'Wind Direction'
},
pane: {
startAngle: 0,
},
tooltip: {
enabled: false
},
legend: {
enabled: false
},
// the value axis
xAxis: {
tickInterval: 15,
min: 0,
max: 360,
labels: {
formatter: function() {
return this.value + '°';
}
}
},
plotOptions: {
series: {
pointStart: 0,
pointInterval: 30,
marker: {
enabled: false
},
},
}
};
// The polar chart
$('#graph-1').highcharts(Highcharts.merge(polarOptions, {
yAxis: {
tickInterval: 5,
min: 0,
max: 25,
visible: false
},
credits: {
enabled: false
},
series: [{
type: 'line',
name: 'Direction',
data: [
[0, 0],
[direction, 20]
],
lineColor: '#7cb5ec',
enableMouseTracking: false,
visible: true,
lineWidth: 2,
zIndex: 8,
}
]
}));
function RefreshDataWind()
{
var chart = $('#graph-1').highcharts();
$.getJSON('wind_graph.php?callback=?', function(dataWind)
{
var direction = Wind_direction;
chart.redraw();
});
chart.redraw();
}
});
});
To be more precise: if given Wind_direction value is equal to 0 (zero), then I need to display on chart the following "spline":
{
type: 'spline',
name: 'CentralCicrleCalmWind1',
data: [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
pointInterval: 30,
pointStart: 0,
lineColor: windLineColor,
enableMouseTracking: false,
lineWidth: windLineWidth,
visible: showCentralCicrleCalmWind,
}, {
type: 'spline',
name: 'CentralCicrleCalmWind2',
data: [2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5],
pointInterval: 30,
pointStart: 0,
lineColor: windLineColor,
enableMouseTracking: false,
lineWidth: windLineWidth,
visible: showCentralCicrleCalmWind,
}
So as You can see, I have additional parameters like "showCentralCircleCalmWind" set to TRUE or FALSE depends on the given "Wind_direction" value and logic for this I have prepared at top of my code (not pasted here).
The thing what I need is:
Read value of variable in given JSON
Set variable "direction" at the begining of javascript code
Display the chart using higcharts library
Read the new value from JSON
Change the variable "direction" to the new value.
Display the new chart for a given value
Back to the point number 4...
Your problem may be helped by using the setData() function (see http://api.highcharts.com/highcharts/Series.setData).
In your example, I'd suggest the following:
function RefreshDataWind()
{
var chart = $('#graph-1').highcharts();
$.getJSON('wind_graph.php?callback=?', function(dataWind)
{
var direction = Wind_direction;
chart.series[0].setData(direction);
/* assuming "direction" to be an array like [1, 2, 3] */
});
}
The following Highcharts demo shows you how this works: http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/members/series-setdata/
Depending on the format of your "Wind_direction" variable, you may need to have a statement before setData() that explicitly makes it an array, since that's what the function is expecting.
I'd also suggest you remove the second instance of chart.redraw(), as the setData() makes that unnecessary.
I hope this is helpful for you!

How do I remove padding from both sides of Highcharts area category chart?

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/

Highcharts column fit/adjust on chart

I write because I go back to being stuck in a problem with Highcharts. I have a monthly chart that works fine except for one thing. The zoom level. The X axis is always shown me a value of 0 (today), so that the zoom level is incorrect. I am attaching a picture to try to explain it better. I need this column set in the graph.
I appreciate your help! Thank you!
The json returned by PHP is (correct results):
{"data":[[1401580800000,2],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0],[1400025600000,0]]}
And Javascript file:
chart = new Highcharts.Chart({
chart: {
renderTo: 'divStatsGrupo',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: tituloMes
},
tooltip: {
formatter: function() {
return Highcharts.dateFormat('%d/%m/%Y',new Date(this.x)) + '<br/>' +'Alarmas: ' + this.y
}
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats : {
day: '%e. %b',
labels: {
style: {
width: '200px','min-width': '100px'
},
useHTML : true,
}
}
},
yAxis: {
title: {
text: 'Total alarmas'
},
allowDecimals: false,
min: 0
},
series : [{
showInLegend: false,
name : 'Grafica Mensual',
type : 'column',
data: data.data,
dataLabels: {
enabled: true,
rotation: 0,
color: '#000000',
align: 'center',
y: 0,
style: {
fontSize: '14px',
fontFamily: 'Verdana, sans-serif',
}}
}]
});
}); ///cierra get
EDIT: I need a graphic for month (user select), but, the white area and Xaxis only appers info for the month selected. The PHP file return a correct JSON chain, but highcharts not fit the columns fine. Sorry for my english!
The problem is with your JSON, where you have duplicated values for the same timestamp. Just remove them.
Then! You have unsorted data, it should be sorted ascending by timestamp.
After fixed, it works fine, see: http://jsfiddle.net/4nCx3/
var data = {
"data": [
[1400025600000, 0],
[1401580800000, 2]
]
};

Flot chart rendering unexpectedly

I'm trying to display a flot chart with 3 arrays. To make things simple the arrays are all the same:
[[1,1],[2,3],[3,6],[4,10],[5,15],[6,21]]
I create the arrays with the following ruby code:
def flot_chart_series
total=0
foo=[]
(1..6).each do |number|
foo.push [number, total+=number]
end
foo
end
Here is my Erb processed Javascript code:
var fb_shares = <%= flot_chart_series %>;
var twitter_shares = <%= flot_chart_series %>;
var email_shares = <%= flot_chart_series %>;
var plot = $.plot($("#statsChart"),
[ { data: fb_shares, label: "Facebook shares"},
{ data: twitter_shares, label: "Twitter shares" },
{ data: email_shares, label: "Email shares" }], {
series: {
lines: { show: true,
lineWidth: 1,
fill: true,
fillColor: { colors: [ { opacity: 0.1 }, { opacity: 0.13 }, { opacity: 0.15 } ] }
},
points: { show: true,
lineWidth: 2,
radius: 3
},
shadowSize: 0,
stack: true
},
grid: { hoverable: true,
clickable: true,
tickColor: "#f9f9f9",
borderWidth: 0
},
legend: {
// show: false
labelBoxBorderColor: "#fff"
},
colors: ["#3071eb", "#30a0eb", "#a7b5c5"],
xaxis: {
ticks: [[1, "JAN"], [2, "FEB"], [3, "MAR"], [4,"APR"], [5,"MAY"], [6,"JUN"],
[7,"JUL"], [8,"AUG"], [9,"SEP"], [10,"OCT"], [11,"NOV"], [12,"DEC"]],
font: {
size: 12,
family: "Open Sans, Arial",
variant: "small-caps",
color: "#697695"
}
},
yaxis: {
ticks:3,
tickDecimals: 0,
font: {size:12, color: "#9da3a9"}
}
});
The problem is that the chart doesnt plot 3 of the same lines, it creates lines that are increasing in value. Here is a screen shot of the graph: flot chart screen shot
Any ideas what I'm doing wrong?
As #captain hints at in his comment this is because you are using the stacking plugin with stack: true. This is going to stack the 3 identical lines on top of each other.
Compare these fiddles: stack true and stack false.
If you don't want to stack just get rid of the plugin (less javascript == faster loading) and the stack: true option.

Categories