I’ve been wanting to make a google map with workable mouseovers for a quite a while. Fusion Tables are super useful for drawing shapes on a map and clicking for more info. But, the excessive clicking can be tedious and hide a great deal of the data.
I decided to play around with Albert Sun’s GMap Features that draws shapes based on a KML file. Link: https://github.com/albertsun/gmap-features. And since the payroll tax extension was in the news, I took the median income by census tract dataset from the American Community Survey through American Fact Finder2 and calculated how much people would save for the approved tax cut extension, which is 3.1% of income under $110,100. I got the shapefiles from the census (link: http://www.census.gov/geo/www/tiger/tgrshp2010/tgrshp2010.html) and merged the data and the shapes into one Fusion Table. Why a Fusion Table? FT seemed like the easiest way I knew of to quickly merge a table of polygons with a table of data as long as they shared a common column. Also, FT lets you export all of this as a single KML file, which I could plug into Sun’s template.
I did all that but it wasn’t working and wasn’t giving me an error. After comparing the sample KML files with my FT export, I noticed that my data was wrapped in <Polygon> tags but the sample files were <Multigeometry>. I wrote a simple macro in TextMate that added the tag and it worked! I looked deeper into Sun’s code and it looks like it searches specifically for the <Multigeometry> tag when it draws the shapes, but I’m no KML expert so perhaps there are other important differences for drawing polygons.
UPDATE: After learning some more about KML shapes, I found that you need to clean up the data a bit more to render complex shapes correctly. Sometimes FT outputs some KML polygons as MultiGeometry shapes by default. If you just run a find change to replace “<Polygon>” with “<MultiGeometry><Polygon>” and “</Polygon>” with “</Polygon></MultiGeometry>” you’ll get duplicates on those shapes that are already wrapped in MG tags. The structure should look like:
The macro I recorded is just a series of find/replaces but if you’d like a copy, send me a message at @mhkeller.
Sun included callbacks, which let me add the hoverbox that updates on mouseover, which was awesome and what I’ve been wanting to do for ages now. Here’s the map — more code talk after the jump:
One important feature that I wanted was to be able to put in your address and then have an infowindow appear, so the map could really add some value to people using it. I had used similar functionality in the NY World redistricting map and I realized that since my data was already in a Fusion Table, I could use the same method of querying that table without even adding its data to my map.
The code looks like this and since it just sends back the information from each polygon, the shapes just needed to be the same as my KML shapes:
var queryText = encodeURIComponent(“SELECT censusTract,totalEst,medianIncome,savingsYear,twoMonth,medianMoe FROM “+ tableid +” WHERE ST_INTERSECTS(geometry, CIRCLE(LATLNG(” + coordinate.lat() + “,” + coordinate.lng() + “), 0.1))”);
var query = new google.visualization.Query(‘http://www.google.com/fusiontables/gvizdata?tq=’ + queryText);
The next step was to make a more attractive infowindow to pop up when people look up their address. What’s wrong with the default? It has that extra shadow, white pointer and why use something default when you’re making something custom? Also, I wanted it to be draggable so it wouldn’t hide any data below it. Especially when maps are zoomed out, the infowindow can hide a lot of data points below it — often making comparisons between neighboring shapes impossible. Since those can be the most interesting comparisons, I wanted an info window that would keep that data visible but still movable so it wouldn’t get in the way.
Unfortunately, the google maps API doesn’t have a draggable option that I know of, but markers do (I didn’t want to just make another floating div since it would lose its placement when the map moved or zoomed). In a GoogleCode Group that Ryan Murphy at the Texas Tribune turned me on to there’s a script for a RichMarker, which lets you put custom css/html into a google maps marker (linke: http://google-maps-utility-library-v3.googlecode.com/svn/trunk/richmarker/docs/reference.html).
That worked well for turning it into an infowindow except I wanted the existing mouseover box to disappear when I moused over the new marker. Without this detail, the interaction very felt awkward with both boxes visible. Unfortunately, the RichMarker JS didn’t include a mouseover event listeners so I added it around line 270 with the other event listeners. That worked.
I added some dynamic boundaries for the mouseover box based on the width and height of the map and box, which could probably be refined a bit, as could the overall organization of the js and css, but so far it works. It also wasn’t obvious that people could drag that darker infowindow so I modifed the RichMarker.js to add the “move” cursor on mouseover and added those tooltips you see after you put in your address. Feel free to embed!