I'm new here and not really experienced with highcharts / javascripts and variable data from SQL.
The Situation is that I've got three Pi3 with DHT22 Sensor, the Scripts on the Pis working well, the data is stored to my NAS into a Maria5 DB.
I've managed to display the data (date/time, temperature, humidity) in a table for each sensor:
Data shown in a table
I've also managed to display the date/time and temperature (OR humidity) of all three Pi3Sensors (data) in separate highcharts on one page:
three charts with temperature
What I want to do now is to show the temperature AND humidity in each highchart of the single Pi's charts. When I enter the 2nd yAxis Data (Series 2) for the humidity manually, then it's working:
2nd data series entered manually
There must be something wrong with the variables of temperature and humidity data. I searched a lot online but wasn't able to find something that helps, or I'm just not able to understand it the right way...
In the DB are the fields 'dateandtime' (2018-04-18 15:05:00), 'unix_timestamp' (1524056702), 'sensor' (value "1", "2" or "3" for each sensor), 'temperature' and 'humidity.
The html page should be alright (index.html);
<html>
<head>
<title>Temperatur Uebersicht</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<script type="text/javascript" src="data.js" ></script>
</head>
<body>
<div id="chart1" style="height: 400px; margin: 0 auto"></div>
</body>
</html>
The php file (values1.php) with the SQL connection / statement;
<?php
$con = mysql_connect("localhost","user","password");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("piSensors", $con);
$result = mysql_query("SELECT *
FROM `temperaturedata`
WHERE sensor=1
ORDER BY unix_timestamp DESC
LIMIT 288 ")
or die ("Connection error");
while($row = mysql_fetch_array($result)) {
echo $row['unix_timestamp'] . "/" . $row['temperature'] . "/" . $row['humidity'] . "/" ;
}
mysql_close($con);
?>
...and the javascript (data.js) with the two series. The data of the 2nd serie is entered manually. Here I don't know how to do it with the variables, that the actual data (of humidity) from sql is also shown in the same chart like the temperature:
$(function() {
var x_values1 = [];
var y_values1 = [];
var switch1 = true;
$.get('values1.php', function(data1) {
data1 = data1.split('/');
for (var i in data1)
{
if (switch1 == true)
{
var ts = timeConverter(data1[i]);
x_values1.push(ts);
switch1 = false;
}
else
{
y_values1.push(parseFloat(data1[i]));
switch1 = true;
}
}
x_values1.pop();
$('#chart1').highcharts({
chart : {
type : 'spline'
},
title : {
text : 'Pi1'
},
subtitle : {
text : 'PiSensor # 1'
},
xAxis : {
title : {
text : 'Datum & Zeit'
},
categories : x_values1,
reversed : true
},
yAxis : [{
title : {
text : 'Temperatur'
},
labels : {
formatter : function() {
return this.value + ' C'
}
}
}, {
lineWidth: 1,
opposite: true,
title: {
text: 'Luftfeuchtigkeit'
},
labels : {
formatter : function() {
return this.value + ' %'
}
}
}],
tooltip : {
crosshairs : true,
shared : true,
valueSuffix : ''
},
plotOptions : {
spline : {
marker : {
radius : 4,
lineColor : '#666666',
lineWidth : 1
}
}
},
series : [{
name : 'Temperatur',
data : y_values1,
tooltip : {
valueSuffix: ' C'
}
}, {
name : 'Luftfeuchtigkeit',
data : [20,30,40,20],
yAxis : 1,
tooltip : {
valueSuffix : ' %'
}
}]
});
});
});
function timeConverter(UNIX_timestamp){
var a = new Date(UNIX_timestamp * 1000);
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var year = a.getFullYear();
var month = months[a.getMonth()];
var date = a.getDate();
var hour = a.getHours();
var min = a.getMinutes() < 10 ? '0' + a.getMinutes() : a.getMinutes();
var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min ;
return time;
}
If anyone could help out or route me on the right way, I would be really thankfull!
Edit:
I tried to manage the highchart with the two yAxis data series with this variant.
Output of "values1.php" (unix_timestamp / temperature / humidity):
1524060302/27.3/36.4/1524060002/27.3/36.4/1524059702/27.3/36.4/
Output of "values1.php" with dateandtime (dateandtime / temperature / humidity):
2018-04-18 16:05:00/27.3/36.4/2018-04-18 16:00:00/27.3/36.4/2018-04-18 15:55:00/27.3/36.4/
Picture of the DB structure: DB structure
Picture of the DB values: DB values
Edit (19.04.2018 / 12:25)
I changed the php code like you said:
<?php
$con = mysql_connect("localhost","user","password");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("piSensors", $con);
$result = mysql_query("SELECT *
FROM `temperaturedata`
WHERE sensor=1
ORDER BY unix_timestamp DESC
LIMIT 288 ")
or die ("Connection error");
while($row = mysql_fetch_array($result)) {
echo $row['unix_timestamp'] . "/" . $row['temperature'] . "/" . $row['humidity'] . ";" ;
}
mysql_close($con);
?>
The output of the php file is now like that:
1524134103/26.1/38.1;1524133802/26.1/38.2;1524133502/26.1/37.8;1524133202/26.2/37.9;
Also I made the changes in the javascript:
$(function() {
var x_values1 = [];
var y_values1 = [];
var y_values2 = [];
var switch1 = true;
$.get('values1.php', function(data1) {
data1 = data1.split(';').reverse();
for (var i in data1) {
let tmpData = data1[i].split('/');
y_values1.push({x: parseInt(tmpData[0])*1000, y: parseFloat(tmpData[1])});
y_values2.push({x: parseInt(tmpData[0])*1000, y: parseFloat(tmpData[2])});
}
//x_values1.pop();
console.log(y_values1);
$('#chart1').highcharts({
chart : {
type : 'spline'
},
title : {
text : 'Buro'
},
subtitle : {
text : 'PiSensor # 1'
},
xAxis : {
title : {
text : 'Datum & Zeit'
},
categories : x_values1,
reversed : false
},
yAxis : [{
title : {
text : 'Temperatur'
},
labels : {
formatter : function() {
return this.value + ' C'
}
}
}, {
lineWidth: 1,
opposite: true,
title: {
text: 'Luftfeuchtigkeit'
},
labels : {
formatter : function() {
return this.value + ' %'
}
}
}],
tooltip : {
crosshairs : true,
shared : true,
valueSuffix : ''
},
plotOptions : {
spline : {
marker : {
radius : 4,
lineWidth : 1
}
}
},
series : [{
name : 'Temperatur',
data : y_values1,
color : '#FF0033',
tooltip : {
valueSuffix: ' C'
}
}, {
name : 'Luftfeuchtigkeit',
data : y_values2,
dashStyle: 'shortdot',
color : '#58ACFA',
zones : [{
value: 45,
color: '#00cc00',
}, {
value: 60,
color: '#ff9900',
}, {
value: 100,
color: '#ff0000',
}],
yAxis : 1,
tooltip : {
valueSuffix : ' %'
}
}]
});
});
});
function timeConverter(UNIX_timestamp){
var a = new Date(UNIX_timestamp * 1000);
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var year = a.getFullYear();
var month = months[a.getMonth()];
var date = a.getDate();
var hour = a.getHours();
var min = a.getMinutes() < 10 ? '0' + a.getMinutes() : a.getMinutes();
var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min ;
return time;
}
I added some zone-colors for the humidity (Luftfeuchtigkeit) and another dashStyle. This changes are working well.
But there's a problem with the xAxis Date & Time (or unix_timestamp right now).
xAxis DateTime - Unix_Timestamp Problem in the HighCharts
The SQL statement is still the same (unix_timestamp) and the time converter function at the end is also not changed.
Okay, I managed now to change the xAxis (datetime) with the following code:
xAxis : {
type : 'datetime',
labels: {
format: '{value:%e.%m. %H:%M}'
},
title : {
text : 'Datum & Zeit'
},
categories : x_values1,
reversed : false
},
But I've still two Points which should be changed.
One is the shown time on the HighCharts. The hour is 2 hours to late, the local/server time is +2 hours. I don't know how to add +2 hours to the HighChart Output on the xAxis and Tooltip, or how to adjust the time calculation.
Here are two screenshots of the mentioned problem:
Screenshot 1, 2h time difference
Screenshot 2, SQL DB Data (correct time)
The used javascript code looks now like that:
$(function() {
var x_values1 = [];
var y_values1 = [];
var y_values2 = [];
var switch1 = true;
$.get('values1.php', function(data1) {
data1 = data1.split(';').reverse();
for (var i in data1) {
let tmpData = data1[i].split('/');
y_values1.push({x: parseInt(tmpData[0])*1000, y: parseFloat(tmpData[1])});
y_values2.push({x: parseInt(tmpData[0])*1000, y: parseFloat(tmpData[2])});
}
//x_values1.pop();
console.log(y_values1);
$('#chart1').highcharts({
chart : {
type : 'spline'
},
title : {
text : 'Buro'
},
subtitle : {
text : 'PiSensor # 1'
},
xAxis : {
type : 'datetime',
labels: {
format: '{value:%e.%m. %H:%M}'
},
title : {
text : 'Datum & Zeit'
},
categories : x_values1,
reversed : false
},
yAxis : [{
title : {
text : 'Temperatur'
},
labels : {
formatter : function() {
return this.value + ' C'
}
}
}, {
lineWidth: 1,
opposite: true,
title: {
text: 'Luftfeuchtigkeit'
},
labels : {
formatter : function() {
return this.value + ' %'
}
}
}],
tooltip : {
crosshairs : true,
shared : true,
valueSuffix : '',
},
plotOptions : {
spline : {
marker : {
radius : 4,
lineWidth : 1
}
}
},
series : [{
name : 'Temperatur',
data : y_values1,
color : '#FF0033',
tooltip : {
valueSuffix: ' C'
}
}, {
name : 'Luftfeuchtigkeit',
data : y_values2,
dashStyle: 'shortdot',
color : '#58ACFA',
zones : [{
value: 40,
color: '#FE9A2E',
}, {
value: 60,
color: '#2E9AFE',
}, {
value: 100,
color: '#FE9A2E',
}],
yAxis : 1,
tooltip : {
valueSuffix : ' %'
}
}]
});
});
});
$(function() {
var x_values3 = [];
var y_values3 = [];
var y_values4 = [];
var switch1 = true;
$.get('values2.php', function(data2) {
data2 = data2.split(';').reverse();
for (var i in data2) {
let tmpData = data2[i].split('/');
y_values3.push({x: parseInt(tmpData[0])*1000, y: parseFloat(tmpData[1])});
y_values4.push({x: parseInt(tmpData[0])*1000, y: parseFloat(tmpData[2])});
}
//x_values1.pop();
console.log(y_values3);
$('#chart2').highcharts({
chart : {
type : 'spline'
},
title : {
text : 'Wohnzimmer'
},
subtitle : {
text : 'PiSensor # 2'
},
xAxis : {
type : 'datetime',
labels: {
format: '{value:%e.%m. %H:%M}'
},
title : {
text : 'Datum & Zeit'
},
categories : x_values3,
reversed : false
},
yAxis : [{
title : {
text : 'Temperatur'
},
labels : {
formatter : function() {
return this.value + ' C'
}
}
}, {
lineWidth: 1,
opposite: true,
title: {
text: 'Luftfeuchtigkeit'
},
labels : {
formatter : function() {
return this.value + ' %'
}
}
}],
tooltip : {
crosshairs : true,
shared : true,
valueSuffix : ''
},
plotOptions : {
spline : {
marker : {
radius : 4,
lineWidth : 1
}
}
},
series : [{
name : 'Temperatur',
data : y_values3,
color : '#FF0033',
tooltip : {
valueSuffix: ' C'
}
}, {
name : 'Luftfeuchtigkeit',
data : y_values4,
dashStyle: 'shortdot',
color : '#58ACFA',
zones : [{
value: 40,
color: '#FE9A2E',
}, {
value: 60,
color: '#2E9AFE',
}, {
value: 100,
color: '#FE9A2E',
}],
yAxis : 1,
tooltip : {
valueSuffix : ' %'
}
}]
});
});
});
$(function() {
var x_values5 = [];
var y_values5 = [];
var y_values6 = [];
var switch1 = true;
$.get('values3.php', function(data3) {
data3 = data3.split(';').reverse();
for (var i in data3) {
let tmpData = data3[i].split('/');
y_values5.push({x: parseInt(tmpData[0])*1000, y: parseFloat(tmpData[1])});
y_values6.push({x: parseInt(tmpData[0])*1000, y: parseFloat(tmpData[2])});
}
//x_values1.pop();
console.log(y_values5);
$('#chart3').highcharts({
chart : {
type : 'spline'
},
title : {
text : 'Schlafzimmer'
},
subtitle : {
text : 'PiSensor # 3'
},
xAxis : {
type : 'datetime',
labels: {
format: '{value:%e.%m. %H:%M}'
},
title : {
text : 'Datum & Zeit'
},
categories : x_values5,
reversed : false
},
yAxis : [{
title : {
text : 'Temperatur'
},
labels : {
formatter : function() {
return this.value + ' C'
}
}
}, {
lineWidth: 1,
opposite: true,
title: {
text: 'Luftfeuchtigkeit'
},
labels : {
formatter : function() {
return this.value + ' %'
}
}
}],
tooltip : {
crosshairs : true,
shared : true,
valueSuffix : ''
},
plotOptions : {
spline : {
marker : {
radius : 4,
lineWidth : 1
}
}
},
series : [{
name : 'Temperatur',
color : '#FF0033',
data : y_values5,
tooltip : {
valueSuffix: ' C'
}
}, {
name : 'Luftfeuchtigkeit',
data : y_values6,
dashStyle: 'shortdot',
color : '#58ACFA',
zones : [{
value: 40,
color: '#FE9A2E',
}, {
value: 60,
color: '#2E9AFE',
}, {
value: 100,
color: '#FE9A2E',
}],
yAxis : 1,
tooltip : {
valueSuffix : ' %'
}
}]
});
});
});
I think the point is somewhere there:
for (var i in data1) {
let tmpData = data1[i].split('/');
y_values1.push({x: parseInt(tmpData[0])*1000, y: parseFloat(tmpData[1])});
y_values2.push({x: parseInt(tmpData[0])*1000, y: parseFloat(tmpData[2])});
values1.php
<?php
$con = mysql_connect("localhost","user","password");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("piSensors", $con);
$result = mysql_query("SELECT *
FROM `temperaturedata`
WHERE sensor=1
ORDER BY unix_timestamp DESC
LIMIT 288 ")
or die ("Connection error");
while($row = mysql_fetch_array($result)) {
echo $row['unix_timestamp'] . "/" . $row['temperature'] . "/" . $row['humidity'] . ";" ;
}
mysql_close($con);
?>
And the 2nd Point is the Tooltip Information.
There should also displayed only the information as on the xAxis is shown.
Like "day.month hour.min" (%e.%m. %H:%M)
Maybe someone can help me out here... thx.
Edit (20.04.2018, 13:19)
I added following code to fix the issue with the time difference of 2 hours:
Highcharts.setOptions({
time: {
timezoneOffset: -2 * 60
}
});
correct display of time
(The SensorData is recorded every 5 minutes)
Now I just have to fix the tooltip information with the date/time format (only display %H:%M)
Related
I am trying to change a time int, such as 010511 into a human readable format of 01:05:11 for both the tooltip, and YAxis of Echarts.
Note that this isn't a timestamp, and is a stopwatch-type piece of data, always starting from 00:00:00 and going up.
Below is the current state of the EChart.
<!-- Echart JS CC -->
<script>
var chart = document.getElementById('cc_chart');
var myChart = echarts.init(chart);
var option = {
title: { text: '' },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
textStyle: {
color: '#fff'
},
grid: {
left: '0',
right: '4%',
bottom: '27%',
top: '4%',
containLabel: true
},
dataZoom: [
{
type: 'inside',
start: 0,
end: 100
},
{
show: true,
type: 'slider',
y: '75%',
start: 0,
end: 100
}
],
legend: {
data: ["Bobby", "Freddy"],
textStyle: {
},
textStyle: {
color: '#fff'
},
bottom: 0,
},
xAxis: {
boundaryGap : false,
data: ["19/03/18","20/03/18","21/03/18","22/03/18","23/03/18","26/03/18","27/03/18","29/03/18","03/04/18"]
},
yAxis: {
boundaryGap : false
},
series: [
{
name: 'Bobby',
type: 'line',
areaStyle: {normal: {}},
symbol: 'circle',
symbolSize: 8,
data: ["011441","011614","011614","003815","001915","003610","000432","000458","005801"]
},
{
name: 'Freddy',
type: 'line',
areaStyle: {normal: {}},
symbol: 'circle',
symbolSize: 8,
data: ["001725","001725","001725","003239","010239","002531","005208","004547","002441"]
},
]
};
myChart.setOption(option);
</script>
How do I change the int value into a more human readable format, within ECharts?
Solved it with the below!
tooltip: {
trigger: 'axis',
formatter: function(params) {
params.sort(function(a,b) { // Sort params by value size first
return parseInt(b.value) - parseInt(a.value)
});
output = '<b>' + params[0].name + '</b><br/>'
for (i = 0; i < params.length; i++) {
output += params[i].marker + params[i].seriesName + ': ' + params[i].value.match(/\d\d/g).join(':'); // : every 2nth
if (i != params.length - 1) { // Append a <br/> tag if not last in loop
output += '<br/>'
}
}
return output
}
}
First we sort the params array with a .sort() function, then we create an output containing the date of the first result as the title (The date will be on every other record, so grabbing it from the first result is fine), then we iterate over the length of the array, appending values we want to the output (formatted using kshetline's answer!), and checking if it's the last result in the array so we can add break tags.
If the time value is reliably six characters like in your examples, call the time value t, and formatting would look like this:
t.substr(0, 2) + ':' + t.substr(2, 2) + ':' + t.substr(4, 2)
Or this, a bit more elegant:
t.match(/\d\d/g).join(':')
params.value[0] contains date in yyyy-mm-dd format
tooltip: {
trigger: 'axis',
formatter: function(params) {
params = params[0];
var chartdate = echarts.format.formatTime('dd-MM-yyyy', params.value[0]);
var val = '<li style="list-style:none">' + params.marker +
params.seriesName + ' ' + params.value[1] + '</li>';
return chartdate + val;
}
},
Based on #pujitha-pinky answer you can adapt it to a multiple series chart like this (example with formating the date to a fr-FR local):
tooltip = {
trigger: "axis",
formatter: function (params) {
var chartdate = (new Date(params[0].value[0])).toLocaleDateString("fr-FR", {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
var vals = params.reduce((prev, curr) => prev + '<li style="list-style:none">' + curr.marker + curr.seriesName + " " + curr.value[1] + "</li>", "");
return chartdate + vals;
},
};
I have written a function that creates a chart based on some graphdata as parameter and renders it to a div . Now I am reusing this function to generate same type of chart on same div to load different series data . The problem is I can see the graph rendering shows previous charts labels for a second and then the new graph gets loaded with new labels . I dont want to see the old graph when my new graph gets loaded . Please help .
My chart function :
<html>
<head>
<script src="./jquery.min.jsl"></script>
<script src="./highcharts.jsl"></script>
<script src="./exporting.jsl"></script>
<meta name="viewport" content="user-scalable=no">
<script>
function renderGraph(graphdata) {
var graphObj = JSON.parse(graphdata);
var chart = null;
Highcharts.setOptions({
lang : {
numericSymbols : ["K", "M", "G", "T", "P", "E"]
}
});
var change = {
0 : '$0K',
2 : '$2K',
4 : '$4K',
6 : '$6K',
8 : '$8K'
};
var xAxisLegends = graphObj.bottomLegends;
var seriesData = graphObj.seriesData;
var xAxisLegends = graphObj.bottomLegends;
//['Q2, 16', 'Q3, 16', 'Q4, 16', 'Q1, 17'];
var columnColors = ["#69C3DB", "#3a8a9f"];
var seriesData = graphObj.seriesData;
/*[{
name : 'Budget',
showInLegend : false,
data : [2, 4, 6, 8]
}, {
name : 'Utilisation',
showInLegend : false,
data : [1, 2, 3, 4]
}];*/
// variables which have diff values according to OS
var chartProperties = {};
// properties to assign to Charts's object
var graphHeight = 0;
// height of chart
var graphWidth = 0;
//Width of the column
var pointWidth;
// Separating the graph dimensions & styling properties as per OS name & version
if (graphObj.osname == "iphone") {
chartProperties = {
type : 'column',
renderTo : 'container'
};
xAxisProp = {
gridLineWidth : 0,
categories : xAxisLegends,
crosshair : true
};
yAxisProp = {
min : 0,
gridLineWidth : 0,
tickAmount : 5,
title : {
text : ' '
},
labels : {
formatter : function() {
var value = this.axis.defaultLabelFormatter.call(this);
return '$' + value;
}
}
};
pointWidth = 5;
} else if (graphObj.osname == "android") {
chartProperties = {
type : 'column',
plotBackgroundColor : null,
plotBackgroundImage : null,
plotBorderWidth : 0,
plotShadow : false,
height : 450,
marginTop : 100,
marginLeft : 120
},
xAxisProp = {
categories : xAxisLegends,
width : 800,
tickmarkPlacement : 'on',
labels : {
y : 40,
style : {
color : '#333333',
fontSize : '25',
fontFamily : 'Metropolis-Light',
opacity : '.6'
},
}
};
yAxisProp = {
gridLineWidth : 0,
min : 0,
tickAmount : 5,
offset : 60,
title : {
text : ''
},
labels : {
align : 'left',
style : {
color : '#333333',
fontSize : '28',
fontFamily : 'Metropolis-Light',
opacity : '.5'
},
formatter : function() {
var value = this.axis.defaultLabelFormatter.call(this);
return '$' + value;
}
},
};
pointWidth = 10;
if (parseInt(graphObj.osversion) >= 500 && parseInt(graphObj.osversion) <= 600) {
graphHeight = 600;
} else {
graphHeight = 630;
}
}
chart =
Highcharts.chart('container', {
chart : chartProperties,
credits : {
enabled : false
},
tooltip : {
enabled : false
},
exporting : {
enabled : false
},
title : {
text : ''
},
xAxis : xAxisProp,
yAxis : yAxisProp,
plotOptions : {
column : {
pointPadding : 0.2,
borderWidth : 0,
groupPadding : 0.38,
pointWidth : pointWidth
}
},
colors : columnColors,
series : seriesData
});
}
</script>
</head>
<body>
<div id="container" style="height: 100%; width: 100%; position : center;"></div>
</body>
The function that calls this chart :
$.webViewPerformanceGraph.url = "/html/Performance.html";
$.webViewPerformanceGraph.addEventListener('load', function() {
$.webViewPerformanceGraph.evalJS("renderGraph('" + JSON.stringify(params) + "');");
Since you're using jQuery, have you tried simply emptying the container div as follows before redrawing the chart?
$('#container').html();
Perhaps this would be more beneficial since chart.destroy() doesn't seem to be working in your case.
From http://api.jquery.com/html/#html2:
When .html() is used to set an element's content, any content that was in that element is completely replaced by the new content. Additionally, jQuery removes other constructs such as data and event handlers from child elements before replacing those elements with the new content.
So I'm working with a bar graph in Chart.js, and I'm trying to get the custom tooltips working. Searching around, it seems like the thing to do in this context is to add
tooltipTemplate: "<%= value %>% test"
to my options section, and that would display the word test after my data value in the resulting tooltip. However, my tooltip remains completely unchanged in reality. And ideas?
Thanks!
Here is an example of custom tooltip label:
var ctx = document.getElementById("myChart");
var barChartData = {
labels : [ "Jan/16", "Feb/16", "Mar/16", "Abr/16", "May/16", "Jun/16", "Jul/16" ],
datasets : [ {
type : 'bar',
label : "Revenue (US$)",
data : [ 4000, 4850, 5900, 6210, 2500, 4000, 6500 ],
backgroundColor : 'rgba(0, 0, 255, 0.3)'
} ]
};
var myChart = new Chart(ctx,
{
type : 'bar',
data : barChartData,
options : {
responsive : true,
tooltips : {
callbacks : { // HERE YOU CUSTOMIZE THE LABELS
title : function() {
return '***** My custom label title *****';
},
beforeLabel : function(tooltipItem, data) {
return 'Month ' + ': ' + tooltipItem.xLabel;
},
label : function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].label + ': ' + tooltipItem.yLabel;
},
afterLabel : function(tooltipItem, data) {
return '***** Test *****';
},
}
},
scales : {
xAxes : [ {
display : true,
labels : {
show : true,
}
} ],
yAxes : [ {
type : "linear",
display : true,
position : "left",
labels : { show : true },
ticks : {
beginAtZero : true
}
} ]
}
}
});
I have some UV Sensors (currently running on Thingspeak) - but I need to have multiple series on the same chart, so I made a sample .php page on my website.
I have the basic chart working nicely, but I have not been able to get it to do live updates - my coding skills are very lacking & I would appreciate any help I can get!
The sample chart is here: http://www.sesupply.co.nz/test.php
I have the code on JSFiddle here: https://jsfiddle.net/SESupply/9xn65qrL/9/
// variables for the first series
var series_1_channel_id = 43330;
var series_1_field_number = 4;
var series_1_read_api_key = '7ZPHNX2SXPM0CA1K';
var series_1_results = 480;
var series_1_color = '#d62020';
var series_1_name = 'Zims Sensor';
// variables for the second series
var series_2_channel_id = 45473;
var series_2_field_number = 2;
var series_2_read_api_key = 'N12T3CWQB5IWJAU9';
var series_2_results = 480;
var series_2_color = '#00aaff';
var series_2_name = 'UVM30A';
// chart title
var chart_title = 'UV Sensors Zim / UVM30A';
// y axis title
var y_axis_title = 'UV Index';
// user's timezone offset
var my_offset = new Date().getTimezoneOffset();
// chart variable
var my_chart;
// when the document is ready
$(document).on('ready', function () {
// add a blank chart
addChart();
// add the first series
addSeries(series_1_channel_id, series_1_field_number, series_1_read_api_key, series_1_results, series_1_color, series_1_name);
// add the second series
addSeries(series_2_channel_id, series_2_field_number, series_2_read_api_key, series_2_results, series_2_color, series_2_name);
});
// add the base chart
function addChart() {
// variable for the local date in milliseconds
var localDate;
// specify the chart options
var chartOptions = {
chart: {
renderTo: 'chart-container',
defaultSeriesType: 'spline',
zoomType: 'x', // added here
panning: true,
panKey: 'shift',
backgroundColor: '#ffffff',
events: {
load: addSeries
}
},
title: {
text: chart_title
},
subtitle: {
text: 'Click and drag to zoom in. Hold down shift key to pan.'
},
plotOptions: {
series: {
marker: {
radius: 2
},
animation: true,
step: false,
borderWidth: 0,
turboThreshold: 0
}
},
scrollbar: {
enabled: true
// barBackgroundColor: 'gray',
// barBorderRadius: 7,
// barBorderWidth: 0,
// buttonBackgroundColor: 'gray',
// buttonBorderWidth: 0,
// buttonArrowColor: 'yellow',
// buttonBorderRadius: 7,
// rifleColor: 'yellow',
// trackBackgroundColor: 'white',
// trackBorderWidth: 1,
// trackBorderColor: 'silver',
// trackBorderRadius: 7
},
tooltip: {
// reformat the tooltips so that local times are displayed
formatter: function () {
var d = new Date(this.x + (my_offset * 60000));
var n = (this.point.name === undefined) ? '' : '<br>' + this.point.name;
return this.series.name + ':<b>' + this.y + '</b>' + n + '<br>' + d.toDateString() + '<br>' + d.toTimeString().replace(/\(.*\)/, "");
}
},
xAxis: {
type: 'datetime',
title: {
text: 'Date'
}
},
rangeSelector: {
enabled: true,
buttons: [{
type: 'minute',
count: 60,
text: 'Hour'
}, {
type: 'day',
count: 1,
text: 'Day'
}, {
type: 'week',
count: 1,
text: 'Week'
}, {
type: 'all',
text: 'All'
}]
},
yAxis: {
title: {
text: y_axis_title
}
},
exporting: {
enabled: true
},
legend: {
enabled: true
},
credits: {
text: 'ThingSpeak.com',
href: 'https://thingspeak.com/',
style: {
color: '#D62020'
}
}
};
// draw the chart
my_chart = new Highcharts.Chart(chartOptions);
}
// add a series to the chart
function addSeries(channel_id, field_number, api_key, results, color, name) {
var field_name = 'field' + field_number;
// get the data with a webservice call
$.getJSON('https://api.thingspeak.com/channels/' + channel_id + '/fields/' + field_number + '.json?offset=0&round=2&results=' + results + '&api_key=' + api_key, function (data) {
// blank array for holding chart data
var chart_data = [];
// iterate through each feed
$.each(data.feeds, function () {
var point = new Highcharts.Point();
// set the proper values
var value = this[field_name];
point.x = getChartDate(this.created_at);
point.y = parseFloat(value);
// add location if possible
if (this.location) {
point.name = this.location;
}
// if a numerical value exists add it
if (!isNaN(parseInt(value))) {
chart_data.push(point);
}
});
// add the chart data
my_chart.addSeries({
data: chart_data,
name: name,
color: color
});
});
setTimeout(addSeries, 1000);
}
cache: false;
// converts date format from JSON
function getChartDate(d) {
// offset in minutes is converted to milliseconds and subtracted so that chart's x-axis is correct
return Date.parse(d) - (my_offset * 60000);
}
I have tried following the livedata example but seem to be failing miserably. The sensors update about every 60 seconds (only during the day - as there is no UV at night, I put the sensors into "sleep" mode to save battery power)
I currently have a working chart using this:
$.ajax({
type: "GET",
url: graphURL,
data: "",
cache: false,
success: function (response) {
//alert(response);
jsonData = JSON.parse(response);
if(jsonData != '' && jsonData != null) {
var category = jsonData.XData.split(",");
var series = jsonData.YData.split(",");
series = $.each(series, function (i, amt) {
series[i] = parseFloat(series[i]);
});
//Display chart
UserChart(series, category, jsonData.YAxisTitle);
}
}
});
... but it doesn't allow me to set options like if I wanted an area chart instead of line etc.. how do I modify the code so I could include something like the following which I see in all examples:
chart : {
renderTo : 'container'
},
rangeSelector : {
selected : 1
},
title : {
text : 'AAPL Stock Price'
},
series : [{
name : 'AAPL Stock Price',
data : data,
type : 'area',
threshold : null,
tooltip : {
valueDecimals : 2
},
fillColor : {
linearGradient : {
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops : [[0, Highcharts.getOptions().colors[0]], [1, 'rgba(0,0,0,0)']]
}
}]
The problem is that series is the series points' data.
Try to pass a serie to UserChart.
Like the following:
var points = jsonData.YData.split(",");
points = $.each(series, function (i, amt) {
points[i] = parseFloat(series[i]);
});
// here you set your serie config
var serie = {
name: 'AAPL Stock Price',
type: 'area',
data: points,
threshold : null,
tooltip : {
valueDecimals : 2
}
};
UserChart(serie, category, jsonData.YAxisTitle);
Then in UserChart you should add the serie directly to the chart series.
Example:
var options: {
chart : {
renderTo : 'container'
},
rangeSelector : {
selected : 1
},
title : {
text : 'AAPL Stock Price'
},
series : []
};
function UserChart(serie, category, jsonData.YAxisTitle) {
options.series.push(serie);
// add your code
}