Supstat nyc subway

1,254 views

Published on

find us at http://www.meetup.com/NYC-Open-Data/events/137298432/
Hack Session 2: New Yorker Magazine Vis---Inequalit­y and New York’s Subway
Magazine link: http://www.newyorker.com/sandbox/business/subway.html

Published in: Technology, Business
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,254
On SlideShare
0
From Embeds
0
Number of Embeds
555
Actions
Shares
0
Downloads
12
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Supstat nyc subway

  1. 1. Data Source Chart Axis Background Label Path Station Map New York’s map Subway line Station(position) Projection,data Scale,Axis,line Attribute Class,id,etc..
  2. 2. subway line New York city subway_inequality_live (excel from google doc) topojson drawChart([json]); tabletop
  3. 3. <script type="text/javascript" src="tabletop.js"></script> <script src="topojson.v0.min.js"></script> var sourceData; window.onload = function() { init() }; var url = 'https://docs.google.com/spreadsheet/pub? key=0ApL2ZVhpOmONdFdTUWhxV252elNORVNqT0g5Y0NzV1E&outp ut=html'; function init() { Tabletop.init( { key: url, callback: show, simpleSheet: true } ); } function show(data) { sourceData = data; drawChart();
  4. 4. D3.geo.mercator() d3.geo.path().projection data(map data).enter().append(“pat h”).attr(“d”,path) New York city map Subway line
  5. 5. create map var projection = d3.geo.mercator() .center([-73.955, 40.678) .translate([w/2, h/2]) .scale([34000]); var path = d3.geo.path() .projection(projection); var g = svg.append("g") .attr("class", "borough_lines");
  6. 6. create map var w = 400; var h = 400; var svg = d3.select("#map") .append("svg") .attr("width", w) .attr("height", h);
  7. 7. create map g.selectAll("path.borough_map") .data(topojson.object(nyc_boroughs[0], nyc_boroughs[0].objects.new_york_city_boroughs).geometries) .enter() .append("path") .attr("d", path) .attr("class", "borough_map");
  8. 8. create map var g1 = svg.append("g") .attr("class", "map_lines"); g1.selectAll("path.map_line") .data(topojson.object(subway_lines[0], subway_lines[0].objects.subways).geometries) .enter() .append("path") .attr("d", path) .attr("class", function(d){ return "map_line l_" + d.properties.route_id }) .style("fill", "white") .style("fill-opacity", 0) .style("opacity", .5) .style("stroke-width", 3) .style("stroke-linecap", "round");
  9. 9. create map svg.selectAll("circle.map_circle") .data(sourceData) .enter() .append("circle") .attr("cx", function(d){//transform position return projection([d.long, d.lat])[0]; }) .attr("cy", function(d){ return projection([d.long, d.lat])[1]; }) .attr("r", 4) .attr("id", function(d){ return "t_" + d.county + "_" + d.tract }) .attr("opacity", 0); point marker : t_61_24302 hidden
  10. 10. line D3.svg.line().x().y().interpolate() Axis d3.scale.linear() d3.svg.axis().scale(); Bla.call(↑) Data container Label Format,tick
  11. 11. 118px 20px 500px 900px 30px
  12. 12. var containerSize = { width : 900, height : 400 }, create chart margins = {top : 20,right : 20,bottom : 30,left : 118}, chartSize = { width : containerSize.width - margins.left - margins.right - 20, height : containerSize.height - margins.top - margins.bottom }; var chart = d3.select("#graphic") .append("svg") .attr("width", containerSize.width) .attr("height", containerSize.height) .append("g") .attr("transform", "translate(" + margins.left + "," + margins.top + ")") .attr("id","chart");
  13. 13. X position,50px Y position,0px 100px Data: [{x:5},{y:0}] What is scale? var test_scale = d3.scale.linear() .range([0,100) .domain([0, 10]); test_scale(5)? Get 50px Test_scale(0)? Get 0 px X: test_scale
  14. 14. Make the scale var stop_scale = d3.scale.linear() .range([0,chartSize.width]) .domain([1, 49]); X: stop_scale Y: incomeScale var incomeScale = d3.scale.linear() //data range .range([chartSize.height, 0]) .domain([0,230000]); //income axis, max230000
  15. 15. Make the axis convert function formatNum(d){ return d.toString().replace(/(?=(?!b)(?:d{3})+(?!d))/g, ',') } 10000 to 10,000 var stop_axis = d3.svg.axis() .scale(stop_scale); var incomeAxis = d3.svg.axis() .scale(incomeScale) .orient("left") .tickValues([0, 50000, 100000, 150000, 200000])//tick .tickSize(-chartSize.width, 0) .tickPadding(20) .tickFormat(function(d) { return "$" + formatNum(d); }); //format number
  16. 16. create line g.selectAll("circle") .data(sourceData) .enter() .append("circle"); window ['lineBox'] = g //dispose var line2011Path = d3.svg.line() .x(function(d){return stop_scale(d.position)}) .y(function(d){return incomeScale(d.income2011)}) .interpolate("cardinal");
  17. 17. d3.select("#chart") .append("g") .attr("id", "areaBox"); Make the chart chart.append("g") .attr("class", "y axis") .call(incomeAxis); d3.select(".y.axis") .append("text") .attr("text-anchor","middle") .text("median household income") .attr("transform", "rotate (270, 0, 0)") .attr("x", -180) .attr("y", -110); var g = d3.select("#chart") .append("g") .attr("id","line_path_2011"; g.append("path");
  18. 18. Whole data Trigger by Button brushed data By “id” map chart Hide all line ShowLine (id) Hide all points Matching path Transition path (id) Show related points (brushed data)
  19. 19. Class: line l_1 <div class="line l_1">1</div> <div class="line l_2">2</div> <div class="line l_3">3</div> <div class="line l_4">4</div> <div class="line l_5">5</div> <div class="line l_6">6</div> <div class="line l_7">7</div> .... .. <div class="line l_J">J</div> <div class="line l_Z">Z</div> <div class="line l_G">G</div> <div class="line l_L">L</div> <div class="line l_SIR">SIR</div> Create button
  20. 20. use css to color the line .l_123, .l_1, .l_2, .l_3 { background-color: #FF3535; stroke: #FF3535;} .l_456, .l_4, .l_5, .l_6 { background-color: #019733; stroke: #019733;} .l_7 { background-color: #CC02C8; stroke: #CC02C8;} .l_ace, .l_A, .l_C, .l_E { background-color: #0F6797; stroke: #0F6797;} .l_bdfm, .l_B, .l_D, .l_F, .l_M { background-color: #FF9800; stroke: #FF9800;} .l_nqr, .l_N, .l_Q, .l_R { background-color: #ffe400; stroke: #ffe400;} .l_SIR { background-color: #164480; stroke: #164480;} .l_jz, .l_J, .l_Z { background-color: #986701; stroke: #986701;} .l_L, .l_l { background-color: #999999; stroke: #999999;} .l_G, .l_g { background-color: #9BCF00; stroke: #9BCF00;}
  21. 21. Make the transition function drawLine(filteredData, id){ d3.selectAll(".line") .on(“click”, brushData) function brushData(){ id = d3.select(this).text(); filteredData = sourceData.filter(function(d){return d.line === id}); drawLine(filteredData, id); … Draw chart line(l_+id) … Draw subway (l_+id) … Show circles(filteredData) }
  22. 22. function drawLine(filteredData, id){ Draw chart line(l_+id) Draw subway (l_+id) Show circles(filteredData) } Show circles(filteredData) d3.selectAll("circle") .transition() .duration(500) .attr("r", 0);//minimize all circle window['lineBox'].selectAll("circle") .data(filteredData) .transition() .duration(1000) .attr("r", 4) .attr("class", function(d) {return "t_" + d.county + "_" + d.tract }) .attr("cx", function(d) {return stop_scale(d.position)}) .attr("cy", function(d) {return incomeScale(d.income2011)});
  23. 23. function drawLine(filteredData, id){ Draw chart line(l_+id) Draw subway (l_+id) Show circles(filteredData) } Draw chart line(l_+id) d3.select("#line_path_2011 path") .attr("class", "graph_line l_" + id .transition() .duration(1000) .attr("d", line2011Path(filteredData) var line2011Path = d3.svg.line() .x(function(d){return stop_scale(d.position)}) .y(function(d){return incomeScale(d.income2011)}) .interpolate("cardinal");
  24. 24. function drawLine(filteredData, id){ Draw chart line(l_+id) Draw subway (l_+id) Show circles(filteredData) } Draw subway (l_+id) //hideall d3.selectAll(".map_line") .transition() .duration(500) .style("opacity", 0); //show d3.selectAll(".map_line.l_" + id) .transition() .duration(500) .style("opacity", 1); d3.selectAll(".line") .classed("selected", false); d3.select(".line.l_" + id) .classed("selected", true);
  25. 25. Create info box <div id="tooltip" class=""> <div class="line l_F ">F</div> <div id="stop-name"> <span id="name">East Broadway</span> </div> <div class="label-wrap"> <div class="label-number" id="income2011">$86,806</div> <div class="label">2011 median household income in census tract <span id="census">001401</span></div> </div> </div>
  26. 26. Define point activity //hover overs/interactions d3.selectAll("circle") .on("mouseover", function(d) { //Show tooltip(mouse position) //Bigger the point on chart //Insert content //Show the point on map }) .on("mouseout", function() { //hide tooltip //Smaller the point });
  27. 27. d3.select(this) .transition() Bigger the point on chart .attr("r", 8); d3.select("#tooltip") .style("left", (d3.event.pageX) + 20 + "px") .style("top", (d3.event.pageY) - 30 + "px").transition() Show tooltip .style("opacity", 1); d3.select('#stop-name #name') .text(d.stopname) d3.select('#tooltip .line') .text(id) .attr("class", "line l_" + id, true) Fill the content d3.select('#income2011') .text("$" + formatNum(d.income2011)); d3.select('#census') .text(d.tractlookup); d3.select("circle#" + this.className.animVal) .transition() .duration(500) .attr("opacity", 1) .attr("r", 5); Show point on map
  28. 28. //Hide the tooltip d3.select("#tooltip") .transition() .style("opacity", 0); d3.select(this) .transition() .attr("r", 4); d3.selectAll("#map circle") .transition() .duration(500) .attr("opacity", 0); Hide tooltip Smaller point on chart Hide point on map
  29. 29. Start:where we can draw the next county Cut the county County:id Span: how many points
  30. 30. Whole data Memo:[] Match the line “id” Filtered data Reduce data County change? yes Push new county data(start,span,county ) no Span++
  31. 31. Filter data Boroughs = filteredData.reduce( function (memo, stop, i) { var len = memo.length; if (len == 0 || (memo[len - 1].county != stop.county)) { memo.push({ county : stop.county, start : i + 1, span : 1 }); } else { memo[len - 1].span++; } [{"county":"47","start":1,"span":19}, return memo; {"county":"61","start":20,"span":15}] }, [])
  32. 32. Draw county var gCounties = d3.select("#areaBox") .selectAll('g.borough') .data(boroughs).enter() .append('g') .attr('class', 'borough') .attr('transform', function (d) return 'translate(' + stop_scale(d.start) + });
  33. 33. Add label gCounties.append('rect') .attr('x', -5) .attr('width', function (d) { return stop_scale(d.span + .8) }) .attr('height', chartSize.height); gCounties.append('text') .attr("y", 15) .text(function (d) { if (d.county == "5") { return "BRX" } else if (d.county == "61") { return "MAN" } else if (d.county == "81") { return "QNS" } else if (d.county == "47") { return "BRK" }; });

×