CSV file not reloading (Google GeoCharts) - javascript

I am loading csv file using https://github.com/evanplaice/jquery-csv. Everything works okay until I try to reload the .csv file and load new data into GeoCharts. I know its a problem with reloading the file but how to deal with it? Here is the example code:
function load(file, colorForSex){
var region = $('select[name="region"] option:selected').val();
setTimeout(1000);
$.get(file, function(data) {
var newData = $.csv.toArrays(data);
var j = 1;
for (var i = 1; i < newData.length; i++) {
newData[i][j] = parseFloat(newData[i][j]);
}
}, 'text');
console.log(newData[1][1]);
setTimeout(1000);
var data = google.visualization.arrayToDataTable(newData);
var options = {
region: region,
backgroundColor: 'none',
chartArea: { width: '100%', height: '100%' },
colorAxis: {colors: ['#ddd', colorForSex]},
datalessRegionColor: 'white',
legend: {
numberFormat: '.##',
textStyle: {
fontName: 'Verdana',
color: '#ff1a1a',
fontSize: 14
}
}
};
setTimeout(1000);
chart.draw(data, options);
}

need to include the rest of the chart code in the $.get function
$.get is asynchronous
as such, the code after the $.get function runs before the $.get function finishes
see following snippet...
function loadData(file, colorForSex){
var region = $('select[name="region"] option:selected').val();
var file = file + '?q=' + Math.random();
$.get(file, function(data) {
var processedData = $.csv.toArrays(data);
var j = 1;
for (var i = 1; i < processedData.length; i++) {
processedData[i][j] = parseFloat(processedData[i][j]);
}
var data = google.visualization.arrayToDataTable(processedData);
var options = {
region: region,
backgroundColor: 'none',
chartArea: { width: '100%', height: '100%' },
colorAxis: {colors: ['#ddd', colorForSex]},
datalessRegionColor: 'white',
legend: {
numberFormat: '.##',
textStyle: {
fontName: 'Verdana',
color: '#ff1a1a',
fontSize: 14
}
}
};
chart.draw(data, options);
}, 'text');
}

