d3美国状态图与标记,缩放变换问题 [英] d3 US state map with markers, zooming transform issues
问题描述
我已经创建了一个美国各州的d3地图,以下示例:
var width = 900,
height = 500,
active = d3.select
var projection = d3.geo.albersUsa()
.scale(1000)
.translate([width / 2,height / 2]);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select(。rebates)append(svg)
.attr(width,width)
.attr ,height);
svg.append(rect)
.attr(class,background)
.attr(width,width)
.attr (height,height)
.on(click,reset);
var g = svg.append(g)
.style(stroke-width,1.5px);
d3.json(/ files / d3-geo / us.json,function(error,us){
if(error){throw error;}
g.selectAll(path)
.data(topojson.feature(us,us.objects.states).features)
.enter $ b .attr(d,path)
.attr(class,function(item){
return window.US_STATES [item.id] .water_authorities> 0?'avail': ';
})
.on(click,clicked);
g.append(path)
.datum(topojson.mesh (us,us.objects.states,function(a,b){return a!== b;}))
.attr(class,mesh)
.attr ,path);
});
d3.json('/ files / coordinates.json',function(error,coords){
if(error){throw error;}
svg .selectAll(。mark)
.data(coords)
.enter()
.append(image)
.attr('class','mark' )
.attr('width',20)
.attr('height',20)
.attr(xlink:href,'assets / gmap_red.png')
.attr(transform,function(d){
returntranslate(+ projection([d [1],d [0]])+);
}
});
function clicked(d){
if(active.node()=== this){return reset(); }
if(window.US_STATES [d.id] .water_authorities === 0){return; }
active.classed(active,false);
active = d3.select(this).classed(active,true);
var bounds = path.bounds(d),
dx = bounds [1] [0] - bounds [0] [0],
dy = bounds [1] [1] - bounds [0] [1],
x =(bounds [0] [0] + bounds [1] [0] + bounds [1] [1])/ 2,
scale = .9 / Math.max(dx / width,dy / height),
translate = [width / 2- / 2-scale * y];
g.transition()
.duration(750)
.style(stroke-width,1.5 / scale +px)
.attr transform,translate(+ translate +)scale(+ scale +));
}
function reset(){
active.classed(active,false);
active = d3.select(null);
rebatesTable.clear()。draw();
g.transition()
.duration(750)
.style(stroke-width,1.5px)
。 ,);
}
/ strong>
添加组中的所有点,而不是svg中的点。
这将确保标记点与主组翻译。
g.selectAll(。mark) //在组中添加标记
.data(marks)
.enter()
.append(image)
.attr('class','mark')
.attr('width',20)
.attr('height',20)
.attr(xlink:href,'https://cdn3.iconfinder.com/ data / icons / softwaredemo / PNG / 24x24 / DrawingPin1_Blue.png')
.attr(transform,function(d){
returntranslate(+ projection([d.long,d。 lat])+);
});
第2步
取消主组的缩放效果。
g.selectAll(。mark)
.transition b $ b .duration(750)
.attr(transform,function(d){
var t = d3.transform(d3.select(this).attr(transform))。 translate; // maintain aold marker translate
returntranslate(+ t [0] +,+ t [1] +)scale(+ 1 / scale +) of parent
});
Step3
缩小时将标记缩放为1。
g.selectAll(。mark)
.attr(transform,function(d){
var t = d3.transform(d3.select(this).attr(transform))。translate;
console.log
returntranslate(+ t [0] +,+ t [1] +)scale(+ 1+);
}
工作代码此处
希望这有助于!
I've created a d3 map with US states, following this example:
http://bl.ocks.org/mbostock/4699541
and added markers following this SO question:
Put markers to a map generated with topoJSON and d3.js
The problem is that on zoom, the map markers stay in place. I believe I need to translate them into a new position, but not sure how to make that happen.
var width = 900,
height = 500,
active = d3.select(null);
var projection = d3.geo.albersUsa()
.scale(1000)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select(".rebates").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height)
.on("click", reset);
var g = svg.append("g")
.style("stroke-width", "1.5px");
d3.json("/files/d3-geo/us.json", function(error, us) {
if (error) { throw error; }
g.selectAll("path")
.data(topojson.feature(us, us.objects.states).features)
.enter().append("path")
.attr("d", path)
.attr("class", function(item) {
return window.US_STATES[item.id].water_authorities > 0 ? 'avail' : 'unavail';
})
.on("click", clicked);
g.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
.attr("class", "mesh")
.attr("d", path);
});
d3.json('/files/coordinates.json', function(error, coords) {
if (error) { throw error; }
svg.selectAll(".mark")
.data(coords)
.enter()
.append("image")
.attr('class','mark')
.attr('width', 20)
.attr('height', 20)
.attr("xlink:href",'assets/gmap_red.png')
.attr("transform", function(d) {
return "translate(" + projection([d[1],d[0]]) + ")";
});
});
function clicked(d) {
if (active.node() === this) { return reset(); }
if (window.US_STATES[d.id].water_authorities === 0) { return; }
active.classed("active", false);
active = d3.select(this).classed("active", true);
var bounds = path.bounds(d),
dx = bounds[1][0] - bounds[0][0],
dy = bounds[1][1] - bounds[0][1],
x = (bounds[0][0] + bounds[1][0]) / 2,
y = (bounds[0][1] + bounds[1][1]) / 2,
scale = .9 / Math.max(dx / width, dy / height),
translate = [width / 2 - scale * x, height / 2 - scale * y];
g.transition()
.duration(750)
.style("stroke-width", 1.5 / scale + "px")
.attr("transform", "translate(" + translate + ")scale(" + scale + ")");
}
function reset() {
active.classed("active", false);
active = d3.select(null);
rebatesTable.clear().draw();
g.transition()
.duration(750)
.style("stroke-width", "1.5px")
.attr("transform", "");
}
Step 1
Add all the points in the group and not in the svg. This will ensure that the marker points translate with the main group.
g.selectAll(".mark")//adding mark in the group
.data(marks)
.enter()
.append("image")
.attr('class', 'mark')
.attr('width', 20)
.attr('height', 20)
.attr("xlink:href", 'https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/24x24/DrawingPin1_Blue.png')
.attr("transform", function(d) {
return "translate(" + projection([d.long, d.lat]) + ")";
});
Step2
Negate the scaling effect of the main group. else the markers will come zoomed up.
g.selectAll(".mark")
.transition()
.duration(750)
.attr("transform", function(d) {
var t = d3.transform(d3.select(this).attr("transform")).translate;//maintain aold marker translate
return "translate(" + t[0] +","+ t[1] + ")scale("+1/scale+")";//inverse the scale of parent
});
Step3
On zoom out make the marker scale back to 1.
g.selectAll(".mark")
.attr("transform", function(d) {
var t = d3.transform(d3.select(this).attr("transform")).translate;
console.log(t)
return "translate(" + t[0] +","+ t[1] + ")scale("+1+")";
});
Working code here
Hope this helps!
这篇关于d3美国状态图与标记,缩放变换问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!