Format date string into highcharts - javascript

I've been trying to insert min and max string dates into my highcharts graph as follows:
var formatted_startDate = startDate.replace(/-/g, ",");
var formatted_endDate = endDate.replace(/-/g, ",");
//Format now is "yyyy,mm,dd"
options = {
chart: {
renderTo: 'container',
type: 'bar'
},
xAxis: {
type: "datetime",
dateTimeLabelFormats: {
day: '%m-%d'
},
tickInterval: 24 * 3600 * 1000,
min: Date.UTC(formatted_startDate),
max: Date.UTC(formatted_endDate)
},
Clearly the above won't work because I'm passing in a string. I've just written it like this to illustrate what I am trying to do rather than post code of numerous failed attempts. I've attempted using JSON.parse and eval() but had problems with the syntax.
Any help would be appreciated. Cheers

ended up just uses the setExtremes method within highcharts API
var formatted_startDate = startDate.replace(/-/g, ",");
var formatted_endDate = endDate.replace(/-/g, ",");
//Format now is "2000,00,00"
var startdatearray = formatted_startDate.split(",");
var enddatearray = formatted_endDate.split(",");
var sy = parseInt(startdatearray[0]);
var sm = parseInt(startdatearray[1],10) - 1;
var sd = parseInt(startdatearray[2]);
var ey = parseInt(enddatearray[0]);
var em = parseInt(enddatearray[1],10) - 1;
var ed = parseInt(enddatearray[2]);
chart = new Highcharts.Chart(options);
chart.xAxis[0].setExtremes(Date.UTC(sy,sm,sd), Date.UTC(ey, em, ed));

Related

Error "Array: Parameter 'values' is required"

I'm working on a platform called Google Earth Engine that allows compute heavy analysis of satellite images on a cloud.
I have written a code in Javascript that takes two images, use one band inside them and then it suppose to create scatter plot.
I have problem with the part of the scatter plot which I struggle to understand.
Any time I run this part:
// Convert the band data to plot on the y-axis to arrays.
var x= ee.Array(imageNDVIcor.get('NDVI'));
var y = ee.Array(SARreproject.get('VH'));
// Make a band correlation chart.
var chart = ui.Chart.array.values(y, 0, x)
.setSeriesNames(['SAR vs NDVI'])
.setOptions({
title: 'NDVI vs SAR VH',
hAxis: {'title': 'SAR VH'},
vAxis: {'title': 'NDVI'},
pointSize: 3,
});
// Print the chart.
print(chart);
I get the following error:
Array: Parameter 'values' is required
I don't understand which values are missing or how and when they got lost. I put here the full code I have, any help to understand where the values dissapeard will be helpful.
//STEP 1:NDVI
/**
* Function to mask clouds using the Sentinel-2 QA band
* #param {ee.Image} image Sentinel-2 image
* #return {ee.Image} cloud masked Sentinel-2 image
*/
function maskS2clouds(image) {
var qa = image.select('QA60');
// Bits 10 and 11 are clouds and cirrus, respectively.
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
// Both flags should be set to zero, indicating clear conditions.
var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
.and(qa.bitwiseAnd(cirrusBitMask).eq(0));
return image.updateMask(mask).divide(10000)
.copyProperties(image, ['system:time_start']);
}
// Map the function over one year of data and take the median.
// Load Sentinel-2 TOA reflectance data.
var dataset = ee.ImageCollection('COPERNICUS/S2')
.filterDate('2019-01-01', '2019-11-12')
// Pre-filter to get less cloudy granules.
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
.select('B2','B3','B4','B8','QA60')
.filterBounds(geometry)
.map(maskS2clouds);
var clippedCol=dataset.map(function(im){
return im.clip(geometry);
});
// Get the number of images.
var count = dataset.size();
print('Count: ',count);
// print(clippedCol);//here I get the error messege "collection query aborted after accumulation over 5000 elements
// print(dataset,'dataset');//the same error here
//function to calculate NDVI
var addNDVI = function(image) {
var ndvi = image.normalizedDifference(['B8', 'B4'])
.rename('NDVI')
.copyProperties(image,['system:time_start']);
return image.addBands(ndvi);
};
//NDVI to the clipped image collection
var withNDVI = clippedCol.map(addNDVI).select('NDVI');
var NDVIcolor = {
min: 0,
max:1,
palette: ['FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
'66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
'012E01', '011D01', '011301'],
};
//Filter according to number of pixels
var ndviWithCount = withNDVI.map(function(image){
var countpixels = ee.Number(image.reduceRegion({
reducer: ee.Reducer.count(),
geometry: geometry,
crs: 'EPSG:4326',
scale: 20,
}).get('NDVI'));
return image.set('count', countpixels);
});
print(ndviWithCount, 'ndviWithCount');
var max = ndviWithCount.reduceColumns(ee.Reducer.max(), ["count"]);
print('Number of pixels max:',max.get('max'));
//filter between a range
var filterNDVI = ndviWithCount.filter(ee.Filter.rangeContains(
'count', 98258, 98258));
print('Filtered NDVI:', filterNDVI);
var listOfImages =(filterNDVI.toList(filterNDVI.size()));
var listOfNumbers = [5]
for (var i in listOfNumbers) {
var image = ee.Image(listOfImages.get(listOfNumbers[i]));
var toexport=image.visualize(NDVIcolor).addBands(image);
// do what ever you need with image
Map.addLayer(image, NDVIcolor, i);
// Export.image.toDrive({
// image: toexport.toFloat(),
// description: i,
// scale:20,
// crs:'EPSG:4326',
// maxPixels:1310361348,
// region:geometry.geometry().bounds()
// });
}
Map.centerObject(geometry);
//STEP2: SAR
// Filter the collection for the VH product from the descending track
//var geometry=MITR;
var Sentinel1 = ee.ImageCollection('COPERNICUS/S1_GRD')
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))
.filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))
.filter(ee.Filter.eq('instrumentMode', 'IW'))
.select('VH')
.filterDate('2019-01-01','2019-11-12')
.filterBounds(geometry);
var clippedVH= Sentinel1.map(function(im){
return im.clip(geometry);
});
var clippedVHsize=clippedVH.size();
print('SAR Size:',clippedVHsize);
print('SAR images data:',clippedVH)
var listOfImagesSAR =(clippedVH.toList(clippedVH.size()));
var listOfNumbersSAR = [3];
for (var i in listOfNumbersSAR) {
var image = ee.Image(listOfImagesSAR.get(listOfNumbersSAR[i]));
var toexport=image.visualize({min: -30, max: 1}).addBands(image);
// do what ever you need with image
Map.addLayer(image,{min: -30, max: 1}, i);
// Export.image.toDrive({
// image: toexport.toFloat(),
// description: i,
// scale:10,
// crs:'EPSG:4326',
// maxPixels:1310361348,
// region:geometry.geometry().bounds()
// });
}
//print(ui.Chart.image.series(filterNDVI, geometry, ee.Reducer.mean(), 20));
//(ui.Chart.image.series(clippedVH, geometry, ee.Reducer.mean(), 10));
//select the images for scatter plot
//select NDVI
var imageNDVIcor=ee.Image(listOfImages.get(5));
var imageSARcor=ee.Image(listOfImagesSAR.get(3));
// Get information about the projection.
var sar1Projection = imageSARcor.projection();
print('SAR projection:', sar1Projection);
var NDVIProjection = imageNDVIcor.projection();
print('NDVI projection:', NDVIProjection);
//resample SAR image to NDVI image
var SARreproject=imageSARcor.reduceResolution({reducer: ee.Reducer.mean()}).reproject({crs: NDVIProjection});
Map.addLayer(SARreproject,{min: -30, max: 1},'Reproject SAR');
// print(imageNDVIcor)
// print(imageSARcor)
//Map.addLayer(imageNDVIcor,NDVIcolor,'NDVI select');
//Map.addLayer(imageSARcor,{min: -30, max: 1},'SAR select');
// Convert the band data to plot on the y-axis to arrays.
var x= ee.Array(imageNDVIcor.get('NDVI'));
var y = ee.Array(SARreproject.get('VH'));
// Make a band correlation chart.
var chart = ui.Chart.array.values(y, 0, x)
.setSeriesNames(['SAR vs NDVI'])
.setOptions({
title: 'NDVI vs SAR VH',
hAxis: {'title': 'SAR VH'},
vAxis: {'title': 'NDVI'},
pointSize: 3,
});
// Print the chart.
print(chart);
Not sure what you are trying to accomplish. But if you are trying to compare the values between NDVI and VH, here's a way to do that. Click on any point inside the geometry, and the values for the point in the time-series are plotted in the console tab.
var geometry =
ee.Geometry.Polygon(
[[[-122.56145019531249, 37.93899992220671],
[-122.56145019531249, 37.37365054197817],
[-121.80888671874999, 37.37365054197817],
[-121.80888671874999, 37.93899992220671]]], null, false);
Map.centerObject(geometry, 10);
function maskS2clouds(image) {
var qa = image.select('QA60');
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(qa.bitwiseAnd(cirrusBitMask).eq(0));
return image.updateMask(mask).divide(10000).copyProperties(image, ['system:time_start']);
}
// Sentinel 2
var sentinel2 = ee.ImageCollection('COPERNICUS/S2')
.filterDate('2019-01-01', '2019-12-31')
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
.select('B2','B3','B4','B8','QA60').filterBounds(geometry).map(maskS2clouds);
// NDVI
var addNDVI = function(image) {
var ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI').copyProperties(image,['system:time_start']);
return image.addBands(ndvi);
};
var sentinel2NDVI = sentinel2.map(addNDVI).select('NDVI');
// SAR
var sentinel1 = ee.ImageCollection('COPERNICUS/S1_GRD')
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))
.filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))
.filter(ee.Filter.eq('instrumentMode', 'IW'))
.select('VH').filterDate('2019-01-01','2019-12-31').filterBounds(geometry);
var list1 = sentinel2NDVI.toList(sentinel2NDVI.size());
var list2 = sentinel1.toList(sentinel1.size());
var list = list1.cat(list2);
var combinedData = ee.ImageCollection(list);
// chart
var generateChart = function (coords) {
print('-----------------------');
var lat = coords.lat;
var lon = coords.long;
var point = ee.Geometry.Point(coords.lon, coords.lat);
var dot = ui.Map.Layer(point, {color: '000000'}, 'clicked location');
var chart = ui.Chart.image.series(combinedData, point, ee.Reducer.mean(), 30);
chart.setOptions({
title: 'VH vs NDVI',
hAxis: {'title': 'Time'},
vAxis: {'title': 'SAR VH'},
pointSize: 3,
});
print(chart);
};
Map.onClick(generateChart);
Map.style().set('cursor', 'crosshair');
Also, get the GEE link for the same from here.

