Live update highcharts-gauge from dweet - javascript

I would like to have the gauge chart update live dweet data, which is success.
The problem is that every time a new data is pushed to the array humidityData, a new pointer is added in the gauge chart as shown here:
guage chart Though I'd like to have one live-updating-pointer instead.
Could this be done by pop() the prev data?
<script language="JavaScript">
//Array to store sensor data
var humidityData = []
<!--START-->
$(document).ready(function() {
//My Dweet thing's name
var name = 'dweetThingName'
//Humidity chart
var setupSecondChart = function() {
var chart2 = {
type: 'gauge'
};
var title = {...};
var pane = {...};
var yAxis = {...};
var tooltip = {
formatter: function () {
return '<b>' + "Humidity: " + Highcharts.numberFormat(this.y, 2) + "%";
}
};
//Series_Humidity
humiditySeries = [{
name: 'Humidity %',
data: humidityData,
tooltip: {
valueSuffix: '%'
}
}]
//Json_Humidity
var humJson = {};
humJson.chart = chart2;
humJson.title = title;
humJson.tooltip = tooltip;
humJson.xAxis = xAxis;
humJson.yAxis = yAxis;
humJson.legend = legend;
humJson.exporting = exporting;
humJson.series = humiditySeries;
humJson.plotOptions = plotOptions;
console.log("Sereies: : " +humJson)
//Container_Humidity
$('#containerHumidity').highcharts(humJson);
}
var humiditySeries = [] ....
dweetio.get_all_dweets_for(name, function(err, dweets){
for(theDweet in dweets.reverse())
{
var dweet = dweets[theDweet];
//Dweet's variables' names
val2 = dweet.content["Humidity"]
//Add the vals into created arrayDatas
humidityData.push(val2)
console.log("HumidityData: " + humidityData)
}
//Call other charts
setupSecondChart()
});

When you initialize/update your chart make sure that data array contains only one element. The dial is created for every point in this array (to visualize it on the plot).

Related

Chart.js How to sum the values in a pie chart and display them in the header

I have a pie chart that shows how many people have registered by area. What I need to do is sum the pie slices and display the total in the header/title of the pie chart.
I am using chart.js and c#.
Data
Area People Registered
BBB 618
GG 1186
KK 575
HTC 630
This is my code so far.
#Scripts.Render("~/bundles/chartjs")
<script type="text/javascript">
var seriesColors = [
"#5b9bd5", "#a5a5a5", "#4472c4", "#255e91", "#636363", "#264478", "#7cafdd", "#335aa1", "#698ed0",
"#327dc2", "#848484"
];
var quorumData = [];
var prisecData = [];
//var raincheckData = [];
var groupData = defineGroupDataArray();
//var percent = defineGroupDataArray();
var barData = defineBarDataArray();
$(function() {
// Global Chart Options
Chart.defaults.global.tooltips.mode = "label";
Chart.defaults.global.legend.display = false;
Chart.defaults.global.maintainAspectRatio = true;
// Pie Chart Options
Chart.defaults.pie.segmentShowStroke = true;
// Bar Chart Options
Chart.defaults.bar.scaleBeginAtZero = false;
updateQuorumChart(true);
updateGroupCharts(true);
setInterval(function() {
updateQuorumChart(false),
updateGroupCharts(false);
},
5000);
});
function defineGroupDataArray() {
return {
labels: [],
datasets: [
{
data: [],
backgroundColor: []
}
]
};
};
function drawAttendByAreaChart(animate, quorumData) {
$("#attendbyarea").remove();
$("#attendbyarea-container").append('<canvas id="attendbyarea"></canvas>');
$("#attendbyarea-header").text("Attendees by Area ("+ + ")");
var context = $("#attendbyarea");
var chart = new Chart(context,
{
type: 'pie',
data: groupData,
options: {
animation: {
animateRotate: animate,
animateScale: animate
}
}
});
};
function updateGroupCharts(animate) {
$.getJSON('#Url.Action("GetGroupStatistics", "Account")',
null,
function (result, quorumData) { onUpdateGroupCharts(animate, result) });
};
function onUpdateGroupCharts(animate, result) {
$.each(result,
function(groupIndex, groupValue) {
groupData = defineGroupDataArray();
$.each(groupValue.Data,
function(statIndex, statValue) {
groupData.labels.push(statValue.Description);
groupData.datasets[0].data.push(statValue.Count);
groupData.datasets[0].backgroundColor.push(seriesColors[statIndex]);
});
switch (groupValue.Type) {
case 0:
drawRegByAreaChart(animate);
break;
case 1:
groupData = defineGroupDataArray();
$.each(groupValue.Data,
function(statIndex, statValue) {
groupData.labels.push(statValue.Description +
': ' + statValue.Count +' (' + statValue.ToolTip);
groupData.datasets[0].data.push(statValue.Count);
groupData.datasets[0].backgroundColor.push(seriesColors[statIndex]);
});
drawRegByDistrictChart(animate);
break;
case 2:
barData = defineBarDataArray();
$.each(groupData.datasets[0].data,
function(barIndex, barValue) {
//barData.labels.push(groupData.labels[barIndex]);
barData.datasets[0].data.push(barValue);
});
drawRegByHourChart(animate);
break;
case 3:
drawRegByEmpChart(animate);
break;
case 4:
drawAttendByAreaChart(animate);
break;
}
});
};
</script>
}
In the image below I need the total which is 3,009 to be displayed beside Attendees by Area.
Pie Chart
Figured it out. I used a function to add all the values for people registered and then passed that to my function that draws the pie chart.
In my case statment:
case 4:
groupData = defineGroupDataArray();
var totalAttendees = 0;
$.each(groupValue.Data,
function(statIndex, statValue) {
groupData.labels.push(statValue.Description);
groupData.datasets[0].data.push(statValue.Count);
groupData.datasets[0].backgroundColor.push(seriesColors[statIndex]);
totalAttendees += statValue.Count;
});
drawAttendeesByAreaChart(animate,totalAttendees);
break;
In the draw chart function:
function drawAttendeesByAreaChart(animate,totalAttendees) {
$("#attendbyarea").remove();
$("#attendbyarea-container").append('<canvas id="attendbyarea"></canvas>');
$("#attendbyarea-header").text("Attendees by Area ("+ $.number(totalAttendees) +")");
...rest of code...
};

CanvasJS not properly rendering chart

I am using the following code to render an OHLC chart in CanvasJS:
<script>
var candleData = [];
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: 'Demo Stacker Candlestick Chart (Realtime)'
},
zoomEnabled: true,
axisY: {
includeZero: false,
title: 'Price',
prefix: '$'
},
axisX: {
interval: 1,
},
data: [{
type: 'ohlc',
dataPoints: candleData
}
]
});
function mapDataToPointObject(data) {
var dataPoints = [];
for(var i = 0; i < data.length; i++) {
var obj = data[i];
var newObj = {
x: new Date(obj.time),
y: [
obj.open,
obj.high,
obj.low,
obj.close
]
}
dataPoints.push(newObj);
}
return dataPoints;
}
function updateChart() {
$.ajax({
url: 'http://localhost:8080',
success: function(data) {
candleData = JSON.parse(data);
candleData = mapDataToPointObject(candleData);
chart.render();
}
});
}
$(function(){
setInterval(() => {
updateChart();
}, 500);
});
The data properly loads, parses into the correct format, and render() is called on the interval like it should. The problem is, while the chart axes and titles all render properly, no data shows up. The chart is empty.
What DOES work is setting the data directly to the chart using
chart.options.data[0].dataPoints = candleData;
Why does my above solution not work then? Is there a way I can update the chart's dataPoints without having to hardcode a direct accessor to the chart's dataPoints?
It's related to JavaScript pass by value and pass by reference.
After execution of the following line.
dataPoints: candleData
dataPoints will refer to the current value of candleData. ie. dataPoints = [];
Now if you redefine candleData to any other value.
candleData = JSON.parse(data);
candleData = mapDataToPointObject(candleData);
Then dataPoints won't be aware of this update and will still refer to the empty array (that you pointed earlier).
The following snippet will make it easy to understand
//pass by value
var a = "string1";
var b = a;
a = "string2";
alert("b is: " + b); //this will alert "string1"
//pass by reference
var c = { s: "string1" };
var d = c;
c.s = "string2";
alert("d.s is: " + d.s); //this will alert "string2"
For more, you can read about pass by value and pass by reference.
Javascript by reference vs. by value
Explaining Value vs. Reference in Javascript

