使用计时器更新 d3 生成的圆的位置



我是 d3 的新手,总的来说对 javascript 相当陌生,遇到了一个我无法用我目前的知识解释的错误......

我使用 2d 数组(成功(生成了 6 个圆圈,并创建了一个函数来调用计时器,以每次调用将 x 和 y 位置递增 1。目前,我的代码生成了 6 个圆圈,但计时器无限地创建了更多的"NaN"圆圈,而不是更新初始 6 个圆圈的位置。我的代码如下;

<body>
    <div id="svgDiv"></div>
    <script src="~/scripts/d3/d3.min.js"></script>
    <script src="~/scripts/App/test.js"></script>
</body>

和 JS;

var windowWidth = window.innerWidth;
var windowLength = window.innerHeight;
var pos =
    [[50, 40],
    [100, 80],
    [150, 120],
    [200, 160],
    [250, 200],
    [300, 240]];
var base = d3.select("#svgDiv").append("svg")
  .attr("width", windowWidth)
  .attr("height", windowLength);
function initSetup() {
    windowWidth = window.innerWidth;;
    windowLength = window.innerHeight;
    base.attr("width", windowWidth)
        .attr("height", windowLength);
    document.body.style.overflow = 'hidden';
}
window.onload = initSetup;
function windowResize() {
    windowWidth = window.innerWidth;;
    windowLength = window.innerHeight;
    base.attr("width", windowWidth)
       .attr("height", windowLength);
};
window.addEventListener("resize", windowResize);
function svgDivClick() {
    base.selectAll("circle")
        .data(pos) // .data(pos, function (d) { return d; })
        .enter()
        .append("circle")
        .attr("cx", function (d, i) {
            return pos[i][0];
        })
        .attr("cy", function (d, i) {
            return pos[i][1];
        })
        .attr("r", 0)
        .style("fill", "00ACCD")
        .transition()
        .attr("r", 20)
        .style("fill", "00ACCD")
        .duration(500);
    base.exit().transition()
        .attr("r", 0)
        .remove();
    console.log("click works");
    d3.timer(animate);
};
document.getElementById("svgDiv").addEventListener("click", svgDivClick);
function animate() {
    base.selectAll("circle")
        .data("circle", function (d) { return d; })
        .enter()
        .append("circle")
        .attr("cx", function (d, i) {
            return d.cx + 1;
        })
        .attr("cy", function (d, i) {
            return d.cy + 1;
    });
    base.exit().transition()
        .attr("r", 0)
        .remove();
};

最终目标是让圆圈随机浮动,但此时我只是试图控制位置。编辑:动画函数中出现错误。

任何见解都会很棒,提前感谢!

你在这里遇到了一些问题。最主要的是你每秒将相同的数据绑定到 DOM 元素 60 次,这是没有意义的。第二个是你不是增加仓位,而只是重置它们。第三个是数据中没有cxcy属性。最后一个是你没有声明你的圈子的选择。

我做了一个简单的演示来向您展示如何使用d3.timer。检查如何检索和更改位置。另外,请记住,在此示例中,我删除了所有过渡:混合过渡和计时器很复杂,而且通常是不必要的。

这是演示:

var windowWidth = 500;
var windowLength = 300;
var pos = [
  [50, 40],
  [100, 80],
  [150, 120],
  [200, 160],
  [250, 200],
  [300, 240]
];
var base = d3.select("body").append("svg")
  .attr("width", windowWidth)
  .attr("height", windowLength);
var circles = base.selectAll("charlesDarwin")
  .data(pos)
  .enter()
  .append("circle")
  .attr("cx", function(d, i) {
    return pos[i][0];
  })
  .attr("cy", function(d, i) {
    return pos[i][1];
  })
  .attr("r", 20)
  .style("fill", "00ACCD");
var timer = d3.timer(animate);
function animate() {
  circles.attr("cx", function() {
    if (+d3.select(this).attr("cx") > 500) {
      timer.stop()
    }
    return +d3.select(this).attr("cx") + 1
  });
};
<script src="https://d3js.org/d3.v4.min.js"></script>

最新更新