Spurious point is being added in the end C3 charts

I'm using C3 charts library to draw charts. I send data to the chart using two arrays, which are 'timeArray' and 'dataArray', one for the X-Axis and the other one for Y-Axis respectively. This simple logic was working fine.
Later I had to implement a change such that I had to take average of every three elements of an array and then make a new array and then plot the graph using averaged values.
I started facing a problem that a spurious point was being plotted on the graph. Whenever this error occurs, only one spurious point is added in the end. I've checked the arrays that are used to plot the graph, they do not have that spurious point. When I take the average of every three elements, I face this problem almost every time, however when I take average of 500 or 1000 points I face this error only sometimes.
As you can see in the code I have already tried removing the last point of the final array since the spurious point that was being added was always the last point in the chart. I've also tried changing the graph type, it did not help.
socket.on('get-avg-graph', function(data) {
// dataPoints = Points for Y-Axis
// mili = Points for X-Axis
var dataPoints = data.dataPoints;
var mili = data.mili;
var sumX = 0;
var sumY = 0;
var avgXGraph = 0;
var avgYGraph = 0;
var avgXArray = [];
var avgYArray = [];
for (var i = 0; i < dataPoints.length - 999; i++) {
for (var j = i; j < i + 999; j++) {
sumX = sumX + mili[j];
sumY = sumY + dataPoints[j];
}
if (sumY !== 0) {
avgXGraph = ( sumX / 1000 );
avgXArray.push(avgXGraph);
avgYGraph = ( sumY / 1000 );
avgYArray.push(avgYGraph);
sumX = 0;
sumY = 0;
avgXGraph = 0;
avgYGraph = 0;
}
}
io.emit('get-avg-graph-response', avgXArray, avgYArray);
});
socket.on('get-avg-graph-response', function(avgXArray, avgYArray) {
plot_X_axis = [];
plot_Y_axis = [];
drawChart();
avgXArray.splice( -1, 1);
avgYArray.splice( -1, 1);
plot_X_axis.push.apply(plot_X_axis, avgXArray);
plot_Y_axis.push.apply(plot_Y_axis, avgYArray);
drawChart();
});
function drawChart() {
var graphTitle = $("#test_type_show").val();
dataArray = [];
dataArray[0] = "PRESSURE";
dataArray.push.apply(dataArray, plot_Y_axis);
timeArray = [];
timeArray[0] = "TIME";
timeArray.push.apply(timeArray, plot_X_axis);
if (chart==null) {
chart = c3.generate({
bindto: '#chart1',
title: {
text: graphTitle
},
data: {
x: 'TIME',
columns: [
timeArray,
dataArray
],
type: 'spline'
},
axis: {
x: {show:false},
y: {show: true}
},
grid: {
x: {
show: true
},
y: {
show: true
}
},
point: {
show: false
}
});
} else {
chart.load({
x: 'TIME',
columns: [
timeArray,
dataArray
],
type: 'spline'
});
}
chart.internal.xAxis.g.attr('transform', "translate(0," + chart.internal.y(0) + ")");
chart.internal.yAxis.g.attr('transform', "translate(" + chart.internal.x(0) + ", 0)");
}
I expect the output of the code to be the actual graph without any spurious data added anywhere.

