| 
          
 | 
        
        
           | 
          // move elements to front | 
        
        
           | 
          // http://tributary.io/tributary/3922684 | 
        
        
           | 
          d3.selection.prototype.moveToFront = function() { | 
        
        
           | 
            return this.each(function(){ | 
        
        
           | 
            this.parentNode.appendChild(this); | 
        
        
           | 
            }); | 
        
        
           | 
          }; | 
        
        
           | 
          
 | 
        
        
           | 
            var width = 960, | 
        
        
           | 
              height = 500, | 
        
        
           | 
              active = d3.select(null); //zoom | 
        
        
           | 
          
 | 
        
        
           | 
            // set projection and map position | 
        
        
           | 
            // tweek these settings for a nice display | 
        
        
           | 
            var projection = d3.geo.albers() // popular alternative is geo.mercator() | 
        
        
           | 
              .center([0, 40.0]) //[30, 45.0] | 
        
        
           | 
              .scale(900) // 275 | 
        
        
           | 
              .rotate([97.8717, 0]) | 
        
        
           | 
              .translate([width / 2, height / 2]) | 
        
        
           | 
              .precision(.1); | 
        
        
           | 
          
 | 
        
        
           | 
            var path = d3.geo.path() | 
        
        
           | 
              .projection(projection); | 
        
        
           | 
          
 | 
        
        
           | 
            var svg = d3.select("body").append("svg") | 
        
        
           | 
              .attr("width", width) | 
        
        
           | 
              .attr("height", height) | 
        
        
           | 
              .attr("class", "chart"); | 
        
        
           | 
          
 | 
        
        
           | 
            var graticule = d3.geo.graticule(); | 
        
        
           | 
          
 | 
        
        
           | 
            var dataset; | 
        
        
           | 
          
 | 
        
        
           | 
            var destination = [-75.1667 , 39.9500];		// Philly lat lon | 
        
        
           | 
          
 | 
        
        
           | 
            var map = svg.append("g") | 
        
        
           | 
              .attr("class", "map"); | 
        
        
           | 
          
 | 
        
        
           | 
            var | 
        
        
           | 
              vizGroup = svg.append("g").attr("class", "viz"), | 
        
        
           | 
              countryGroup = map.append("g"), | 
        
        
           | 
              stateGroup = map.append("g") | 
        
        
           | 
              ; | 
        
        
           | 
          
 | 
        
        
           | 
            // plot world, states, and people data | 
        
        
           | 
            queue() | 
        
        
           | 
              .defer(d3.json, "world-50m.json") | 
        
        
           | 
              .defer(d3.json, "us.json") | 
        
        
           | 
              .defer(d3.csv, "people.csv") | 
        
        
           | 
              .await(visualize); | 
        
        
           | 
          
 | 
        
        
           | 
            function visualize(error, world, us, people){ | 
        
        
           | 
              if (error) return console.log(error); | 
        
        
           | 
          
 | 
        
        
           | 
            dataset = people; | 
        
        
           | 
          
 | 
        
        
           | 
            // draw backgound to for reset function | 
        
        
           | 
            map.append("rect") | 
        
        
           | 
              .attr("class", "background") | 
        
        
           | 
              .attr("width", width) | 
        
        
           | 
              .attr("height", height) | 
        
        
           | 
              .on("click", reset); | 
        
        
           | 
          
 | 
        
        
           | 
            // draw graticules | 
        
        
           | 
            map.append("path") | 
        
        
           | 
              .datum(graticule) | 
        
        
           | 
              .attr("class", "graticule") | 
        
        
           | 
              .attr("d", path); | 
        
        
           | 
          
 | 
        
        
           | 
            // draw world | 
        
        
           | 
            countryGroup | 
        
        
           | 
              .selectAll("path") | 
        
        
           | 
              .data(topojson.feature(world, world.objects.countries).features) | 
        
        
           | 
              .enter().insert("path", ".graticule") | 
        
        
           | 
              .attr("class", "boundary") | 
        
        
           | 
              .attr("d", path); | 
        
        
           | 
          
 | 
        
        
           | 
            // draw states | 
        
        
           | 
            stateGroup | 
        
        
           | 
              .selectAll("path") | 
        
        
           | 
                .data(topojson.feature(us, us.objects.states).features) | 
        
        
           | 
              .enter().append("path") | 
        
        
           | 
                // .attr("d", path) | 
        
        
           | 
                .attr("class", "state-boundary") | 
        
        
           | 
                .attr("d", path); | 
        
        
           | 
          
 | 
        
        
           | 
            // create a group for each person record | 
        
        
           | 
            var groups = vizGroup.selectAll("g") | 
        
        
           | 
              .data(dataset) | 
        
        
           | 
              .enter() | 
        
        
           | 
              .append("g") | 
        
        
           | 
              .attr("class", function (d) { | 
        
        
           | 
                return d.name; | 
        
        
           | 
              }) | 
        
        
           | 
              .on("mouseover", function() { | 
        
        
           | 
                d3.select(this).attr("class", "highlight"); | 
        
        
           | 
                // move to front | 
        
        
           | 
                var sel = d3.select(this); | 
        
        
           | 
                sel.moveToFront(); | 
        
        
           | 
              }) | 
        
        
           | 
              .on("mouseout", function (d) { | 
        
        
           | 
                d3.select(this).attr("class", function () { | 
        
        
           | 
                  return d.name;}); | 
        
        
           | 
              }) | 
        
        
           | 
              ; | 
        
        
           | 
              // draw arcs from each record origin to destination | 
        
        
           | 
              groups.append("path") | 
        
        
           | 
                .attr("class", "arc") | 
        
        
           | 
                .attr("d", function (d) { | 
        
        
           | 
                    var coordDepart = [ d.longitude, d.latitude ]; | 
        
        
           | 
                    var coordArrive = destination; | 
        
        
           | 
                    return path({ | 
        
        
           | 
                      type: "LineString", | 
        
        
           | 
                      coordinates: [coordDepart,coordArrive] | 
        
        
           | 
                      }); | 
        
        
           | 
                  }) | 
        
        
           | 
                  .call(d3.helper.tooltip(function(d, i){ | 
        
        
           | 
                       return "<IMG SRC=" + "'" +d.avatar+ "'" + ">"+ | 
        
        
           | 
                       "<div class='name'>" + d.name + "</div>"+ | 
        
        
           | 
                       "<div class = 'org'>" + d.org + "</div>"+ | 
        
        
           | 
                       "<div class = 'place'>" + d.place + "</div>" | 
        
        
           | 
                       } | 
        
        
           | 
                     )); | 
        
        
           | 
              // draw circles for each record origin | 
        
        
           | 
              groups.append("circle") | 
        
        
           | 
               .attr("cx", function(d) { | 
        
        
           | 
                 return projection([d.longitude, d.latitude])[0]; | 
        
        
           | 
               }) | 
        
        
           | 
               .attr("cy", function(d) { | 
        
        
           | 
                 return projection([d.longitude, d.latitude])[1]; | 
        
        
           | 
               }) | 
        
        
           | 
               .attr("r", function(d) { return 4 + (d.count * 2); }) | 
        
        
           | 
               .attr("class", "origin") | 
        
        
           | 
               .call(d3.helper.tooltip(function(d, i){ | 
        
        
           | 
                   return "<IMG SRC=" + "'" +d.avatar+ "'" + ">"+ | 
        
        
           | 
                   "<div class='name'>" + d.name + "</div>"+ | 
        
        
           | 
                   "<div class = 'org'>" + d.org + "</div>"+ | 
        
        
           | 
                   "<div class = 'place'>" + d.place + "</div>" | 
        
        
           | 
                   } | 
        
        
           | 
                  )) | 
        
        
           | 
              .on("click", clicked); // zoom | 
        
        
           | 
          
 | 
        
        
           | 
              function clicked(d) { | 
        
        
           | 
                if (active.node() === this) return reset(); | 
        
        
           | 
                active.classed("active", false); | 
        
        
           | 
                active = d3.select(this).classed("active", true); | 
        
        
           | 
          
 | 
        
        
           | 
                var | 
        
        
           | 
                    cx = projection([d.longitude, d.latitude])[0], | 
        
        
           | 
                    cy = projection([d.longitude, d.latitude])[1], | 
        
        
           | 
                    scale = 3.75, | 
        
        
           | 
                    translate = [width / 2 - scale * cx, height / 2 - scale * cy]; | 
        
        
           | 
          
 | 
        
        
           | 
                // TODO how to link this to main.css? | 
        
        
           | 
                d3.selectAll(".chart circle").transition() | 
        
        
           | 
                    .duration(1000) //750 | 
        
        
           | 
                    .style("stroke-width", 1 / scale *1.5 + "px") // *1.5 is just a fudge | 
        
        
           | 
                    .attr("r", 6 / scale *1.5 ) | 
        
        
           | 
                    .attr("transform", "translate(" + translate + ")scale(" + scale + ")"); | 
        
        
           | 
          
 | 
        
        
           | 
                d3.selectAll(".chart path").transition() | 
        
        
           | 
                    .duration(1000) //750 | 
        
        
           | 
                    .style("stroke-width", 2 / scale *1.5 + "px") // *1.5 is just a fudge | 
        
        
           | 
                    .attr("transform", "translate(" + translate + ")scale(" + scale + ")"); | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              // TODO how to link this to main.css? | 
        
        
           | 
              function reset() { | 
        
        
           | 
                active.classed("active", false); | 
        
        
           | 
                active = d3.select(null); | 
        
        
           | 
          
 | 
        
        
           | 
                d3.selectAll(".chart path, circle").transition() | 
        
        
           | 
                    .duration(1000) //750 | 
        
        
           | 
                    .style("stroke-width", "1.5px") // this is a fudge | 
        
        
           | 
                    .attr("r", 6 ) | 
        
        
           | 
                    .attr("transform", ""); | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              // backgound for sidebar | 
        
        
           | 
              groups.append("rect") | 
        
        
           | 
                 .attr("class", "side-menu") | 
        
        
           | 
                 .attr("y", function(d, i) { return (0 + (20 * i)); }) | 
        
        
           | 
                 .attr("x", "0") | 
        
        
           | 
                 .attr("width", "150") | 
        
        
           | 
                 .attr("height", "20") | 
        
        
           | 
                 .call(d3.helper.tooltip(function(d, i){ | 
        
        
           | 
                      return "<IMG SRC=" + "'" +d.avatar+ "'" + ">" | 
        
        
           | 
                      +"<div class='name'>" + d.name + "</div>" | 
        
        
           | 
                      +"<div class = 'org'>" + d.org + "</div>" | 
        
        
           | 
                      } | 
        
        
           | 
                    )) | 
        
        
           | 
                  .on("click", clicked); | 
        
        
           | 
               ; | 
        
        
           | 
          
 | 
        
        
           | 
              // add sidebar list of names for each person record | 
        
        
           | 
              groups.append("text") | 
        
        
           | 
                 .attr("class", "speaker-list") | 
        
        
           | 
                 .attr("y", function(d, i) { return (15 + (20 * i)); }) | 
        
        
           | 
                 .attr("x", "10") | 
        
        
           | 
                 .text(function(d) {return d.name;}) | 
        
        
           | 
                 .call(d3.helper.tooltip(function(d, i){ | 
        
        
           | 
                     return "<IMG SRC=" + "'" +d.avatar+ "'" + ">"+ | 
        
        
           | 
                     "<div class='name'>" + d.name + "</div>"+ | 
        
        
           | 
                     "<div class = 'org'>" + d.org + "</div>"+ | 
        
        
           | 
                     "<div class = 'place'>" + d.place + "</div>" | 
        
        
           | 
                     } | 
        
        
           | 
                    )) | 
        
        
           | 
                .on("click", clicked); | 
        
        
           | 
               ; | 
        
        
           | 
          
 | 
        
        
           | 
            }; | 
        
        
           | 
          
 | 
        
        
           | 
          d3.select(self.frameElement).style("height", height + "px"); | 
        
        
           | 
          
 | 
        
        
           | 
          // universal zoom and pan listener, disabled | 
        
        
           | 
          // http://bl.ocks.org/d3noob/5189284 | 
        
        
           | 
          //   var zoom = d3.behavior.zoom() | 
        
        
           | 
          //     .on("zoom",function() { | 
        
        
           | 
          //         d3.selectAll(".chart path, circle").attr("transform","translate("+ | 
        
        
           | 
          //             d3.event.translate.join(",")+")scale("+d3.event.scale+")"); | 
        
        
           | 
          //         d3.selectAll(".chart path, circle").selectAll("path") | 
        
        
           | 
          //             .attr("d", path.projection(projection)); | 
        
        
           | 
          // }); | 
        
        
           | 
          // svg.call(zoom) |