Actionscript: Sorting ArrayCollection by date: YYYY-MM-DD - apache-flex

I have an ArrayCollection of Objects. Each Object has the following keys/values:
{date: 2009-12-01, visits=13555, bouceRate=45}
{date: 2009-12-05, visits=46955, bouceRate=45}
{date: 2009-12-06, visits=13685, bouceRate=45}
{date: 2009-12-02, visits=13685, bouceRate=45}
{date: 2009-12-04, visits=68755, bouceRate=45}
{date: 2009-12-03, visits=35875, bouceRate=45}
I need to sort this ArrayCollection by date, so it would be from past to present - like so:
{date: 2009-12-01, visits=13555, bouceRate=45}
{date: 2009-12-02, visits=13685, bouceRate=45}
{date: 2009-12-03, visits=35875, bouceRate=45}
{date: 2009-12-04, visits=68755, bouceRate=45}
{date: 2009-12-05, visits=46955, bouceRate=45}
{date: 2009-12-06, visits=13685, bouceRate=45}
I have tried the following with no prevail (not sorting):
var dateSort:Sort = new Sort();
dateSort.fields = [new SortField("date", false, false, true)];
newAreaChartData.sort = dateSort;
newAreaChartData.refresh();
// traceout
for (var i:int = 0; i <newAreaChartData.length; i++)
trace ("Object #" + i + ": " + ObjectUtil.toString(newAreaChartData.getItemAt(i)));

This worked for me:
for(i = 0; i < newAreaChartData.length; ++i) {
newAreaChartData[i].formattedDate = getActualDate(newAreaChartData[i].date);
newAreaChartData[i].dateTime = newAreaChartData[i].formattedDate.time;
trace(newAreaChartData[i].dateTime);
}
var dateSort:Sort = new Sort();
dateSort.fields = [new SortField("dateTime", false, false, true)];
newAreaChartData.sort = dateSort;
newAreaChartData.refresh();
for (var i:int = 0; i <newAreaChartData.length; i++)
trace ("Object #"+ i + ": " + ObjectUtil.toString(newAreaChartData.getItemAt(i)));

The way your creating the SortField :
new SortField("date", false, false, true)
From the API , the last parameter should mean that you want the value to be sorted numerically instead of as a string.
What is the type of the "date" field in the Object ? If it is a string, then you might want to sort things alphabetically
new SortField("date", false, false, null)
Hoping this helps
PH

I don't believe that the sort is applied until you call ArrayCollection.refresh():
newAreaChartData.sort = dateSort;
newAreaChartData.refresh();

Related

Google Trends polynomial regression does not work

