2014-01-02 4 views
3

Я пытаюсь сделать мою карту отзывчивой, поэтому она будет изменена в соответствии с размером окна браузера. Это то, что я до сих пор,Как создать отзывчивую карту с помощью d3

style.css

#mapbox { 
border:2px solid #000; 
width:960px; 
height:550px; 
background:#FFFFFF; 
} 

viz.js

var margin = {top: 10, left: 10, bottom: 10, right: 10}, 
width = parseInt(d3.select('#mapbox').style('width')), 
width = width - margin.left - margin.right, 
mapRatio = .5, 
height = width * mapRatio; 
. 
. 
d3.select(window).on('resize', resize); 
. 
. 
function resize(){ 
    width = parseInt(d3.select('#mapbox').style('width')); 
    width = width - margin.left - margin.right; 
    height = width * mapRatio; 


     projection.translate([width/2, height/2]) 
       .scale(width); 

     svg.style('width', width + 'px') 
      .style('height', height + 'px'); 

} 

При изменении размера окна, его все еще сохраняя ту же ширину и высоту для моего контейнера SVG , Я думаю, это потому, что в функции изменения размера я получаю ширину и высоту от CSS, который будет таким же, независимо от того, изменяю ли я размер окна прямо?

Я застрял здесь, я пропустил что-нибудь очевидное? было бы здорово, если бы у вас были какие-то указатели для меня, чтобы это работало.

Я довольно много следующий следующая example,

+0

Вы видели [этот вопрос] (http://stackoverflow.com/questions/9400615/whats-the-best-way-to-make-a-d3-js-vi sualisation-макет реагирующий)? –

ответ

3

Я установил так, как SVG, чтобы иметь адаптивное изменение размера:

var svg = d3.select("body") 
     .append("div") 
     .attr("id", "svg") 
     .append("svg") 
     .attr("viewBox", "0 0 " + width + " " + height) 
     .attr("preserveAspectRatio", "xMinYMin"); 

А затем установить CSS так:

#svg { 
    width:100%; 
    height: auto; 
} 
0

В вашем вопросе недостаточно подробностей, чтобы точно сказать, что вы делаете. Есть несколько распространенных вещей, которые могут нарушить изменение размера кода, подобного этому ...

Возможно, ваш карточный номер не меняется. Вы можете использовать console.log (...) с шириной/высотой для каждого изменения размера звонка, и это точно скажет вам, что там происходит.

Кроме того, в зависимости от того, как вы первоначально указываете размер SVG (например, используя атрибуты width/height vs с использованием настроек высоты/ширины CSS), вы можете создать конфликт, в котором спецификация размера атрибута имеет приоритет над css ,

Если ваши значения ширины/высоты неправильно обрабатываются и впоследствии неправильно установлены, они просто игнорируют эти настройки CSS, и размер никогда не изменится.

Наконец, если вы прочитаете SO, с которым связан Lars, вы увидите, что более простой способ масштабирования svg - использовать метод viewbox/preserveaspectration. Вот скрипка я сделал, когда я получал эту работу для моего материала: http://jsfiddle.net/reblace/Ku2UQ/2/

var svg = container.selectAll("svg").data([data]); 
var svgEnter = svg.enter().append("svg"); 

// Append a clip path that will hide any data points outside of the xExtent and yExtent 
svgEnter 
    .attr("viewBox", "0 0 600 200") // This is the "ideal" size of the chart 
    .attr("preserveAspectRatio", "xMinYMin"); 

... 

var resize = function(w, h){ 
    svg.transition().duration(500) 
     .attr("width", w) 
     .attr("height", w/(width/height));   
}; 

function doResize() { 
    var overflow = $("body").css("overflow"); 
    $("body").css("overflow", "hidden"); 

    var width = $("#center").innerWidth(); 
    var height = $(window).innerHeight() - 10; 

    $("body").css("overflow", overflow); 
    resize(width, height); 
}; 

var resizeTimer; 
$(window).resize(function() { 
    clearTimeout(resizeTimer); 
    resizeTimer = setTimeout(doResize, 250); 
}); 

doResize(); 

Этого код делает несколько вещей стоит посмотреть, в том числе фильтрации события изменения размера, так что он не требует коды изменения размера для каждого изменение размера пикселя в окне. Вместо этого он в основном буферизирует событие, пока вы не остановите изменение размера окна на 250 мс.

Затем он скрывает полосы прокрутки на странице, чтобы получить точный размер окна, если вы пытаетесь масштабировать предмет, чтобы он поместился на странице без полос прокрутки.

Наконец, он масштабирует элемент SVG, который обрабатывает размер и устанавливает его в правильный размер, учитывая размер родительского контейнера (масштабирование высоты в зависимости от исходного соотношения ширины и высоты.

0

Спасибо за указателями,

Это то, что работает для меня, не уверен в том, что это лучшая практика или нет, хотя ..

HTML

 <section id = "mapContainer"> 
     <svg id = "map" width="960" height="550" 
      viewBox="0 0 960 550" preserveAspectRatio="xMidYMid"> 
     </svg> 
    </section> 

Javascript

var svgContainer = $("#map"); 
    var width = svgContainer.width(); 
    var height = svgContainer.height(); 
    var aspect = width/height; 
    var container = svgContainer.parent(); 

    var svg = d3.select("svg"); 

    //responsive map 
function resize(){ 
    // adjust things when the window size changes 
    var targetWidth = container.width(); 

    svg.attr("width", targetWidth); 
    svg.attr("height", Math.round(targetWidth/aspect)); 

    console.log ("width : " + targetWidth); 
    console.log ("height : " + Math.round(targetWidth/aspect)); 

    // update projection 
    projection.translate([width/2, height/2]) 
       .scale(width); 

    // resize the map 
     svg.select('.lga').attr('d', path); 
} 
Смежные вопросы