我已经使D3直方图具有响应性,但是我希望它在任何屏幕(div)调整大小时都具有100%响应性。我认为这个想法是计算父div的对角线,并使用它来相应地更改轴长。在这种情况下,上述想法可以计算出水平尺寸,但我无法识别垂直长度,从而弄乱了水平尺寸。
var color = "steelblue";
// Generate a 1000 data points using normal distribution with mean=20, deviation=5
var values = d3.range(1000).map(d3.random.normal(20, 5));
//var values = {{data}}
// A formatter for counts.
var formatCount = d3.format(",.0f");
var margin = {
top: 30,
right: 5,
bottom: 20,
left: 5
},
width = parseInt(d3.select("#histog").style("width")) - margin.left - margin.right
height = 275 - margin.top - margin.bottom;
var max = d3.max(values);
var min = d3.min(values);
var x = d3.scale.linear()
.domain([min, max])
.range([0, width]);
// Generate a histogram using twenty uniformly-spaced bins.
var data = d3.layout.histogram()
.bins(x.ticks(20))
(values);
var yMax = d3.max(data, function(d) {
return d.length
});
var yMin = d3.min(data, function(d) {
return d.length
});
var colorScale = d3.scale.linear()
.domain([yMin, yMax])
.range([d3.rgb(color).brighter(), d3.rgb(color).darker()]);
var y = d3.scale.linear()
.domain([0, yMax])
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bOkottom");
var svg = d3.select("#histog").append("svg")
.attr("width", "100%")
.attr("height", "26vh")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var bar = svg.selectAll(".bar")
.data(data)
.enter().append("g")
.attr("class", "bar")
.attr("transform", function(d) {
return "translate(" + x(d.x) + "," + y(d.y) + ")";
});
bar.append("rect")
.attr("x", 1)
.attr("width", (x(data[0].dx) - x(0)) - 1)
.attr("height", function(d) {
return height - y(d.y);
})
.attr("fill", function(d) {
return colorScale(d.y)
});
bar.append("text")
.attr("dy", ".75em")
.attr("y", -12)
.attr("x", (x(data[0].dx) - x(0)) / 2)
.attr("text-anchor", "middle")
.text(function(d) {
return formatCount(d.y);
});
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
/*
* Adding refresh method to reload new data
*/
function refresh(values) {
// var values = d3.range(1000).map(d3.random.normal(20, 5));
var data = d3.layout.histogram()
.bins(x.ticks(20))
(values);
// Reset y domain using new data
var yMax = d3.max(data, function(d) {
return d.length
});
var yMin = d3.min(data, function(d) {
return d.length
});
y.domain([0, yMax]);
var colorScale = d3.scale.linear()
.domain([yMin, yMax])
.range([d3.rgb(color).brighter(), d3.rgb(color).darker()]);
var bar = svg.selectAll(".bar").data(data);
// Remove object with data
bar.exit().remove();
bar.transition()
.duration(1000)
.attr("transform", function(d) {
return "translate(" + x(d.x) + "," + y(d.y) + ")";
});
bar.select("rect")
.transition()
.duration(1000)
.attr("height", function(d) {
return height - y(d.y);
})
.attr("fill", function(d) {
return colorScale(d.y)
});
bar.select("text")
.transition()
.duration(1000)
.text(function(d) {
return formatCount(d.y);
});
}
.histocontainer {
float: right;
width: 55%;
margin-right: auto;
margin-left: auto;
text-align: top;
}
@media (min-width: 576px) {
.histocontainer {
max-width: 540px;
}
}
@media (min-width: 768px) {
.histocontainer {
max-width: 720px;
}
}
@media (min-width: 992px) {
.histocontainer {
max-width: 960px;
}
}
@media (min-width: 1200px) {
.histocontainer {
max-width: 1140px;
}
}
#scalesvg {
width: 20%;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<svg id="scalesvg">
<div id=histog></div>
</svg>
答案 0 :(得分:1)
我将示例简化了一点,并使用了refresh
函数的结构来创建resize
函数。我使用window.addEventListener("resize")
检测大小并触发函数。
在不知道宽度和高度的情况下可以完成的所有工作,我在函数外部执行,而在内部仅重绘垃圾箱和轴。
这是您所有的代码,我只是将其移动了一点。
var color = "steelblue";
// Generate a 1000 data points using normal distribution with mean=20, deviation=5
var values = d3.range(1000).map(d3.random.normal(20, 5));
// A formatter for counts.
var formatCount = d3.format(",.0f");
var margin = {
top: 30,
right: 5,
bottom: 20,
left: 5
};
var max = d3.max(values);
var min = d3.min(values);
var x = d3.scale.linear()
.domain([min, max]);
var data = d3.layout.histogram()
.bins(x.ticks(20))
(values);
var yMax = d3.max(data, function(d) {
return d.length
});
var yMin = d3.min(data, function(d) {
return d.length
});
var colorScale = d3.scale.linear()
.domain([yMin, yMax])
.range([d3.rgb(color).brighter(), d3.rgb(color).darker()]);
var y = d3.scale.linear()
.domain([0, yMax]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var svg = d3.select("svg")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis");
function resize() {
var rect = d3.select('svg').node().getBoundingClientRect();
var width = rect.width - margin.left - margin.right;
var height = Math.min(rect.height, window.innerHeight) - margin.top - margin.bottom;
x.range([0, width]);
y.range([height, 0]);
// Reposition elements
svg.select('x.axis')
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var bar = svg.selectAll(".bar").data(data);
// Remove object with data
bar.exit().remove();
var newBars = bar.enter()
.append("g")
.attr("class", "bar");
newBars.append("rect")
.attr("x", 1);
newBars.append("text")
.attr("dy", ".75em")
.attr("y", -12)
.attr("text-anchor", "middle")
bar.transition()
.duration(1000)
.attr("transform", function(d) {
return "translate(" + x(d.x) + "," + y(d.y) + ")";
});
bar.select("rect")
.transition()
.duration(1000)
.attr("width", (x(data[0].dx) - x(0)) - 1)
.attr("height", function(d) {
return height - y(d.y);
})
.attr("fill", function(d) {
return colorScale(d.y);
});
bar.select("text")
.transition()
.duration(1000)
.attr("x", (x(data[0].dx) - x(0)) / 2)
.text(function(d) {
return formatCount(d.y);
});
}
window.addEventListener("resize", function() {
console.log('resize!');
resize();
});
resize();
svg {
float: left;
width: 100%;
height: 300px;
margin-right: auto;
margin-left: auto;
text-align: top;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<svg></svg>