我试图在D3中创建一个可以使用滑块调整比例的绘图。看起来它略有失败;当我重新调整比例时,网格线会产生伪影。d3.js中的动态缩放在网格线中有奇怪的痕迹
任何想法我做错了什么?我使用onChange
方法调用ysc.domain([0,this.value]);
来重新调整y轴的滑块,并重新绘制包括坐标轴和网格线的图形。
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.8.0/d3.min.js"></script>
<script type='text/javascript'>
document.addEventListener("DOMContentLoaded", function(event) {
var margin = {top: 10, right: 20, bottom: 20, left: 30},
width = 600,
height = 180;
// add the graph canvas to the body of the webpage
var svg = d3.select("div#plot1").append("svg")
.attr("width", width)
.attr("height", height);
var axis = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xsc= d3.scaleLinear().domain([0,1]).range([0, width-margin.left-margin.right]),
ysc= d3.scaleLinear().domain([0,1]).range([height-margin.top-margin.bottom,0]);
var N = 500;
axis.append("path");
var line = d3.line()
.x(function(d,i) { return xsc(i/N); })
.y(function(d,i) { return ysc(d); });
var axis_drawn = d3.axisLeft( ysc);
axis.call(axis_drawn);
function drawGridLines()
{
var grid=axis.selectAll("line.horizontalGrid");
grid.data(ysc.ticks()).enter()
.append("line")
.attr('class','horizontalGrid')
.attr('x1',margin .right)
.attr('x2',width)
.attr('fill','none')
.attr("shape-rendering" , "crispEdges")
.attr("stroke" , "black")
.attr("stroke-width" , "1px")
.attr('opacity','0.2')
.merge(grid)
.attr('y1', ysc)
.attr('y2', ysc);
grid.exit().remove();
}
function drawGraph()
{
var data = [];
var ylim = ysc.domain();
for (var i = 0; i < N; ++i)
{
data.push((Math.cos(i*8*Math.PI/N) + 1)/2.0);
}
var waveform = axis.selectAll("path");
waveform.datum(data)
.attr("fill","none")
.attr("stroke","steelblue")
.attr("d", line);
axis.call(axis_drawn);
drawGridLines();
}
drawGraph();
function showRange(x) {
d3.select('#rangeLabel').text(x);
}
showRange(1);
d3.select('#range')
.on('change', function(d) {
ysc.domain([0,this.value]);
drawGraph();
showRange(this.value);
});
}); // DOMContentLoaded event
</script>
<style type='text/css'>
svg {
display: block;
margin-left: auto;
margin-right: auto;
}
.grid line {
stroke: lightgrey;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}
.hidden {
display: none;
}
div#interactive-container {
vertical-align: top;
display: inline-block;
position: relative;
left: 0;
}
form#interactive-controls {
border: 1px solid black;
display: inline-block;
}
div#plot2 {
display: inline-block;
position: relative;
left: 0;
}
</style>
</head><body>
<div id="plot1">
</div>
<div id='bottom-panel'>
<div id='interactive-container' class='hidden'>
<form id='interactive-controls'>
<input type="range" id='range' value='1', min='1', max='10', step='1'><span id='rangeLabel'></span>
</form>
</div>
</div>
</body>
</html>
的感谢!你能详细说明为什么'selection.data().enter()...'与'selection.data()不同。 selection.enter()...'?我读过三个小圈子,这对我没有意义。所以'selection.data()'不会返回选择本身? –
哦,没关系,我现在明白了:https://github.com/d3/d3-selection/blob/master/README.md#selection_data --selection.data([data [,key]]) - 将指定的数据数组与选定的元素进行连接,返回表示更新选择的新选择:成功绑定到数据的元素。 –
什么时候把东西放入'selection.data()....'vs'selection.merge(selection)...'? –