2015-12-16 14 views
5

米国は述べて、この例以下、問題点を変換しますD3米国の州のマップは、ズーム私はD3マップを作成しました

ズームでは、マップマーカーがそのまま残ります。私はそれらを新しい位置に翻訳する必要があると信じていますが、それをどうやって作るのかはわかりません。

enter image description here

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", ""); 
} 
+0

私は拡大投影するように変更し、変更された投影でマーカーの位置を再計算します。 –

答えて

6

ステップ1

は、グループ内ではなくSVG内のすべてのポイントを追加します。 これにより、マーカポイントがメイングループに変換されます。ステップ2

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]) + ")"; 
    }); 

はメイングループのスケーリング効果を無効。さもなければマーカーがズームアップされます。

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 
    });   

ステップ3

ズームに出て作業するコードhere

・ホープ、このことができますバック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+")"; 
    }); 

にマーカースケールを作ります!

+1

本当に優れた答え、ありがとう!ズームイン時と同じ種類のイージングをズームアウト時に追加する.transform()。duration(750)(.attr(...)の前に)を追加することで、ステップ3を少し改善しました。 – Troy

+0

選択した状態のパスの中央に移動するのではなく、ズームするときにどのようにマーカーの相対位置を維持できますか? – Nathan

+0

'clicked'関数の中でtranslateが計算されます。それに応じてそれを更新する必要があります。 – Cyril

関連する問題