Highcharts 2 groups of series

I want to display a chart (that takes the data from a PHP file with JSON) with two dimensions of series : the first one is the technology used (5 in total), and the other one is the export or import.
So when the user is on the page, he can choose to diplay the technology, as export, import or both.
In first, to join one technology import with the same in export, I have used a "linkedto=previous", the result is a single item in the legend per technology.
But I would like to add two items in the legend : "Import" and "Export", with 0 data, that would permit to display or not the import or the export.
I have used this code, but I can't find how to display the choice of import, export, the both, or nothing.
Thank you very much if you take a bit of time to read my post. BR
$(function () {
var chart;
$(document).ready(function() {
var options = {
chart: {
renderTo: 'euro',
type: 'column'
},
title: {
text: 'Vision en euro'
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'k€'
},
stackLabels: {
enabled: true,
rotation: 30,
}
},
tooltip: {
headerFormat: '{point.x}<b></b><br/>',
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: false,
},
}
},
series: []
};
Highcharts.setOptions(Highcharts.theme);
$.getJSON('SOURCE.php', function(json) {
options.xAxis.categories = json[0]['month'];
options.series[0] = {};
options.series[0].name = 'TECHNO 1';
options.series[0].data = json[1]['data'];
options.series[0].stack ='EXPORT';
options.series[0].color= '#808080';
options.series[1] = {};
options.series[1].name = 'TECHNO 1';
options.series[1].data = json[0]['data'];
options.series[1].stack = 'IMPORT';
options.series[1].linkedTo = ':previous';
options.series[1].color= 'url(#highcharts-default-pattern-0)';
options.series[2] = {};
options.series[2].name = 'TECHNO 2';
options.series[2].data = json[3]['data'];
options.series[2].stack = 'EXPORT';
options.series[2].color= '#FFC125';
options.series[3] = {};
options.series[3].name = 'TECHNO 2';
options.series[3].data = json[2]['data'];
options.series[3].stack = 'IMPORT';
options.series[3].linkedTo = ':previous';
options.series[3].color= 'url(#highcharts-default-pattern-1)';
options.series[4] = {};
options.series[4].name = 'TECHNO 3';
options.series[4].data = json[5]['data'];
options.series[4].stack = 'EXPORT';
options.series[4].color= '#2B99FF';
options.series[5] = {};
options.series[5].name = 'TECHNO 3';
options.series[5].data = json[4]['data'];
options.series[5].stack = 'IMPORT';
options.series[5].linkedTo = ':previous';
options.series[5].color= 'url(#highcharts-default-pattern-2)';
options.series[6] = {};
options.series[6].name = 'TECHNO 4';
options.series[6].data = json[7]['data'];
options.series[6].stack = 'EXPORT';
options.series[6].color= '#C72828';
options.series[7] = {};
options.series[7].name = 'TECHNO 4';
options.series[7].data = json[6]['data'];
options.series[7].stack = 'IMPORT';
options.series[7].linkedTo = ':previous';
options.series[7].color= 'url(#highcharts-default-pattern-3)';
options.series[8] = {};
options.series[8].name = 'TECHNO 5';
options.series[8].data = json[9]['data'];
options.series[8].stack = 'Sortie';
options.series[8].color= '#1CA154';
options.series[9] = {};
options.series[9].name = 'TECHNO 5';
options.series[9].data = json[8]['data'];
options.series[9].stack = 'EXPORT';
options.series[9].linkedTo = ':previous';
options.series[9].color= 'url(#highcharts-default-pattern-4)';
options.series[10] = {};
options.series[10].name = 'IMPORT';
options.series[10].data = json[10]['data'];
options.series[10].stack = 'IMPORT';
options.series[10].color= 'url(#highcharts-default-pattern-5)';
options.series[11] = {};
options.series[11].name = 'EXPORT';
options.series[11].data = json[11]['data'];
options.series[11].stack = 'IMPORT';
options.series[11].color= 'url(#highcharts-default-pattern-5)';
//options.series[1].color= '#C89B9B';
chart = new Highcharts.Chart(options);
});
});
});
First of all, you can hide or show a series in a chart by modifying the "visible" property of a series object to false or true respectively. For example:
options.series[10].visible = true; // or false
Secondly, you can achieve that in an event listener (the push of a button for example), using chart.update() method, and passing the changes as an argument. Have a look in here: Dynamic charts -> update options after render.
But the simplest solution is to just repeat the
chart = new Highcharts.Chart(options);
statement, after you have put in the series object the "visible" property with the value you like, for each series (import/export) you want to show or hide.
Finally, having 2 kinds of clickable labels in the legend can only be done with some custom jquery programming of your own. I think a couple of small buttons next to the chart would be much easier and faster to implement.