You can just add to file some parameter to cache disable
replace:
$.get(file, function(data) {
to:
var d = new Date();
$.get(file + '?' + d.getTime(), function(data) {

Related

Javascript variable not working inside of highcharts

I am trying to show high charts pie chart dynamically, i pass exact value format into data index in high chart but it doesn't show anything in chart, if i give what a variable have a value directly it's working fine, but passing variable directly it show empty pie chart,
Here is my javascript code,
function get_product_chart_by_filter()
{
var product_year_raw = $('#top_least_pro_year_filt').val();
var pro_top_least = $('#top_least_pro_filt').val();
var next_year = '';
var product_year = '';
var pro_top_res = '';
if (product_year_raw.length == 4) {
next_year = parseInt(product_year_raw) + 1;
product_year = product_year_raw+'-'+next_year;
}
else {
product_year = product_year_raw;
}
if (pro_top_least == 1) {
$('#pro_top_or_least').empty().html('Top ');
}
else {
$('#pro_top_or_least').empty().html('Least ');
}
$.ajax({
type:"POST",
url:baseurl+'Dashboard/product_dashboard_dynamic',
data:{'year':product_year,'top_or_least':pro_top_least},
cache: false,
dataType: "html",
success: function(result){
pro_top_res = JSON.parse(result);
var data_series = '';
for (var i = pro_top_res.length - 1; i >= 0; i--) {
data_series += "['"+pro_top_res[i].product_name+"',"+Number(pro_top_res[i].product_order_count)+"],";
}
data_series = data_series.replace(/,\s*$/, "");
// Output of 'data_series' variable = ['Basmathi',6],['null',6],['Basmathi',6],['Basmathi',20],['Basmathi',21]
Highcharts.chart('top_5_products_container', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: 0,
plotShadow: false
},
credits:false,
title: {
text: 'Products',
align: 'center',
verticalAlign: 'middle',
y: 60
},
tooltip: {
pointFormat: '{series.name}: <b>{point:y}</b>'
},
accessibility: {
point: {
valueSuffix: '%'
}
},
plotOptions: {
pie: {
dataLabels: {
enabled: true,
distance: -50,
style: {
fontWeight: 'bold',
color: 'white'
}
},
startAngle: -90,
endAngle: 90,
center: ['50%', '75%'],
size: '110%'
}
},
series: [{
type: 'pie',
name: 'Product',
innerSize: '50%',
data: [data_series]
}]
});
}
});
}
Here is my server side code,
public function product_dashboard_dynamic()
{
$dashboard_settings_info = get_dashboard_settings_info();
$top_or_least = $this->input->post('top_or_least');
$raw_yr = $this->input->post('year');
$exp_yr = explode('-', $raw_yr);
$yr1 = $exp_yr[0];
$yr2 = $exp_yr[1];
$top_least_count = $dashboard_settings_info->max_product_count;
$get_top_least_product = $this->Dashboard_model->get_top_least_product($top_or_least,$yr1,$yr2,$top_least_count);
echo json_encode($get_top_least_product);
}
Anyone can assist me?
My thought is that it has something to do with the use of a concatenated string rather than an array so you could perhaps try... though I have not used highcharts before
Change
var data_series = '';
for (var i = pro_top_res.length - 1; i >= 0; i--) {
data_series += "['"+pro_top_res[i].product_name+"',"+Number(pro_top_res[i].product_order_count)+"],";
}
to:
var data_series = [];
for( var i = pro_top_res.length - 1; i >= 0; i-- ) {
var obj=pro_top_res[i];
data_series.push( [ obj.product_name, parseInt( obj.product_order_count ) ] );
}
remove
data_series = data_series.replace(/,\s*$/, "");
Finally modify the configuration to accomodate new input data as an array
'series': [{
'type': 'pie',
'name': 'Product',
'innerSize': '50%',
'data':data_series
}]

Live Update Callback -> afterTitle with Array via JSON file

I'm working on a chart, I'm live updating the Chart every 5 seconds that the data comes in. I could manage to get the info from the database and update it really easy, but I just came across a problem with involves setting a path to a part of the chart, in the case: options->tootltips->callbacks->afterTitle and inside of it create an array and pass the array from the JSON to an array inside the callback.
What I would need to do, In a really brief way is, since I already made a function to update the info from my Data and Labels, somehow I will need to make inside this function, a path to the afterTitle, than I will be able send the fifth array, in with stores the data. As you can see in my function, I could manage to do it for the data and label.
I can't have another function that updates, so basically I can't have 2 loadData(), because it makes the Chart blink every time it updates, and that's not what I'm aiming for (The chart can't blink).
Inside this patch, I made an example that didn't work, with is the //:
$.getJSON('loadchart.php', function(response) {
myLineChart.data.datasets[0].data = response[0];
myLineChart.data.datasets[1].data = response[1];
myLineChart.data.datasets[2].data = response[2];
myLineChart.data.datasets[3].data = response[3];
myLineChart.data.labels = response[4];
//The response array that I need is response[5];
//myLineChart.options.tooltips.callbacks[1] = return response[tooltipItem[0]['index']];
myLineChart.update();
});
All my Chart so you can see the path:
<script>
function loadData() {
$.getJSON('loadchart.php', function(response) {
myLineChart.data.datasets[0].data = response[0];
myLineChart.data.datasets[1].data = response[1];
myLineChart.data.datasets[2].data = response[2];
myLineChart.data.datasets[3].data = response[3];
myLineChart.data.labels = response[4];
myLineChart.update();
});
}
loadData();
setInterval(loadData, 5000);
var lbl = [];
var ctx1 = document.getElementById('mychart1').getContext('2d');
var myLineChart = new Chart(ctx1, {
type: 'line',
data: {
labels: lbl,
datasets: [
{
label: "Corrente 1",
data: [],
borderWidht: 6,
borderColor: 'red',
backgroundColor: 'transparent'
},
{
label: "Corrente 2",
data: [],
borderWidht: 6,
borderColor: 'blue',
backgroundColor: 'transparent'
},
{
label: "Corrente 3",
data: [],
borderWidht: 6,
borderColor: 'green',
backgroundColor: 'transparent'
},
{
label: "Corrente Total",
data: [],
borderWidht: 6,
borderColor: 'black',
backgroundColor: 'transparent'
},
]
},
options: {
animation:{
update: 0
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
gridLines: {
display: false
}
}]
},
title: {
display: true,
fontSize: 20,
text: "Gráfico das Correntes"
},
labels: {
fontStyle: "bold",
},
layout: {
padding: {
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
tooltips: {
enabled: true,
mode: 'single',
responsive: true,
backgroundColor: 'black',
titleFontFamily: "'Arial'",
titleFontSize: 14,
titleFontStyle: 'bold',
titleAlign: 'center',
titleSpacing: 4,
titleMarginBottom: 10,
bodyFontFamily: "'Mukta'",
bodyFontSize: 14,
borderWidth: 2,
borderColor: 'grey',
callbacks:{
title: function(tooltipItem, data) {
return data.labels[tooltipItem[0].index];
},
afterTitle: function(tooltipItem, data) {
var tempo = [];
return tempo[tooltipItem[0]['index']];
},
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
label += (tooltipItem.yLabel)+"A";
return label;
}
}
},
aspectRatio: 1,
maintainAspectRatio: false
}
});
</script>
The part I need is this one:
afterTitle: function(tooltipItem, data) {
var tempo = [];
return tempo[tooltipItem[0]['index']];
This will display a clock but you can also set it to 5000 seconds and call your chart update. Which i would suggest to put in some kind of AJAX to let it work asynchonous.
<!DOCTYPE html>
<html>
<head>
<script>
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = checkTime(m);
s = checkTime(s);
document.getElementById('txt').innerHTML =
h + ":" + m + ":" + s;
var t = setTimeout(startTime, 500); //<---- !!!
}
function checkTime(i) {
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
return i;
}
</script>
</head>
<body onload="startTime()">
<div id="txt"></div>
</body>
</html>
As you mention in afterTitle function you want to create an array and pass the array from the JSON to an array inside the callback, and the missing part is you are creating an array tempo and treating it like an object tempo[tooltipItem[0]['index']];, but what you need to do is push this object tooltipItem[0]['index'] to tempo array.
Please replace afterTitle function with the below code
afterTitle: function(tooltipItem, data) {
var tempo = [];
return tempo.push(tooltipItem[0]['index']);

Unable to pass Json data into ajax success call in asp.net mvc

i have made an application in mvc dot net using highcharts
i have connected them to DB and showed them in view
till now every thing is running fine
but now i want to do is that if DB is updated the charts will be automatically show the updated data. for now i have to refresh the page to view updated data and it's showing well but all i want is not refresh it.
i have searched many articles and found than ajax polling should help me out so in my controller code i have passed all data in ViewData coming from reader
while (reader.Read())
{
energy_kwh.Add(Convert.ToDouble(reader["Energy_kWh"]));
power_kw.Add(Convert.ToDouble(reader["Power_kW"]));
voltage_1.Add(Convert.ToDouble(reader["Voltage_Phase_1"]));
voltage_2.Add(Convert.ToDouble(reader["Voltage_Phase_2"]));
voltage_3.Add(Convert.ToDouble(reader["Voltage_Phase_3"]));
current_1.Add(Convert.ToDouble(reader["Current_Phase_1"]));
current_2.Add(Convert.ToDouble(reader["Current_Phase_2"]));
current_3.Add(Convert.ToDouble(reader["Current_Phase_3"]));
Meter_datetime.Add(sample_con.ConvertToUnixTimestamp(Convert.ToDateTime(reader["Data_Datetime"])));
device_id = Convert.ToInt32(reader["Device_ID"]);
}
ViewData["energy_kwh"] = energy_kwh;
ViewData["Meter_datetime"] = Meter_datetime;
ViewData["power_kw"] = power_kw;
ViewData["voltage_1"] = voltage_1;
ViewData["voltage_2"] = voltage_2;
ViewData["voltage_3"] = voltage_3;
ViewData["current_1"] = current_1;
ViewData["current_2"] = current_2;
ViewData["current_3"] = current_3;
ViewData["x"] = x;
ViewData["events"] = events;
return View();
above 'x' is the sreen width only
in my view i have created a global getSVG method that takes an array of charts as an argument
$(function () { Highcharts.getSVG = function (charts) {
var svgArr = [],
top = 0,
width = 0;
$.each(charts, function(i, chart) {
var svg = chart.getSVG();
svg = svg.replace('<svg', '<g transform="translate(0,' + top + ')" ' );
svg=svg.replace('</svg>', '</g>');
top += chart.chartHeight;
width = Math.max(width, chart.chartWidth);
svgArr.push(svg);
});
return '<svg height="'+ top +'" width="' + width + '" version="1.1" xmlns="http://www.w3.org/2000/svg">' + svgArr.join('') + '</svg>';
};
and also created a global export Charts method that takes an array of charts as an argument, and exporting options as the second argument
Highcharts.exportCharts = function(charts, options) {
// Merge the options
options = Highcharts.merge(Highcharts.getOptions().exporting, options);
// Post to export server
Highcharts.post(options.url, {
filename: options.filename || 'chart',
type: options.type,
width: options.width,
svg: Highcharts.getSVG(charts)
});
};
after that i have arranged data coming from controller like this
var myArrayX_kwh = [];
var myArrayY_kwh = [];
var myArrayY_power = [];
var myArrayY_voltage_1 = [];
var myArrayY_voltage_2 = [];
var myArrayY_voltage_3 = [];
var myArrayY_current_1 = [];
var myArrayY_current_2 = [];
var myArrayY_current_3 = [];
var arry_kwh = [];
var arry_power = [];
var arry_voltage_1 = [];
var arry_voltage_2 = [];
var arry_voltage_3 = [];
var arry_current_1 = [];
var arry_current_2 = [];
var arry_current_3 = [];
then i have 2 for loops that will push data in array like this
#foreach (var st in ViewData["Meter_datetime"] as List<double?>)
{
#:myArrayX_kwh.push(#st);
}
#foreach (var st in ViewData["energy_kwh"] as List<double?>)
{
#:myArrayY_kwh.push(#st);
}
#foreach (var st in ViewData["power_kw"] as List<double?>)
{
#:myArrayY_power.push(#st);
}
#foreach (var st in ViewData["voltage_1"] as List<double?>)
{
#:myArrayY_voltage_1.push(#st);
}
#foreach (var st in ViewData["voltage_2"] as List<double?>)
{
#:myArrayY_voltage_2.push(#st);
}
#foreach (var st in ViewData["voltage_3"] as List<double?>)
{
#:myArrayY_voltage_3.push(#st);
}
#foreach (var st in ViewData["current_1"] as List<double?>)
{
#:myArrayY_current_1.push(#st);
}
#foreach (var st in ViewData["current_2"] as List<double?>)
{
#:myArrayY_current_2.push(#st);
} #foreach (var st in ViewData["current_3"] as List<double?>)
{
#:myArrayY_current_3.push(#st);
}
for (var i = 0; i < myArrayX_kwh.length; i++) {
arry_kwh.push({ x: myArrayX_kwh[i], y: myArrayY_kwh[i], });
arry_power.push({ x: myArrayX_kwh[i], y: myArrayY_power[i], });
arry_voltage_1.push({ x: myArrayX_kwh[i], y: myArrayY_voltage_1[i], });
arry_voltage_2.push({ x: myArrayX_kwh[i], y: myArrayY_voltage_2[i], });
arry_voltage_3.push({ x: myArrayX_kwh[i], y: myArrayY_voltage_3[i], });
arry_current_1.push({ x: myArrayX_kwh[i], y: myArrayY_current_1[i], });
arry_current_2.push({ x: myArrayX_kwh[i], y: myArrayY_current_2[i], });
arry_current_3.push({ x: myArrayX_kwh[i], y: myArrayY_current_3[i], });
}
then i have initialized and written the code for my charts
var chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container1',
type: 'column',
zoomType: 'xy',
resetZoomButton: {
position: {
align: 'right', // by default
verticalAlign: 'top', // by default
x: -250,
y: 5,
//height: 25
},
relativeTo: 'chart'
}
},
title: {
text: 'Energy vs Date & Time',
style: {
//color: '#FF00FF',
fontWeight: 'bold',
//fontSize: '12px'
//sfont: 'bold 200px Verdana, sans-serif',
}
},
xAxis: {
// categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
type: 'datetime',
// max: new Date().getTime(),
//labels: {
// // format: {value:}
// style: {
// fontSize: '13px',
// fontFamily: 'Verdana, sans-serif'
// }
//}
}, yAxis: {
title: {
text: 'Energy (kWh)',
style: {
//color: '#FF00FF',
fontSize: '12px',
//sfont: 'bold 200px Verdana, sans-serif',
}
}
},
as i am displaying 4 charts so i have done the same as like above with other 3 here the things are working good all the data from DB is showing in charts and if DB is updated then on page refresh it is showed but as i wrote above i don't want to refresh the page
for this i have done
var dt = JSON.stringify({
"arryKwh": arry_kwh,
"arryPower": arry_power,
"arryVoltage_1": arry_voltage_1,
"arryVoltage_2": arry_voltage_2,
"arryVoltage_3": arry_voltage_3,
"arryCurrent_1": arry_current_1,
"arryCurrent_2": arry_current_2,
"arryCurrent_3": arry_current_3
});
after that i have done an ajax call and passed data into success alert to view whether it's having my data or not
(function poll() {
setTimeout(function () {
$.ajax({
type: "POST",
url: "/Home/MultiGraph/",
data:dt,
success: function (data)
{
alert(data)
},
});
poll();
}, 5000);
})();
But when i run the application the alert message display with this
I am missing something but what it is i don't know
I have found SignalR but i think it would be time taking as i have to write all things again
Another solution came to mind is that may be if i set a condition in view or controller in which it checks if the DB is updated than it automatically refresh the page
I am confused any help will be appreciated

Google Charts format date not working

I have a Google line chart that works fine:
btcPriceHistoryGraphInit() {
this.priceHistoryData.unshift(['Time', 'Bitcoin Price ($)']);
var graphData = this.priceHistoryData;
google.charts.setOnLoadCallback(drawMarketCapChart);
function drawMarketCapChart() {
var data = google.visualization.arrayToDataTable(graphData);
var options = {
animation: {
duration: 1000,
startup: true
},
chartArea: {
width: '85%',
height: '70%'
},
legend: {
position: 'in'
},
explorer: {
actions: ['dragToZoom', 'rightClickToReset']
},
hAxis: {
titleTextStyle: {
color: '#333'
}
},
vAxis: {
minValue: 0,
format: '$#,###'
}
};
var date_formatter = new google.visualization.DateFormat({
pattern: "MMM dd, yyyy"
});
date_formatter.format(data, 0);
var chart = new google.visualization.AreaChart(document.getElementById('price-history-graph'));
chart.draw(data, options);
}
}
Now I have extracted this function/options into function that I import to simplify it and the google.visualization.DateFormat function doesnt do any thing any more. The code for the function is below:
export function Graph(chartDivId, chartData, xAxisLabel, yAxisLabel, vAxisFormat, chartWidthPercent, chartHeightPercent, title, animationDuration) {
var goodData = [];
chartData.forEach(function(elem) {
var num = Number(elem[1]);
goodData.push([elem[0], num])
});
var title = title || '';
var chartWidthPercent = chartWidthPercent || '85%';
var chartHeightPercent = chartHeightPercent || '70%';
var duration = animationDuration || 1000;
var vAxisFormat = vAxisFormat || '';
var xAxisLabel = xAxisLabel || '';
var yAxisLabel = yAxisLabel || '';
goodData.unshift([xAxisLabel, yAxisLabel]);
var graphData = goodData;
google.charts.setOnLoadCallback(drawMarketCapChart);
function drawMarketCapChart() {
var data = google.visualization.arrayToDataTable(graphData);
var options = {
title: title,
animation: {
duration: duration,
startup: true
},
chartArea: {
width: chartWidthPercent,
height: chartHeightPercent
},
legend: {
position: 'in'
},
explorer: {
actions: ['dragToZoom', 'rightClickToReset']
},
hAxis: {
titleTextStyle: {
color: '#333'
}
},
vAxis: {
minValue: 0,
format: vAxisFormat
}
};
var date_formatter = new google.visualization.DateFormat({
pattern: "MMM dd, yyyy"
});
date_formatter.format(data, 0);
var chart = new google.visualization.AreaChart(document.getElementById(chartDivId));
chart.draw(data, options);
}
}
I call the function like this: Graph(parameters)
How do I get the date formatter to work?
Thanks for and advice
I had the porblem, that the code hAxis.format: 'dd.MM.yyyy was not working. The reason was the explorer.actions: [dragToZoom', 'rightClickToReset'] line. When using the explorer.actions, the hAxis.format doesn't work.

How can I add a label to each createTableViewRow and center everything?

Im populating each Titanium.UI.createTableViewRow from a json file, and I wonder how I can add a label (Titanium.UI.createLabel) to each created Titanium.UI.createTableViewRow and center all outputed text?
I have created a Titanium.UI.createLabel, but how to add my Label to each created Titanium.UI.createTableViewRow, and center all text?
This is a created Label:
var wrapperLabel = Titanium.UI.createLabel({
text: 'Signed:',
color: '#ffffff',
textAlign:'center',
font: {
fontWeight: 'bold',
fontSize: 22
},
height:'auto'
});
win3.add(wrapperLabel);
var view = Titanium.UI.createTableView({
maxRowHeight:40,
minRowHeight:30,
height: Titanium.UI.SIZE,
width: Titanium.UI.FILL,
color: 'black'
});
win3.add(view);
xhr.onload = function() {
var data = [];
var objects = JSON.parse(this.responseText);
for (s in objects) {
data.push(Titanium.UI.createTableViewRow({
title: objects[s]
}));
data.push(Titanium.UI.createTableViewRow({
title: objects[s].New
}));
data.push(Titanium.UI.createTableViewRow({
title: objects[s].Signed
}));
data.push(Titanium.UI.createTableViewRow({
title: objects[s].Returned
}));
}
view.data = data;
};
Something like this:
for (s in objects) {
var label = Ti.UI.createLabel (_properties_);
var row = Ti.UI.createTableViewRow(_propeties_);
row.add(label);
data.push(row);
}
try this one...
var row_propetiy = {
height : "40dp"
};
var lbl_propetiy = {
color: '#000',
textAlign:'center',
font: {
fontWeight: 'bold',
fontSize: '22dp'
},
height:Ti.UI.FILL
};
xhr.onload = function() {
var data = [];
var objects = JSON.parse(this.responseText);
for (s in objects) {
var row = Ti.UI.createTableViewRow(row_propetiy);
var lbl = Ti.UI.createLable(lbl_propetiy);
lbl.text = objects[s];
row.add(lbl);
data.push(row);
}
view.data = data;
};

Categories

Resources