我正在使用D3制作地图。我已经在地图上添加了点和圆圈。当我平移地球(这是一个立体地图)时,点会更新到新位置,但圆圈会发生变化。如何以与圈子类似的方式更新积分?
我使用以下方法添加点和圆圈:
// POINTS
svg.append("g").attr("class","points")
.selectAll("text").data(places.features)
.enter().append("path")
.attr("class", "point")
.style("pointRadius", 2)
.style("fill", "red");
// CIRCLES
svg.append("g").attr("class","circles")
.selectAll("path").data(places.features)
.enter().append("circle")
.attr('cx', function(d) { return proj(d.geometry.coordinates)[0]})
.attr('cy', function(d) { return proj(d.geometry.coordinates)[1]})
.attr("r", 4)
.style('fill', 'green')
.attr("d", path);
然后在平移地图时,我调用一个名为refresh
的函数来更新这些对象:
function refresh() {
// redraw land
svg.selectAll(".land").attr("d", path);
// redraw circles
svg.selectAll(".point").attr("d", path.projection(proj));
// redraw circles
svg.selectAll(".circles").attr("d", path.projection(proj));
}
此处显示了一个工作示例(需要链接world-110m.json
才能使其生效)。我应该以不同的方式添加圈子,以便重绘它们吗?
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.land {
fill: rgb(117, 87, 57);
stroke-opacity: 1;
stroke: #fff;
stroke-width: 0.75;
}
</style>
<head>
<!-- libraries -->
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/queue.v1.min.js"></script>
<script src="http://d3js.org/topojson.v0.min.js"></script>
</head>
<body>
<div class="map"></div>
</body>
<script>
// Lots of code from:
// http://bl.ocks.org/3757125
// http://bl.ocks.org/3795040
// data
var places = {"type": "FeatureCollection","features": [
{ "type": "Feature", "properties": { "id": 34, "status": 1}, "geometry": { "type": "Point", "coordinates": [ 55.321249, 24.104000 ] }},
{ "type": "Feature", "properties": { "id": 34, "status": 1}, "geometry": { "type": "Point", "coordinates": [ 55.321249, 24.104000 ] }},
{ "type": "Feature", "properties": { "id": 272, "status": 1}, "geometry": { "type": "Point", "coordinates": [ 54.002962, 23.455742 ] }},
{ "type": "Feature", "properties": { "id": 272, "status": 1}, "geometry": { "type": "Point", "coordinates": [ 54.002962, 23.455742 ] }},
{ "type": "Feature", "properties": { "id": 350, "status": 1}, "geometry": { "type": "Point", "coordinates": [ 136.321249,-24.496000 ] }},
{ "type": "Feature", "properties": { "id": 427, "status": 0}, "geometry": { "type": "Point", "coordinates": [ 136.321249,-26.296000 ] }},
{ "type": "Feature", "properties": { "id": 427, "status": 0}, "geometry": { "type": "Point", "coordinates": [ 136.321249,-26.296000 ] }},
{ "type": "Feature", "properties": { "id": 96, "status": 0}, "geometry": { "type": "Point", "coordinates": [ 138.259022,-24.491771 ] }}]};
var width = 700,
height = 700;
var proj = d3.geo.orthographic()
.translate([width / 2, height / 2])
.clipAngle(90)
.scale(310);
var sky = d3.geo.orthographic()
.translate([width / 2, height / 2])
.clipAngle(90)
.scale(360);
var path = d3.geo.path().projection(proj);
d3.select(window)
.on("mousemove", mousemove)
.on("mouseup", mouseup);
var svg = d3.select("body").select('.map').append("svg")
.attr("width", width)
.attr("height", height)
.on("mousedown", mousedown)
queue()
.defer(d3.json, "data/world-110m.json")
.await(ready);
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
function ready(error, world) {
var globe_highlight = svg.append("defs").append("radialGradient")
.attr("id", "globe_highlight")
.attr("cx", "75%")
.attr("cy", "25%");
globe_highlight.append("stop")
.attr("offset", "5%").attr("stop-color", "#ffd")
.attr("stop-opacity","0.6");
globe_highlight.append("stop")
.attr("offset", "100%").attr("stop-color", "#ba9")
.attr("stop-opacity","0.2");
svg.append("circle")
.attr("cx", width / 2).attr("cy", height / 2)
.attr("r", proj.scale())
.attr("class", "noclicks")
.style("fill", "url(#ocean_fill)");
svg.append("path")
.datum(topojson.object(world, world.objects.land))
.attr("class", "land noclicks")
.attr("d", path);
// POINTS
svg.append("g").attr("class","points")
.selectAll("text").data(places.features)
.enter().append("path")
.attr("class", "point")
.style("pointRadius", 2)
.style("fill", "red");
// CIRCLES
svg.append("g").attr("class","circles")
.selectAll("path").data(places.features)
.enter().append("circle")
.attr('cx', function(d) { return proj(d.geometry.coordinates)[0]})
.attr('cy', function(d) { return proj(d.geometry.coordinates)[1]})
.attr("r", 4)
.style('fill', 'green')
.attr("d", path);
refresh();
}
function refresh() {
// redraw land
svg.selectAll(".land").attr("d", path);
// redraw circles
svg.selectAll(".point").attr("d", path.projection(proj));
// redraw circles
svg.selectAll(".circles").attr("d", path.projection(proj));
}
// modified from http://bl.ocks.org/1392560
var m0, o0;
function mousedown() {
m0 = [d3.event.pageX, d3.event.pageY];
o0 = proj.rotate();
d3.event.preventDefault();
}
function mousemove() {
if (m0) {
var m1 = [d3.event.pageX, d3.event.pageY]
, o1 = [o0[0] + (m1[0] - m0[0]) / 6, o0[1] + (m0[1] - m1[1]) / 6];
o1[1] = o1[1] > 30 ? 30 :
o1[1] < -30 ? -30 :
o1[1];
proj.rotate(o1);
sky.rotate(o1);
refresh();
}
}
function mouseup() {
if (m0) {
mousemove();
m0 = null;
}
}
</script>
</html>
答案 0 :(得分:2)
circle
个元素没有d
属性,只有path
个元素。因此,您可能希望附加path
而不是circle
。
此外,您要将课程分配给父g
元素,因此refresh
中的选择实际上是指g
不是形状本身。您应该将类放在形状上,或者将选择更改为:
svg.selectAll(".point")
.selectAll("path")
.attr("d", path.projection(proj));