jqxChart with relative values

I was playing around with the waterfall series of the jqxChart.
According to its API, the following piece of code defines the values of the axis, in this case it's the y-axis:
valueAxis:
{
title: {text: 'Population<br>'},
unitInterval: 1000000,
labels:
{
formatFunction: function (value) {
return value / 1000000 + ' M';
}
}
}
Is it possible to define the intervals not with absolute values, but with relative values. So that the interval are e.g. 10% and the overall value is 100%?
Simply doing unitInterval: '10%' doesn't work.
This is how it should look like:
Here is a fiddle.
I think you're looking for these options :
logarithmicScale: true,
logarithmicScaleBase: 1.10,
Example:
valueAxis:
{
title: {text: 'Population<br>'},
logarithmicScale: true,
logarithmicScaleBase: 1.10,
labels:
{
formatFunction: function (value) {
return value / 1000000 + ' M';
}
}
},
Edit:
var accuracy = 2;
var first = data[0].population;
var last = data[data.length - 2].population;
var unit = (100 / last);
// convert raw data to differences
for (var i = 0; i < data.length - 2; i++)
data[i].population = (data[i].population * unit).toFixed(accuracy);

dates cannot be shown on highcharts

I am having difficulty showing a string separated with dates on a basic high chart
I am getting and saving the tweets from twitter into arrays and then converting the array into a string separated by commas and quotes.
Unfortunately I cant display them on the graph, I have no idea what I'm doing wrong.
function search(){
var value = $('#box').val();
var array=[];
var dateArray = [];
var dateString;
if (value!==""){$.getJSON("",
function(data){
$.each(data.results, function(i, item){
var user=item.from_user;
var created_at=new Date(item.created_at);
var month = created_at.getMonth();
var day = created_at.getDate();
var year = created_at.getFullYear();
var created= day +'/'+ month+ '/'+ year;
array.push({date:created,username:user});
});
// console.log(array);
for (var i in array) {
dateArray.push(array[i].date);
}
dateString="'" + dateArray.join("','") + "'";
console.log(dateString);
});
}
var chart;
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 130,
marginBottom: 25
},
title: {
text: 'Monthly Average Temperature',
x: -20 //center
},
subtitle: {
text: 'Source: WorldClimate.com',
x: -20
},
xAxis: {
categories: [dateString]
},
Fixed JsFiddle
Your x-axis parameter should be as follows:
xAxis: {
categories: dateString
},
Als, just change this :-)
for (var i in array) {
dateString.push(array[i].date);
}
highchart(dateString);
Oh, and you should change to this, definately.
<input type="text" id="box" value="a"/>
Extra investigation info:
It appeared that (in the old situation)
console.log(stringArray);
highchart(stringArray);
was empty. Would you pass
highchart(["ab", "b", "c"]);
then you'd be fine. This is because you are passing an empty array, you are creating the chart before you have the JSON data. I therefore moved the creation to the JSON function.
Why not use xAxis as datetime:
xAxis: {
type: 'datetime'
},
Parse the dates into JS time from the twitter data and have something like this as your series data array:
[[<jstime1>, "big cool tweet1"], [<jstime2>, "big cool tweet2"]]

