xDSticker
xDSticker

Reputation: 31

How to drag an rect on an dragable space?

i m relativ new to web programming like javascript and d3. So maybe my basics are a bit low. Ich know to programm in Java, PHP and have a very good SQL knowlegde.

My Question is: How can I drag a rect on a dragable space. I try to program a java script where i can drag the background (in this time all objects move) and a specific object where just a one selected move. I also try to build d3-groups because i need to work with groups in future.

I will provide my code below so maybe you can help me out.

var $ = jQuery.noConflict();

var width = $(window).width();
var height = $(window).height();

var workspace_width = 500;
var workspace_height = 500;



var zoom = d3.behavior.zoom()
    .scaleExtent([1, 10])
    .on("zoom", function() {
            background.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        });

var first_zoom = d3.behavior.zoom()
    .on("zoom", function() {
            first.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        });

var drag = d3.behavior.drag()
  .origin(Object)
  .on("drag", function(d) {
    d.x = d3.event.x;
    d.y = d3.event.y;
    draw();
  });
// Append SVG to HTML
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .call(zoom)
    .style("pointer-events", "all");

//Append Background
var background = svg.append("g");

//Append to Background Stripes from up to down
background.append("g")
    .attr("class", "x axis")
    .selectAll("line")
    .data(d3.range(0, workspace_width, 10))
    .enter().append("line")
    .attr("x1", function(d) { return d; })
    .attr("y1", 0)
    .attr("x2", function(d) { return d; })
    .attr("y2", workspace_height);

//Append to Background stripes from right to left
background.append("g")
    .attr("class", "y axis")
    .selectAll("line")
    .data(d3.range(0, workspace_height, 10))
    .enter().append("line")
    .attr("x1", 0)
    .attr("y1", function(d) { return d; })
    .attr("x2", workspace_width)
    .attr("y2", function(d) { return d; });

//Append Foreground to background
var foreground = background.append("g");

//Append rect to foreground
var first = foreground.append("rect")
            .attr("x", 5)
            .attr("y", 5)
            .attr("width", 100)
            .attr("height", 60)
            .attr("rx", 10)
            .attr("ry", 10)
            .style("fill", "lightgray")
            .style("stroke","black")
            .style("stroke-width","2")
            .style("opacity","0.7")
            .call(first_zoom);

Thank you for you help Hans

Upvotes: 0

Views: 305

Answers (1)

Gilsha
Gilsha

Reputation: 14589

Here is a small example for dragging a rect using d3 drag behavior. JSFiddle. Hope this helps.

var data = [{ x: 0, y: 0},{ x: 20, y: 20},{ x: 0, y: 60},{ x: 52, y: 0}]

var zoom = d3.behavior.zoom()
    .on("zoom",function(){
       g.attr("transform","translate(" + d3.event.translate + ")"); 
    });

var svg = d3.select("body")
    .append("svg")
    .attr("width",window.innerWidth)
    .attr("height",window.innerHeight)
    .call(zoom)

var g = svg.append("g");

var drag = d3.behavior.drag()
  .origin(function(d,i) { return {x:d.x, y:d.y}; })
  .on("drag", function(d) {  
      d.x = d3.event.x;
      d.y = d3.event.y;
      d3.select(this).attr("transform",function(d){ return "translate("+d.x+","+d.y+")"; });       
      d3.event.sourceEvent.stopImmediatePropagation();
  });

g.selectAll("rect")
    .data(data)
    .enter()
    .append("rect") 
    .attr("transform",function(d){ return "translate("+d.x+","+d.y+")"; })
    .attr("width","30")
    .attr("height","40")
    .call(drag);

Update : I think, it would be better using d3 zoom behavior for panning all rectangles. Updated the fiddle URL.

Upvotes: 1

Related Questions