2013-07-13 3 views
42

У меня есть эта диаграмма D3 - в значительной степени из коробки. Есть ли способ сделать его отзывчивым и использовать проценты для переменных ширины и высоты, innerRadius и externalRadius? Я работаю на быстро реагирующем сайте и нуждаюсь в этом, чтобы измениться в зависимости от размера экрана/размера браузера.отзывчивый график D3

jsfiddle здесь: http://jsfiddle.net/BTfmH/1/

Код:

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<style type="text/css"> 
html, 
body { 
    margin:0; 
    padding:0; 
    width:100%; 
    height:100%; 
} 

.chart-container { 
/* width:50%; 
    height:50%;*/ 
} 
</style> 
<body> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<script> 
    var width = 350, 
     height = 350, 
     τ = 2 * Math.PI; 

    var arc = d3.svg.arc() 
     .innerRadius(100) 
     .outerRadius(135) 
     .startAngle(0); 

var svg = d3.select("body").append("svg") 
     .attr("width", width) 
     .attr("height", height) 
    .append("g") 
     .attr("transform", "translate(" + width/2 + "," + height/2 + ")") 

    var background = svg.append("path") 
     .datum({endAngle: τ}) 
     .style("fill", "green") 
     .attr("d", arc); 

    var foreground = svg.append("path") 
    .datum({endAngle: .127 * τ}) 
     .style("fill", "grey") 
     .attr("d", arc); 

setInterval(function() { 
    foreground.transition() 
     .duration(750) 
     .call(arcTween, Math.random() * τ); 
}, 1500); 

    function arcTween(transition, newAngle) { 

    transition.attrTween("d", function(d) { 

     var interpolate = d3.interpolate(d.endAngle, newAngle); 

     return function(t) { 

     d.endAngle = interpolate(t); 

     return arc(d); 
     }; 
    }); 
} 
</script> 
+0

Возможный дубликат [Что лучше всего подходит для отображения макета d3.js?] (Http://stackoverflow.com/questions/9400615/whats-the-best-way-to-make-a-d3 -js-visualization-layout-отзыв) – user456584

ответ

102

Вы можете сделать диаграмму изменения размера, используя комбинацию viewBox и preserveAspectRatio атрибутов элемента SVG.

Смотрите эту jsfiddle для полного примера: http://jsfiddle.net/BTfmH/12/

var svg = d3.select('.chart-container').append("svg") 
    .attr("width", '100%') 
    .attr("height", '100%') 
    .attr('viewBox','0 0 '+Math.min(width,height)+' '+Math.min(width,height)) 
    .attr('preserveAspectRatio','xMinYMin') 
    .append("g") 
    .attr("transform", "translate(" + Math.min(width,height)/2 + "," + Math.min(width,height)/2 + ")"); 

Вам не нужно даже resize обработчик с помощью этого метода.

+0

СПАСИБО за помощь! Я особенно ценю это, так как он остался без ответа/долгое время! – TechyDude

+1

@TechyDude, проблем нет. Мне это тоже нужно, и я увидел ваш вопрос. Я не мог найти хороший ответ в другом месте, поэтому расширил ваш пример. –

+0

@SamSehnert, Спасибо за ответ, я сделал что-то подобное здесь, в https://jsfiddle.net/adityap16/11edxrnq/1/. Но когда я переношу его в Реакт, мои сюжеты становятся действительно маленькими, Можете ли вы подумать о какой-либо причине? –

6

Вы можете использовать window.innerWidth и window.innerHeight, чтобы получить размеры экрана и настроить свой график соответствующим образом, например,

var width = window.innerWidth, 
    height = window.innerHeight, 
    innerRadius = Math.min(width,height)/3, 
    outerRadius = innerRadius + 30; 
+0

Спасибо за ваш ответ Ларс! Это определенно работает с точки зрения определения размеров диаграмм на основе оконной страницы. Как мне изменить размер окна браузера? – TechyDude

+0

Вы можете использовать событие onresize (см., Например, [этот вопрос] (http://stackoverflow.com/questions/641857/javascript-window-resize-event)), но вам придется перерисовывать себя. –