HighCharts and Javascript to pass data as array - javascript

I am trying to pass an Array as a variable, with Javascript, into a HighCharts graph. The points with their markers are displayed correcty, but there is NO spline connecting the dots (Data 2, Purple).
I tried on the same chart as well, to pass an Array directly with the values, and this time HighCharts is displaying the markers and the splines (Data 1, Red).
For both series, all the line parameters (lineWidth, dashStyle, color) are set up.
I tested it on IE11 and Chrome and FireFox, and the result is the same...
Below is the full code. If anybody already encountered this or, better !, have an idea on how to solve this (have both set of data displayed with markers AND line joining those markers), I would be very very interested ! Thanks a lot !!
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Chart</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
var myData = new Array();
for (n=1;n<=10;n++)
{
myData[n]=Math.floor((Math.random() * 10) + 1);
}
var mySeries = [];
for (var i = 0; i < myData.length; i++){
mySeries.push([i,myData[i]]);
}
$('#container').highcharts({
title: {
text: 'Chart',
x: -20 //center
},
xAxis: {
opposite:true,
title: {text: 'Horizontal Axis'},
showFirstLabel: true,
showLastLabel: true,
min: 0, max: 12,
tickInterval: 1,
startOnTick: true,
endOnTick: true,
},
yAxis: {
title: {text: 'Vertical Axis - inverted'},
reversed: true,
showFirstLabel: true,
showLastLabel: true,
min: 0, max: 12,
tickInterval: 1,
startOnTick: true,
endOnTick: true,
},
tooltip: {
valueSuffix: 'Week'
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: [
{name:'Data 1',data:[0,1,2,3,4,5,6,7,8,9,10],marker:{symbol:'circle'},lineWidth:1,dashStyle:'Solid',color:'#FF0000'},
{name:'Data 2',data:mySeries ,marker:{symbol:'circle'},lineWidth:1,dashStyle:'Solid',color:'#FF00FF'},
]
});
});
</script>
</head>
<body>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="width: 1000px; height: 700px; margin: 0 auto"></div>
</body>
</html>

I believe Highcharts is silently failing to draw the spline because your first value of mySeries is undefined.
With myData you start off at n = 1, so myData[0] is still undefined after you run through your for loop. Then you start off mySeries with i = 0so that first undefined value is added to mySeries. If instead you either start i = 1 or change your myData for loop to i = 0 then it should work.
In other words, do this:
var myData = new Array();
for (var n=0; n<10; n++){
myData[n]=Math.floor((Math.random() * 10) + 1);
}
var mySeries = [];
for (var i = 0; i < myData.length; i++){
mySeries.push([i,myData[i]]);
}
That said, I would condense your data generation to one for loop for efficiency reasons which would also remove the problem:
//define an empty array
var mySeries = [];
for (var i = 0; i < 10; i++){
//create your value
var d = Math.floor((Math.random() * 10) + 1);
//push an array into your array
mySeries.push([i,d]);
}

Related

How to change highcharts radius according to data

i have data comprised of both positive and negative values which are to be displayed in a chart. i
am trying to display data in such a way that data point of positive values is greater than that of negative values.
the following is my code
<html>
<head>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div id="demochart"></div>
<button id="update"> Update</button>
<script>
Highcharts.chart('demochart', {
chart: {
type: 'scatter'
},
xAxis: {
categories: [0, 10, 20, 30, 40, 50, 60, 70, 80]
},
series: [{
name: 'Temperature',
data: [15, 50, -56.5, -46.5, -22.1, -2.5, -27.7, -55.7, 76.5]
}]
},function(chart){
$('#update').click(function(){
var data = chart.series[0].data;
var new_array = [];
new_array = data;
console.log(new_array);
for(var i = 0; i < new_array.length; i++){
console.log("For: "+ new_array[i].y);
if(new_array[i].y > 0){
new_array[i].y = "{y:"+ new_array[i] +",marker: {radius: 10}}"
console.log("If: "+ new_array[i].y);
}else{
new_array[i].y = "{y:"+ new_array[i] +",marker: {radius: 4}}"
console.log("Else: "+ new_array[i].y);
}
}
chart.series[0].setData(new_array);
})
});
</script>
</body>
</html>
When i click the update button, the size of data point value radius has to be changed.
Can this scenario will work ?
You can simply use the update method for points that meet your condition and change marker options. For performance reasons, it is better to set redraw parameter to false and redraw the chart after loop to avoid redrawing on every iteration.
Highcharts.chart('container', {
...
}, function(chart) {
$('#update').click(function() {
var points = chart.series[0].points;
points.forEach(function(point) {
if (point.y > 0) {
point.update({
marker: {
radius: 10
}
}, false);
}
});
chart.redraw();
})
});
Live demo: http://jsfiddle.net/BlackLabel/jznums3L/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.Point#update
https://api.highcharts.com/class-reference/Highcharts.Chart#redraw

