added "istime" parameter to the options, now numeric columns should work as the sort, will fubar any clock though as a lot of the internals still think they are dates

This commit is contained in:
Andrew Hill 2013-04-17 18:35:15 -04:00
parent 10656eb3b6
commit 0209c52acf
5 changed files with 79 additions and 19 deletions

View File

@ -69,7 +69,8 @@
var TorqueOptions = { var TorqueOptions = {
user: "viz2", user: "viz2",
table: "madrid_osm_line", table: "madrid_osm_line",
column: "fake_date", column: "osm_id",
istime: false,
cumulative: false, cumulative: false,
resolution: 2, resolution: 2,
steps: 750, steps: 750,

View File

@ -157,6 +157,17 @@ TimePlayer.prototype.get_time_data = function (tile, coord, zoom) {
// take se and sd as a matrix [se|sd] // take se and sd as a matrix [se|sd]
var numTiles = 1 << zoom; var numTiles = 1 << zoom;
var sql = "" var sql = ""
var column_conv = "";
var expir_conv = "";
if (this.options.istime == true){
column_conv = "date_part('epoch',{0})".format(this.t_column);
expir_conv = "date_part('epoch',{0})".format(this.options.expiration_column);
} else {
column_conv = this.t_column;
expir_conv = this.options.expiration_column;
}
if ( this.options.cumulative_expires == true) { if ( this.options.cumulative_expires == true) {
sql = "WITH hgrid AS ( " + sql = "WITH hgrid AS ( " +
" SELECT CDB_RectangleGrid( " + " SELECT CDB_RectangleGrid( " +
@ -172,16 +183,16 @@ TimePlayer.prototype.get_time_data = function (tile, coord, zoom) {
" round(CAST (st_xmax(hgrid.cell) AS numeric),4) x, " + " round(CAST (st_xmax(hgrid.cell) AS numeric),4) x, " +
" round(CAST (st_ymax(hgrid.cell) AS numeric),4) y, " + " round(CAST (st_ymax(hgrid.cell) AS numeric),4) y, " +
" {0} c, ".format(this.countby) + " {0} c, ".format(this.countby) +
" floor((date_part('epoch',{0})- {1})/{2}) d, ".format(this.t_column, this.MIN_DATE, this.step) + " floor(({0}- {1})/{2}) d, ".format(column_conv, this.MIN_DATE, this.step) +
" floor((date_part('epoch',{0})- {1})/{2}) de ".format(this.options.expiration_column, this.MIN_DATE, this.step) + " floor(({0}- {1})/{2}) de ".format(expir_conv, this.MIN_DATE, this.step) +
" FROM " + " FROM " +
" hgrid, {0} i ".format(this.table) + " hgrid, {0} i ".format(this.table) +
" WHERE " + " WHERE " +
" ST_Intersects(i.the_geom_webmercator, hgrid.cell) " + " ST_Intersects(i.the_geom_webmercator, hgrid.cell) " +
" GROUP BY " + " GROUP BY " +
" hgrid.cell, " + " hgrid.cell, " +
" floor((date_part('epoch',{0})- {1})/{2}), ".format(this.t_column, this.MIN_DATE, this.step) + " floor(({0}- {1})/{2}), ".format(column_conv, this.MIN_DATE, this.step) +
" floor((date_part('epoch',{0})- {1})/{2})".format(this.options.expiration_column, this.MIN_DATE, this.step) + " floor(({0}- {1})/{2})".format(expir_conv, this.MIN_DATE, this.step) +
" ) f GROUP BY x, y"; " ) f GROUP BY x, y";
} else { } else {
sql = "WITH hgrid AS ( " + sql = "WITH hgrid AS ( " +
@ -196,13 +207,13 @@ TimePlayer.prototype.get_time_data = function (tile, coord, zoom) {
" FROM ( " + " FROM ( " +
" SELECT " + " SELECT " +
" round(CAST (st_xmax(hgrid.cell) AS numeric),4) x, round(CAST (st_ymax(hgrid.cell) AS numeric),4) y, " + " round(CAST (st_xmax(hgrid.cell) AS numeric),4) x, round(CAST (st_ymax(hgrid.cell) AS numeric),4) y, " +
" {0} c, floor((date_part('epoch',{1})- {2})/{3}) d ".format(this.countby, this.t_column, this.MIN_DATE, this.step) + " {0} c, floor(({1}- {2})/{3}) d ".format(this.countby, column_conv, this.MIN_DATE, this.step) +
" FROM " + " FROM " +
" hgrid, {0} i ".format(this.table) + " hgrid, {0} i ".format(this.table) +
" WHERE " + " WHERE " +
" ST_Intersects(i.the_geom_webmercator, hgrid.cell) " + " ST_Intersects(i.the_geom_webmercator, hgrid.cell) " +
" GROUP BY " + " GROUP BY " +
" hgrid.cell, floor((date_part('epoch',{0})- {1})/{2})".format(this.t_column, this.MIN_DATE, this.step) + " hgrid.cell, floor(({0} - {1})/{2})".format(column_conv, this.MIN_DATE, this.step) +
" ) f GROUP BY x, y"; " ) f GROUP BY x, y";
} }

View File

@ -76,6 +76,7 @@ Torque.modules.layer = function (torque) {
user:'viz2', user:'viz2',
table:'ny_bus', table:'ny_bus',
column:'timestamp', column:'timestamp',
istime: true,
steps:250, steps:250,
resolution:3, resolution:3,
cumulative:false, cumulative:false,
@ -185,7 +186,14 @@ Torque.modules.layer = function (torque) {
}, },
getDeltas:function (options) { getDeltas:function (options) {
var that = this; var that = this;
var sql = "SELECT st_xmax(st_envelope(st_collect(the_geom))) xmax,st_ymax(st_envelope(st_collect(the_geom))) ymax, st_xmin(st_envelope(st_collect(the_geom))) xmin, st_ymin(st_envelope(st_collect(the_geom))) ymin, date_part('epoch',max({0})) max, date_part('epoch',min({0})) min FROM {1}".format(this.options.column, this.options.table); if (this.options.istime == true){
var max_col = "date_part('epoch',max({0}))".format(this.options.column);
var min_col = "date_part('epoch',min({0}))".format(this.options.column);
} else {
var max_col = "max({0})".format(this.options.column);
var min_col = "min({0})".format(this.options.column);
}
var sql = "SELECT st_xmax(st_envelope(st_collect(the_geom))) xmax,st_ymax(st_envelope(st_collect(the_geom))) ymax, st_xmin(st_envelope(st_collect(the_geom))) xmin, st_ymin(st_envelope(st_collect(the_geom))) ymin, {0} max, {1} min FROM {2}".format(max_col, min_col, this.options.table);
var timeExtents = this._cartodb.CartoDBCollection.extend({ var timeExtents = this._cartodb.CartoDBCollection.extend({
sql:sql sql:sql

View File

@ -33,25 +33,40 @@ body {
} }
#slider-spark .head { #slider-spark .head {
position: relative; position: relative;
background: transparent; background: steelblue;
border: 2px solid steelblue; border: 2px solid steelblue;
width: 10px; height: 10px; width: 10px; height: 10px;
border-radius: 6px; border-radius: 6px;
cursor: pointer; cursor: pointer;
z-index: 5;
} }
#slider-spark .pin { #slider-spark .pin {
position: relative; position: relative;
background: rgba(255,191,0,0.5); background: rgba(255,191,0,0.2);
margin-top: -3px;
border: 0px; border: 0px;
margin-left: 6px; margin-left: 3px;
margin-right: 3px;
padding-left: 3px;
padding-right: 3px;
width: 2px; width: 2px;
height: 180px; height: 183px;
} }
path { path {
stroke: steelblue; stroke: steelblue;
stroke-width: 1; stroke-width: 2;
fill: none; fill: none;
} }
circle {
stroke: steelblue;
}
text {
font-family: Arial;
font-size: 9pt;
font-color: white;
stroke-weight: 300;
stroke: rgba(255,255,255,0.45);
}
.axis { .axis {
shape-rendering: crispEdges; shape-rendering: crispEdges;
} }

View File

@ -38,7 +38,9 @@
var sql = new cartodb.SQL({ user: user_name}); var sql = new cartodb.SQL({ user: user_name});
var table_name = 'ow'; var table_name = 'ow';
var date_col = 'date'; var date_col = 'date';
var date_format = 'year' //year, time or date
var steps = 750; var steps = 750;
var wm = 10; //left/right margins
var map = new google.maps.Map(document.getElementById('map'), { var map = new google.maps.Map(document.getElementById('map'), {
center:new google.maps.LatLng(30.95940879245423, -0.609375), center:new google.maps.LatLng(30.95940879245423, -0.609375),
@ -78,29 +80,30 @@
var wm = 10; //left/right margins
sql.execute("WITH extents AS (SELECT max({{date_col}}) mx, min({{date_col}}) mn FROM {{table_name}} WHERE the_geom IS NOT NULL) SELECT count(*) count, mn + i*(mx - mn)/{{steps}} frame FROM {{table_name}}, extents, GENERATE_SERIES(1,{{steps}}) i WHERE mn + (i-1)*(mx - mn)/{{steps}} < {{date_col}} AND {{date_col}} < mn + (i)*(mx - mn)/{{steps}} GROUP BY mn + i*(mx - mn)/{{steps}} ORDER BY mn + i*(mx - mn)/{{steps}} ASC", {table_name: table_name, date_col: date_col, steps: steps}) sql.execute("WITH extents AS (SELECT max({{date_col}}) mx, min({{date_col}}) mn FROM {{table_name}} WHERE the_geom IS NOT NULL) SELECT count(*) count, mn + i*(mx - mn)/{{steps}} frame FROM {{table_name}}, extents, GENERATE_SERIES(1,{{steps}}) i WHERE mn + (i-1)*(mx - mn)/{{steps}} < {{date_col}} AND {{date_col}} < mn + (i)*(mx - mn)/{{steps}} GROUP BY mn + i*(mx - mn)/{{steps}} ORDER BY mn + i*(mx - mn)/{{steps}} ASC", {table_name: table_name, date_col: date_col, steps: steps})
.error(function(e){console.log(e)}) .error(function(e){ })
.done(function(data){ .done(function(data){
console.log(data)
var m = 20; var m = 20;
var w = $('#slider-container').width(); var w = $('#slider-container').width();
var h = $('#slider-container').height()-2*m; var h = $('#slider-container').height()-2*m;
data = data.rows; data = data.rows;
var mxX = new Date(data[data.length-1].frame); var mnX = new Date(data[0].frame);
var mxY = data[0].count, mnY = data[0].count; var mxY = data[0].count, mnY = data[0].count;
$.each(data,function(i,d){ $.each(data,function(i,d){
if (d.count < mnY) mnY = d.count; if (d.count < mnY) mnY = d.count;
if (mxY < d.count) mxY = d.count; if (mxY < d.count) mxY = d.count;
}) })
var x = d3.scale.linear().domain([0, data.length]).range([0, w - 2*wm ]); var x = d3.scale.linear().domain([mnX, mxX]).range([0, w - 2*wm ]);
// var x = d3.scale.linear().domain([0, data.length]).range([0, w - 2*wm ]);
var y = d3.scale.linear().domain([mnY, mxY]).range([h, 0]); var y = d3.scale.linear().domain([mnY, mxY]).range([h, 0]);
var line = d3.svg.line() var line = d3.svg.line()
.x(function(d,i) { .x(function(d,i) {
return x(i); return x(new Date(d.frame));
}) })
.y(function(d) { .y(function(d) {
return y(d.count); return y(d.count);
@ -112,6 +115,28 @@
.attr("height", h + m) .attr("height", h + m)
.append("svg:g"); .append("svg:g");
graph.selectAll(".xLabel")
.data(x.ticks(10))
.enter().append("svg:text")
.attr("class", "xLabel")
.text(function(i, d) {
// if (d==0) {return null}
if (date_format == 'time'){
return new Date(i).toTimeString().split(' ')[0];
}
else if (date_format == 'year') {
return new Date(i).getFullYear();
}
else {
var d = new Date(i).toDateString().split(' ');
return d.slice(1, 4).join(' ')
}
})
.attr("x", function(d) { return x(new Date(d)) })
.attr("y", h+18)
.attr("text-anchor", "middle")
graph.append("svg:path").attr("d", line(data)); graph.append("svg:path").attr("d", line(data));
var TorqueOptions = { var TorqueOptions = {