block by nitaku c5607cfabe7a238f3853

Drag

Full Screen

This example shows a way to create draggable SVG shapes using d3.js‘s drag behavior.

index.js

(function() {
  var drag, height, nodes, nodes_data, svg, width;

  nodes_data = [
    {
      x: 0,
      y: 0
    }, {
      x: 80,
      y: 80
    }, {
      x: -80,
      y: 80
    }, {
      x: -80,
      y: -80
    }, {
      x: 80,
      y: -80
    }
  ];

  svg = d3.select('svg');

  width = svg.node().getBoundingClientRect().width;

  height = svg.node().getBoundingClientRect().height;

  svg.attr({
    viewBox: "" + (-width / 2) + " " + (-height / 2) + " " + width + " " + height
  });

  drag = d3.behavior.drag().origin(function(d) {
    return d;
  });

  drag.on('drag', function(d) {
    d.x = d3.event.x;
    d.y = d3.event.y;
    return d3.select(this).attr({
      transform: "translate(" + d.x + "," + d.y + ")"
    });
  });

  nodes = svg.selectAll('.node').data(nodes_data);

  nodes.enter().append('circle').call(drag).attr({
    "class": 'node',
    r: 20,
    fill: 'gray',
    transform: function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    }
  });

}).call(this);

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="description" content="Drag" />
        <title>Drag</title>
        <link type="text/css" href="index.css" rel="stylesheet"/>
        <script src="//d3js.org/d3.v3.min.js"></script>
    </head>
    <body>
        <svg height="500" width="960"></svg>
        <script src="index.js"></script>
    </body>
</html>

index.coffee

# data
nodes_data = [
  {x:   0, y:   0},
  {x:  80, y:  80},
  {x: -80, y:  80},
  {x: -80, y: -80},
  {x:  80, y: -80}
]


svg = d3.select('svg')
width = svg.node().getBoundingClientRect().width
height = svg.node().getBoundingClientRect().height

# translate the viewBox to have (0,0) at the center of the vis
svg
  .attr
    viewBox: "#{-width/2} #{-height/2} #{width} #{height}"


# define a drag behavior
drag = d3.behavior.drag()
  .origin((d) -> d)
  
drag.on 'drag', (d) ->
  # update the datum of the dragged node
  d.x = d3.event.x
  d.y = d3.event.y
  
  # translate the representation
  d3.select(this)
    .attr
      transform: "translate(#{d.x},#{d.y})"


# add draggable nodes
nodes = svg.selectAll('.node')
    .data(nodes_data)

nodes.enter().append('circle')
  .call(drag) # enable dragging for nodes
  .attr
    class: 'node'
    r: 20
    fill: 'gray'
    transform: (d) -> "translate(#{d.x},#{d.y})"
    
    

index.css

svg {
  background: white;
}