如何用draggable html div替换raphaeljs盒子?

时间:2017-06-16 00:32:09

标签: javascript jquery html jquery-ui raphael

我正在使用Raphaeljs创建UML类图,我已经创建了某种方式使用框,但看起来很糟糕。我想添加可拖动的div而不是可拖动的盒子。这应该与盒子的方式相同,即连接线随着盒子的移动而移动。 如何用可拖动的div替换这些盒子?
任何其他方式做这样的事情也将不胜感激
这是我的第一个或第二个问题。所以,请原谅我,如果问题含糊不清,请看看小提琴,了解我实际上在问什么 这就是我用盒子做的方式

var boxes = [
  {x:200,y:100,text:'User  \n--------------------------------\n Login ()\n 
  Signup () \n ViewProduct ()  '}, 
  {x:400,y:400,text:'Product  \n--------------------------------\n 
  AddProduct ()\n DeleteProduct () \n UpdateProduct ()  '},
  {x:1000,y:430,text:'Cart  \n--------------------------------\n AddtoCart 
  ()\n DeleteFromCart () \n ResetCart () '}
   ];


 var connections = [
 {from:boxes[0], to:boxes[1]},  {from:boxes[1], to:boxes[2]} ];

这是小提琴UML Fiddle

2 个答案:

答案 0 :(得分:0)

所以我找到了信息框,看了看他们做了什么:https://github.com/kreynolds/RaphaelJS-Infobox/blob/master/raphaeljs-infobox.js

它有点奏效,我希望Raphael能帮助SVG中的<foreignobject>元素,但它看起来并不像那样。我以前从未使用过它。因此,我可以进一步研究它,或者看看我是否可以将其注入paper另一种方式,以便获得:

<svg width="500" height="300" style="border:1px red solid">
  <foreignobject class="node" x="46" y="22" width="100" height="100">
    <div style="border:1px green solid">I'm a div inside a SVG.</div>                
  </foreignobject>
</svg>

到目前为止我所得到的是:

https://jsfiddle.net/Twisty/pq7p05nc/1/

<强>的JavaScript

$(function() {
  // Model
  var boxes = [{
    x: 109,
    y: 120,
    text: 'User  \n--------------------------------\n Login ()\n Signup () \n ViewProduct ()  '
  }, {
    x: 180,
    y: 270,
    text: 'Product  \n--------------------------------\n AddProduct ()\n DeleteProduct () \n UpdateProduct ()  '
  }, {
    x: 370,
    y: 230,
    text: 'Cart  \n--------------------------------\n AddtoCart ()\n DeleteFromCart () \n ResetCart () '
  }];

  var connections = [{
    from: boxes[0],
    to: boxes[1]
  }, {
    from: boxes[1],
    to: boxes[2]
  }];

  // Render
  var paper = new Raphael($('#paper')[0], 700, 500);
  var w = 100;
  var h = 100;

  function redraw() {

    connections.forEach(function(connection) {
      if (typeof connection.view != 'undefined') {
        connection.view.remove();
      }
      connection.view = paper.path(
        'M' + connection.from.x + ',' + connection.from.y + ' ' +
        'L' + connection.to.x + ',' + connection.to.y
      );
      connection.view.toBack();
    });

    var i = 0;
    boxes.forEach(function(box) {
      if (typeof box.view == 'undefined') {
        box.view = {
          rect: paper.rect(-h / 2, -h / 2, w, h),
          text: paper.text(0, 0, box.text)
        };
        box.view.c_id = box.view.rect.node.parentNode.parentNode.id ? box.view.rect.node.parentNode.parentNode.id : box.view.rect.node.parentNode.parentNode.parentNode.id;
        box.view.div_c = $("#" + box.view.c_id);
        box.view.div = $("<div>", {
            id: "ui-box-" + i++,
            class: "dialog-box",
            title: box.text.slice(0, box.text.indexOf("\n"))
          })
          .html(box.text.slice(box.text.indexOf("\n", 12)))
          .appendTo(box.view.div_c)
          .dialog({
            position: {
              my: "left top",
              at: "left+" + box.x + " top+" + box.y,
              of: "#" + box.view.c_id
            },
            width: w,
            height: h + 20
          });
        console.log(box, box.view.div.position());
        box.view.rect.attr({
          //fill: 'lightyellow'
        });
        box.view.rect.drag(function(dx, dy, x, y) {
          box.x = x;
          box.y = y;
        });
      }
      var tbox = 't' + box.x + ',' + box.y;
      box.view.rect.transform(tbox);
      box.view.text.transform(tbox);
    });
  }

  // Controller
  var a = 0;

  function slide() {
    a += 0;
    redraw();
    setTimeout(slide, 10);
  }
  slide();
});

这会附加<div>并进行对话,但它不在<svg>范围内。我怀疑这不会对您的drag事件造成太大问题,但应将其移至对话框drag回调以保留“连接”。

这实现了你最初提出的问题,但我怀疑你现在有更多的兔子洞需要挖掘。

更新1

固定位置,隐藏关闭按钮和更新的拖动:https://jsfiddle.net/Twisty/pq7p05nc/3/

<强> CSS

.dialog-box .ui-dialog-titlebar-close {
  display: none;
}

.dialog-box .ui-dialog-titlebar {
  text-align: center;
  padding: 0.125em;
}

.dialog-box .ui-dialog-content {
  padding: 0.2em;
}

<强> JS

box.view.div = $("<div>", {
  id: "ui-box-" + i++,
  title: box.text.slice(0, box.text.indexOf("\n"))
})
.html(box.text.slice(box.text.indexOf("\n", 12)).replace("/\n/g", "<br />"))
.appendTo(box.view.div_c)
.dialog({
  classes: {
    "ui-dialog": "dialog-box ui-corner-all"
  },
  position: {
    my: "left top",
    at: "left+" + (box.x - (w / 2) - 2) + " top+" + (box.y - (h / 2) - 2),
    of: "#" + box.view.c_id
  },
  width: w,
  height: h,
  drag: function(e, ui) {
    box.x = ui.position.left + (w / 2);
    box.y = ui.position.top + (h / 2);
  }
});

您可以禁止创建rect&amp;此时的文字隐藏了它们。

更新2

添加了包含并隐藏了SCG矩形和文本。

https://jsfiddle.net/Twisty/pq7p05nc/5/

drag: function(e, ui) {
  if (ui.position.left >= $("#paper svg").width() - (w / 2)) {
    ui.position.left = $("#paper svg").width() - (w / 2);
  }
  if (ui.position.top >= $("#paper svg").height() - (h / 2)) {
    ui.position.top = $("#paper svg").height() - (h / 2);
  }
  box.x = ui.position.left + (w / 2);
  box.y = ui.position.top + (h / 2);
}

答案 1 :(得分:0)

代码很棒,谢谢你。 @twisty。

我做错了。

 var boxes = [{
x: 109,
y: 120,
text: 'User \n--------------------------------\n <a href="asdsad.html" 
style="text-decoration:none">USERID \n<br> Name\n<br> Address\n <hr> Login 
()
<br>Signup ()<br> </a>'
 }, {
x: 180,
y: 270,
 text: 'Product  \n--------------------------------\n ProdID \n<br> 
 Name\n<br> 
  Storeid\n <hr>GetPRoduct()<br>DeleteProduct()<br> ViewProduct ()'
 }, {
  x: 370,
 y: 230,
 text: 'Cart  \n--------------------------------\n Cartid \n<br> Items\n<br> 
 Type\n<br>  <hr> AddProduct()<br>RemoveProduct ()<br> ViewCart ()'  
 }];

 var connections = [{
from: boxes[0],
to: boxes[1]
  }, {
from: boxes[1],
to: boxes[2]
   }];

JS FIDDLE UML Class Diagram 此链接适用于想要使用JS生成uml类图的人。