我試圖在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)...'? –