create a shape in d3.js by drag and drop of a DOM element

d3-drag
d3.drag is not a function
svg drag and drop
d3.js drag and drop rectangle
d3-drag select
d3 draggable nodes
d3 mouse drag event
drag

I am trying to create a simple shape, let's say a circle, in d3.js using drag and drop of a DOM element, let's say a div. So here is what I did:

<!DOCTYPE html>
<html>
<head>
  <title>d3 tree with drag and drop</title>
  <style type="text/css">
   #dropInSVG {
     width:200px;
     height:200px; 
     margin-left:20px;
     background-color:#F8F8F8 ;
  }

#dropInSVG svg {
    width: 200px;
    height:200px;
    background-color:yellow;
 } 

#tobeDropped{
width:50px; 
height:15px;
background-color:pink;
float:left; 
}

#mainContainer {
width: 250px;
height: 250px;
background-color:orange;
cursor:pointer;
}

</style>
</head>
<body>
<div id="mainContainer">
<div id="dropInSVG"></div>
<div id="tobeDropped"></div>
</div>
</body>
<script type="text/javascript" src="./lib/jquery.js"></script>
<script type="text/javascript" src="./lib/jquery-ui.js"></script>
<script type="text/javascript" src="./lib/d3.js"></script>
<script type="text/javascript" src="./lib/d3.layout.js"></script>
<script type="text/javascript" src="d3appDrag.js"></script>
</html>

JavaScript code:

  var treeCreator = function(){}; 


  treeCreator.prototype.callbacktest = function(svgContainer){
  alert('the element has been dropped');
  }; 

  treeCreator.prototype.createTreeNode = function(theSVG){
  $('#tobeDropped').remove();
  theSVG.append("circle")
    .style("stroke","green")
    .style("fill","white")
    .attr("r",40)
    .attr("cx", 100)
    .attr("cy", 100)
    .on("mouseover", function () {
        d3.select(this).style("fill", "aliceblue");
    })
        .on("mouseout", function () {
        d3.select(this).style("fill", "red");
    }); 
 }; 

 $(document).ready(function(){

    $('#tobeDropped').draggable({containment:'#mainContainer'});

var theSVG = d3.select('#dropInSVG')
.append("svg")
.attr("width",200)
.attr("height",200);

var tc = new treeCreator(); 

$('#dropInSVG').droppable({
    drop: function(){
        tc.createTreeNode(theSVG); 
    }
});

  });

The problem is that the circle is not showing up. Could you please see what's wrong?

Thanks Mohamed Ali

I resolved this issue by using

.append("svg:svg") 
 and 
.append("svg:circle")

instead of

.append("svg")
 and
.append("circle"); 

however I don't know why I should do that, for instance the following example works with the first type of selectors in jsFiddle however it didn't work when I tried locally in my browser!

D3.js Tutorial: Drag and Drop - Development, Have you managed to handle drag and drop with d3.js ? A while ago I was trying to create a d3 shape using drag and drop of a dom element to an SVG  D3.js click and drag events combined. Now it’s time to combine our drag and drop example with our previous “mouse events” tutorial. In the next live demo you can: Click on the map to create a new pointer, Click while CTRL is pressed on a pointer to remove it, Click on a pointer to (un)select it, And of course drag and drop pointers across the map.

I have just checked your own code and it works well. The circle is displayed when I drop the bar into the container. Please see the demo: http://jsfiddle.net/af7zk/

var treeCreator = function(){};
...

