score:1

You can get any point in the data array using the second argument, which is the index.

When you pass a datum to any D3 method, traditionally using a parameter named d (for datum), you are in fact using data[i], i being the current index. You can change this index to get data points before or after the current datum.

Thus, in any D3 method:

.attr("foo", function(d, i){
    console.log(d)//this is the current datum
    console.log(data[i])//this is the same current datum!
    console.log(data[i + 1])//this is the next (adjacent) datum
});

Here is a simple snippet showing this:

var data = ["foo", "bar", "baz", "foobar", "foobaz"];

var foo = d3.selectAll("foo")
  .data(data)
  .enter()
  .append("foo")
  .attr("foo", function(d, i) {
    if (data[i + 1]) {
      console.log("this datum is " + d + ", the next datum is " + data[i + 1]);
    }
  })
<script src="https://d3js.org/d3.v4.min.js"></script>

Have a look at the if statement: we have to check if there is a data[i + 1] because, of course, the last data point has no adjacent data after it.

Here is a demo using your data array:

var svg = d3.select("svg");

var scale = d3.scaleLinear()
  .domain([-1, 1])
  .range([0, 150]);

var data = [
  [0.1, 0.2],
  [0.3, 0.4],
  [0.5, 0.4],
  [0.7, 0.2]
];

var triangles = svg.selectAll("foo")
  .data(data)
  .enter()
  .append("polygon");

triangles.attr("stroke", "teal")
  .attr("stroke-width", 2)
  .attr("fill", "none")
  .attr("points", function(d, i) {
    if (data[i + 1]) {
      return scale(0) + "," + scale(0) + " " + scale(data[i][0]) + "," + scale(data[i][1]) + " " + scale(data[i + 1][0]) + "," + scale(data[i + 1][1]) + " " + scale(0) + "," + scale(0);
    }
  })
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="150" height="150"></svg>

PS: I'm not using your snippet because I'm drawing the triangles using polygons, but the principle is the same.


Related Query

More Query from same tag