3

我正在尝试在 d3.js 中使用 DOM 元素的拖放来创建一个简单的形状,比如说一个圆圈,比如说一个 div。所以这就是我所做的:

<!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 代码:

  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); 
    }
});

  });

问题是圆圈没有出现。你能看看有什么问题吗?

感谢穆罕默德·阿里

4

3 回答 3

2

我通过使用解决了这个问题

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

代替

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

但是我不知道为什么我应该这样做,例如下面的示例适用于 jsFiddle 中的第一种选择器,但是当我在浏览器中本地尝试时它不起作用!

于 2013-08-01T18:33:11.853 回答
0

我刚刚检查了您自己的代码,它运行良好。当我将条放入容器时会显示圆圈。请看演示:http: //jsfiddle.net/af7zk/

var treeCreator = function(){};
...
于 2013-08-01T15:11:13.930 回答
-1

您需要在网页上定义 SVG 命名空间才能将 SVG 元素添加到嵌入的 SVG。在 jsFiddle 上不需要这样做的原因是因为它们在页面上使用了自己的 SVG 图像,其中至少有一个使用命名空间定义(xmlns="http://www.w3.org/2000/svg" SVG 的属性根元素)。

如果您没有在您自己的托管网页中的 SVG 元素上定义该名称空间,则 Web 浏览器无法向其中添加元素,因为它希望它们位于 XHTML 名称空间中。那当然不知道其中定义了 SVG 和 CIRCLE 标签。

更新:我在下面的代码中添加了 SVG 命名空间属性(xmlns属性)。但是由于 Web 浏览器现在很智能,并且可以包含 SVG 命名空间,因此该示例可能适用于本地。真正的问题是省略了指向 CDN 上主 jQuery 库的链接,因为原始示例在 jsFiddle 之外无法工作。所以加个链接

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

以上两个关于 jQuery 资源的参考。

其他注意事项:对于在 SVG 中工作的链接,您还必须添加 XLink 命名空间(在标记中或通过类似于 SVG 命名空间的 javascript 动态添加)。遵循 SVG 规范,但当 xlink:href 属性在 SVG 2.0 中被广泛使用并在 Web 浏览器中得到支持时,它将被更改为仅 href。

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); 
    }
});

  });
于 2018-08-16T20:59:56.483 回答