allanberry
allanberry

Reputation: 7765

d3: follow mouse coordinates?

I'm trying to make an element follow the mouse (in this case a set of three lines). The d3.mouse(this) call is working fine, but the draw_lines function is not updated with each subsequent call; the lines are only drawn once.

What am I doing wrong?

var w = 100, h = 100

var svg = d3.select('body').append("svg")
    .attr("width", w)
    .attr("height", h)
    .on('mousemove', function() {
        var coordinates = d3.mouse(this)
        draw_lines(coordinates)
    })

function draw_lines(coordinates) {
    var x = coordinates[0]
    var y = coordinates[1]

    var data = [
        [x, y, x+20, y-40],
        [x+10, y, x+30, y-40],
        [x+20, y, x+40, y-40]
    ]

    var lines = svg.selectAll("line")
        .data(data)
        .enter().append("line")
        .attr({
            "x1": function(d) {return d[0]},
            "y1": function(d) {return d[1]},
            "x2": function(d) {return d[2]},
            "y2": function(d) {return d[3]},
        })
}

Upvotes: 0

Views: 1708

Answers (1)

Gilsha
Gilsha

Reputation: 14591

During the initial call for draw_lines function, you creates 3 lines. Either you should update the line attributes in the subsequent calls OR just delete the old lines and create new lines with latest attributes.

Here is the demo.

var w = 100,
  h = 100

var svg = d3.select('body').append("svg")
  .attr("width", w)
  .attr("height", h)
  .on('mousemove', function() {
    var coordinates = d3.mouse(this)
    draw_lines(coordinates)
  })

function draw_lines(coordinates) {
  var x = coordinates[0]
  var y = coordinates[1]

  var data = [
    [x, y, x + 20, y - 40],
    [x + 10, y, x + 30, y - 40],
    [x + 20, y, x + 40, y - 40]
  ]
  //Selects all existing lines(Initially this will return empty array)
  var lines = svg.selectAll("line");
  
  //Binds the data array, create lines if does not exists 3(Data array length) lines (Creates the new lines only during the intial call to the function)
  lines.data(data).enter().append("line");
 
  //Updates the attributes using data bonded
  lines.attr({
    "x1": function(d) {
      return d[0]
    },
    "y1": function(d) {
      return d[1]
    },
    "x2": function(d) {
      return d[2]
    },
    "y2": function(d) {
      return d[3]
    },
  })
}
svg {
  background-color: grey;
}
line {
  stroke: white;
  stroke-width: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Upvotes: 2

Related Questions