From 1e389f8c405e45f95f2c5f01eedcaaeea178bc60 Mon Sep 17 00:00:00 2001 From: David Schoonover Date: Wed, 23 May 2012 17:50:52 -0700 Subject: [PATCH] Cleans up geo chart in prep for making a chart-type. --- lib/main-geo.co | 256 ++++++++++++++++++++++++---------------------- www/css/geo-display.styl | 64 ++++++++---- www/geo.jade | 53 +++++----- 3 files changed, 206 insertions(+), 167 deletions(-) diff --git a/lib/main-geo.co b/lib/main-geo.co index 75a3300..bc2613e 100644 --- a/lib/main-geo.co +++ b/lib/main-geo.co @@ -1,22 +1,23 @@ # Seq = require 'seq' +# d3 = require 'd3' ColorBrewer = require 'colorbrewer' -root = this -# root.data = null +# Loaded below +data = map = feature = infobox = null width = 960 height = 500 - +# chloropleth coloring fill = d3.scale.log() .domain [1, 10000] .range ["black", "red"] quantize = (d) -> # console.log d.properties.name - if root.data[d.properties.name]? - return fill root.data[d.properties.name]['editors'] + if data[d.properties.name]? + return fill data[d.properties.name]['editors'] else # console.log 'Country '+d.properties.name+' not in data' return fill "rgb(0,0,0)" @@ -28,7 +29,7 @@ move = -> .scale d3.event.scale feature.attr "d", path -## zooming/panning +### zooming/panning projection = d3.geo.mercator() .scale width @@ -43,127 +44,138 @@ zoom = d3.behavior.zoom() .scaleExtent [height,height*8] .on "zoom", move - -# main svg object - -# svg = d3.select '#worldmap' -# .append "svg" -# .attr "width", width -# .attr "height", height -# .append "g" -# .attr "transform", "translate(0,0)" -# .call zoom - -map = d3.select '#worldmap' - .attr "width", width - .attr "height", height - .append "g" - .attr "transform", "translate(0,0)" - .call zoom - - - -# path objects -feature = map.selectAll ".feature" - -# rectangle -map.append "rect" - .attr "class", "frame" - .attr "width", width - .attr "height", height - - -# infobox -infobox = d3.select '#infobox' - .style "display","none" - -infobox.select '#ball' - .append "svg" - .attr "width", "100%" - .attr "height", "20px" - .append "rect" - .attr "width", "60%" - .attr "height", "20px" - .attr "fill", '#f40500' - - -setInfoBox = (d) -> - c = d.properties.name - ae = 0 - e5 = 0 - e100 = 0 - if root.data[d.properties.name]? - ae = parseInt(root.data[d.properties.name]['editors']) - e5 = parseInt(root.data[d.properties.name]['editors5']) - e100 = parseInt(root.data[d.properties.name]['editors100']) +# Configure Spin.js Options +spinner = (overrides={}) -> + opts = { + lines : 11 # [12] The number of lines to draw + length : 4 # [7] The length of each line + width : 1 # [5] The line thickness + radius : 18 # [10] The radius of the inner circle + rotate : -10.5 # [0] rotation offset + trail : 50 # [100] Afterglow percentage + opacity : 1/4 # [1/4] Opacity of the lines + shadow : false # [false] Whether to render a shadow + speed : 1 # [1] Spins per second + zIndex : 2e9 # [2e9] zIndex; uses a very high z-index by default + color : '#333' # ['#000'] Line color; '#rgb' or '#rrggbb'. + top : 'auto' # ['auto'] Top position relative to parent in px; 'auto' = center vertically. + left : 'auto' # ['auto'] Left position relative to parent in px; 'auto' = center horizontally. + className : 'spinner' # ['spinner'] CSS class to assign to the element + fps : 20 # [20] Frames per second when falling back to `setTimeout()`. + hwaccel : Modernizr.csstransforms3d # [false] Whether to use hardware acceleration. + } import overrides + jQuery '.geo-spinner' .show().spin opts + +spinner() + +# on DOM ready +main = -> + ### main svg object - infobox.select '#country' .text c - infobox.select '#ae' .text ae - infobox.select '#e5' .text e5+" ("+(100.0*e5/ae).toPrecision(3)+"%)" - infobox.select '#e100' .text e100+" ("+(100.0*e100/ae).toPrecision(3)+"%)" + map := d3.select '#worldmap' + .append "svg:svg" + .attr "width", width + .attr "height", height + .append "svg:g" + .attr "transform", "translate(0,0)" + .call zoom - xy = d3.svg.mouse this - infobox.style "left", xy[0]+'px' - infobox.style "top", xy[1]+'px' - infobox.style "display", "block" - - -worldmap = -> - d3.json do - "/data/geo/maps/world-countries.json" - (json) -> - root.feature = feature - .data json.features - .enter().append "path" - .attr "class", "feature" - .attr "d", path - .attr "fill", quantize - .attr do - "id" - (d) -> - d.properties.name - .on "mouseover",setInfoBox - # .on do - # "mouseover" - # (d) -> - # if root.data[d.properties.name]? - - # p.text d.properties.name+" - All:"+root.data[d.properties.name]['editors']+' 5+:'+root.data[d.properties.name]['editors5']+' 100+:'+root.data[d.properties.name]['editors100'] - # # console.log root.data[d.properties.name]['editors'] - # else - # p.text d.properties.name+": No edits" - # # console.log 'Country '+d.properties.name+' not in data' - - # # xy = path.centroid d - # xy = d3.svg.mouse this - # infobox.style "left", xy[0]+'px' - # infobox.style "top", xy[1]+'px' - # infobox.style "display", "block" - .on do - "mouseout" - (d) -> - infobox.style "display", "none" - - - -jQuery.ajax do - url : "/data/geo/data/en_geo_editors.json" - dataType : 'json' - success : (res) -> - # result will be the returned JSON - - root.data = res + # path objects + feature := map.selectAll ".feature" + + # rectangle + map.append "svg:rect" + .attr "class", "frame" + .attr "width", width + .attr "height", height + + + ### infobox + infobox := d3.select '#infobox' + + infobox.select '#ball' + .append "svg:svg" + .attr "width", "100%" + .attr "height", "20px" + .append "svg:rect" + .attr "width", "60%" + .attr "height", "20px" + .attr "fill", '#f40500' + + setInfoBox = (d) -> + name = d.properties.name + ae = 0 + e5 = 0 + e100 = 0 - # load the world map - worldmap() + if data[name]? + ae = parseInt data[name].editors + e5 = parseInt data[name].editors5 + e100 = parseInt data[name].editors100 - # adding bootstrap tooltips - # $ '.page-header' .tooltip title:"for the header it works but is useless" - # $ '.feature' .tooltip title:"here it doesn't work" + infobox.select '#country' .text name + infobox.select '#ae' .text ae + infobox.select '#e5' .text e5+" ("+(100.0*e5/ae).toPrecision(3)+"%)" + infobox.select '#e100' .text e100+" ("+(100.0*e100/ae).toPrecision(3)+"%)" - console.log 'Loaded geo coding map!' + xy = d3.svg.mouse this + infobox.style "left", xy[0]+'px' + infobox.style "top", xy[1]+'px' + infobox.style "display", "block" - error : (err) -> console.error err - + worldmap = -> + d3.json do + "/data/geo/maps/world-countries.json" + (json) -> + feature := feature + .data json.features + .enter().append "svg:path" + .attr "class", "feature" + .attr "d", path + .attr "fill", quantize + .attr "id", (d) -> d.properties.name + .on "mouseover",setInfoBox + # .on do + # "mouseover" + # (d) -> + # if data[d.properties.name]? + + # p.text d.properties.name+" - All:"+data[d.properties.name]['editors']+' 5+:'+data[d.properties.name]['editors5']+' 100+:'+data[d.properties.name]['editors100'] + # # console.log data[d.properties.name]['editors'] + # else + # p.text d.properties.name+": No edits" + # # console.log 'Country '+d.properties.name+' not in data' + + # # xy = path.centroid d + # xy = d3.svg.mouse this + # infobox.style "left", xy[0]+'px' + # infobox.style "top", xy[1]+'px' + # infobox.style "display", "block" + .on "mouseout", -> infobox.style "display", "none" + + + jQuery.ajax do + url : "/data/geo/data/en_geo_editors.json" + dataType : 'json' + success : (res) -> + # result will be the returned JSON + data := res + + # delete & hide spinner + jQuery '.geo-spinner' .spin(false).hide() + + # load the world map + worldmap() + + # adding bootstrap tooltips + # $ '.page-header' .tooltip title:"for the header it works but is useless" + # $ '.feature' .tooltip title:"here it doesn't work" + + console.log 'Loaded geo coding map!' + error : (err) -> console.error err + +# jQuery main + + diff --git a/www/css/geo-display.styl b/www/css/geo-display.styl index d1544ac..d4c20cc 100644 --- a/www/css/geo-display.styl +++ b/www/css/geo-display.styl @@ -1,23 +1,47 @@ @import 'colors' @import 'nib' -svg - background #eee - max-width 900px - margin 0 auto - -.frame - stroke #000 - fill none - pointer-events all - -.feature - stroke #ccc - -#infobox - position absolute - pointer-events none - // width 180px - // padding 5px - // border-radius 5px; - // background-color rgba(200,200,200,.85) +section.geo + position relative + margin 0 auto + min-width 640px + max-width 960px + + #worldmap + position relative + min-width 960px + min-height 500px + + .geo-spinner + position absolute + z-index 300 + top 0 + left 0 + width 100% + height 100% + + .help + text-align right + + #infobox + display none + position absolute + pointer-events none + border 1px solid #333 + // width 180px + // padding 5px + // border-radius 5px; + // background-color rgba(200,200,200,.85) + + svg + background #eee + margin 0 auto + // max-width 900px + + .frame + stroke #000 + fill none + pointer-events all + + .feature + stroke #ccc diff --git a/www/geo.jade b/www/geo.jade index cd28bd8..bf0c0d2 100644 --- a/www/geo.jade +++ b/www/geo.jade @@ -1,34 +1,37 @@ extends layout -block content - .page-header - h1 Wikimedia Geolocation Map - small English Wikipedia - February 2012 - - svg#worldmap - - .well#infobox - .row - .span4 - h3#country - .row - .span2 All editors - .span2#ae - .row - .span2 5+ editors - .span2#e5 - .row - .span2 100+ editors - .span2#e100 - - .page-footer.pull-right - h6 Zoom/Pan using mouse. - block title - title Geolocation + title Editors by Location, February 2012 | English Wikipedia + +block content + section.geo + .page-header + h1 Editors by Location + small English Wikipedia — February 2012 + + #worldmap + .geo-spinner + + .well#infobox + .row + .span4 + h3#country + .row + .span2 All editors + .span2#ae + .row + .span2 5+ editors + .span2#e5 + .row + .span2 100+ editors + .span2#e100 + + .help + h6 Zoom/Pan using mouse. append styles mixin css('geo-display.css') block main-scripts script(src="/js/kraken/main-geo.js?"+version) + -- 1.7.0.4