2016-09-05 10 views
0

フローティング: http://plnkr.co/edit/MeAA55fbY5dMZETCXpFo?p=previewD3スムーズな国、私はD3を使用して実装され、世界中持つ

var width = 600, 
    height = 500, 
    sens = 0.25, 
    focused; 

//Setting projection 

var projection = d3.geo.orthographic() 
    .scale(245) 
    .rotate([0, 0]) 
    .translate([width/2, height/2]) 
    .clipAngle(90); 

var path = d3.geo.path() 
    .projection(projection); 

//SVG container 

var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

//Adding water 

svg.append("path") 
    .datum({ 
    type: "Sphere" 
    }) 
    .attr("class", "water") 
    .attr("d", path) 
    .call(d3.behavior.drag() 
    .origin(function() { 
     var r = projection.rotate(); 
     return { 
     x: r[0]/sens, 
     y: -r[1]/sens 
     }; 
    }) 
    .on("drag", function() { 
     var rotate = projection.rotate(); 
     projection.rotate([d3.event.x * sens, -d3.event.y * sens, rotate[2]]); 
     svg.selectAll("path.land").attr("d", path); 
     svg.selectAll(".focused").classed("focused", focused = false); 
    })); 

var countryTooltip = d3.select("body").append("div").attr("class", "countryTooltip"), 
    countryList = d3.select("body").append("select").attr("name", "countries"); 


queue() 
    .defer(d3.json, "world.json") 
    .defer(d3.tsv, "names.tsv") 
    .await(ready); 

//Main function 

function ready(error, world, countryData) { 

    var countryById = {}, 
    countries = topojson.feature(world, world.objects.countries).features; 

    //Adding countries to select 

    countryData.forEach(function(d) { 
    countryById[d.id] = d.name; 
    option = countryList.append("option"); 
    option.text(d.name); 
    option.property("value", d.id); 
    }); 

    //Drawing countries on the globe 

    var world = svg.selectAll("path.land") 
    .data(countries) 
    .enter().append("path") 
    .attr("class", "land") 
    .attr("d", path) 

    //Drag event 

    .call(d3.behavior.drag() 
    .origin(function() { 
     var r = projection.rotate(); 
     return { 
     x: r[0]/sens, 
     y: -r[1]/sens 
     }; 
    }) 
    .on("drag", function() { 
     var rotate = projection.rotate(); 
     projection.rotate([d3.event.x * sens, -d3.event.y * sens, rotate[2]]); 
     svg.selectAll("path.land").attr("d", path); 
     svg.selectAll(".focused").classed("focused", focused = false); 
    })) 

    //Mouse events 

    .on("mouseover", function(d) { 
     countryTooltip.text(countryById[d.id]) 
     .style("left", (d3.event.pageX + 7) + "px") 
     .style("top", (d3.event.pageY - 15) + "px") 
     .style("display", "block") 
     .style("opacity", 1); 
    }) 
    .on("mouseout", function(d) { 
     countryTooltip.style("opacity", 0) 
     .style("display", "none"); 
    }) 
    .on("mousemove", function(d) { 
     countryTooltip.style("left", (d3.event.pageX + 7) + "px") 
     .style("top", (d3.event.pageY - 15) + "px"); 
    }); 

    //Country focus on option select 

    d3.select("select").on("change", function() { 
    var rotate = projection.rotate(), 
     focusedCountry = country(countries, this), 
     p = d3.geo.centroid(focusedCountry); 

    svg.selectAll(".focused").classed("focused", focused = false); 

    //Globe rotating 

    (function transition() { 
     d3.transition() 
     .duration(2500) 
     .tween("rotate", function() { 
      var r = d3.interpolate(projection.rotate(), [-p[0], -p[1]]); 
      return function(t) { 
      projection.rotate(r(t)); 
      svg.selectAll("path").attr("d", path) 
       .classed("focused", function(d, i) { 
       return d.id == focusedCountry.id ? focused = d : false; 
       }); 
      }; 
     }) 
    })(); 
    }); 

    function country(cnt, sel) { 
    for (var i = 0, l = cnt.length; i < l; i++) { 
     if (cnt[i].id == sel.value) { 
     return cnt[i]; 
     } 
    } 
    }; 

}; 

を私は次の効果を追加したい:国がクリックされた場合、国の陸地は、残りの上に浮くはずです。ここでは: http://bl.ocks.org/mbostock/6738360

私は複雑なロジック、単純なアニメーションを必要としません。スケールが増え、影が現れるとき。

いくつかのアドバイスがあれば、数日を費やしてください。

答えて

1

2番目のリンクの例によれば、水と土地を異なる投影尺度(土地投影が大きい)でプロットする必要があります。

土地を残りの部分の上に浮かせたい場合は、土地を前面に持っていく必要があります(d3はZ-インデックスをサポートしておらず、要素は描かれている順序に従って階層化されています)。

まず最初に、あなたはこれがあなたに先頭に要素を移動できるようになります(クレジットはhereに行く)

// Credit goes to http://bl.ocks.org/eesur/4e0a69d57d3bfc8a82c2 
d3.se lection.prototype.moveToFront = function() { 
    return this.each(function(){ 
    this.parentNode.appendChild(this); 
    }); 
}; 

あなたのコードに以下の機能を追加する必要があります。

第二部では、国を描くクリックイベントを追加することです:助けを

clicked = null 
var world = svg.selectAll("path.land") 
    .data(countries) 
    .enter().append("path") 
    .attr("class", "land") 
    .attr("d", path).on('click', function(){ 

      // Move the clicked land to the top 
      d3.select(this).moveToFront() 

      // Rescale the projection 
      projection.scale(265) 

     // Redraw the land with the new projection 
     d3.select(this) 
      .transition() 
      .duration(500) 
      .attr('d',path) 

     // Changed back to original scale 
     projection.scale(245) 

     // Bring previous selected land to the original scale 
     if (clicked != null) 
     clicked.transition() 
       .duration(500) 
       .attr('d',path) 

    // Store clicked scale 
    clicked = d3.select(this)  
    }) 
}; 
+0

ありがとう! –

関連する問題