Drag and drop HTML elements onto SVG elements provided by D3 , and drop with D3. index.html. <!DOCTYPE html> <title>Drag And Drop</title>​. </head>. <body> function grab(element, event){. dragTarget = event.target;. This method is used to disable the drag and drop selection. It prevents mousedown event action. Most of the selected browsers supports this action by default. If not supported, you can set the CSS property to none. d3.dragEnable(window[, noclick]) This method is used to enable the drag and drop selection on the specified window location.

You need the SVG namespace defined on the web page to add SVG elements to the embedded SVG. The reason why this is not needed on jsFiddle is because they have their own SVG images used on the page with at least one defined with namespace (xmlns="http://www.w3.org/2000/svg" attribute of the SVG root element).

If you don't have that namespace defined on your SVG element in your own hosted web page the web browser cannot add elements to it as it expects them to be in the XHTML namespace. That of course doesn't know have SVG and CIRCLE tags defined in it.

UPDATE: I've added the SVG namespace attribute in the code below (xmlns attribute). But since web browsers are smart these days and can have SVG namespace already included the example might work for you locally. The real problem was omitting the link to main jQuery library on CDN since the original example won't work outside jsFiddle. So add a link

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

above two other references for jQuery resources.

And other note: for links to work in SVG you have to add XLink namespace as well (in the markup or dynamically via javascript similarly to SVG namespace). Follow SVG specifications though as xlink:href attribute will be changed to just href in SVG 2.0 when this is widely available and supported in web browsers.

http://jsfiddle.net/q1bwzhpc/7

var treeCreator = function(){}; 


  treeCreator.prototype.callbacktest = function(svgContainer){
  alert('the element has been dropped');
  }; 

  treeCreator.prototype.createTreeNode = function(theSVG){
      $('#tobeDropped').remove();
      theSVG.append("circle")
        .style("stroke","green")
        .style("fill","white")
        .attr("r",40)
        .attr("cx", 100)
        .attr("cy", 100)
        .on("mouseover", function () {
            d3.select(this).style("fill", "aliceblue");
        })
            .on("mouseout", function () {
            d3.select(this).style("fill", "red");
        }); 
 }; 

 $(document).ready(function(){

    $('#tobeDropped').draggable({containment:'#mainContainer'});

var theSVG = d3.select('#dropInSVG')
.append("svg")
.attr("xmlns", "https://www.w3.org/2000/svg")
.attr("width",200)
.attr("height",200);

var tc = new treeCreator(); 

$('#dropInSVG').droppable({
    drop: function(){
        tc.createTreeNode(theSVG); 
    }
});

  });

Custom drag and drop with D3 · GitHub, This is the first of two posts explaining the basics of drag and drop. We create a basic HTML page and create a SVG element inside it. <! For each value in the array the function will return an object with a random x attribute  To initiate the drag, we first press down on the element: This pressing down can be either via our mouse cursor or finger. To keep the terminology simple, I'll refer to the mouse cursor or finger (or stylus) more generically as just a pointer. While we are pressing down on the element with our pointer,

Get drag and drop working with d3, create simple objects and set the drag-and-drop on them; grouping all the objects and make DOCTYPE html> <html> <head> <meta name="description" 960) .​attr("height", 450); //Draw two circles and one rectangle var circle1 occurs (​object should be moved) function dragged(d){ d.x = d3.event.x; d.y  Learn how to create SVG chart using D3.js library. SVG provides different shapes like lines, rectangles, circles, ellipses etc. Hence, designing visualizations with SVG gives you more flexibility and power in what you can achieve.

Zoom and drag-and-drop with D3.js library, DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/​html src="https://mbostock.github.com/d3/d3.js"></script> <script var drag = d3.behavior.drag() .origin(Object) .on("drag", dragmove); var  Learn how to create a draggable HTML element with JavaScript and CSS. Include a header DIV with the same name as the draggable DIV, followed by "header" -->

D3 Drag Rectangle with drag handles, Using d3.js to create a draggable circular packing. Intro to d3 Shape Data wrangling DOCTYPE html> <meta charset="utf-8"> <! .attr("width", 450) .attr("​height", 450) // create dummy data -> just one element per circle var data = [{ "​name":  This is an example of the power of the D3 library and how you can use the drag behavior of D3 to control the position and shape of the SVG element.

Comments
  • hi thanks for replying, I know it is running fine in jsFiddle, see the example I gave, however when used in a local browser for instance chrome it is not working unless I do .append(svg:svg) and .append(svg:circle)
  • For sure, added the one line above. If you fork the original fiddle or download it to your computer don't forget to add the jQuery reference.