2015-11-22 3 views
1

я сделал this map используя datamaps по @markmarkohделают d3.js datamap вращать путем перетаскивания курсора

я люблю, как это получилось, но я хочу, чтобы я мог заставить его вращаться, когда вы перетащите его с помощью курсора, так что вы можете увидеть все континенты. как примеры here и here.

вот фрагмент моего кода:

//basic map config with custom fills, mercator projection 
 
       
 
       var series = [ 
 
     ["USA",36.2],["GBR",7.4],["CAN",6.2],["DEU",5.7],["FRA", 4.1],["ESP",4.1],["ITA",3.3],["MEX",3.0],["AUS",2.5],["NLD",2.4], 
 
     ["IND",2.1],["BRA",2.0],["GRC",1.4],["AUT",1.2],["ROU",1.2],["SRB",1.0],["COL",0.8],["POL",0.8],["ZAF",0.7],["SWE",0.7], 
 
     ["DNK",0.6],["VEN",0.6],["JPN",0.6],["KOR",0.6],["BEL",0.5],["RUS",0.5],["PRT",0.5] 
 
          ]; 
 
         
 
     var dataset = {}; 
 
      // We need to colorize every country based on "percent" 
 
      // colors should be uniq for every value. 
 
      // For this purpose we create palette(using min/max series-value) 
 
      var onlyValues = series.map(function(obj){ return obj[1]; }); 
 
      var minValue = Math.min.apply(null, onlyValues), 
 
        maxValue = Math.max.apply(null, onlyValues); 
 
      // create color palette function 
 
      // color can be whatever you wish 
 
      var paletteScale = d3.scale.linear() 
 
        .domain([minValue,maxValue]) 
 
        .range(["rgb(0,0,0)","rgb(219,219,219)"]); // color 
 
      // fill dataset in appropriate format 
 
      series.forEach(function(item){ // 
 
       // item example value ["USA", 36.2] 
 
       var iso = item[0], 
 
         value = item[1]; 
 
       dataset[iso] = { percent: value, fillColor: paletteScale(value) }; 
 
      }); 
 
       var map = new Datamap({ 
 
       scope: 'world', 
 
       element: document.getElementById('world'), 
 
       projection: 'orthographic', 
 
       projectionConfig: { 
 
        rotation: [90,-30] 
 
       }, 
 
       fills: {defaultFill: 'rgba(30,30,30,0.1)'}, 
 
       data: dataset, 
 
       geographyConfig: { 
 
        borderColor: 'rgba(222,222,222,0.2)', 
 
        highlightBorderWidth: 1, 
 
        // don't change color on mouse hover 
 
        highlightFillColor: function(geo) { 
 
         return geo['fillColor'] || 'rgba(30,30,30,0.5)'; 
 
        }, 
 
        // only change border 
 
        highlightBorderColor: 'rgba(222,222,222,0.5)', 
 
        // show desired information in tooltip 
 
        popupTemplate: function(geo, data) { 
 
         // don't show tooltip if country don't present in dataset 
 
         if (!data) { return ; } 
 
         // tooltip content 
 
         return ['', 
 
         \t '<div style="opacity:0.7;" class="hoverinfo">% of visitors in ' + geo.properties.name, 
 
           ': ' + data.percent, 
 
           ''].join('');   
 
           
 
        } 
 
       } 
 
      }); 
 
      
 
      
 
      //draw a legend for this map 
 
      map.legend(); 
 
      
 
       map.graticule();
<script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.min.js"></script> 
 
<script src="http://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js"></script> 
 
<script src="http://unilogue.github.io/js/map/datamaps.world.min.js"></script> 
 

 
<div id="world" style="fill-opacity:0.7; height: 600px; width: 500px; margin-top:-100px;"></div>

редактировать: по-видимому, сделали обратный вызов позволяет использовать событие, я создал этот масштаб/панорамирование функции в качестве теста, но как я могу использовать это для поворота моей карты с углами d3.behavior.drag и euler?

var map = new Datamap({ 
       done: function(datamap) { 
      datamap.svg.call(d3.behavior.zoom().on("zoom", redraw)); 
      function redraw() { 
       datamap.svg.selectAll("g").attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); 
      } 
     }, 

Редактировать 2: похоже, что это может сработать! взято из here.

Я попробовал copying в проделанный обратный вызов, но ничего не произошло, никаких идей?

var dragBehaviour = d3.behavior.drag() 
    .on('drag', function(){ 
     var dx = d3.event.dx; 
     var dy = d3.event.dy; 

     var rotation = projection.rotate(); 
     var radius = projection.scale(); 
     var scale = d3.scale.linear() 
      .domain([-1 * radius, radius]) 
      .range([-90, 90]); 
     var degX = scale(dx); 
     var degY = scale(dy); 
     rotation[0] += degX; 
     rotation[1] -= degY; 
     if (rotation[1] > 90) rotation[1] = 90; 
     if (rotation[1] < -90) rotation[1] = -90; 

     if (rotation[0] >= 180) rotation[0] -= 360; 
     projection.rotate(rotation); 
     redraw(); 
    }) 

ответ

1
var livemap; 
scope.rotation = [97, -30]; 

function redraw() { 
    d3.select("#map-wrapper").html(''); 
    init(); 
}// redraw 


function init() { 
    livemap = new Datamap({...}) 

    var drag = d3.behavior.drag().on('drag', function() { 
    var dx = d3.event.dx; 
    var dy = d3.event.dy; 

    var rotation = livemap.projection.rotate(); 
    var radius = livemap.projection.scale(); 
    var scale = d3.scale.linear().domain([-1 * radius, radius]).range([-90, 90]); 
    var degX = scale(dx); 
    var degY = scale(dy); 
    rotation[0] += degX; 
    rotation[1] -= degY; 
    if (rotation[1] > 90) rotation[1] = 90; 
    if (rotation[1] < -90) rotation[1] = -90; 

    if (rotation[0] >= 180) rotation[0] -= 360; 
    scope.rotation = rotation; 
    redraw(); 
    }) 

d3.select("#map-wrapper").select("svg").call(drag); 

}// init 
+0

спасибо за Ваш ответ! я ждал более года lol .. у меня есть некоторые проблемы с включением этого в мой код, хотя, не могли бы вы скопировать и вставить мой фрагмент в свой ответ и добавить свой код в javascript? – unilogue

+1

привет, вы можете использовать это - https://jsfiddle.net/z51pzm9z/1/ –

+0

ах спасибо большое! я собираюсь сделать запрос на получение кода на github, разработчик должен действительно включить эту функцию. – unilogue