Is there a way to keep the scroll on the most right?
I am trying live update on highchart and it seems that sometimes I am encountering scroll being left behind.
$(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
// Create the chart
$('#container').highcharts('StockChart', {
chart: {
events: {
load: function() {
// set up the updating of the chart each second
var series = this.series[0],
hasPlotLine = false,
$button = $('#button'),
chart = $('#container').highcharts(),
yAxis = chart.yAxis[0],
plotLine,
d,
newY;
yAxis.addPlotLine({
value: 66,
color: 'red',
width: 2,
id: 'plot-line-1',
label: {
text: 66,
align: 'right',
y: newY,
x: 0
}
});
setInterval(function() {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, true);
plotLine = yAxis.plotLinesAndBands[0].svgElem;
d = plotLine.d.split(' ');
newY = yAxis.toPixels(y) - d[2];
plotlabel = yAxis.plotLinesAndBands[0].label;
plotlabel.animate({
translateY:newY,
text:y
},400),
plotLine.animate({
translateY: newY
}, 400);
}, 1000);
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title: {
text: 'Live random data'
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -999; i <= 0; i += 1) {
data.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data;
}())
}]
});
});
I know it a little bit hard to explain my concern, but check this image
I have search setExtremes but I am not sure if how it works or how it will be set up on future dated in case this is the function that I am looking for.
Here is the jsfiddle http://jsfiddle.net/kttfv1h3/3/
Appreciate your help
setExtremes() will work - see API http://api.highcharts.com/highcharts/Axis.setExtremes.
The only thing you need to adjust is the min value - you can calculate it from the last point or set some fixed value.
xAxis.setExtremes(x - 1000 * 60, x)
example: http://jsfiddle.net/nmx5hruo/
Related
I have got into little trouble with hiding the markers in the navigator
The problem is that after I set marker.enabled to false. It does nothing. (JS fiddle - line 75)
navigator: {
series: {
lineWidth: 0,
marker: {
enabled: false // this should hide markers
}
}
}
It is doing nothing because I have some condition where if the condition is true I need to insert the marker at that point, like this:(JS fiddle - line 63).
Btw.. in that JSfiddle example I'm setting it for every point, but that doesn't matter.
series: [{
data: {
x: ...,
y: ...,
marker: {
enabled: true
}
}
]}
- so when I set it manually on that point, it will override the global navigator options
PROBLEM - The global navigator option for the marker is overriden by every single point.
GOAL - Hide all markers in the navigator.
JSFiddle
OLD SOLUTION
If you have only 1 serie in the graph - take the Wojciech Smiel answer.
If you have more than 1 serie in the graph - you have to first make an array of the series with the disabled marker, and then set the options like this
navigator: {
series: seriesArray // array with the series and disabled marker
}
NEW SOLUTION
My friend recently discovered better and easier solution, each serie has navigatorOptions property where you can set radius for the marker, if you set it to 0 it will be hidden.
serie.navigatorOptions = { marker: { radius: 0 } };
Quoting the Highcharts navigator documentation:
Unless data is explicitly defined on navigator.series, the data is
borrowed from the first series in the chart.
That's why navigator series has markers despite the fact that you disabled it in navigator options. However, you can add separate data for the navigator where you can disable marker for each point. Check the demo posted below.
Code:
function generateData(markers) {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -999; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.round(Math.random() * 100),
marker: {
enabled: markers
}
});
}
return data;
}
// Create the chart
Highcharts.stockChart('container', {
chart: {
events: {
load: function() {
// set up the updating of the chart each second
var chart = this,
series = this.series[0],
seriesNav = this.series[1];
setInterval(function() {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], false);
seriesNav.addPoint([x, y], true, true);
}, 1000);
}
}
},
time: {
useUTC: false
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title: {
text: 'Live random data'
},
exporting: {
enabled: false
},
plotOptions: {
series: {
marker: {
enabled: true
}
}
},
series: [{
name: 'Random data',
showInNavigator: true,
data: generateData(true)
}],
navigator: {
series: {
lineWidth: 0,
marker: {
enabled: false
},
data: generateData(false)
}
}
});
Demo:
https://jsfiddle.net/BlackLabel/1um9gs47/21/
I want to create a chart that reads its data from an Api. To do that i have this fiddle http://jsfiddle.net/68oe1oLf/69/
Note: https://jsfiddle.net/68oe1oLf/69/ will lead to mixed content error and will fail to load data from the api
This is the javascript code
$(document).ready(function () {
$.get( "http://firmbridgecapital.com/live.php", function( dt ) {
localStorage.setItem("data", dt);
});
window.setInterval(function(){
$.get( "http://firmbridgecapital.com/live.php", function( dt ) {
localStorage.setItem("data", dt);
});
}, 5000);
Highcharts.setOptions({
global: {
useUTC: false
}
});
Highcharts.chart('container', {
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = parseInt(localStorage.getItem("data"));
series.addPoint([x, y], true, true);
}, 5000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
max: 3,
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -150; i <= 0; i += 25) {
data.push({
x: time,
y: parseInt(localStorage.getItem("data"))
});
}
return data;
}())
}]
});
});
I borrowed the idea from this docs example http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/dynamic-update/
My chart is always grounded on value 1 and does not show the changing values in the y axis. How may i fix this?.
The value you are referencing, i.e. live php page, seems to be 1.x and increasing very slowly. (1.7 while I was looking).
In your parsing you do the following:
y = parseInt(localStorage.getItem("data"));
And since the value is 1.7, and you try to parse it as an integer with parseInt, it gets converted to 1. Using parseFloat will give you a slowly increasing graph.
I have a pie chart here that I'm working on that has two "rings" in it. The inner ring is just a summation of the outer ring for that given category.
Here is the fiddle: http://jsfiddle.net/jeffvan576/a50859s7/1/
(Apologies for the code - it's a bit of a mess right now)
I've been messing around with the showInLegend functionality but that will (as it's intended) only pull out the given piece of the pie chart. So, for instance, if you click google, it pulls out that piece of the pie chart but leaves the outer ring. To completely eliminate google you need to click "google", "match", "funds added" and "organic" for google.
My question is, is there a way to remove the entire slice (google and all it's children) from the chart at once?
The issue is that in order to get the functionality / layout on the chart that I need, this pie chart is actually built out of two series.
ShowInLegend code:
pie: {
shadow: false,
center: ['50%', '50%'],
showInLegend: true
}
I started building a custom visibility function at the bottom of the fiddle but dialed it back until I understood showInLegend a little better.
Thanks in advance!
you can achieve this by getting name of series on which clicked by using http://api.highcharts.com/highcharts#plotOptions.pie.events.click of plotoptions -> pie.
after that calling visibility function to hide Channel series along with its children to hide/show.
Event:
plotOptions: {
pie: {
shadow: false,
center: ['50%', '50%'],
showInLegend: true,
point: {
events: {
}
}
}
}
also static line put into visibility function to hide/show need to remove.
// chart.series[0].data[0].visible = false;
http://jsfiddle.net/a50859s7/27/
Full code:
$(function () {
var dataObject = {
facebook: {
'organic': 10.85,
'match': 7.35,
'fundsadded': 33.06,
'total': 0,
'status': 'disabled'
},
google: {
'organic': 10.85,
'match': 7.35,
'fundsadded': 33.06,
'total': 0,
'status': 'disabled'
},
email: {
'organic': 10.85,
'match': 7.35,
'fundsadded': 33.06,
'total': 0,
'status': 'enabled'
},
colorSelections: {
'facebook': '#3b5998',
'google': '#dd4b39',
'disabled': '#c6c6c6'
}
}
var sumObjects = function () {
for (var channel in dataObject) {
if (channel === 'colorSelections') continue;
var sum = 0;
for (var key in dataObject[channel]) {
if (key === 'status') continue;
sum += dataObject[channel][key];
}
dataObject[channel].total = sum;
}
}
sumObjects();
var colors = Highcharts.getOptions().colors,
categories = ['Facebook', 'Google', 'Email'],
data = [{
y: dataObject.facebook.total + 1,
//color: dataObject.facebook.status === 'disabled' ? dataObject.colorSelections.disabled : dataObject.colorSelections.facebook,
color: 'rgba(59, 89, 152, 0.3)',
drilldown: {
name: 'Facebook',
categories: ['organic', 'match', 'funds added'],
data: [
dataObject.facebook.organic,
dataObject.facebook.match,
dataObject.facebook.fundsadded],
color: 'rgba(59, 89, 152, 0.3)'
},
}, {
y: dataObject.google.total + 1,
color: '#dd4b39',
drilldown: {
name: 'Google',
categories: ['organic', 'match', 'funds added'],
data: [
dataObject.google.organic,
dataObject.google.match,
dataObject.google.fundsadded],
color: '#e46f61'
}
}, {
y: dataObject.email.total + 1,
color: colors[2],
drilldown: {
name: 'Email',
categories: ['organic', 'match', 'funds added'],
data: [
dataObject.email.organic,
dataObject.email.match,
dataObject.email.fundsadded],
color: colors[2]
}
}],
browserData = [],
versionsData = [],
i,
j,
dataLen = data.length,
drillDataLen,
brightness;
// Build the data arrays
for (i = 0; i < dataLen; i += 1) {
// add browser data
browserData.push({
name: categories[i],
y: data[i].y,
color: data[i].color
});
// add version data
drillDataLen = data[i].drilldown.data.length;
for (j = 0; j < drillDataLen; j += 1) {
brightness = 0.2 - (j / drillDataLen) / 5;
versionsData.push({
name: data[i].drilldown.categories[j],
y: ((data[i].drilldown.data[j] / browserData[0].y) * 100),
color: Highcharts.Color(data[i].color).brighten(brightness).get()
});
}
}
// Create the chart
$('#container').highcharts({
chart: {
type: 'pie'
},
title: {
text: 'Browser market share, April, 2011'
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
pie: {
shadow: false,
center: ['50%', '50%'],
showInLegend: true,
point: {
events: {
click: function (event) {
var seriesIndex;
var secondarySeriesIndex;
if (this.name == 'Facebook') {
seriesIndex = 0;
secondarySeriesIndex = 0;
} else if (this.name == 'Google') {
seriesIndex = 1;
secondarySeriesIndex = 3;
} else if (this.name == 'Email') {
seriesIndex = 2;
secondarySeriesIndex = 6;
}
var chart = $('#container').highcharts();
visibility(chart.series[0].data[seriesIndex]);
visibility(chart.series[1].data[secondarySeriesIndex]);
visibility(chart.series[1].data[secondarySeriesIndex + 1]);
visibility(chart.series[1].data[secondarySeriesIndex + 2]);
}
}
}
}
},
tooltip: {
valueSuffix: '%'
},
series: [{
name: 'Channel',
type: 'pie',
data: browserData,
size: '120%',
dataLabels: {
formatter: function () {
return this.y > 5 ? this.point.name : null;
},
color: 'white',
distance: -30
}
}, {
name: 'Added',
type: 'pie',
data: versionsData,
size: '120%',
innerSize: '80%',
dataLabels: {
formatter: function () {
// display only if larger than 1
return this.y > 1 ? '<b>' + this.point.name + ':</b> ' + this.y + '%' : null;
}
}
}]
});
var visibility = function (series) {
series.visible ? series.graphic.hide() : series.graphic.show();
// chart.series[0].data[0].visible = false;
}
var chart = $('#container').highcharts();
$('.update').click(function () {
visibility(chart.series[0].data[0]);
visibility(chart.series[1].data[0]);
visibility(chart.series[1].data[1]);
visibility(chart.series[1].data[2]);
chart.redraw();
});
function synchronizePieSeries(event, slice) {
debugger;
$(chart.series[1].data).each(function (i, e) {
if (slice.name === e.name) {
slice.visible ? e.graphic.hide() : e.graphic.show();
}
});
}
//$('.update').click(function (event) {
// synchronizePieSeries(event, this);
//});
});
Is it possible to remove certain points from a series?
I'm looking for some way to draw a chart with a fixed back period,
something like: the last 1 hour.
I know how to add points using dynamic update:
http://www.highcharts.com/demo/dynamic-update
But in my case the time interval between points is not constant,
so I can't just use the shift option of addPoint.
Thanks,
Omer
If you want to have the same, you can use the same logic as in addPoint, see: http://jsfiddle.net/JKCLx/1/
However, why can't you just use shift argument in addPoint()?
I think I found a partial answer to my own question:
I can iterate over the series datapoints like this:
http://api.highcharts.com/highcharts#Series.data
and then call point.Remove.
The problem with this solution is that it does not draw monitor style like in the example,
but rather it redrwas the entire chart on each change.
http://jsfiddle.net/JKCLx/
$(function () {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
$('#container').highcharts({
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function() {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function() {
var x = (new Date()).getTime(), // current time
y = Math.random();
series.addPoint([x, y], true, false);
// series.data[0].remove(false);
series.data[0].remove(true);
}, 1000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'<br/>'+
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
})()
}]
});
});
});
Im using multiple highchart chart inside my page and i use addpoint function to update the chart.
the problem is after some time the chart will be compressed into less than a half of original chart size.
i captured my screen which could be found here for make the problem clear:
http://www.screenr.com/f3E7
sample chart generation code:
$(function () {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
//var chart;
chart = new Highcharts.Chart({
chart: {
renderTo: 'ch_trafficio',
type: 'spline',
marginRight: 10,
events: {
load: function() {
// set up the updating of the chart each second
var series = this.series[0];
var series1= this.series[1];
}
}
},
title: {
text: ''
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'<br/>'+
Highcharts.numberFormat(this.y, 2);
}
},
plotOptions : {
area : {
lineWidth : 1,
marker : {
enabled : false,
states : {
hover : {
enabled : true,
radius : 5
}
}
},
shadow : false,
states : {
hover : {
lineWidth : 1
}
}
}
},
legend: {
enabled: true
},
exporting: {
enabled: true
},
series: [{
name: 'InBound',
type : "area",
color: '#89A54E',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -119; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
})()
},{
name: 'OutBound',
type : "area",
color: '#AA4643',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -119; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
})()
}
]
});
chart update functions:
chart.series[0].addPoint([x,data.oid1], false, true);
chart.series[1].addPoint([x,data.oid2], true, true);
chart1.series[0].addPoint([x,data.oid5], true, true);
chart2.series[0].addPoint([x,data.oid3], false, true);
chart2.series[1].addPoint([x,data.oid4], true, true);
chart3.series[0].addPoint([x,data.oid7], true, true);
thanks in advance
you need to add a shifting parameter for your points to shift over the chart
var series = chart.series[0],
shift = series.data.length > 100; // shift if the series is longer than 100
and to change adding point like below
chart.series[0].addPoint([x,data.oid1], true, shift);
example here