-
-
Save mbostock/899711 to your computer and use it in GitHub Desktop.
license: gpl-3.0 |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/> | |
<style> | |
html, body, #map { | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
padding: 0; | |
} | |
.stations, .stations svg { | |
position: absolute; | |
} | |
.stations svg { | |
width: 60px; | |
height: 20px; | |
padding-right: 100px; | |
font: 10px sans-serif; | |
} | |
.stations circle { | |
fill: brown; | |
stroke: black; | |
stroke-width: 1.5px; | |
} | |
</style> | |
<div id="map"></div> | |
<script src="//maps.google.com/maps/api/js?sensor=true"></script> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script> | |
// Create the Google Map… | |
var map = new google.maps.Map(d3.select("#map").node(), { | |
zoom: 8, | |
center: new google.maps.LatLng(37.76487, -122.41948), | |
mapTypeId: google.maps.MapTypeId.TERRAIN | |
}); | |
// Load the station data. When the data comes back, create an overlay. | |
d3.json("stations.json", function(error, data) { | |
if (error) throw error; | |
var overlay = new google.maps.OverlayView(); | |
// Add the container when the overlay is added to the map. | |
overlay.onAdd = function() { | |
var layer = d3.select(this.getPanes().overlayLayer).append("div") | |
.attr("class", "stations"); | |
// Draw each marker as a separate SVG element. | |
// We could use a single SVG, but what size would it have? | |
overlay.draw = function() { | |
var projection = this.getProjection(), | |
padding = 10; | |
var marker = layer.selectAll("svg") | |
.data(d3.entries(data)) | |
.each(transform) // update existing markers | |
.enter().append("svg") | |
.each(transform) | |
.attr("class", "marker"); | |
// Add a circle. | |
marker.append("circle") | |
.attr("r", 4.5) | |
.attr("cx", padding) | |
.attr("cy", padding); | |
// Add a label. | |
marker.append("text") | |
.attr("x", padding + 7) | |
.attr("y", padding) | |
.attr("dy", ".31em") | |
.text(function(d) { return d.key; }); | |
function transform(d) { | |
d = new google.maps.LatLng(d.value[1], d.value[0]); | |
d = projection.fromLatLngToDivPixel(d); | |
return d3.select(this) | |
.style("left", (d.x - padding) + "px") | |
.style("top", (d.y - padding) + "px"); | |
} | |
}; | |
}; | |
// Bind our overlay to the map… | |
overlay.setMap(map); | |
}); | |
</script> |
{"KMAE":[-120.12,36.98,"MADERA MUNICIPAL AIRPORT",[26,1,2,5,6,3,2,1,2,7,29,12,3]],"KSJC":[-121.92,37.37,"SAN JOSE INTERNATIONAL AIRPORT",[28,1,1,1,6,10,5,3,2,4,14,21,7]],"KMCE":[-120.50,37.28,"MERCED MUNICIPAL AIRPORT",[29,1,1,3,7,5,2,1,3,6,12,26,5]],"KMER":[-120.57,37.37,"Merced / Castle Air Force Base",[34,1,1,1,4,5,2,1,1,4,17,22,7]],"KAPC":[-122.28,38.20,"NAPA COUNTY AIRPORT",[23,2,1,6,3,3,8,18,11,13,4,3,5]],"KSUU":[-121.95,38.27,"Fairfield / Travis Air Force Base",[13,7,4,3,3,6,4,13,33,4,1,2,7]],"KSQL":[-122.25,37.52,"San Carlos Airport",[18,3,2,2,3,4,3,2,5,17,16,12,12]],"KSNS":[-121.60,36.67,"SALINAS MUNICIPAL AIRPORT",[21,1,1,6,12,3,1,2,9,21,17,5,1]],"KMOD":[-120.95,37.62,"MODESTO CITY CO SHAM FLD",[27,1,1,2,10,5,1,1,1,3,17,24,8]],"KOAK":[-122.23,37.72,"METRO OAKLAND INTERNATIONAL AIRPORT ",[16,3,3,2,4,6,3,4,9,23,20,6,2]],"KSCK":[-121.23,37.90,"STOCKTON METROPOLITAN AIRPORT ",[21,2,2,3,6,8,2,1,4,15,19,12,4]],"KCCR":[-122.05,38.00,"CONCORD BUCHANAN FIELD",[24,3,2,1,1,5,17,12,9,9,7,6,4]],"KMRY":[-121.85,36.58,"MONTEREY PENINSULA AIRPORT",[26,1,2,9,5,3,4,9,13,14,9,4,1]],"KPAO":[-122.12,37.47,"Palo Alto Airport",[31,3,1,1,2,5,1,1,1,4,10,25,14]],"KSAC":[-121.50,38.50,"SACRAMENTO EXECUTIVE AIRPORT ",[32,1,0,1,3,11,12,16,5,2,4,9,3]],"KHWD":[-122.12,37.67,"HAYWARD AIR TERMINAL",[20,2,7,2,2,6,3,3,6,23,18,6,2]],"KSTS":[-122.82,38.50,"SANTA ROSA SONOMA COUNTY",[46,1,0,1,5,13,10,4,3,3,4,6,3]],"KSMF":[-121.60,38.70,"SACRAMENTO INTERNATIONAL AIRPORT",[19,2,1,2,4,21,18,8,3,2,5,12,4]],"KNUQ":[-122.05,37.43,"MOFFETT FIELD",[35,3,1,1,4,7,2,1,2,5,6,17,15]],"KRHV":[-121.82,37.33,"San Jose / Reid / Hillv",[35,0,0,1,4,4,2,1,1,10,28,11,1]],"KWVI":[-121.78,36.93,"WATSONVILLE MUNICIPAL AIRPORT ",[44,1,2,3,4,5,7,9,8,4,6,5,2]],"KMHR":[-121.30,38.55,"Sacramento, Sacramento Mather Airport",[21,1,1,2,8,15,12,12,7,4,5,7,3]],"KVCB":[-121.95,38.38,"VACAVILLE NUT TREE AIRPORT",[36,2,1,1,2,6,10,18,10,2,2,5,6]],"KSFO":[-122.37,37.62,"SAN FRANCISCO INTERNATIONAL AIRPORT ",[13,3,3,2,3,4,4,4,7,31,20,2,3]],"KLVK":[-121.82,37.70,"LIVERMORE MUNICIPAL AIRPORT ",[32,2,7,3,1,1,2,7,9,17,16,2,1]]} |
Has a solution been found for this mouse event problem? I also would like to create some more interaction with my graphs.
I've implemented this and the marker shows up. However, when zooming in and out, the marker doesn't update its position (though panning works just fine). Any hint?
cc @mbostock
ah, nm, it turns out some css style is needed. In my case, this was needed:
.stations, .stations svg {
position: absolute;
}
any examples on how to add d3 circles in real time as data is received?
I, too, am looking for a solution to mouseover/onclick events for the svg circles. Anyone found anything?
I ended up answering my own question. You have to make a couple changes. First make the overlayLayer
an overlayMouseTarget
like so:
var layer = d3.select(this.getPanes().overlayMouseTarget).append("div") .attr("class", "stations");
I added the following attr to the circle:
marker.append("svg:circle").attr("r", 4.5).attr("cx", padding).attr("cy", padding).on("click",toggleExpand);
...and then had to define the toggleExpand()
method:
function toggleExpand() { if(d3.select(this).attr("r") == 4.5) { d3.select(this).transition().duration(100).attr("r",7) } else { d3.select(this).transition().duration(100).attr("r",4.5) } }
(please forgive the formatting, I can't make the function look good)
Thanks for this example it got me heading in the right direction.
I copied it (didn't fork) and made some changes for my own purposes so that I could use a single SVG instead of one per map marker and like several others mentioned so I could have my markers get mouse events (using overlayMouseTarget
instead of overlayLayer
.
I did a small writeup of my changes here and the end result is here.
I've already loaded data from Elasticsearch, doing a query to ES, into an object called "resp"... I've this values:
"hits": {
"hits": [
"_source": {"location": "43.54526,-5.661926"},
"_source": {"location": "40.41669,-3.700346"}
]}
so values from "resp.hits.hits._source.location" is what i want to draw in the map
I've tried to adapt the code with
var marker = layer.selectAll("svg")
.data(resp.hits.hits)
and:
d = new google.maps.LatLng(d.location)
or
d = new google.maps.LatLng(d.location[1],d.location[0])
It doens't works ¿? Thanks!
In some cases, the map is part of a document, that contains some css like the following:
*, *::before, *::after {
box-sizing: border-box;
}
if you add the above css to the example, the overlay div is still placed but not rendered.
Highlighting each html svg element shows it's in the right location, but the content is not displayed.
any idea why?
hi mbostock, i took a copy of your code and tweaked it a little bit to get live lat and long from an api, by this i could get live tracking of my car!
but now i want just only the live locations to be plotted on the map , and aviod the trailing points, but i dont know how to remove the trailing points.. can someone tell me how?
i got the solution to the described problem, we have to remove the existing svg layer us9ing the folowing command
d3.select("svg").remove();
Thanks anyways :)
if i add the <div id="map"></div>
inside another div, the map not show
Hi,
Can someone help me with drawing a line between two points? My main idea is to not just plot nodes but to plot a graph over a map. Since, the above code shows how to plot the nodes, can some one help me with plotting lines between the plotted nodes?
Thank you in advance.
Hello,
I am new here so please accept my apologizes in advance if I am asking something wrongly. If possible I would like to ask you for help, I am using the code above in this article to plot two set of circles in a google map with some variations, so I am getting the two sets from two different files, for that I am using 2 overlays, that are added to the map separately, but it is plotting only the first set of circles, if possible could I post my code and the two files anywhere to get any help with that?
Thank you in advance.
Tatiana