I'm trying to add polynomial regression line to my google trends live graph but it does not work properly:
as you can see the polynomial regression trendline is not fitting the data points properly (it's straight trendline and not a polynomial trendline).
My code is:
google.charts.load("current", {packages:["corechart"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('datetime', 'Time of Day');
data.addColumn('number', 'Depth');
var options = {
title: 'graph',
legend: 'none',
crosshair: { trigger: 'both', orientation: 'both' },
trendlines: {
0: {
type: 'polynomial',
degree: 3,
visibleInLegend: true,
}
},
hAxis: {
viewWindow: {
min: new Date(),
}
},
vAxis: {
viewWindow: {
min: 0,
max: 100
}
}
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart'));
chart.draw(data, options);
var interval = setInterval(function() {
var time = new Date();
data.addRow([time, newValue])
chart.draw(data, options);
}, 10);

Map layer is not defined

I am trying to do a point cluster layer based on the JSON objects I obtained from database. Here is my JavaScript to plot a point cluster layer:
function addClusters() {
$.ajax({
url: "index.aspx/getBusCommuter",
type: "POST",
data: "",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var parsed = JSON.parse(data.d);
$.each(parsed, function (i, jsondata) {
var coordXicon = jsondata.BusStopX;
var coordYicon = jsondata.BusStopY;
var commuterAmt = jsondata.CommuterAmt;
var latlng = new esri.geometry.Point({ "x": coordXicon, "y": coordYicon, "spatialReference": { "wkid": 4326 } });
// cluster layer that uses OpenLayers style clustering
clusterLayer = new ClusterLayer({
"data": commuterAmt,
"distance": 100,
"id": "clusters",
"labelColor": "#fff",
"labelOffset": 10,
"resolution": map.extent.getWidth() / map.width,
"singleColor": "#888"
});
var defaultSym = new SimpleMarkerSymbol().setSize(4);
var renderer = new ClassBreaksRenderer(defaultSym, "clusterCount");
var picBaseUrl = "http://static.arcgis.com/images/Symbols/Shapes/";
var blue = new PictureMarkerSymbol(picBaseUrl + "BluePin1LargeB.png", 32, 32).setOffset(0, 15);
var green = new PictureMarkerSymbol(picBaseUrl + "GreenPin1LargeB.png", 64, 64).setOffset(0, 15);
var red = new PictureMarkerSymbol(picBaseUrl + "RedPin1LargeB.png", 72, 72).setOffset(0, 15);
renderer.addBreak(0, 2, blue);
renderer.addBreak(2, 200, green);
renderer.addBreak(200, 1001, red);
clusterLayer.setRenderer(renderer);
map.addLayer(clusterLayer);
});
},
error: function (request, state, errors) {
}
});
}
However, when I try to run it, it told me an error message which is clusterLayer is not defined. I wonder which part I missed and am I doing in the correct way.
Also, I wonder is it possible/correct to set the commuterAmt I obtained to data so that for each point on the map will be attached with the correct amount?
I get the reference from: ArcGIS Documentation
Thanks in advance.
Try to download the sample code ArcGIS Documentation
Include ClusterLayer.js from extras direxctory
var dojoConfig = {
paths: {
extras: location.pathname.replace(/\/[^/]+$/, "") + "/extras"
}
};
then in your code use
define dojo.provide("extras.ClusterLayer");
and call
clusterLayer = new extras.ClusterLayer({
"data": commuterAmt,
"distance": 100,
"id": "clusters",
"labelColor": "#fff",
"labelOffset": 10,
"resolution": map.extent.getWidth() / map.width,
"singleColor": "#888"
});

Crossfilter - Minimum Value by Day

How do I find the minimum value per day? The dimension being the Days, the group the minimum amount.
Using the following data as an example -
var data = [
{date: "2011-11-14T10:17:54Z", amount: 10 },
{date: "2011-11-14T12:20:19Z", amount: 1 },
{date: "2011-11-14T14:20:19Z", amount: 0 },
{date: "2011-11-15T06:30:43Z", amount: 10 },
{date: "2011-11-15T10:30:43Z", amount: 10 },
{date: "2011-11-15T16:28:54Z", amount: 100 },
{date: "2011-11-16T18:48:46Z", amount: 100 },
{date: "2011-11-16T20:53:41Z", amount: 11 },
{date: "2011-11-16T22:54:06Z", amount: 10 },
];
So the results should be -
{date: "2011-11-14T14:20:19Z", amount: 0 },
{date: "2011-11-15T06:30:43Z", amount: 10 },
{date: "2011-11-15T10:30:43Z", amount: 10 },
{date: "2011-11-16T22:54:06Z", amount: 10 },
I'm going round in circles trying to work this out and I'm now completely confused so any help would be appreciated!
Thanks.
The following will get your your absolute minimum. Won't work with filtering though!
var data = [
{date: "2011-11-14T10:17:54Z", amount: 10 },
{date: "2011-11-14T12:20:19Z", amount: 1 },
{date: "2011-11-14T14:20:19Z", amount: 0 },
{date: "2011-11-15T06:30:43Z", amount: 10 },
{date: "2011-11-15T10:30:43Z", amount: 10 },
{date: "2011-11-15T16:28:54Z", amount: 100 },
{date: "2011-11-16T18:48:46Z", amount: 100 },
{date: "2011-11-16T20:53:41Z", amount: 11 },
{date: "2011-11-16T22:54:06Z", amount: 10 },
];
var ndx = crossfilter(data);
var dayDim = ndx.dimension(function (d) { return "" + d.date.substr(8,2); });
var minGroup = dayDim.group().reduce(
function (p, v) { if(v.amount < p || p === null) p = v.amount; return p; },
function (p, v) { return p; },
function () { return null; }
);
console.table(minGroup.top(Infinity));
If you want filtering to work, you need to keep a sorted array of all the values found in each array and then add/remove values as data is filtered and unfiltered. Then use this sorted array to figure out your minimum. Something like the following (untested):
var data = [
{date: "2011-11-14T10:17:54Z", amount: 10 },
{date: "2011-11-14T12:20:19Z", amount: 1 },
{date: "2011-11-14T14:20:19Z", amount: 0 },
{date: "2011-11-15T06:30:43Z", amount: 10 },
{date: "2011-11-15T10:30:43Z", amount: 10 },
{date: "2011-11-15T16:28:54Z", amount: 100 },
{date: "2011-11-16T18:48:46Z", amount: 100 },
{date: "2011-11-16T20:53:41Z", amount: 11 },
{date: "2011-11-16T22:54:06Z", amount: 10 },
];
var ndx = crossfilter(data);
var dayDim = ndx.dimension(function (d) { return "" + d.date.substr(8,2); });
var minGroup = dayDim.group().reduce(
function (p, v) {
if(v.amount < p.min || p.min === null) {
p.min = v.amount;
}
p.values.push(v.amount);
return p;
},
function (p, v) {
p.values.splice(p.values.indexOf(v.amount),1);
if(v.amount === p.min) {
p.values.sort(function(a,b) { return a < b ? -1 : 1; });
p.min = p.values[0];
}
return p;
},
function () { return { min: null, values: [] }; }
);
console.log(minGroup.top(Infinity));

Asp.net webform with flot.js chart on return Json does not work

I am using ASP.NET webforms for flot charts I connected to database in test.aspx.cs file using [Webmethod] where I can return json.
I stored the return value both in textarea and $.plot(placeholder, [and also here], options) It does not print the graph in placeholder however when I do:
var data = past
the value of textarea here and run applicationn it prints to me the value.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static List<string> GetLocation(string location)
{
List<string> result = new List<string>();
StringBuilder strQuery = new StringBuilder();
strQuery.Append("SELECT Location.Nome_Location, DATEPART(day, Statistiche.Data_Statistica) AS SDay, COUNT(Statistiche.ID_Tabella) AS Stats");
strQuery.Append(" FROM Statistiche INNER JOIN Tabelle ON Statistiche.ID_Tabella = Tabelle.ID_Tabella INNER JOIN");
strQuery.Append(" Location ON Statistiche.ID_Colonna_Statistica = Location.ID_Location");
strQuery.Append(" WHERE (Statistiche.ID_Tabella = 2) AND (Statistiche.ID_Box = 60) AND (Location.Nome_Location = 'Albilò')");
strQuery.Append("GROUP BY Location.Nome_Location, DATEPART(day, Statistiche.Data_Statistica)");
string query = strQuery.ToString();
SqlConnection con = new SqlConnection("");
SqlCommand cmd = new SqlCommand(query, con);
con.Open();
int counter = 1;
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
if (counter == 1)
{
result.Add("[{'label': 'Europe (EU27)','data':[[" + dr["SDay"].ToString() + "," + dr["Stats"].ToString() + "]");
}
else
result.Add("[" + dr["SDay"].ToString() + "," + dr["Stats"].ToString() + "]");
if (counter==31)
{
result.Add("[" + dr["SDay"].ToString() + "," + dr["Stats"].ToString() + "]]}]");
}
counter++;
}
return result;
}
$.ajax({
type: "POST",
async: true,
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "test.aspx/GetLocation",
data: "{'location':'Albilò'}",
success: function drawChart(msg) {
var options = { lines: { show: true }, points: { show: true }, xaxis: { tickDecimals: 0, tickSize: 1} };
var ddata = [];
var data = msg.d;
for (var i = 0; i < 32; i++) {
ddata.push(data[i]);
}
var placeholder = $("#placeholder");
$("#txtvalue").val(ddata);
var datad = $("#txtvalue").text();
$.plot(placeholder, ddata, options);
},
error: function () {
alert("call is called111");
}
});
First of all, why do you create JSON yourself? You've already specified to return JSON in you attributes.
Refactore method to return simple array of POCO objects like
[Serializable]
public class pocoObject
{
public string Label;
..
}
Then your method should just return list of object and have attributes set up:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static List<pocoObject> GetLocation(string location)
{
...
return result; // result is list of pocoObjects
}
Flot.js is rather sensitive to data you set as source, so after this take a look at data in firebug, it should be correct json formatted data. So please visit wiki and also compare your data to working samples.
This how you can initiliaze legend names of you plot:
$(function () {
var d1 = [];
for (var i = 0; i < Math.PI * 2; i += 0.25)
d1.push([i, Math.sin(i)]);
var d2 = [];
for (var i = 0; i < Math.PI * 2; i += 0.25)
d2.push([i, Math.cos(i)]);
var d3 = [];
for (var i = 0; i < Math.PI * 2; i += 0.1)
d3.push([i, Math.tan(i)]);
$.plot($("#placeholder"), [
{ label: "sin(x)", data: d1},
{ label: "cos(x)", data: d2},
{ label: "tan(x)", data: d3}
], {
series: {
lines: { show: true },
points: { show: true }
},
xaxis: {
ticks: [0, [Math.PI/2, "\u03c0/2"], [Math.PI, "\u03c0"], [Math.PI * 3/2, "3\u03c0/2"], [Math.PI * 2, "2\u03c0"]]
},
yaxis: {
ticks: 10,
min: -2,
max: 2
},
grid: {
backgroundColor: { colors: ["#fff", "#eee"] }
}
});
});

Graph Generation in flex

I need to generate a graph using the following XML in FLEX.
[Bindable]
public var stockDataAC:ArrayCollection = new ArrayCollection( [
{date: "2010, 4, 27", close: 41.71},
{date: "2010, 4, 28", close: 42.21},
{date: "2010, 5, 2", close: 42.71},
{date: "2010, 5, 3", close: 42.99},
{date: "2010, 5, 4", close: 44} ]);
..............
< mx:horizontalAxis >
< mx:DateTimeAxis dataUnits="days" displayLocalTime="true" parseFunction="myParseFunction" / >
< /mx:horizontalAxis>
But this displays the graph from 2010/4/27 till 2010/5/4 including 2010/4/29, 2010/4/30 and 2010/5/1. I require the graph to display only the points in XML and exclude remaining thought it lies in between since it contains no data. How this can be done?
Maybe you should consider tracing lines between the XML points, instead of displaying points.
See Canvas.lineTo(x,y) for more.

Resources