

Mapping with D3 - NelsonMinar
http://eyeseast.github.com/visible-data/2012/12/14/mapping-with-d3/

======
duopixel
You are attaching 9420 event listeners (three for each county). A better
solution would be to do the equivalent of delegate in jQuery:

    
    
      var counties = map.append('g');
    
      counties.attr('class', 'counties')
    	  .selectAll('path')
    	    .data(countylines.features)
    	  .enter().append('path')
    	    .attr('d', path);
    
      counties.on('mouseover', function(){
               if (d3.event.target.tagName == "path")
                  showCaption();
            })
    	.on('mouseout', function() {
               if (d3.event.target.tagName != "path")
    	    	caption.html(starter);
    	    });
    

You also don't need to repeat the process on mousemove, that triggers dozens
of events per second for what mouseover and mouseout already accomplished.

Try it out, I'm sure it will feel snappier.

------
idan
I recently built a web-based tool for visualizing usage of Tel Aviv's
municipal bicycle rental system using D3 and mapbox (warning, hebrew):
<http://telostats.com>

Source is up at <https://github.com/idan/telostats>, janky though it may be.
This was my first effort with geo and D3, and I'm a python person, so the JS
is probably eight different kinds of terrible, but hopefully it's useful.
There are a lot of examples like the OP's blogpost where D3 is used to render
geometry, but very few that show you how to use D3 as an informational layer
above an existing slippymap (which is what we did).

------
johncoogan
I think the value of TopoJSON is a bit understated here. MBostock reported
some pretty awesome results about a month ago. "With TopoJSON, reduced 2.2M
shapefile to 628K (-72%, 176K gzipped)!"
<https://twitter.com/mbostock/status/269548330663677952>

Additionally, smoothing shapefiles with tools like <http://mapshaper.org> can
really help trim down filesizes.

~~~
tgasson
Absolutely agree. I'm currently in the process of producing a thematic map as
part of a set of data visualisations[1]. TopoJSON is proving to be an absolute
godsend. It's allowed us to reduce ~100MB+ geoJSON down to ~1MB and the shared
arc's means we can include multiple levels of boundaries without duplicating
the data needed to be sent over the network.

There's still some issues we're having. SVG rendering performance isn't fast
or consistent across browsers for 3000+ polygons and although TopoJSON shares
arcs between common boundaries the rendered polygons don't. Also the large
differences in the size of boundaries we're dealing with means the map needs
to be zoom-able. Delivering higher detail boundaries dynamically is tough
problem to solve. Ideally you could request a bounding box from a TopoJSON
based server, and it would deliver a delta of higher detailed points
precomputed from Visvalingam’s algorithm[2].

I found the default quantization level to be much too blocky. For anyone
working with TopoJSON I'd recommend you first raise the quantization level
while looking at your smallest features until they're no longer blocky, then
use the inbuilt simplification to bring the file size down to manageable.

[1]: <http://www.bts.nsw.gov.au/BTS-Visual> [2]:
<http://bost.ocks.org/mike/simplify/> (explained at the bottom)

~~~
mbostock
Hey, that's fantastic. Thank you for the feedback. I can see how you would
need to raise TopoJSON's quantization level for creating zoomable geometry;
the default level is designed for display approximately 10,000px by 10,000px,
and you'd quickly exceed that if you allow people to zoom in. I probably
wouldn't want to change the default, though, as that would make the files
larger than necessary for static display. (Perhaps there's a way to decide the
appropriate quantization automatically?)

A useful technique with zoomable geometry is using Visvalingam's algorithm to
precompute the salience (visual importance) of each point, but not
prefiltering; then, you filter the points based on the zoom level during
rendering. Thus, the rendered detail increases as you zoom in, but you only
need to download one TopoJSON file.

Depending on how much zooming you're doing, breaking the geometry into tiles
and zoom-level specific data would be helpful (à la Polymaps), but I think for
many visualization applications it's overkill. For example, a single TopoJSON
file of U.S. states and counties with enough detail for both a national and
state-specific view is easily doable without tiling.

The next release of D3 (3.0) includes streaming geometry transformations. This
can enable fast filtering of geometry using the precomputed salience during
rendering as described above without the overhead of creating multiple copies
of the geometry during the rendering pipeline. Also, D3 3.0 supports rendering
directly to Canvas, which is excellent for animated or interactive changes to
the projection. For example:

<http://bl.ocks.org/4183330>

You can see the stream interface here:

<https://github.com/mbostock/d3/blob/3.0/src/geo/stream.js>

------
apinstein
st_simplify() is your friend.

<http://postgis.org/docs/ST_Simplify.html>

~~~
mbostock
As mentioned in the post, take a look at TopoJSON's topology-preserving
simplification:

<https://github.com/mbostock/topojson/wiki>

TopoJSON's --simplify flag uses Visvalingam's algorithm. And, since it's the
mesh that is simplified rather than independent features, shared borders
between features will be preserved. Without this feature, you end up with
something that resembles shattered glass:

<http://twitter.yfrog.com/z/mn13gp>

------
anilyeni
<http://d3js.com/> -> <http://d3js.org/>

------
FiloSottile
Please note that the json data he used is not from bl.ocks.org as it is only a
proxy for GH Gist data. In this case it is a Gist [1] from @mbostock.

[1] <https://gist.github.com/3750900>

------
ericfrigot
Concerning the size of the json file with geo path, I don't know if you can
rename the attributes, but you can save 300ko just by using simplified
coordinates ("-86.411786" becomes "-86.4"). I don't think you need sub-pixel
precision :)

~~~
tgasson
That's actually something topojson will do for you. It stores a translate and
scale value that fits so all the values can be simple integers.

