我正在尝试使用新数据更新我的 d3js 等高线图。我正在使用设置间隔方法来创建新的随机数据,并且希望生成新的轮廓/将当前轮廓动画到新的位置(如果有意义的话)。目前,代码为第一个数据创建等高线图,并且不会使用不同的数据更新等高线。理想情况下,我希望根据我提供的数据将轮廓从一种状态平滑过渡到另一种状态。
values = []
function solve() {
var svg = d3.select('svg'),
svgWidth = +svg.attr('width'),
n = 31, // data width
m = 31 // data height
var thresholds = d3.range(0, 1, 0.1);
var color = d3.scaleLinear()
.domain(d3.extent(thresholds))
.interpolate(function() {
return d3.interpolateCool;
});
svg.selectAll('path')
.data(d3.contours()
.size([n, m])
.thresholds(thresholds)(values) // this will create 6 step
)
.enter().append('path')
.attr('d', d3.geoPath(d3.geoIdentity().scale(svgWidth / n)))
.style('fill', function(d) {
return color(d.value);
})
.style('stroke', function(d) {
return color(d.value);
})
.style('stroke-width', 2.5)
.style('stroke-dasharray', '0, 1000');
// march the contours into existence
/* svg.selectAll('path')
.transition()
.duration(1000)
.style('stroke-dasharray', '1000, 0'); */
return
}
function updateData() {
for (var v = 0; v < 31 * 31; v++) {
values[v] = Math.floor(Math.random() * Math.floor(2))
}
return values
}
setInterval(function() {
updateData()
solve()
}, 10);
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-contour.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<svg width="310" height="310" stroke-linejoin="bevel" stroke-linecap="round">
</svg>
最佳答案
您缺少惯用的 D3“输入”、“更新”和“退出”选项。这是重构的代码,选择的名称是不言自明的:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" />
</head>
<body>
<svg width="310" height="310" stroke-linejoin="bevel" stroke-linecap="round">
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-contour.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script>
values = []
updateData()
solve();
function solve() {
var svg = d3.select('svg'),
svgWidth = +svg.attr('width'),
n = 31, // data width
m = 31 // data height
var thresholds = d3.range(0, 1, 0.1);
var color = d3.scaleLinear()
.domain(d3.extent(thresholds))
.interpolate(function() {
return d3.interpolateCool;
});
let paths = svg.selectAll('path')
.data(d3.contours()
.size([n, m])
.thresholds(thresholds)(values) // this will create 6 step
);
const pathsExit = paths.exit().remove();
const pathsEnter = paths.enter().append('path')
.attr('d', d3.geoPath(d3.geoIdentity().scale(svgWidth / n)))
.style('fill', function(d) {
return color(d.value);
})
.style('stroke', function(d) {
return color(d.value);
})
.style('stroke-width', 2.5)
.style('stroke-dasharray', '0, 1000');
paths = pathsEnter.merge(paths);
paths.transition()
.duration(1000)
.attr('d', d3.geoPath(d3.geoIdentity().scale(svgWidth / n)))
// march the contours into existence
/* svg.selectAll('path')
.transition()
.duration(1000)
.style('stroke-dasharray', '1000, 0'); */
return
}
function updateData() {
for (var v = 0; v < 31 * 31; v++) {
values[v] = Math.floor(Math.random() * Math.floor(2))
}
return values
}
setInterval(function() {
updateData()
solve()
}, 2000);
</script>
</body>
</html>
但是,请注意,这只会插入路径的 d 属性。这可能不是您想要的。
关于javascript - 如何使用setInterval更新D3轮廓?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62508825/