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

标签 javascript asp.net-mvc d3.js

我是 d3 的新手,一般来说是 javascript 的新手,遇到了一个我无法用我目前的知识解释的错误......

我使用二维数组生成了 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();
};

最终目标是让圆圈随机 float ,但此时我只是想控制位置。编辑:错误发生在动画功能中。

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

最佳答案

你这里有一些问题。最主要的是您每秒将相同的数据绑定(bind)到 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>

关于javascript - 使用计时器更新 d3 生成的圆圈的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44229996/

相关文章:

JavaScript 字符串初始化

javascript - 切换时自动选择输入字段

javascript - 从对象函数获取 CodeMirror 值

css - 如何在 Twitter Bootstrap 中使用从数据库动态加载的参数

ios - 如何在 iOS Safari 上禁用前后缓存?

javascript - 将回调函数传递给 d3.xml?

asp.net-mvc - 两个内联文本框使用 bootstrap 与其他控件正确对齐

javascript - d3js v5 + Topojson v3 map 不呈现

javascript - scaleQuantile 函数没有输出我所期望的

arrays - d3 数组中缺少第一个值