如何防止 jointjs 单元格溢出纸张?

How can I keep jointjs cells from overflowing the paper?

我正在使用 jointjs 制作用户可编辑的图表。用户可以四处拖动它们并重新定位每个单元格。但是,当单元格被拖到边缘时,它会溢出并被截断。我想防止这种情况发生,而是让单元格在到达纸张边缘之前停止并且不允许越过边缘,从而始终完全停留在纸张内。可以在此处的 jointjs 自己的演示中看到该行为:

http://www.jointjs.com/tutorial/ports

尝试将单元格拖到边缘,您会发现它最终会在越过纸张元素的边缘时隐藏起来。

其次,我正在使用用于定向图布局的插件,可在此处找到:

http://jointjs.com/rappid/docs/layout/directedGraph

如您所见,每当您点击布局时,树位置会自动移动到纸元素的左上角。如何修改这些默认位置?对于所提供的函数,我看到的唯一选项是 space 之间的等级和 space 之间的节点,没有初始位置。假设我希望树在单击 'layout' 时出现在纸的中间,我必须在哪里进行更改?在此先感谢您的帮助。

编辑:我觉得这个方法还是可行的,但我现在觉得我的另一个答案是simpler/better。

JointJS 文档提供了一个示例,其中形状的移动被限制在椭圆上:

http://www.jointjs.com/tutorial/constraint-move-to-circle

它的工作原理是

  1. 正在为您的元素定义新视图,扩展 joint.dia.ElementView
  2. 覆盖视图中的 pointerdownpointermove 事件以实现约束。这是通过根据鼠标位置和约束计算新位置,然后将其传递给基础 ElementView 事件处理程序
  3. 来完成的
  4. 强制 paper 使用您的自定义元素视图

这种方法可以很容易地进行调整,以防止形状被拖离纸张的边缘。在第 2 步中,不是像教程中那样计算与椭圆的交点,而是使用 Math.min()Math.max() 来计算新位置。

我觉得我之前的回答还是可行的,但是我在项目中是这样实现的。它优于其他答案,因为它不需要您使用自定义 elementView 并且看起来更简单(对我来说)。

(工作 jsfiddle:http://jsfiddle.net/pL68gs2m/2/

paper 上,处理 cell:pointermove 事件。在事件处理程序中,计算出触发事件的 cellView 的边界框,并使用它来约束移动。

var graph = new joint.dia.Graph;

var width = 400;
var height = 400;
var gridSize = 1;

var paper = new joint.dia.Paper({
    el: $('#paper'),
    width: width,
    height: height,
    model: graph,
    gridSize: gridSize
});

paper.on('cell:pointermove', function (cellView, evt, x, y) {

    var bbox = cellView.getBBox();
    var constrained = false;

    var constrainedX = x;

    if (bbox.x <= 0) { constrainedX = x + gridSize; constrained = true }
    if (bbox.x + bbox.width >= width) { constrainedX = x - gridSize; constrained = true }

    var constrainedY = y;

    if (bbox.y <= 0) {  constrainedY = y + gridSize; constrained = true }
    if (bbox.y + bbox.height >= height) { constrainedY = y - gridSize; constrained = true }

    //if you fire the event all the time you get a stack overflow
    if (constrained) { cellView.pointermove(evt, constrainedX, constrainedY) }
});

我。为了防止元素溢出纸张,您可以使用 restrictTranslate 纸张选项 (JointJS v0.9.7+)。

paper.options.restrictTranslate = function(cellView) {
    // move element inside the bounding box of the paper element only
    return cellView.paper.getArea();
}

http://jointjs.com/api#joint.dia.Paper:options

二.使用 marginXmarginY DirectedGraph 布局选项移动结果图的左上角,即在左侧和顶部添加边距。

http://jointjs.com/rappid/docs/layout/directedGraph#configuration

作为Roman答案的补充,restrictTranslate也可以配置为true来限制元素移动到纸张区域的边界。

示例:

var paper = new joint.dia.Paper({
    el: $('#paper'),
    width: 600,
    height: 400,
    model: graph,
    restrictTranslate: true
})