Make google chart work with large amounts of data - javascript

What I have done
I have added google charts to my page. The data is populated based on the date and duration the user selects. (The duration can be any amount of hours).
What I need to do
I need to ensure that the chart can accommodate the duration selected. By spacing the gant data and making the chart movable.
The problem
Is that I cannot get the chart to accomodate large sets of data without cramping the data. I need the data spaced out and thus make the chart movable (responsive) based on the amount of data searched for.
The Code
function drawChart() {
var data = [];
var header = ['Activity', 'Start Time', 'End Time'];
data.push(header);
for(var i =0; i < $scope.timelineArr.length;i++){
var year = $scope.timelineArr[i].thumbnail_date.substring(0,4);
var month = $scope.timelineArr[i].thumbnail_date.substring(5,7) -1;
var day = $scope.timelineArr[i].thumbnail_date.substring(8,10);
var hour = $scope.timelineArr[i].thumbnail_time.substring(0,2);
var min = $scope.timelineArr[i].thumbnail_time.substring(3, 5);
console.log(year+ " "+month+ " "+day);
var tmp = [];
tmp.push(""+$scope.timelineArr[i].cam_name, new Date(year, month, day, hour, min), new Date(year, month, day, hour, min));
data.push(tmp);
}
$scope.data = google.visualization.arrayToDataTable(data);
var options = {
'legend':'left',
'title':'Camera Events',
'is3D':true,
tooltip: {
isHtml: true
},
'width':1000,
'height':400
}
$scope.chart = new google.visualization.Timeline(document.getElementById('chart_div'));
$scope.chart.draw($scope.data, options);
//////////
google.charts.load('current', {'packages':['timeline']});
google.charts.setOnLoadCallback(drawChart);
I also included what it looks like now.As you can see the data is cramped, imagine if I choose more hours. Thank you.
Is there a way to make the timeline ZOOMABLE?

Related

Reduce daily data to monthly using Google Earth Engine

I am looking at precipitation data (both GPM and CHIRPS) for different provinces in Indonesia using Google Earth Engine. GPM is sub-daily (every 30 minutes) and CHIRPS is daily. I am only interested in getting the monthly values. Unlike here and here I am not interested in getting the multi-annual monthly values, but simply the average of each month and make a time series.
Here I found a way to create a list of values containing the mean of each month.
Edit: Thanks to Nicholas Clinton's answer I managed to get it to work:
var fc = ee.FeatureCollection('ft:1J2EbxO3zzCLggEYc57Q4mzItFFaaPCAHqe1CBA4u') // Containing multiple polygons
.filter(ee.Filter.eq('name', 'bangka')); // Here I select my ROI
Map.addLayer(fc, {}, 'area');
Map.centerObject(fc, 7);
var aggregate_array = fc.aggregate_array('name');
print('Name of area: ', aggregate_array, 'Selected data in FeatureCollection:', fc);
var month_mean = ee.List.sequence(0, 16*12).map(function(n) { // .sequence: number of years from starting year to present
var start = ee.Date('2002-01-01').advance(n, 'month'); // Starting date
var end = start.advance(1, 'month'); // Step by each iteration
return ee.ImageCollection("UCSB-CHG/CHIRPS/DAILY")
.filterDate(start, end)
.mean()
.set('system:time_start', start.millis());
});
print(month_mean);
var collection = ee.ImageCollection(month_mean);
print(collection);
// Plotting
var area_name = fc.aggregate_array('name').getInfo();
var title = 'CHIRPS [mm/hr] for ' + area_name;
var TimeSeries = ui.Chart.image.seriesByRegion({
imageCollection: collection,
regions: fc,
reducer: ee.Reducer.mean(),
scale: 5000,
xProperty: 'system:time_start',
seriesProperty: 'label'
}).setChartType('ScatterChart')
.setOptions({
title: title,
vAxis: {title: '[mm/hr]'},
lineWidth: 1,
pointSize: 1,
});
print('TimeSeries of selected area:', TimeSeries);
Have not tested, but should be something like this (or set some other date property):
return ee.ImageCollection("UCSB-CHG/CHIRPS/DAILY")
.filterDate(start, end)
.sum()
.set('system:time_start', start.millis());
aggregate_prob function in pkg_trend, works just like aggregate in R language.
var imgcol_all = ee.ImageCollection('NASA/GPM_L3/IMERG_V05');
function add_date(img){
var date = ee.Date(img.get('system:time_start'));
var date_daily = date.format('YYYY-MM-dd');
return img.set('date_daily', date_daily);
}
var startdate = ee.Date.fromYMD(2014,3,1);
var enddate = ee.Date.fromYMD(2014,4,1);
var imgcol = imgcol_all
.filter(ee.Filter.date(startdate,enddate)).select('precipitationCal')
.map(add_date);
// imgcol = pkg_trend.imgcol_addSeasonProb(imgcol);
print(imgcol.limit(3), imgcol.size());
var pkg_trend = require('users/kongdd/public:Math/pkg_trend.js');
var imgcol_daily = pkg_trend.aggregate_prop(imgcol, "date_daily", 'sum');
print(imgcol_daily);
Map.addLayer(imgcol_daily, {}, 'precp daily');
The GEE link is https://code.earthengine.google.com/2e04ad4a4bee6789af23bfac42f63025

Passing angular scope variable to javascript

I have angular scope variable which is being used in ng-repeat as well. I want to create a chart starting from a date and ending at a certain date with the current day marker. I am using javascript loader.js for drawing the charts but since I need to draw multiple charts inside ng-repeat.
My code looks like this:
$scope.items = [{"title1":"start_day: 01-01-2017", "end_day:15-02-2018"},
{"title2":"start_day: 05-10-2017", "end_day:10-01-2019"}];
and javascript code from google charts:
anychart.onDocumentReady(function () {
// create data tree on our data
var treeData = anychart.data.tree(getData());
// create resource gantt chart
var chart = anychart.ganttResource();
// set container id for the chart
chart.container('container');
// set data for the chart
chart.data(treeData);
// set start splitter position settings
chart.splitterPosition(150);
var now = (new Date()).getTime();
var sec = 1000;
var min = 60*sec;
var hour = 60*min;
var day = 24*hour;
// create linemarkers
var tl = chart.getTimeline();
tl.lineMarker(0).value("current");
// get chart data grid link to set column settings
var dataGrid = chart.dataGrid();
// initiate chart drawing
chart.draw();
// zoom chart to specified date
chart.fitAll();
});
function getData() {
var now = (new Date()).getTime();
var sec = 1000;
var min = 60*sec;
var hour = 60*min;
var day = 24*hour;
return [
{
"periods": [
{"id": "1_1", "start": now - 365*day, "end": now + 100*day }]
},
];
}
I want to pass the dates from angularjs scope variable to javascript code here which will replace the existing data of start and end, also I need to convert the dates difference.
Thanks in advance! :)
I would recommend to use another JS object that stores common data for both angular and js.
var DATES = [{"title1":"start_day: 01-01-2017", "end_day:15-02-2018"},
{"title2":"start_day: 05-10-2017", "end_day:10-01-2019"}];
...
//in agular
$scope.items = DATES;
...
//in loader
function getData() {
...
return DATES;
}
You can also store an angular $scope into a variable and then use it as a usual variable into JS code, var ctrl = $scope but I would recommend to go with the first option.
--
Regarding to dates difference. Try to use standard Date class.
For example:
var deltaMS = new Date("02-15-2018") - new Date("01-01-2017");
var deltaDays = delta / 1000 / 60/ 60 / 24;
//410 days

