javascript - 沿着具有离散点和延迟的线图进行迭代/链式转换

标签 javascript select d3.js transition

我创建了一个jsfiddle here .

我确实有一个图表 - 在本例中是一个正弦波 - 并且想要沿着这条线移动一个圆(由单击事件触发),停在该图表上的某些 x 和 y 值对处,然后继续前进到图表的最后一点,从那里再次跳到第一个点(理想情况下,这应该继续下去,直到我按下停止按钮)。

我当前的问题是圆仅水平移动,而不是沿纵坐标方向移动,并且延迟仅可见一次(在最开始时)。

相关代码是这个(整个运行示例可以在上面的链接中找到):

创建圆圈:

// the circle I want to move along the graph
  var circle = svg.append("circle")
                .attr("id", "concindi")
                .attr("cx", x_scale(xval[0]))
                .attr("cy", y_scale(yval[0]))
                .attr("transform", "translate(" + (0) + "," + (-1 * padding + 15) + ")")
                .attr("r", 6)
                .style("fill", 'red');

搬家过程:

var coordinates = d3.zip(xval, yval);

svg.select("#concindi").on("click", function() {

    coordinates.forEach(function(ci, indi){
      //console.log(ci[1] + ": " + indi);
      //console.log(coordinates[indi+1][1] + ": " + indi);
      if (indi < (coordinates.length - 1)){
        //console.log(coordinates[indi+1][1] + ": " + indi);
        console.log(coordinates[indi + 1][0]);
        console.log(coordinates[indi + 1][1]);
        d3.select("#concindi")
          .transition()
          .delay(2000)
          .duration(5000)
          .ease("linear")
          .attr("cx", x_scale(coordinates[indi + 1][0]))
          .attr("cy", y_scale(coordinates[indi + 1][1]));
      }

    });

我很确定我以错误的方式使用了循环。这个想法是从第一个 x/y 对开始,然后移动到下一个(需要 5 秒),在那里等待 2 秒,然后移动到下一个,依此类推。目前,延迟仅在最初可见,然后它只是水平移动。

如何正确完成此操作?

最佳答案

为什么不使用 Bostock 的 translateAlong功能?

function translateAlong(path) {
    var l = path.getTotalLength();
    return function(d, i, a) {
        return function(t) {
            var p = path.getPointAtLength(t * l);
            return "translate(" + p.x + "," + p.y + ")";
        };
    };
}

这是演示:

// function to generate some data
function get_sin_val(value) {
  return 30 * Math.sin(value * 0.25) + 35;
}

var width = 400;
var height = 200;
var padding = 50;

var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var xrange_min = 0;
var xrange_max = 50;

var yrange_min = 0;
var yrange_max = 100;

var x_scale = d3.scale.linear()
  .domain([xrange_min, xrange_max])
  .range([padding, width - padding * 2]);

var y_scale = d3.scale.linear()
  .domain([yrange_min, yrange_max])
  .range([height - padding, padding]);

// create the data
var xval = d3.range(xrange_min, xrange_max, 1);
var yval = xval.map(get_sin_val);

// just for convenience
var coordinates = d3.zip(xval, yval);

//defining line graph
var lines = d3.svg.line()
  .x(function(d) {
    return x_scale(d[0]);
  })
  .y(function(d) {
    return y_scale(d[1]);
  })
  .interpolate("linear");

//draw graph
var sin_graph = svg.append("path")
  .attr("d", lines(coordinates))
  .attr("stroke", "blue")
  .attr("stroke-width", 2)
  .attr("fill", "none");

// the circle I want to move along the graph
var circle = svg.append("circle")
  .attr("id", "concindi")
  .attr("transform", "translate(" + (x_scale(xval[0])) + "," + (y_scale(yval[0])) + ")")
  .attr("r", 6)
  .style("fill", 'red');

svg.select("#concindi").on("click", function() {
  d3.select(this).transition()
    .duration(5000)
    .attrTween("transform", translateAlong(sin_graph.node()));

});

// Returns an attrTween for translating along the specified path element.
function translateAlong(path) {
  var l = path.getTotalLength();
  return function(d, i, a) {
    return function(t) {
      var p = path.getPointAtLength(t * l);
      return "translate(" + p.x + "," + p.y + ")";
    };
  };
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

您必须了解 forEach 几乎会立即循环到数组末尾。因此,您现在无法通过您的方法使圆从一个坐标跳到另一个坐标(因此,不幸的是,您在这里是正确的:“我很确定我以错误的方式使用了循环”).

如果您想在一个点和另一个点之间添加 2 秒的等待时间,最好的想法是链接转换。像这样的东西(我正在减少演示中的延迟和持续时间,以便我们可以更好地看到效果):

var counter = 0;
transit();
function transit() {
    counter++;
    d3.select(that).transition()
        .delay(500)
        .duration(500)
        .attr("transform", "translate(" + (x_scale(coordinates[counter][0])) 
            + "," + (y_scale(coordinates[counter][1])) + ")")
        .each("end", transit);
}

这是演示:

// function to generate some data
function get_sin_val(value) {
  return 30 * Math.sin(value * 0.25) + 35;
}

var width = 400;
var height = 200;
var padding = 50;

var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var xrange_min = 0;
var xrange_max = 50;

var yrange_min = 0;
var yrange_max = 100;

var x_scale = d3.scale.linear()
  .domain([xrange_min, xrange_max])
  .range([padding, width - padding * 2]);

var y_scale = d3.scale.linear()
  .domain([yrange_min, yrange_max])
  .range([height - padding, padding]);

// create the data
var xval = d3.range(xrange_min, xrange_max, 1);
var yval = xval.map(get_sin_val);

// just for convenience
var coordinates = d3.zip(xval, yval);

//defining line graph
var lines = d3.svg.line()
  .x(function(d) {
    return x_scale(d[0]);
  })
  .y(function(d) {
    return y_scale(d[1]);
  })
  .interpolate("linear");

//draw graph
var sin_graph = svg.append("path")
  .attr("d", lines(coordinates))
  .attr("stroke", "blue")
  .attr("stroke-width", 2)
  .attr("fill", "none");

// the circle I want to move along the graph
var circle = svg.append("circle")
  .attr("id", "concindi")
  .attr("transform", "translate(" + (x_scale(xval[0])) + "," + (y_scale(yval[0])) + ")")
  .attr("r", 6)
  .style("fill", 'red');

svg.select("#concindi").on("click", function() {
  var counter = 0;
  var that = this;
transit();
  function transit() {
    counter++;
    d3.select(that).transition()
      .delay(500)
      .duration(500)
      .attr("transform", "translate(" + (x_scale(coordinates[counter][0])) + "," + (y_scale(coordinates[counter][1])) + ")")
      .each("end", transit);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

关于javascript - 沿着具有离散点和延迟的线图进行迭代/链式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43964322/

相关文章:

javascript - 使用带有 or 语句的正则表达式分割字符串

sql - 在 SQL Server 中将月份名称转换为月份编号

javascript - d3.js 插值不起作用

javascript - 将 JSON-LD 转换为 d3.js Node/链接格式?

ruby-on-rails - 如何正确安装 dc.js 以便与 Rails 5 一起使用?

javascript - 如何将 DOM 元素中的任何内容传递给 $scope 中定义的函数

javascript - 如何在nodejs中下载文件(http和https)并实时查看/显示下载进度?

javascript - 未找到 Google 扩展 native 消息传递主机

xslt - XSl——需要转型帮助

mysql - 是否可以包含连接表中除连接表之外的所有字段?