javascript - 在放置时确定 d3.js SVG 组中的不同元素

标签 javascript jquery svg d3.js

我正在尝试从一个 SVG 组中拖出一条线并将其放到另一个 SVG 组中。在我拖放到的 SVG 组中,我希望能够确定我要拖放到该组的哪一部分。

我有一些代码:

HTML:

<div id="MainDiv">

CSS:

.analogDrag {
  cursor: crosshair;
}

JavaScript:

var startX, startY, linkX, linkY, t;
var selectedNode = null,
  startNode = null,
  endNode = null;

function startHandler(d) {
  startNode = null;
  d3.event.sourceEvent.stopPropagation();
  d3.select(this).style('cursor', 'move');
  this.parentNode.appendChild(this);
  endNode = this.id;
  startX = parseInt(d.x) + parseInt(d3.select(this.cx.animVal.value)) + 15;
  startY = parseInt(d.y) + parseInt(d3.select(this.cy.animVal.value));
  linkX = startX;
  linkY = startY;
  startNode = d3.event.sourceEvent.srcElement.parentNode.id;
}

function onDragDrop(dragHandler, dropHandler) {
  var drag = d3.behavior.drag();
  drag.on("drag", dragHandler).on("dragstart", startHandler).on("dragend", dropHandler);
  return drag;
}

function linkDragMove() {
  linkX += d3.event.dx;
  linkY += d3.event.dy;
  d3.selectAll(".link").remove();
  d3.selectAll("svg").append("line").attr("x1", startX).attr("y1", startY).attr("x2", linkX).attr("y2", linkY).attr("stroke", "black").attr("stroke-width", 1).attr("class", "link");
  d3.selectAll(".analogDrag").style('cursor', "default");
  d3.selectAll(".analogDrop").attr("stroke-width", 6).style('cursor', "crosshair");
}

function linkDropHandler(d) {
  d3.select(this).style('cursor', "crosshair");
  d3.selectAll(".analogDrag").style('cursor', "crosshair");
  d3.selectAll(".analogDrop").attr("stroke-width", 1).style('cursor', "default");
  d3.selectAll(".link").remove();
  var x, y;
  var yAdjust = 0;
  if (selectedNode) {
      var n = selectedNode[0][0].attributes;
    if (selectedNode[0][0].id.charAt(0) == "F") yAdjust = 25;
    if (selectedNode[0][0].id.charAt(0) == "K") yAdjust = 40;
    if (selectedNode[0][0].id.charAt(0) == "S") yAdjust = 110;
    for (var i = 0; i < n.length; i++) {
        if (n[i].name == "transform") {
            var co = n[i].value.match(/[0-9]+/g);
            x = parseInt(co[0]);
            y = parseInt(co[1]) + yAdjust;
            break; //Stop iterating once the named array has been found
        }
    }
    debugger;
    endNode = selectedNode[0][0].id;
    //Check if link already exists.
    var links = d3.selectAll(".Link").filter("." + startNode + "." + endNode);
    if (!links[0][0] || links[0][0].attributes['4'].nodeValue != "Link " + startNode + " " + endNode) { //The link does not already exist
        //Draw line to this node.
        d3.selectAll("svg").append("path").attr("d", "M " + startX + " " + startY + " L " + " " + x + " " + y).attr("fill-opacity", 0).attr("stroke", "black").attr("stroke-width", 1)
            .attr("class", "Link " + startNode + " " + endNode);
    }
}
}

var overNode = function (d) {
  selectedNode = d;
};

var outNode = function () {
  selectedNode = null;
};

