我有一个D3条形图,我试图根据浏览器窗口大小调整其宽度。下面是图表脚本,其中宽度变量是根据SVG的父div宽度(#chart1)设置的,其宽度在css中设置:
var $chartWidth= $('#chart1').width();
var margin = {top:20, right:35, bottom:30, left:35};
var height = 180 - margin.top - margin.bottom;
var width = $chartWidth - margin.left - margin.right;
var parseDate = d3.time.format("%m/%Y").parse;
var yScaleBar = d3.scale.linear()
.domain([0,100])
.range([height, 0]);
var xBarScale = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var yAxisBar = d3.svg.axis()
.scale(yScaleBar)
.ticks(4)
.tickSize(-width, 0, 0)
.orient("left");
var xBarAxis = d3.svg.axis()
.scale(xBarScale)
.ticks(4)
.orient("bottom");
var canvasBars = d3.select("#chart1").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate("+margin.left+","+margin.top+")");
var data = [
{date:"01/2009",bar2:"50",bar:"10",q:"1Q 2009"},
{date:"04/2009",bar2:"56",bar:"32",q:"2Q"},
{date:"07/2009",bar2:"57",bar:"70",q:"3Q"},
{date:"10/2009",bar2:"58",bar:"60",q:"4Q"},
{date:"01/2010",bar2:"52",bar:"45",q:"1Q '10"}
];
data.forEach(function(d) {
d.date = parseDate(d.date);
d.bar2 = +d.bar2;
d.bar = +d.bar;
});
xBarScale.domain(d3.range(data.length));
xBarAxis.tickValues([data[0].q,data[1].q,data[2].q,data[3].q,data[4].q]);
canvasBars.append("g")
.attr("class", "xaxis")
.attr("transform", "translate(0," + height + ")")
.call(xBarAxis);
canvasBars.append("g")
.attr("class", "yaxis")
.call(yAxisBar);
canvasBars.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr({
"x": function(d) {return xBarScale(d.date);},
"y": function(d) {return yScaleBar(d.bar);},
"height": function(d) {return height -yScaleBar(d.bar);},
"width": xBarScale.rangeBand(),
"fill": "steelblue"
});
当窗口调整大小时,width变量会更改并调用resize();
$( window ).resize(function() {
$chartWidth = $('#chart1').width();
width = $chartWidth - margin.left - margin.right;
resize();
});
然后我的调整大小函数应该改变SVG的宽度属性,yAxisBar刻度线的宽度和xBarScale rangeRoundBands .....我认为我需要选择所有的条(rects)并改变它们的宽度属性根据新的xBarScale.rangeRoundBands。但我不确定如何正确选择这3件事。到目前为止,只是条形宽度随窗口一起调整 - 但不是刻度线或SVG。这是我尝试过的:
function resize(){
canvasBars.attr("width", width + margin.left + margin.right);
yAxisBar.tickSize(-width, 0, 0);
xBarScale.rangeRoundBands([0, width], .1);
canvasBars.selectAll("rect").attr("width", xBarScale.rangeBand());
}
答案 0 :(得分:1)
最直接的做法是在css中将元素的width
设置为100%。
答案 1 :(得分:1)
使用Bootstrap 3框架有一个更好的方法。我已经在网站上实现了这一点,所以我可以告诉你我是如何为我做的,也许你可以根据自己的特定需求进行调整。
HTML代码
<div class="container>
<div class="row">
<div class='col-sm-6 col-md-4' id="month-view" style="height:345px;">
<div id ="responsivetext">Something to write</div>
</div>
</div>
</div>
由于我的需要,我设置了一个固定的高度,但你也可以保留 auto 的大小。 &#34; col-sm-6 col-md-4&#34;让div响应。您可以在http://getbootstrap.com/css/#grid-example-basic
了解详情我们可以借助ID 月视图访问图表,下面的代码可以在d3.js中实现。
用d3做神奇:
var visualize = function(data){
// Initialize and select div, get the width and height that you want to use for the bar
var width = document.getElementById('month-view').offsetWidth;
var height = document.getElementById('month-view').offsetHeight - document.getElementById('responsivetext2').offsetHeight;
var total_map = data.map(function (i){ return parseInt(i.total);});
var heightScale = d3.scale.linear()
.domain([0, d3.max(total_map)])
.range([0, height-5]);
var x = d3.scale.ordinal()
.rangeRoundBands([0, width-30], .1);
var canvas = d3.select("#month-view").append("svg")
.attr("width", width - 13)
.attr("height", height + 20)
.append("g")
.attr("transform","translate(5,-20)");
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// Add first bar (total)
canvas.selectAll(".bar2")
.data(data)
.enter()
.append('rect')
.attr('width', width/12 - 5)
.attr('height', function (d){return heightScale(d.total)})
.attr('x', function (d, i) {return i * (width/12 -3 )})
.attr('y', function (d) {return height + 10 - heightScale(d.total)})
.attr('class', 'bar2')
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .95);
div.html(monthNames(d.month) + "<br/>" + d.total.toFixed(0)+" kr total<br/> <span class='green'>"+ ( (d.total * d.eco)/100 ).toFixed(0) + " kr eko</span>")
.style("left", (d3.event.pageX - 45) + "px")
.style("top", (d3.event.pageY - 55) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
// Add second bar (money)
canvas.selectAll(".bar")
.data(data)
.enter()
.append('rect')
.attr('width', width/12 - 5)
.attr('height', function (d){ return heightScale(( (d.total * d.eco)/100).toFixed(0))})
.attr('x', function (d, i) {return i * (width/12 -3 )})
.attr('y', function (d) {return height + 10 - heightScale(( (d.total * d.eco)/100).toFixed(0) )})
.attr('class', 'bar')
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .95);
div.html(monthNames(d.month) + "<br/>" + d.total.toFixed(0)+" kr total<br/> <span class='green'>"+ ( (d.total * d.eco)/100).toFixed(0) + " kr eko</span>")
.style("left", (d3.event.pageX - 45) + "px")
.style("top", (d3.event.pageY - 55) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
canvas.append("g")
.attr("transform", "translate(0,0)");
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
x.domain(data.map(function(d) { return monthNames(d.month).substring(0, 3); }));
}
由于您已经在使用d3,我不会花时间解释我在此代码中使用的所有内容,但它至少是一个有效的代码。你需要的是这个部分:
var width = document.getElementById('month-view').offsetWidth;
var height = document.getElementById('month-view').offsetHeight - document.getElementById('responsivetext2').offsetHeight;
通过获取ID为月视图的div的宽度来设置宽度。
我的情况下的高度不应该包括整个区域。我在条形图上方也有一些文字,所以我也需要计算这个区域。这就是为什么我使用id responsivetext 标识文本区域的原因。为了计算条形的允许高度,我从高度中减去 文本高度。
这使您可以使用一个将采用所有不同屏幕/ div大小的条。
答案 2 :(得分:0)
在D3中,有一种更简单的方法 您可以结合使用SVG元素上的viewBox和preserveAspectRatio属性来调整图表的大小。
const svg = d3
.select('div#chart-container')
.append('svg')
.style(
'padding',
marginRatio.top +
' ' +
marginRatio.right +
' ' +
marginRatio.bottom +
' ' +
marginRatio.left +
' '
)
.attr('preserveAspectRatio', 'xMinYMin meet')
.attr(
'viewBox',
'0 0 ' +
(width + margin.left + margin.right) +
' ' +
(height + margin.top + margin.bottom)
)
请参阅此处以供参考:https://eddyerburgh.me/create-responsive-bar-chart-d3-js