Axis interaction using Dygraph

I have the following plot at jsfiddle that I am trying to put together using dygraph:
var data = [];
function getData() {
data = [];
var theDate = new Date(2012, 01, 01, 0, 0, 0, 0);
for (var x = 0; x < 1000; x++) {
data.push([new Date(theDate.getTime()), Math.random()]);
theDate.setDate(theDate.getDate() + 1);
}
g.updateOptions({
'file': data
});
}
var g = new Dygraph(document.getElementById("div_g"), data, {
drawPoints: true,
showRoller: false,
rollPeriod: 1,
valueRange: [0.0, 1.2],
labels: ['Time', 'Random'],
xlabel: 'Time',
ylabel: 'Random',
legend: 'always',
showRangeSelector: true
});
function change(el) {
g.setVisibility(el.id, el.checked);
}
setInterval(
getData, 1000)
I would like to edit the axes limits on the fly by simple plot interaction (i.e. no use of text boxes, just use the canvas). Does anyone know if there is a way to do this?

flot multibar chart -- bars too far away

I'm having an issue with flot multibar chart (using orderBars plugin) -- the bars are too far from each other, when having many (=24) columns. I started up from this example, directly from http://en.benjaminbuffet.com/labs/flot/
<script type='text/javascript' src='jquery.flot.min.js'></script>
<script type='text/javascript' src='jquery.flot.orderBars.js'></script>
...
var d1 = [];
for (var i = 0; i <= 5; i += 1)
d1.push([i, parseInt(Math.random() * 30)]);
var d2 = [];
for (var i = 0; i <= 5; i += 1)
d2.push([i, parseInt(Math.random() * 30)]);
ds.push({
data:d1,
bars: {
show: true,
barWidth: 0.3,
order: 1,
lineWidth : 2
}
});
ds.push({
data:d2,
bars: {
show: true,
barWidth: 0.3,
order: 2
}
});
$.plot($("#placeholder"), ds, {
grid:{
hoverable:true
}
});
The bars are nicely next to each other, pairs separated by a space.
But, if I put there 24 columns (yes, I want to create chart for values on 24 hours), i.e. change the beginning of the code:
var d1 = [];
for (var i = 0; i <= 23; i += 1)
d1.push([i, parseInt(Math.random() * 30)]);
var d2 = [];
for (var i = 0; i <= 23; i += 1)
d2.push([i, parseInt(Math.random() * 30)]);
There is a space between the bars that belong to the one x-value; and no space between the two pairs. This is very confusing, user is mismatching the pairs. I need no space (or very little space) between the corresponding bars, and reasonable space between the pairs.
Here is a picture of both graphs, so you can see the problem:
Any help on this? Thx.
You have 24 bars in a confined space. You want more space between the groups of bars. Your options are:
1.) you increase width of your plot.
2.) you decrease the size of each bar.
You can't adjust the space between the bars directly. From the comments to the plugin:
The plugin adjust the point by adding a value depanding of the barwidth
* Exemple for 3 series (barwidth : 0.1) :
*
* first bar décalage : -0.15
* second bar décalage : -0.05
* third bar décalage : 0.05
Here's some code snips with possible fixes:
var d1 = [];
for (var i = 0; i <= 23; i += 1)
d1.push([i, parseInt(Math.random() * 30)]);
var d2 = [];
for (var i = 0; i <= 23; i += 1)
d2.push([i, parseInt(Math.random() * 30)]);
ds = [];
ds.push({
data: d1,
bars: {
show: true,
barWidth: 0.3,
order: 1,
lineWidth: 2
}
});
ds.push({
data: d2,
bars: {
show: true,
barWidth: 0.3,
order: 2
}
});
$.plot($("#placeholder"), ds, {
grid: {
hoverable: true
}
});
ds1 = [];
ds1.push({
data: d1,
bars: {
show: true,
barWidth: 0.005,
order: 1,
lineWidth: 2
}
});
ds1.push({
data: d2,
bars: {
show: true,
barWidth: 0.005,
order: 2
}
});
$.plot($("#placeholder1"), ds1, {
grid: {
hoverable: true
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://www.flotcharts.org/flot/jquery.flot.js"></script>
<script src="http://rawgit.com/emmerich/flot-orderBars/master/js/jquery.flot.orderBars.js"></script>
<div id="placeholder" style="width:3000px; height:300px"></div>
<div id="placeholder1" style="width:600px; height:300px"></div>
EDITS - UPDATED ANSWER
Another idea if you could drop the plugin and jitter the values yourself. This would allow better control on the spacing.
See this snip:
var barWidth = 0.2;
var jitterVal = barWidth / 1.5;
var d1 = [];
for (var i = 0; i <= 23; i += 1)
d1.push([i - jitterVal, parseInt(Math.random() * 30)]);
var d2 = [];
for (var i = 0; i <= 23; i += 1)
d2.push([i + jitterVal, parseInt(Math.random() * 30)]);
ds = [];
ds.push({
data: d1,
bars: {
show: true,
barWidth: barWidth
}
});
ds.push({
data: d2,
bars: {
show: true,
barWidth: barWidth
}
});
$.plot($("#placeholder"), ds, {
grid: {
hoverable: true
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://www.flotcharts.org/flot/jquery.flot.js"></script>
<div id="placeholder" style="width:400px; height:300px"></div>

HighCharts Funnel - Set minimum size of each section

First time ever working with JS and HighCharts... But I'll try to formulate a question so it'll make sense!
At the moment I'm working with only 4 sources of data, which is incredibly easy to throw right in to highcharts.
The problem is, the 4 aggregated numbers is... well, not very consistent.
The numbers I have atm is: 349531093, 156777100, 572480, 7 and 0.
The first number and the second covers the whole funnel, which makes the plot very unattractive and hard to visually see the values.
(Yeah, yeah - the labels are brilliant, but I want to be able to visually see each section).
I've been reading through the documentation of the funnel plot, but I cannot find a way to limit the section size in any way.
So I tried to play around a bit with the different kind of limits, like:
minSize - The minimum size for a pie in response to auto margins. The pie will try to shrink to make room for data labels in side the
plot area, but only to this size. (which does exactly what it says,
so I'm not sure why I even tried it...)
size - that ofc just changed the size of the whole chart....
series: {
dataLabels: {
enabled: true,
format: '<b>{point.name}</b> ({point.y:,.0f})',
minSize: '10%',
color: 'black',
softConnector: true
},
neckWidth: '50%',
neckHeight: '50%',
minSize: '20%',
//-- Other available options
height: '200'
// width: pixels or percent
}
You can see my horrible attempt here at it here: JSFiddle thingy
So to the actual question: Is it possible to set an minimum limit for the section in the funnel?
Any suggestions or just a simple: "dude, not possible" is appreciated!
Cheers!
Unfortunately this is not supported (good idea to post this on userVoice!)
However I have created simple example that you can preprocess data and still display proper values: https://jsfiddle.net/69eey/2/
$(function () {
var dataEx = [
['Raw Events', 349531093],
['Filtered/Aggregated Events', 156777100],
['Correlated Events', 2792294],
['Use Case Events', 572480],
['Finalized', 0]
],
len = dataEx.length,
sum = 0,
minHeight = 0.05,
data = [],
i;
for(i = 0; i < len; i++){
sum += dataEx[i][1];
}
for(i = 0; i < len; i++){
var t = dataEx[i],
r = t[1] / sum;
data[i] = {
name: t[0],
y: ( r > minHeight ? t[1] : sum * minHeight ),
label: t[1]
}
}
It is only workaround of course. You also need to use formatter for a tooltip to make sure you will display proper values (like for dataLabels).
I took Paweł Fus's great example and extended it to include the tooltip correction. Just add the snippet below:
tooltip: {
formatter: function() {
return '<b>'+ this.key +
'</b> = <b>'+ Highcharts.numberFormat(this.point.label, 0) +'</b>';
}
},
JSFiddle with a working example:
HTML
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/funnel.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="width: 600px; height: 400px; margin: 0 auto"></div>
JavaScript
$(function () {
var dataEx = [
['Raw Events', 349531093],
['Filtered/Aggregated Events', 156777100],
['Correlated Events', 2792294],
['Use Case Events', 572480],
['Finalized', 0]
],
len = dataEx.length,
sum = 0,
minHeight = 0.05,
data = [];
for(var i = 0; i < len; i++){
sum += dataEx[i][1];
}
for(var i = 0; i < len; i++){
var t = dataEx[i],
r = t[1] / sum;
data[i] = {
name: t[0],
y: ( r > minHeight ? t[1] : sum * minHeight ),
label: t[1]
}
}
$('#container').highcharts({
chart: {
type: 'funnel',
marginRight: 100
},
title: {
text: 'SEIM Metrics',
x: -50
},
tooltip: {
//enabled: false
formatter: function() {
return '<b>'+ this.key +
'</b> = <b>'+ Highcharts.numberFormat(this.point.label, 0) +'</b>';
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
formatter: function(){
var point = this.point;
console.log(point);
return '<b>' + point.name + '</b> (' + Highcharts.numberFormat(point.label, 0) + ')';
},
minSize: '10%',
color: 'black',
softConnector: true
},
neckWidth: '50%',
neckHeight: '50%',
//-- Other available options
height: '200'
// width: pixels or percent
}
},
legend: {
enabled: false
},
series: [{
name: 'Unique users',
data: data
}]
});
});
You can try normalizing the values first by taking log.
log(349531093)=8.5
log(572480)=5.75

Dynamically draw marker on last point in highcharts

I want to draw a marker on the last point. Data source is dynamic.
Have a look at following code
$(function() {
$("#btn").click(function() {
var l = chart.series[0].points.length;
var p = chart.series[0].points[l - 1];
p.marker = {
symbol: 'square',
fillColor: "#A0F",
lineColor: "A0F0",
radius: 5
};
a = 1;
chart.series[0].points[l - 1] = p;
chart.redraw(false);
});
var ix = 13;
var a = 0;
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
events: {
load: function() {
var series = this.series[0];
setInterval(function() {
ix++;
var vv = 500 + Math.round(Math.random() * 40);
chart.series[0].data[0].remove();
var v;
if (a == 1) v = {
y: vv,
x: ix,
marker: {
symbol: 'square',
fillColor: "#A0F",
lineColor: "A0F0",
radius: 5
}
}
else v = {
y: vv,
x: ix
}
a = 0;
series.addPoint(v);
}, 1500);
}
}
},
plotOptions: {
series: {}
},
series: [{
data: [500, 510, 540, 537, 510, 540, 537, 500, 510, 540, 537, 510, 540, 537]}]
});
});
http://jsfiddle.net/9zNUP/
On button click event I am trying to draw marker on last point which is already added to chart.
Is there a way to do that??
$("#btn").click(function() {
var l = chart.series[0].points.length;
var p = chart.series[0].points[l - 1];
p.update({
marker: {
symbol: 'square',
fillColor: "#A0F",
lineColor: "A0F0",
radius: 5
}
});
a = 1;
});
solution # http://jsfiddle.net/jugal/zJZSx/
Also tidied up your code a little, removed the removal of point before adding one at the end, highcharts supports it inbuilt with the third param to addPoint as true, which denotes shift series, which removes first point and then adds the given point.
I didn't really understand what the a vv etc were, but well i didn't bother much either. I think this is enough based on what you asked for.

Categories