Example using the d3.ringNote
plugin to add circle annotations to a map. Drag the dashed circles and
the text to move the annotation elements. These moveable,
dashed-line circles will disappear if ringNote.draggable(false)
is called.
This example also shows how to style (or hide) certain elements of the annotation after it has been drawn. In this example one of the circles is hidden.
The map is a fork of mbostock's block: Choropleth
xxxxxxxxxx
<html>
<head>
<style>
html {
font-family: sans-serif;
}
.hidden { display: none; }
.annotation circle {
fill: none;
stroke: black;
}
.annotation path {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.annotation text {
text-shadow: -2px 0 2px #fff,
0 2px 2px #fff,
2px 0 2px #fff,
0 -2px 2px #fff;
}
.counties {
fill: none;
}
.states {
fill: none;
stroke: #fff;
stroke-linejoin: round;
}
.q0-9 { fill:rgb(247,251,255); }
.q1-9 { fill:rgb(222,235,247); }
.q2-9 { fill:rgb(198,219,239); }
.q3-9 { fill:rgb(158,202,225); }
.q4-9 { fill:rgb(107,174,214); }
.q5-9 { fill:rgb(66,146,198); }
.q6-9 { fill:rgb(33,113,181); }
.q7-9 { fill:rgb(8,81,156); }
.q8-9 { fill:rgb(8,48,107); }
</style>
</head>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/queue.v1.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script src="d3-ring-note.js"></script>
<script>
// After position the annotation, run `copy(annotations)` in the browser's
// console and paste over this array:
var annotations = [
{
"cx": 675,
"cy": 180,
"r": 51,
"text": "Michigan was hit hard by the last recession",
"textWidth": 200,
"textOffset": [
53,
-78
]
},
{
"cx": 378,
"cy": 115,
"r": 25,
"text": "Less than 2% unemployed in parts of North Dakota",
"textWidth": 200,
"textOffset": [
10,
-61
]
},
{
"cx": 131,
"cy": 310,
"r": 89,
"text": "30% unemployment",
"textOffset": [
38,
112
],
"hideCircle": true /* used to identify which circles to hide */
}
];
var width = 960,
height = 600;
var rateById = d3.map();
var quantize = d3.scale.quantize()
.domain([0, .15])
.range(d3.range(9).map(function(i) { return "q" + i + "-9"; }));
var projection = d3.geo.albersUsa()
.scale(1280)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var ringNote = d3.ringNote()
.draggable(true);
queue()
.defer(d3.json, "us.json")
.defer(d3.tsv, "unemployment.tsv", function(d) { rateById.set(d.id, +d.rate); })
.await(ready);
function ready(error, us) {
if (error) throw error;
svg.append("g")
.attr("class", "counties")
.selectAll("path")
.data(topojson.feature(us, us.objects.counties).features)
.enter().append("path")
.attr("class", function(d) { return quantize(rateById.get(d.id)); })
.attr("d", path);
svg.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
.attr("class", "states")
.attr("d", path);
var gAnnotations = svg.append("g")
.attr("class", "annotations")
.call(ringNote, annotations);
gAnnotations.selectAll(".annotation circle")
.classed("hidden", function(d) { return d.hideCircle; });
}
</script>
</body>
</html>
https://d3js.org/d3.v3.min.js
https://d3js.org/queue.v1.min.js
https://d3js.org/topojson.v1.min.js