How to set Date Value for x Axis using gRaphael Line Graph

I've recently started to use gRaphael for my graphing needs and am pretty impressed so far. However, I have run into some difficulty when producing line graphs, specifically that when I attempt to set the values for the X axis to dates, the graph fails to render. My code to generate the graph is:
<script type='text/javascript' charset='utf-8'>
var r = Raphael('holder');
var lines = r.g.linechart(20, 20, 600, 300, [[1, 2, 3, 4, 5, 6, 7]], [['4.16','6.35','1.77','3.1','9.79','10.03','-0.3']], {nostroke: false, axis: '0 0 1 1', symbol: 'o', smooth: false}).hoverColumn(function () {
this.tags = r.set();
for (var i = 0, ii = this.y.length; i < ii; i++) {
this.tags.push(r.g.tag(this.x, this.y[i], this.values[i], 160, 10).insertBefore(this).attr([{fill: '#fff'}, {fill: this.symbols[i].attr('fill')}]));
}
}, function () {
this.tags && this.tags.remove();
});
lines.symbols.attr({r: 3});
</script>
<div id='holder'></div>
How would I be able to replace the X axis values '1, 2, 3, 4, 5, 6, 7' with say, 'Jan 2001, Feb 2001, Mar 2001...etc...etc....'?
Many thanks indeed, all help much appreciated!
At first you have to give the chart some values that it will not complain about.
In your case you could save the UNIX timestamp etc
Then you can alter the values using something like this (Using prototype etc):
lines.axis[0].text.items.each( function ( index, label ) {
//Get the timestamp you saved
originalText = label.attr('text');
newText = 'CONVERT TIMESTAMP TO DATE USING originalText as input HERE';
//label.rotate(75);
label.attr({'text': newText});
});
The .each can be replaced by a regular
for(var x = 0; x < lines.axis[0].text.length; x++)
loop if you like.
$.each(lines.axis[0].text.items , function ( index, label ) {
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
date = new Date(parseInt(label.attr("text"))),
day = date.getDate(),
month = months[date.getMonth()];;
dateText = month + " " + day;
//label.rotate(75);
label.attr({'text': dateText});
});

Categories

Resources