cobolstinks
cobolstinks

Reputation: 7143

D3 make g element drag

I'm new to d3.js, and just trying to learn. How do I make a g draggable? I have a g with a rect and text in it. I want to drag both objects together. Here is my plunkr:

daggable d3.js g element

I've tried googling for samples but they are overly complex and I'm having difficulty understanding most of them.

   let svg = d3.select("body").append("svg")
        .attr("width", 960)
        .attr("height", 500);

    let g = svg.append("g")
        .on("mouseover", function(d) {
            d3.select(this)
                .style("cursor","pointer");
            d3.select(this).select("rect")
                .style("fill", "#325d81");
        })
        .on("mouseout", function(d){
            d3.select(this)
                .style("cursor","default");
            d3.select(this).select("rect")
                .style("fill","#4682b4");
        });

Thanks!

Upvotes: 1

Views: 1509

Answers (2)

Francis Hemsher
Francis Hemsher

Reputation: 3488

You can transform the <g> element, first establishing the onmousedown coordinates.
Try the below:

<!DOCTYPE html>
<html>
<head>
</head>
<meta charset="utf-8">
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

    function wrap(text, width) {
      text.each(function() {
        var text = d3.select(this),
          words = text.text().split(/\s+/).reverse(),
          word,
          line = [],
          lineNumber = 0,
          lineHeight = 1.1, // ems
          y = text.attr("y"),
          dy = parseFloat(text.attr("dy")),
          tspan = text.text(null).append("tspan").attr("x", 10).attr("y", y).attr("dy", dy + "em");
        while (word = words.pop()) {
          line.push(word);
          tspan.text(line.join(" "));
          if (tspan.node().getComputedTextLength() > (width-7.5)) {
            line.pop();
            tspan.text(line.join(" "));
            line = [word];
            tspan = text.append("tspan").attr("x", 10).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
          }
        }
      });
    }

let longText = "Now is the time for all good men to come to the aid of their country and asds and stuff an such jdsfj kljasdkflj kdsfj  sdfkj klsjd kljdsf lk sdfj lkdfs jlk sd a";

var coordX
var coordY
let svg = d3.select("body").append("svg")
    .attr("width", 960)
    .attr("height", 500)

let g = svg.append("g")
	.on("mouseover", function(d) {
  		d3.select(this)
  			.style("cursor","pointer");
  		d3.select(this).select("rect")
  			.style("fill", "#325d81");
	})
	.on("mouseout", function(d){
		d3.select(this)
			.style("cursor","default");
		d3.select(this).select("rect")
			.style("fill","#4682b4");
	})
   .on('mousedown', function () {
  coordX= d3.mouse(this)[0];
  coordY= d3.mouse(this)[1];
})
	.call(d3.drag()
    	.on("drag", dragged))


    let rect2 = g.append("rect")
    .attr("x",5)
	.attr("y",5)
	.attr("rx",20)
	.attr("ry",20)
	.attr("width",300)
	.attr("height",150)
	.style("fill","#4682b4")
	.style("stroke","black")
	.style("stroke-width",5)
	.style("opacity",0.5)

	;

	var txt = g.append('text')
    .text(longText) //<-- our super long text
    .attr('x', 0)
    .attr('y', 30)
    .attr('dy', '.71em')
    .style('fill', 'white')
    .call(wrap, 300); //<-- wrap it according to our width

    var height = txt.node().getBBox().height + 40; //<-- get our height plus a margin
    rect2.attr('height', height); //<-- change our rect


    function dragged() {
    var transX=d3.event.x-coordX
    var transY=d3.event.y-coordY
    d3.select(this).attr("transform","translate("+transX+" "+transY+")")

}



</script>
</body>
</html>

Upvotes: 3

流年灬异彩
流年灬异彩

Reputation: 126

because you did not datanum your selection, function d is always undefined.you can try

function dragged(d) {
      var x=d3.event.x, y=d3.event.y
      d3.select(this).select("text")
        .attr("x", x)
        .attr("y", y);
      d3.select(this).select("rect")
        .attr("x",x)
        .attr("y",y);
    }

Upvotes: 0

Related Questions