Zingchart last element keeps changing color and not matching with legend

My zingchart's last element's color does not match with legend, and keeps on changing unlike the others. Any Ideas? Everything else works good. Though I'm parsing this data through MySQL database, this is how the JavaScript looks like.
My code:
<script>
var myData = ["12","15","7","20","2","22","10","7","7","10","8","15","9"];
var myData = myData.map(parseFloat);
var myLabels = ["General Verbal Insults","General Beatings\/Pushing","Terrorizing\/Threatening Remarks","False Gossip Inflation (Rumors)","Discrimination","Rough Fighting","Sexual Utterance\/Assaults","General Exclusion","Theft","Racist Utterance\/Assaults","Personal Property Damage","Internet Related (Cyber)","Other\/Unspecified"];
window.onload=function(){
var colorCharacters = "ACDEF0123456789";
var globalStylesArray = [];
var myConfig = {
type: "bar",
legend:{},
title: {
"text":"Showing Results For: Canada",
"color":"green"
},
subtitle: {
"text":"Total Bullying Incidents In Country: 144",
"color":"blue"
},
series : [{"values":[ myData[0] ],"text":"General Verbal Insults",},{"values":[ myData[1] ],"text":"General Beatings/Pushing",},{"values":[ myData[2] ],"text":"Terrorizing/Threatening Remarks",},{"values":[ myData[3] ],"text":"False Gossip Inflation (Rumors)",},{"values":[ myData[4] ],"text":"Discrimination",},{"values":[ myData[5] ],"text":"Rough Fighting",},{"values":[ myData[6] ],"text":"Sexual Utterance/Assaults",},{"values":[ myData[7] ],"text":"General Exclusion",},{"values":[ myData[8] ],"text":"Theft",},{"values":[ myData[9] ],"text":"Racist Utterance/Assaults",},{"values":[ myData[10] ],"text":"Personal Property Damage",},{"values":[ myData[11] ],"text":"Internet Related (Cyber)",},{"values":[ myData[12] ],"text":"Other/Unspecified",}]
};
zingchart.render({
id : 'myChart',
data : myConfig,
width:"100%",
height:500,
});
zingchart.gload = function(p) {
console.log(p);
var graphId = p.id;
var graphData = {};
graphData = zingchart.exec(graphId, 'getdata');
graphData = graphData.graphset[0] ? graphData.graphset[0] : graphData;
console.log(graphData);
createColors(graphData.series[0].values.length);
zingchart.exec(graphId, 'modifyplot', {
data: {
styles: globalStylesArray
}
});
}
function createColors(seriesLength) {
console.log('-------createColor seriesLength: ', seriesLength);
globalStylesArray = [];
for (var i = 0; i < seriesLength; i++) {
var colorString = '#';
for (var j = 0; j < 6; j++) {
colorString += colorCharacters.charAt(Math.floor(Math.random() * (colorCharacters.length - 4)));
}
globalStylesArray.push(colorString);
}
console.log('-----globalStylesArray-------', globalStylesArray);
}
};
</script>
Referring to the comment on the OP:
I just want all color to be different, since i dont know how many elements are in MyData - its generated through PHP & MYSQL
If you just want all of the colors to be different, remove the zingchart.gload function and the createColors function. ZingChart will create different colors for each series dynamically.
If you do want to specify each of those colors ahead of time since you do not know how many series your data will produce, you will need to apply a theme to your chart configuration: http://www.zingchart.com/docs/design-and-styling/javascript-chart-themes/

