I am using the highcharts library to collect data from a csv file every 2 minutes and dispaly it in the graph.
Instead of refreshing the data, the function just duplicates the data and my browser ends up crashing. Can some one help ? i am running out of ideas. Below is my code. I have removed all the xAxis,Yaxis,legend from the code to make it shorter
<script type="text/javascript">
var chart;
var options = {
chart: {
renderTo: 'container',
defaultSeriesType: 'spline',
events: {
load: function() {
setInterval(function(){
refresh('file.csv');
}, 120000);
}
}
},
tooltip: {
valueSuffix: ' Views'
},
legend: {
layout: 'left'
},
series : []
};
function refresh(file) {
if(chart) chart.destroy();
$.get(file, function(data) {
var lines = data.split('\n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
var series = {
data: []
};
$.each(items, function(itemNo, item) {
if (itemNo == 0) {
series.name = item;
} else {
series.data.push(parseFloat(item));
}
});
options.series.push(series);
});
chart = new Highcharts.Chart(options);
});
}
$(document).ready(function() {
refresh('file.csv');
});
</script>
<div id="container"></div>
Instead of destroy chart, you can use setData / addSeries function which allows to manipulate data. http://api.highcharts.com/highcharts#Chart.addSeries
http://api.highcharts.com/highcharts#Series.setData
Related
I am using highchart contextmenu (using: https://blacklabel.github.io/custom_events/js/customEvents.js) and drill down and drill up.
Problem:
When I right click on pie chart we are able to call alert which is in contextmenu. At the same time, when I drill down and drill up then right click on pie chart, contextmenu is not working. In plotoption it's working fine but I do not need it in plotoption.
Code:
chart: {
type: 'pie',
events: {
drillup: function () {
var chart = this;
window['chart'] = chart;
setTimeout(function () {
console.log('drillup',chart.series[0].events);
if (!chart.plotOptions){
chart.plotOptions = {};
}
if (!chart.plotOptions.series) {
chart.plotOptions.series = {};
}
if (!chart.plotOptions.series.events) {
chart.plotOptions.series['events'] = {
contextmenu: function () {
alert('hi33')
}
}
}
/*
plotOptions: {
series: {
events: {
contextmenu: function () {
alert('hi33')
}
},
}
},
*/
console.log('drillup222',chart);
}, 100);
},
drilldown: function (e) {
var chart = this;
window['chart'] = chart;
setTimeout(function () {
if (!chart.series[0].events) {
chart.series[0]['events'] = {
contextmenu: function () {
alert('hi33')
}
}
}
console.log('drilldown',chart.series[0]);
}, 100);
}
}
},
https://jsfiddle.net/k14ajzpo/2/
https://jsfiddle.net/0txqk2cn/1/
The workaround for this issue is to add an event to plotOptions and check if event occurred on main series. Check demo and code posted below.
Code:
chart: {
type: 'pie',
events: {
load: function () {
var chart = this;
chart.series[0].customEventsEnabled = true;
}
}
},
plotOptions: {
series: {
events: {
contextmenu: function() {
var series = this;
if (series.customEventsEnabled || series.drilldownLevel) {
console.log('working');
}
}
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/0pLqvmky/
I am trying to update my Highstock candlestick chart with new data points but I can not make it work - and I don't know where is the problem. Everything looks good for me, but chart is not updating.
the updatepoint.php gives this as result
{"time":"1546978140000", "open":"4112.89677", "high":"4112.9", "low":"4112.8", "close":"4112.9"}
when executing the code, the charts updates every minute, but it just clears last candlestick at first update and that's it, no change on next updates
chart: {
events: {
load: function() {
addPopupEvents(this);
var series = this.series[0];
setInterval(function() {
$.ajax({
url: 'http://www.chart.blue/chart/Highstock/updatepoint.php',
dataType: 'json',
success: function(point) {
series.addPoint([point.time, point.open, point.high, point.low, point.close], true, true);
},
});
}, 60000);
}
}
},
You need to convert string values to numbers:
chart: {
events: {
load: function() {
var series = this.series[0];
setInterval(function() {
$.ajax({
url: 'https://www.chart.blue/chart/Highstock/updatepoint.php',
dataType: 'json',
success: function(point) {
series.addPoint([+point.time, +point.open, +point.high, +point.low, +point.close], true, true);
},
});
}, 60000);
}
}
},
Live demo: https://jsfiddle.net/BlackLabel/suj7zaf2/
I have developed one webpage to show multiple charts. It is based on drop down menu selection. For example, if I select line then Line chart should appear in the container, if I select dual axis chart, it should appear in the same container. But while creating synchronized chart. I am facing one problem. It seems that the charts are being created, but they are not getting appended to container. Please help me out.
My code is as follows:
SynchronizedChart.js:
/**
* Synchronize zooming through the setExtremes event handler.
*/
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function (chart) {
if (chart !== thisChart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(e.min, e.max, undefined, false, { trigger: 'syncExtremes' });
}
}
});
}
}
function drawSyncChart(Takennumber) {
/**
* In order to synchronize tooltips and crosshairs, override the
* built-in events with handlers defined on the parent element.
*/
/*$('#displayPanel').bind('mousemove touchmove touchstart', function (e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i = i + 1) {
chart = Highcharts.charts[i];
event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.highlight(e);
}
}
});*/
/**
* Override the reset function, we don't need to hide the tooltips and crosshairs.
*/
Highcharts.Pointer.prototype.reset = function () {
return undefined;
};
/**
* Highlight a point by showing tooltip, setting hover state and draw crosshair
*/
Highcharts.Point.prototype.highlight = function (event) {
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
var output = { "xData": [], "datasets": [] };
//**********************************************
// DATA MANIPULATION AS PER HIGHCHART CONVENTION
//**********************************************
//console.log(JSON.stringify(output));
$.each(output.datasets, function (i, dataset) {
// Add X values
dataset.data = Highcharts.map(dataset.data, function (val, j) {
return [output.xData[j], val];
});
$('<div class="tmp">')
.appendTo('#displayPanel')
.highcharts({
chart: {
marginLeft: 40, // Keep all charts left aligned
spacingTop: 20,
spacingBottom: 20
},
title: {
text: dataset.name,
align: 'left',
margin: 0,
x: 30
},
credits: {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
type: 'datetime',
labels: {
formatter: function () {
return Highcharts.dateFormat('%a %d %b %H:%M:%S', this.value);
}
},
crosshair: true,
},
series: [{
data: dataset.data,
name: dataset.name,
type: dataset.type,
color: Highcharts.getOptions().colors[i],
}]
});
// Append the chart
//div.appendTo("#displayPanel");
});
I am loading JS in following order:
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="../highcharts/highcharts.js"></script>
<script src="../highcharts/modules/exporting.js"></script>
<script src="../highcharts/themes/dark-unica.js"></script>
<script src="../PageJS/Admin/SynchronizedChart.js"></script>
And I am getting the error as follows:
SynchronizedChart.js:94 Uncaught TypeError: $(...).appendTo(...).highcharts is not a function
at Object.<anonymous> (SynchronizedChart.js:94)
at Function.each (datatables.min.js:14)
at drawSyncChart (SynchronizedChart.js:81)
at drawColumnChart (Chart.js:9)
at HTMLSelectElement.<anonymous> (ChemicalAnalysisChart.js:45)
at HTMLSelectElement.dispatch (datatables.min.js:16)
at HTMLSelectElement.r.handle (datatables.min.js:16)
(anonymous) # SynchronizedChart.js:94
each # datatables.min.js:14
drawSyncChart # SynchronizedChart.js:81
drawColumnChart # Chart.js:9
(anonymous) # ChemicalAnalysisChart.js:45
dispatch # datatables.min.js:16
r.handle # datatables.min.js:16
I solved the problem by separating creation of HighCharts and appending to the existing container. Please refer below code for reference:
$('<div id="chart' + i + '" class="col-md-20">').appendTo('#displayPanel');
var chart = new Highcharts.Chart({....... });
Also cleared the container before appending the Charts.
$(".highcharts-container").remove();
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', { 'packages': ['corechart'] });
// Set a callback to run when the Google Visualization API is loaded.
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
$(document).ready(function () {
google.setOnLoadCallback(drawChartCountry);
$("a[href='#tab11']").on('shown.bs.tab', function (e) {
google.load('visualization', '1', {
packages: ['corechart'],
callback: drawChartCountry
});
});
$("a[href='#tab21']").on('shown.bs.tab', function (e) {
google.load('visualization', '1', {
packages: ['corechart'],
callback: drawChartDevice
});
});
$("a[href='#tab31']").on('shown.bs.tab', function (e) {
google.load('visualization', '1', {
packages: ['corechart'],
callback: drawChartVersion
});
});
function drawChartCountry() {
$.post('/AppDashboard/GetCountryChart', {},
function (data) {
var tdata = new google.visualization.DataTable();
tdata.addColumn('string', 'Country');
tdata.addColumn('number', 'No.of Users');
for (var i = 0; i < data.length; i++) {
tdata.addRow([data[i].Name, data[i].Value]);
}
var options = {
title: "",
is3D: true,
//pieSliceText: 'label',
pieStartAngle: 100,
'width': 450,
'height': 350
};
var chart = new google.visualization.PieChart(document.getElementById('chart_country'));
chart.draw(tdata, options);
});
}
function drawChartDevice() {
$.post('/AppDashboard/GetDeviceChart', {},
function (data) {
var devicedata = new google.visualization.DataTable();
devicedata.addColumn('string', 'Device');
devicedata.addColumn('number', 'No.of Users');
for (var i = 0; i < data.length; i++) {
devicedata.addRow([data[i].Name, data[i].Value]);
}
var options = {
title: "",
is3D: true,
pieStartAngle: 100,
'width': 450,
'height': 350
};
var chart = new google.visualization.PieChart(document.getElementById('chart-device'));
chart.draw(devicedata, options);
});
}
function drawChartVersion() {
$.post('/AppDashboard/GetVersionChart', {},
function (data) {
var versiondata = new google.visualization.DataTable();
versiondata.addColumn('string', 'Version');
versiondata.addColumn('number', 'No.of Users');
for (var i = 0; i < data.length; i++) {
versiondata.addRow([data[i].Name, data[i].Value]);
}
var options = {
title: "",
is3D: true,
//pieSliceText: 'label',
pieStartAngle: 100,
'width': 450,
'height': 350
};
var chart = new google.visualization.PieChart(document.getElementById('chart-version'));
chart.draw(versiondata, options);
});
}
});
I have set google chart inside a widget but the sad part is responsive is not working.When i resize it to mobile size the chart data exceeds my widget.Kindly help me with this and if you need more info lemme know,thanks in advance :)
Following is the code that I have developed:
<body>
<div id="container"></div>
</body>
$(function(){
var options = {
chart: {
renderTo: 'container',
type: 'line'
},
xAxis: {
categories: [],
labels: {
y: 20,
rotation: -45,
align: 'right'
}
},
series: []
};
var oDataUrlEntity = serviceUrl;
$.ajax({
type: "GET",
dataType: "json",
url: oDataUrlEntity,
username: "xxxx",
password: "xxxx",
async: false,
cache: false,
timeout: 5000,
error: function(jqXHR, textStatus, errorThrown) {
debugger;
},
success: function(data, textStatus, jqXHR) {
debugger;
data_poRequest = {
rootNode: []
};
for (var i = 0; i < data.d.results.length; i++) {
var obj = data.d.results[i];
data_poRequest.rootNode.push({
key1: obj.fieldName1,
key2: obj.fieldName2
});
}
for (var i = 0; i < data_poRequest.rootNode.length; i++) {
debugger;
options.xAxis.categories.push(data_poRequest.rootNode[i]['fieldName']);
series = {
data: []
};
series.data.push(data_poRequest.rootNode[0]);
options.series.push(series);
//
}
debugger;
chart = new Highcharts.Chart(options);
}
});
});
The problem is now on the highcharts I am getting only one value out of the 24 values in the cateogies array.Also only the legend is coming with 24 series.
Also,in the debugger i can see values inside options.xAxis.categories & also inside series.data,But they are not getting reflected on the Highcharts.
Could anyone help me with this.Thanks in advance.
The problem is that you are creating every time new series. Won't you have instead one series?
So change:
for (var i = 0; i < data_poRequest.rootNode.length; i++) {
debugger;
options.xAxis.categories.push(data_poRequest.rootNode[i]['fieldName']);
series = {
data: []
};
series.data.push(data_poRequest.rootNode[0]);
options.series.push(series);
//
}
To:
series = {
data: []
};
for (var i = 0; i < data_poRequest.rootNode.length; i++) {
options.xAxis.categories.push(data_poRequest.rootNode[i]['fieldName']);
series.data.push(data_poRequest.rootNode[0]);
}
options.series.push(series);