How to limit chart xAxis date range in HighCharts?

The data series in my HighCharts chart only includes dates from the past few days, but the chart's x-axis and zoom bar show a date range all the way back to 1970.
How can I limit the presented date range so it only goes back as far as the first date present in the series data?
Example
HTML
<div id="chart_container" style="height: 500px></div>
JavaScript
$(function () {
var timestamps = [1481000484000,1481108510000,1481215541000,1481316568000,1481417583000];
var series_raw_data = [100,300,750,400,200];
// prepare data
var points = [[],[]];
for (var i = 0; i < timestamps.length; i++) {
points.push([timestamps[i], series_raw_data[i]]);
}
// create chart
$('#chart_container').highcharts('StockChart', {
series: [{
data: points
}]
});
});
Here's Fiddle1 which shows the behavior.
I also tried setting the xAxis 'min' option to the first timestamp, and setting the axis type to 'datetime', but those didn't help - Fiddle2.
The reason why it happens is your points array.
If fact, after filling, it looks like this:
points = [ [], [], [x, y], [x, y]]
Those two empty arrays create unwanted behaviour.
Fix the initial array and it works
var points = [];
example: https://jsfiddle.net/hbwosk3o/3/

How to Redraw HighChart After Dropdown Value is selected

I have a drop down menu called info and I want to update my highchart everytime a user selects a value through the info menu.
Here is the code:
$('#info').on('change', function() {
add_info(this.value);
});
The add_info() method simply gets data via ajax and this is how I am processing it after getting the response back:
if(chart=='stacked_chart'){
console.log(JSON.stringify(response));
var series = [{name:'Coached',data:[]},{name:'Non Coached',data:[],stack: 'yes'},{name:'Delta',data:[],stack: 'yes'}],
year, month, day;
for(var i=0; i<response.length;i++){
var d = response[i].date.split(",");
year = parseFloat(d[0]);
month = parseFloat(d[1])-1; //date.utc method starts month 0-11
day = parseFloat(d[2]);
var coached = +(parseFloat(response[i].coached).toFixed(3));
var non_coached = +(parseFloat (response[i].non_coached).toFixed(3));
var delta = +(parseFloat (response[i].delta).toFixed(3));
series[0].data.push([Date.UTC(year,month,day),coached]);
series[1].data.push([Date.UTC(year,month,day),non_coached]);
series[2].data.push([Date.UTC(year,month,day),delta]);
console.log(Date.UTC(year,month,day));
}
console.log(series);
if(series.length){
stacked_chart.userOptions.series = series;
var chart = new Highcharts.Chart(stacked_chart.userOptions);
console.log(chart.series[0].data[0].options);
console.log(chart.series[1].data[0].options);
console.log(chart.series[2].data[0].options);
}
}
I can see it brings back the new data but It doesn't redraw. I have looked at here but couldn't redraw the chart. Any ideas how to reset the chart every time a user selects a new value from the drop down?