var f = function (container) {
  var d = [{
    x: 100,
    y: 0,
    moveX: 0,
    moveY: 0
}];
var functions = container.data(d).append("g").attr("transform", function (d) {
    return "translate(" + d.x + "," + d.y + ")";
}).attr("id", "F1");
functions.append("rect").attr({
    x: 20,
    y: 0,
    width: 125,
    height: 125,
    fill: "#F5F5FF",
    stroke: "black",
        "stroke-width": 1,
    id: "highlight"
});
functions.append("path").attr({
    "d": "M 20,10 a10,15 0 0,0 0,30",
    fill: "#FFFFFF",
    stroke: "black",
        "stroke-width": 1,
        "class": "analogDrop"
}).on("mouseover", function () {
    overNode(functions);
}).on("mouseout", function () {
    outNode();
});
functions.append("line").attr({
    x1: 0,
    y1: 25,
    x2: 20,
    y2: 25,
    stroke: "black",
        "stroke-width": 1,
        "class": "analogDrop"
}).on("mouseover", function () {
    overNode(functions);
}).on("mouseout", function () {
    outNode();
});
functions.append("path").attr({
    "d": "M 20,80 a10,15 0 0,0 0,30",
    fill: "#FFFFFF",
    stroke: "black",
        "stroke-width": 1,
        "class": "analogDrop"
}).on("mouseover", function () {
    overNode(functions);
}).on("mouseout", function () {
    outNode();
});
functions.append("line").attr({
    x1: 0,
    y1: 95,
    x2: 20,
    y2: 95,
    stroke: "black",
        "stroke-width": 1,
        "class": "analogDrop"
}).on("mouseover", function () {
    overNode(functions);
}).on("mouseout", function () {
    outNode();
});
};

var k = function (container) {
  var d = [{
    x: 0,
    y: 25,
    moveX: 0,
    moveY: 0
}];
var kn = container.data(d).append("g").attr("transform", function (d) {
    return "translate(" + d.x + "," + d.y + ")";
})
    .attr("id", "K1");
kn.append("circle").attr({
    cx: 0,
    cy: 0,
    r: 15,
    stroke: "black",
        "stroke-width": 2,
    fill: "#FFFFFF",
        "class": "analogDrag"
}).call(onDragDrop(linkDragMove, linkDropHandler));
};
d3.selectAll("svg").remove();
var svgContainer = d3.select("#MainDiv").append("svg").attr("width", 800).attr("height", 600).attr("version", 1.1).attr("xmlns", "http://www.w3.org/2000/svg").attr("viewBox", "-40, -40, 1600, 1200");
f(svgContainer);
k(svgContainer);

我这里也有一个 fiddle :

http://jsfiddle.net/Family/x17hxgus/

所以我可以从圆形节点拖动到方形节点上的两个链接,但我找不到确定我拖放到哪个链接的方法。

我发现确定我已降到哪个组的唯一方法是“selectedNode[0][0].id”,但我需要比这更多的信息。

谁能帮我正确的方向,好吗?

编辑

jsfiddle 在 Chrome 和 Firefox 中有效,在 IE 中无效。

最佳答案

我认为你所拥有的已经很接近了。将您的 overNodeoutNode 重新定义为:

var selectedNode = null;
var overNode = function () {
    selectedNode = this; 
};
var outNode = function () {
    selectedNode = null;
};

然后称它们为:

functions.append("path").attr({
    "d": "M 20,80 a10,15 0 0,0 0,30",
    fill: "#FFFFFF",
    stroke: "black",
        "stroke-width": 1,
        "class": "analogDrop"
}).on("mouseover", overNode)
.on("mouseout", outNode);

如果定义了 selectedNode,那么您就在该路径上。

已更新 fiddle .

关于javascript - 在放置时确定 d3.js SVG 组中的不同元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30591457/

相关文章:

php - 两个Post请求,并且不改变变量

jQuery 多个简单的 Rail 菜单(不是嵌套的 ul)

SVG 半圆和 Arc 参数消歧

javascript - D3 Firefox 问题显示图表不正确 - 根本不显示任何 SVG

javascript - 将 svg 元素替换为 icon

javascript - 没有波浪号 (~) 无法从 node_modules 导入样式表

javascript - ng-change on <输入类型 ="file"

jquery - 所有浏览器都支持事件冒泡吗?

javascript - jQuery AJAX,使用 jQuery 从 HTML 数据属性获取变量,然后将其返回给 PHP

jquery - 将变量从链接传递给 jQuery