Re-compile JSON data to make less rows

If I have a JSON result that has many rows, sometimes up to 100
Label:Part1 Value:1000
Label:Part2 Value:700
Label:Part3 Value:600
Label:Part4 Value:500
... and so on
I would like to change the data so that it lists the top 5 results as normal, but instead of listing the rest, it sums the value and changes the label to 'others'.
Example
Label:Part1 Value:1000
Label:Part2 Value:700
Label:Part3 Value:600
Label:Part4 Value:500
Label:Part5 Value:500
Label:other Value:25650
Is this possible to do in javascript, before I pass to a chart.js pie? Or is there a better method to achieve this?
Current code for pie
function chart1(branch, apitime){
$.ajax({
url: jsonpath' + apitime + branch,
dataType: 'jsonp',
success: function (response) {
console.log (response);
var datachart = response;
var ctx2 = document.getElementById("chart-area2").getContext("2d");
var myChart = new Chart(ctx2).Pie(datachart);
}
});
}
Data is sorted and I could change the SQL on the server to do this also, I just don't know what the correct method is to do that.
JSON example here http://pastebin.com/p3Y9mSX3
You can modify your data just before creating the chart.
var top6 = datachart.slice(0,5)
top6[5] = {
label: 'other',
value: datachart.slice(5).reduce(function(sum, data) {
return sum + data.value
}, 0)
}
var ctx2 = document.getElementById("chart-area2").getContext("2d");
var myChart = new Chart(ctx2).Pie(top6);
This can be made more general to get the top N entries
var getTopN = function(dataArray, n)
var tops = dataArray.slice(0, n)
tops[n] = {
label: 'other',
value: dataArray.slice(n).reduce(function(sum, data) {
return sum + data.value
}, 0)
}
return tops
}
var top5 = getTopN(datachart, 5)
var top10 = getTopN(datachart, 10)

Categories