gpt4 book ai didi

javascript - d3.js 中的动态重新缩放在网格线中有奇怪的伪影

转载 作者:行者123 更新时间:2023-11-30 15:15:03 26 4
gpt4 key购买 nike

我正在尝试在 D3 中创建一个比例尺可以使用 slider 调整的图。似乎有点失败;当我重新调整比例时,网格线有伪影。

知道我做错了什么吗?我有一个带有 onChange 方法的 slider 调用 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.exit()...

不同于:

selection.data();
selection.enter()...
selection.exit()...

我们经常看到 .data().enter() 被链接起来,因为所有元素都将被输入,而不会退出:

what if we have no existing elements, such as with an empty page? Then we’re joining data to an empty selection, and all data ends up in enter.

This pattern is so common, you’ll often see the selectAll + data + enter + append methods called sequentially, one immediately after the other. Despite it being common, keep in mind that this is just one special case of a data join. (Mike's three little circles).

您的代码适用于初始追加,因为无论如何所有数据最终都会出现在 enter() 选择中。在滴答数超过 10 之前不会出现问题,此时只要滴答数应该减少,退出选择显然无法按预期工作。它是空的,没有删除任何东西。使用此设置:

selection.data();
selection.enter()...
selection.exit()...

应该解决这个问题:

<!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")
.data( ysc.ticks() );

grid.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>

关于javascript - d3.js 中的动态重新缩放在网格线中有奇怪的伪影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44594612/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com