i get my JSON object from my php code in this format (JSONlint ok) :
[
[1375653600000,3.20104,175.00,116.00,11.00,31.00],[...],[1376776800000,2.85625,10.00,1.00,0.00,8.00]
]
i Have to split in 5 different series:
[1375653600000, 3.201014]
[1375653600000, 175.00]
[1375653600000, 116.00]
[1375653600000, 11.00]
[1375653600000, 31.00]
...
and (obviously) each array is for a different highcharts series.
i follow this post to get an idea about split the JSON:
Retrieving JSON data for Highcharts with multiple series?
This is my code:
$(function() {
// See source code from the JSONP handler at https://github.com/highslide-software/highcharts.com/blob/master/samples/data/from-sql.php
$.getJSON('grafico_nuovo.php?callback=?', function(data) {
// Add a null value for the end date
data = [].concat(data, [[Date.UTC(2012, 9, 14, 19, 59), null, null, null, null]]);
// create the chart
$('#container').highcharts('StockChart', {
chart : {
type: 'spline',
zoomType: 'xy'
},
navigator : {
adaptToUpdatedData: false,
series : {
data : data
}
},
scrollbar: {
liveRedraw: false
},
title: {
text: 'analisi consumi e temperature'
},
subtitle: {
text: 'Analisi test solo temperatura media'
},
rangeSelector : {
buttons: [{
type: 'hour',
count: 1,
text: '1h'
}, {
type: 'day',
count: 2,
text: '2d'
}, {
type: 'week',
count: 1,
text: '1w'
},{
type: 'month',
count: 1,
text: '1m'
}, {
type: 'year',
count: 1,
text: '1y'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: true, // it supports only days
selected : 2 // day
},
/*xAxis : {
events : {
afterSetExtremes : afterSetExtremes
},
minRange: 3600 * 1000 // one hour
},*/
xAxis: {
events : {
afterSetExtremes : afterSetExtremes
},
minRange: 3600 * 1000, // one hour
type: 'datetime',
dateTimeLabelFormats: { minute: '%H:%M', day: '%A. %e/%m' },
// minRange: 15*60*1000,
//maxZoom: 48 * 3600 * 1000,
labels: {
rotation: 330,
y:20,
staggerLines: 1 }
},
yAxis: [{ // Primary yAxis
labels: {
format: '{value}°C',
style: {
color: '#89A54E'
}
},
title: {
text: 'Temperature',
style: {
color: '#89A54E'
}
}
}, { // Secondary yAxis
title: {
text: 'Consumo',
style: {
color: '#4572A7'
}
},
labels: {
format: '{value} Kw',
style: {
color: '#4572A7'
}
},
opposite: true
}],
series: [{
name: 'val1',
data: []
}, {
name: 'val2',
data: []
},
{
name: 'val3',
data: []
},
{
name: 'val4',
data: []
},
{
name: 'val5',
data: []
}]
});
});
});
/**
* Load new data depending on the selected min and max
*/
function afterSetExtremes(e) {
var currentExtremes = this.getExtremes(),
range = e.max - e.min,
chart = $('#container').highcharts();
chart.showLoading('Loading data from server...');
$.getJSON('grafico_nuovo.php?start='+ Math.round(e.min) +
'&end='+ Math.round(e.max) +'&callback=?', function(data) {
val1 = [];
val2 = [];
val3 = [];
val4 = [];
val5 = [];
$.each(data, function(key,value) {
val1.push([value[0], value[1]]);
val2.push([value[0], value[2]]);
val3.push([value[0], value[3]]);
val4.push([value[0], value[4]]);
val5.push([value[0], value[5]]);
});
console.log('val1');
chart.series[0].setData(val1);
chart.series[1].setData(val2);
chart.series[2].setData(val3);
chart.series[3].setData(val4);
chart.series[4].setData(val5);
chart.hideLoading();
});
}
The navigator works fine (with little trouble after 3-4 clicks) but the other series doesn't show.
Everything should be ok, but i've probably missed something
Related
When I try to draw a graph, I get an error:echarts.min.js:45 Uncaught TypeError: Bind must be called on a function at bind (<anonymous>) at Bd (echarts.min.js:45:130031)
My echarts-init.js:
let domTemp = document.getElementById("main");
let mytempChart = echarts.init(domTemp, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var option;
runDaysDatas(sens_data_result, sens_name_list);
function runDaysDatas(sens_data_result, sens_name_list) {
const sens_names = sens_name_list;
const datasetWithFilters = [];
const seriesList = [];
echarts.util.each(sens_names, function (sens) {
var datasetId = 'dataset_' + sens;
datasetWithFilters.push({
id: datasetId,
fromDatasetId: sens_data_result,
transform: {
type: 'filter',
config: {
and: [
{ dimension: 'Uid', '=': sens }
]
}
}
});
seriesList.push({
type: 'line',
datasetId: datasetId,
showSymbol: false,
name: sens,
endLabel: {
show: true,
formatter: function (params) {
return params.value[3] + ': ' + params.value[0];
}
},
labelLayout: {
moveOverlap: 'shiftY'
},
emphasis: {
focus: 'series'
},
encode: {
x: 'Date',
y: 'Temperature',
label: ['Name', 'Temperature'],
itemName: 'Date',
tooltip: ['Temperature']
}
});
});
option = {
animationDuration: 10000,
dataset: [
{
id: 'dataset_sens_names',
source: sens_data_result
},
...datasetWithFilters
],
title: {
text: 'Temperature for Day'
},
tooltip: {
order: 'valueDesc',
trigger: 'axis'
},
xAxis: {
type: 'category',
nameLocation: 'middle'
},
yAxis: {
name: 'Temperature'
},
grid: {
right: 140
},
series: seriesList
};
mytempChart.setOption(option);
}
In sens_data_result i pass data from api.
In sens_name_list i pass names of the sensors.
The console does not send errors to my script, it swears at the library. I took an example from the official site and remade it for my task, displaying the temperature by time of day with the name of the sensor. There can be N number of graphs on one chart.
Thnx for help!
Okey, i'm a solved the problem, this is decision:
let url = '/api/sensdata';
let domTemp = document.getElementById("main");
let mytempChart = echarts.init(domTemp, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var option;
$.get(
url,
sensors_uid,
(_rawData) => {
runDaysDatas(_rawData, sens_name_list);
}
);
function runDaysDatas(_rawData, sens_names) {
const datasetWithFilters = [];
const seriesList = [];
_rawData.unshift(['Name', 'Date', 'Humidity', 'Temperature']);
echarts.util.each(sens_names, function (sens) {
var datasetId = 'dataset_' + sens;
datasetWithFilters.push({
id: datasetId,
fromDatasetId: 'dataset_raw',
transform: {
type: 'filter',
config: {
and: [
{ dimension: 'Name', '=': sens }
]
}
}
});
seriesList.push({
type: 'line',
datasetId: datasetId,
showSymbol: false,
name: sens,
endLabel: {
show: true,
formatter: function (params) {
return 'Uid ' + params.value[0] + ': ' + params.value[3] + '°C';
}
},
labelLayout: {
moveOverlap: 'shiftY'
},
emphasis: {
focus: 'series'
},
encode: {
x: 'Date',
y: 'Temperature',
label: ['Name', 'Temperature'],
itemName: 'Temperature',
tooltip: ['Temperature']
},
});
});
console.log(seriesList);
option = {
toolbox: {
show : true,
feature : {
magicType : {show: true, type: ['line', 'bar']},
restore : {show: true},
saveAsImage : {show: true}
}
},
legend: {},
dataset: [
{
id: 'dataset_raw',
source: _rawData
},
...datasetWithFilters
],
tooltip: {
order: 'valueDesc',
trigger: 'axis'
},
xAxis: {
type: 'time',
nameLocation: 'middle',
axisLabel: {
formatter: (function(value){
moment.locales('RU_ru');
return moment(value).format('MM/DD HH:mm');
})
}
},
yAxis: [
{
type : 'value',
axisLabel : {
formatter: '{value} °C'
}
}
],
grid: {
right: 140
},
series: seriesList
};
mytempChart.clear();
mytempChart.setOption(option);
}
window.addEventListener('resize', mytempChart.resize);
I want to display real time data in highcharts from my MYSQL database, I have tried methods like setInterval and setTimeout and chart.redraw() but cant seem to make it work.
I have also tried the dynamic update chart in highcharts link is here : enter code herehttps://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/stock/demo/dynamic-update but cant seem to convert random data syntax to my database data. my code is :
<html>
<head>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js">
</script>
<script src="https://code.highcharts.com/stock/modules/drag-panes.js">
</script>
<link rel="stylesheet" type="text/css" href="/public/oi chart.css">
</head>
<figure class="highcharts-figure">
<div id="container"></div>
</figure>
<script type="text/javascript">
$(document).ready(function() {
Highcharts.stockChart('container', {
options = {
chart: {
renderTo: 'container',
defaultSeriesType: 'line'
},
Highcharts.stockChart('container', {
rangeSelector: {
enabled: true,
selected: customRange,
buttons: [{
type: 'day',
count: 1,
text: '1D'
}, {
type: 'week',
count: 1,
text: '1W'
}, {
type: 'week',
count: 2,
text: '2W'
}, {
type: 'month',
count: 1,
text: '1M'
}, {
type: 'all',
text: 'All'
}]
},
time: {
timezoneOffset: timezone
},
events: {
load: function requestData() {
$.ajax({
url: 'temp_chart.js',
success: function(points) {
var series = chart.series,
shift;
$.each(series, function(i, s) {
shift = s.data.length > 1;
s.addPoint(points[i], true, true);
});
setTimeout(requestData, 1000);
chart.redraw();
},
cache: false
});
}
},
title: {
text: 'Temperature',
},
subtitle: {
text: 'temperature in maharashtra',
},
yAxis: {
title: {
text: 'temperature'
},
resize: {
enabled: true
}
},
xAxis: {
type: 'datetime'
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
series: {
marker: {
enabled: false
},
label: {
connectorAllowed: false
},
}
},
series: [{
name: 'Mumbai',
data: []
}, {
name: 'Pune',
data: []
}],
};
$.getJSON('temp_chart.js', function(json) {
data1 = [<% data array %>];
data2 = [<% data array %>];
$.each(json, function(key, value) {
data1.push([value[0], value[1]]);
data2.push([value[0], value[2]]);
});
options.series[0].data = data1;
options.series[1].data = data2;
chart = new Highcharts.stockChart(options);
});
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
});
</script>
</html>~
Notice that the load callback should be nested in the chart.events object config. API: https://api.highcharts.com/highcharts/chart.events.load
I push array outside loop with (cpu_usage, timestamp and clientID).Now i want to read on console log values of clientID console.log(result[0][2]); .But it shows me a error "Cannot read property '2' of undefined". Is someone knows where is a problem ? Also if i call this array inside loop it works
content of array:
error after i used console.log(result[0][2]);
<div id="cont"></div>
<script type="text/javascript">
$.getJSON( "http://localhost:8000/api/devices", function( res) {
var result= [];
var devNames = new Array();
console.log(result[0][2]);
$.each( res, function(i) {
var deviceNames=data[i].clientAllias;
var clientId=data[i].clientId;
devNames .push(deviceNames);
$.each( res[i].clientData, function(a) {
$.each( res[i].clientData[a], function(key, val) {
clientId2=res[i].clientData[a].clientId
var cpu=res[i].clientData[a].cpuUsage;
var time_usages=res[i].clientData[a].timestamp;
final=[];
final.push(time_usages, cpu, clientId2);
result.push(final);
});
});
});
result.sort();
$(document).ready(function(){
var Object = {
marker: {
states: {
enabled: true,
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: 'Sec'
}, {
count: 1,
type: 'hour',
text: 'Min'
},
{
count: 1,
type: 'day',
text: 'Hours'
},
{
type: 'all',
text: 'All'
}],
title:'hours',
inputEnabled: true,
_selected: 1
},
title: {
text: clientNames,
},
xAxis: {
title: {
enabled: true,
text: 'CPU USAGE'
},
type: 'datetime',
dateTimeLabelFormats: {
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
},
},
plotOptions: {
series: {
marker: {
enabled: false,
}
}
},
series: [{
name:"CPU USAGE",
data: result,
}],
chart: {
renderTo: 'cont'
}
};
var chart = new Highcharts.StockChart(dataObject);
//var chart = $('#container').highcharts('StockChart', dataObject);
});
});
</script>
You’re console logging at the wrong spot. There’s nothing in result when you’re logging so it errors out when you try to access a nested element.
Put the console log at the end (after result.sort()) and you should get what you need
enter image description herei get dates from server and convert all date to timestamp as required highcharts. But, rangeSelector buttons show wrong date. For, example if i have dateBegin = 02/07/2017, and dateEnd 09/07/2017, highstock dateRange shows wrong date like as 01/07/2017 - 08/07/2017. It seems that highstock show always date - 1 day. How can i fix it?
this is my init of config
onInitConfig = ({ series, periodId, height }) => {
const { onSelectRange } = this.props
moment.locale('ru', localization)
const heightChart = `${ height }px`
const config = {
chart: {
height: heightChart,
events: {
redraw: function(event) {
const currentDateBegin = Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.rangeSelector.minInput.HCTime)
const currentDateEnd = Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.rangeSelector.maxInput.HCTime)
onSelectRange && onSelectRange({ currentDateBegin, currentDateEnd })
}
}
},
rangeSelector: {
buttons: [{
type: 'week',
count: '1',
text: 'н'
},{
type: 'month',
count: 1,
text: 'м',
},{
type: 'month',
count: 3,
text: 'кв'
}, {
type: 'month',
count: '6',
text: 'пг'
},{
type: 'year',
count: 1,
text: 'г'
}],
buttonSpacing: 2,
selected: periodId - 1,
inputDateFormat: '%d/%m/%Y',
labelStyle: {
fontFamily: 'HelveticaLight',
fontSize: '14px',
}
},
title: {
align: 'left',
text: '',
},
navigation: {
buttonOptions: {
enabled: false,
}
},
navigator: {
xAxis: {
labels: {
formatter: function () {
return moment(this.value).format('DD MMMM')
},
style: {
fontFamily: 'HelveticaLight',
fontSize: '14px',
}
}
},
},
xAxis: {
labels: {
formatter: function () {
return moment(this.value).format('DD MMMM')
},
style: {
fontFamily: 'HelveticaLight',
fontSize: '14px',
}
}
},
plotOptions: {
series: {
compare: 'percent',
showInNavigator: true
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
valueDecimals: 2,
split: true
},
series: series
}
return config
}
this is my input
order.map((id) => {
const { dateBegin, dateEnd, valueAmount, valueCount, valueQuantity, valueCountCheck, valueCountCustomers } = data[id] || {}
const dateTimeBegin = moment(dateBegin, 'DD.MM.YYYY').toDate().getTime()
const dateTimeEnd = moment(dateBegin, 'DD.MM.YYYY').toDate().getTime()
_.merge( dataCheckCount, { [id]: { id, x: dateTimeBegin, y: valueCount } })
_.merge( dataCheckCount, { [id + 1]: { id: id + 1, x: dateTimeEnd, y: valueCount } })
}
The problem was in timezoneOffset. I add next code to global setOptions and the problem is fixed.
global: {
useUTC: false,
},
I am using HighCharts to make a graph with columns, drilldown series and scatter. The problem which I am having, is that the HighChart is created before the $.getJSON function is succesfully exicited. I have found several other articles, but non yet where two $.getJSON functions are called. The code which I am using:
$(function () {
// Create the chart
var options = {
chart: {
renderTo: 'container_genomefraction',
type: 'column',
events: {
// Declare the events changing when the drilldown is activated
drilldown: function(options) {
this.yAxis[0].update({
labels: {
format: '{value}'
},
title: {text : "Gbp"}
}, false, false);
options.seriesOptions.dataLabels = {
format: '{point.y:.1f}'
};
options.seriesOptions.tooltip = {
pointFormat: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y:.2f}</b> of total<br/>'
};
},
// Declare the events changing when the drillup is activated
drillup: function () {
this.yAxis[0].update({
labels: {
format: '{value}%'
},
title: {text : "Percentages"}
}, false, false);
}
}
},
title: {
text: 'Comparison'
},
xAxis: {
type: 'category'
},
yAxis: [{
title: {
enabled: true,
text: 'Percentages',
style: {
fontWeight: 'normal'
}
},
labels: {
format: '{value}%'
}
},{
min: 0,
title :{
text : 'input'
},
labels: {
format : '{value}'
},
opposite: true
}],
legend: {
enabled: false
},
plotOptions: {
series: {
marker: {
fillColor: '#FFFFFF',
lineWidth: 2,
lineColor: null, // inherit from series
size : 50
},
borderWidth: 0,
dataLabels: {
enabled: true,
format: '{point.y:.1f}%'
}
}
},
tooltip: {
headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
pointFormat: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y:.2f}%</b> of total<br/>'
},
// Declare an empty series
series: [{
name: '',
colorByPoint: true,
data: []
}],
credits: {
enabled: false
},
// Declare an empty drilldown series
drilldown: {
series: [{
name : '',
id: '',
data: []
}]
}
};
// Your $.getJSON() request is now synchronous...
$.ajaxSetup({
async: false
});
// Get the input into one series
$.getJSON('/uploads/fraction.json', function (list) {
options.series = list;
});
// Get the drilldown estimated and total size into one series
$.getJSON('/uploads/drilldown.json', function (list2) {
options.drilldown.series = list2;
var chart = new Highcharts.Chart(options);
});
$.ajaxSetup({
async: true
});
});
My JSONs are formatted:
fraction.json
[{"name":"1","colorByPoint":true,"data":[{"name":1,"y":80,"drilldown":1},{"name":2,"y":87,"drilldown":2},{"name":3,"y":105.71428571429,"drilldown":3}]},{"name":"input","dataLabels":"{enabled,false}","yAxis":1,"type":"scatter","data":[{"y":38,"name":1,"drilldown":1},{"y":"","name":2,"drilldown":2},{"y":27,"name":3,"drilldown":3}],"tooltip":{"headerFormat":"<span style='font-size:11px'>{series.name}<\/span><br>","pointFormat":"<span style='color:{point.color}'>{point.name}<\/span>: <b>{point.y}<\/b><br\/>"}}]
drilldown.json
[{"name":1,"id":1,"data":[["Total",2],["Estimated",2.5]]},{"name":2,"id":2,"data":[["Total",3.9],["Estimated",4.5]]},{"name":3,"id":3,"data":[["Total",3.7],["Estimated",3.5]]}]
When the page is loaded, the graph displays the values of the previous search done and when I reload the page, the correct data is shown. Could someone please help me out?
Add the second getJSON method in the first getJSON success callback like this:
//Get the genome fraction into one series
$.getJSON('/uploads/fraction.json', function (list) {
options.series = list;
//Get the drilldown estimated and total genome size into one series
$.getJSON('/uploads/drilldown.json', function (list2) {
options.drilldown.series = list2;
var chart = new Highcharts.Chart(options);
});
});