问题
Here's how's the D3.js look currently What I want to achieve is that, when I resize the windows four tables inside needs resize accordingly. No new tables are added.
Currently it just keep adding new tables inside. How to correct this behavior?
The content of 1.json
[
[[1,3,3,5,6,7],[3,5,8,3,2,6],[9,0,6,3,6,3],[3,4,4,5,6,8],[3,4,5,2,1,8]],
[[1,3,3,5,6,7],[3,5,8,3,2,6],[9,0,6,3,6,3],[3,4,4,5,6,8],[3,4,5,2,1,8]],
[[1,3,3,5,6,7],[3,5,8,3,2,6],[9,0,6,3,6,3],[3,4,4,5,6,8],[3,4,5,2,1,8]],
[[1,3,3,5,6,7],[3,5,8,3,2,6],[9,0,6,3,6,3],[3,4,4,5,6,8],[3,4,5,2,1,8]]
]
The content of D3.js:
<!DOCTYPE html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.8/d3.min.js" type="text/JavaScript"></script>
<!--script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.9/d3.js" type="text/JavaScript"></script-->
<style>
rect {
stroke: #9A8B7A;
stroke-width: 1px;
fill: #CF7D1C;
}
svg{
width: 50%;
height: 50%;
}
</style>
<body>
</body>
<script>
function draw(){
d3.json("array_data/1.json", function(data){
for (i=0; i<data.length; ++i) {
main(data[i]);
}
})
}
function main(dataset){
var local = d3.local();
var svg = d3.select("body").append("svg"),
bBox = svg.node().getBoundingClientRect(),
margin = {top: 20, right: 20, bottom: 30, left: 40},
width = bBox.width - margin.left - margin.right,
height = bBox.height - margin.top - margin.bottom;
var x = d3.scaleBand().rangeRound([0, width]);
var y = d3.scaleBand().rangeRound([0, height]);
y.domain(dataset.map(function(d,i) { return i; }));
var maxChildLength= d3.max(dataset, function(d) { return d.length; });
var xArr=Array.apply(null, {length: maxChildLength}).map(Function.call, Number);
x.domain(xArr);
var maxNum = d3.max(dataset, function(array) {
return d3.max(array);
});
var color=d3.scaleLinear().domain([0,maxNum]).range([0,1]);
svg.append("g")
.selectAll("g")
.data(dataset)//use top-level data to join g
.enter()
.append("g")
.selectAll("rect")
.data(function(d, i) {//for each <g>, use the second-level data (return d) to join rect
local.set(this, i);//this is the <g> parent
return d;
})
.enter()
.append("rect")
.attr("x", function(d, i, j) {
// return (i * 20) + 40;
return x(i);
})
.attr("y", function(d) {
// return (local.get(this) * 20) + 40;
return y(local.get(this));
})
//.attr("width",20)
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.attr("fill-opacity",function(d){console.log(color(+d));return color(+d);})
svg.append("g")
.selectAll("g")
.data(dataset)
.enter()
.append("g")
.selectAll("text")
.data(function(d, i) {
local.set(this, i)
return d;
})
.enter()
.append("text")
.text(function(d, i, j) {
return d;
})
.attr("x", function(d, i, j) {
// return (i * 20) + 40;
return x(i);
})
.attr("y", function(d) {
return y(local.get(this));
//return (local.get(this) * 20) + 40;
})
.attr("dx", x.bandwidth()/2)
.attr("dy", y.bandwidth()/2)
.attr("dominant-baseline", "central")//vertical - http://bl.ocks.org/eweitnauer/7325338
.attr("text-anchor", "middle")//horizontal - https://bl.ocks.org/emmasaunders/0016ee0a2cab25a643ee9bd4855d3464
.attr("font-family", "sans-serif")
.attr("font-size", "20px");
svg.append("g")
.append("text")
.attr("x", width/2)
.attr("y", height)
.attr("dominant-baseline", "text-before-edge")
.style("text-anchor", "middle")
//.attr("transform", "translate("+width/2+"," + height+ ")")
.text("Units sold");
}
draw();
window.addEventListener("resize", draw);
</script>
回答1:
Using your method, you'll need to clear out the HTML first, then redraw. So, at the beginning of your main() function:
var element = d3.select('body');
element.innerHTML = '';
svg = d3.select(element).append('svg');
There are other methods for resizing (viewport, having a resize function), but this fits your code as it exists now.
来源:https://stackoverflow.com/questions/46691580/resize-the-svgs-according-to-windows-size