Open Layers 3 get geojson data from specific time date?

I'm trying to figure out the best approach to fetch data from a geojson file by date. Each feature point has a time parameter and I need to show the points in the map that match a specific date and time.
I also have a date select picker which will show the points in the map based on the date selected.
Any ideas? This is how I envision the code process would look like:
// 1. Geojson data:
{ 'type':'FeatureCollection',
'crs': {...},
'features': {
'type': 'Feature',
'geometry': {...},
'properties': {
'reportStartTime': '2015-12-04T00:55:00Z',
'id': '3421',
...
}
}
}
// 2. Get current date
var now = new Date(new Date());
var hour = now.getHours();
var nextHour = hour + 1; // I need to know when the next hour starts
var hourDiff = // I need to get the hours from 00:00 to 00:59min
// 3. Show points in the map that match the current date
function fetchData(feature, timeSelected) {
var reportStartTime = feature.get('reportStartTime');
if(reportStartTime == timeSelected){
return // Show the map points
}
}
fetchData(feature, hourDiff);
// 4. Filter date picker (using bootstrap date picker)
var newTimeSelected = $('#datetimepicker1').find('input').val(); // i.e returns 12/10/2015 11:57 AM
// 5. Change the map points that match the date selected from the date picker
$('button').submit(function() {
fetchData(feature, newTimeSelected);
});

Categories

Resources