为什么我嵌入的 JointJS 元素重叠?

2024-03-28

我正在研究 JointJS 图,使用 DirectedGraph 来处理布局,我试图实现类似于下图的效果。我需要将节点(A、B、C、D、E、F、G、H、I、J)“概述”或包含在单独的节点(Foo、Bar、Hmm)中。当我将所有元素添加到图表中时,所有元素都在彼此之上。但是,如果我不在区域之间添加顶点,则所有元素都会正确布局,但没有连接区域的顶点。

根据下面的代码,我做错了什么?节点(A、B、C、D、E、F、G、H、I、J)是否会因为未连接到图的其余部分而导致错误?

非常感谢您提供的任何反馈。

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

var regions = [ makeRegion('Foo'), makeRegion('Bar'), makeRegion('Hmm')];
var nodes = [
    makeNode('A'),
    makeNode('B'),
    makeNode('C'),
    makeNode('D'),
    makeNode('F'),
    makeNode('G'),
    makeNode('H'),
    makeNode('I'),
    makeNode('J'),
];
regions[0].embed(nodes[0]).embed(nodes[1]).embed(nodes[2]);
regions[1].embed(nodes[3]).embed(nodes[4]).embed(nodes[5]);
regions[2].embed(nodes[6]).embed(nodes[7]).embed(nodes[8]);
var vertices = [
    connect(regions[0], regions[1]),
    connect(regions[1], regions[2]),
    connect(regions[2], regions[0])
    ];
paper.addCells(regions.concat(nodes).concat(vertices));
joint.layout.DirectedGraph.layout(paper, {
    rankDir: 'LR',
    marginX: 30,
    marginY: 30,
    clusterPadding: {
        top: 30,
        left: 10,
        right: 10,
        bottom: 10
    }
});

function makeNode(name) {
    return new joint.shapes.basic.Rect({
        size: {
            width: 35,
            height: 35
        },
        attrs: {
            text: {
                text: name
            }
        }
    });
}

function connect(a, b) {
    return new joint.shapes.fsa.Arrow({
        source: { id: a.id },
        target: { id: b.id }
    });
}

function makeRegion(name) {
    return new joint.shapes.basic.Rect({
        size: {
            width: 300,
            height: 200
        },
        attrs: {
            text: {
                text: name
            }
        }
    });
}

EDIT:

虽然我从未找到解决这个问题的好方法,但我确实发现通过一些额外的工作,这是可以实现的。它假设您的图不太复杂,区域之间的边很少。

如果我单独添加边,在所有节点都添加到图中之后,它就可以正常工作。然而,定向布局并没有完全按照预期工作。我用了joint.layout.DirectedGraph.layout()最初是为了对齐内部节点,然后我重新定位外部区域。最后我添加了边缘,这产生了与上图类似的结果。

以下是我如何实现这一目标的粗略概述:

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

var regions = [ makeRegion('Foo'), makeRegion('Bar'), makeRegion('Hmm')];
var nodes = [
    makeNode('A'),
    makeNode('B'),
    makeNode('C'),
    makeNode('D'),
    makeNode('F'),
    makeNode('G'),
    makeNode('H'),
    makeNode('I'),
    makeNode('J'),
];
regions[0].embed(nodes[0]).embed(nodes[1]).embed(nodes[2]);
regions[1].embed(nodes[3]).embed(nodes[4]).embed(nodes[5]);
regions[2].embed(nodes[6]).embed(nodes[7]).embed(nodes[8]);

paper.addCells(regions.concat(nodes));
joint.layout.DirectedGraph.layout(paper, {
    rankDir: 'LR',
    marginX: 30,
    marginY: 30,
    clusterPadding: {
        top: 30,
        left: 10,
        right: 10,
        bottom: 10
    }
});

var vertices = [
    connect(regions[0], regions[1]),
    connect(regions[1], regions[2]),
    connect(regions[2], regions[0])
    ];
repositionRegions();
// Add the edges after all the nodes are in their final position
graph.addCells(vertices);

function repositionRegions() {
    // Move regions to where you want them
}

function makeNode(name) {
    return new joint.shapes.basic.Rect({
        size: {
            width: 35,
            height: 35
        },
        attrs: {
            text: {
                text: name
            }
        }
    });
}

function connect(a, b) {
    return new joint.shapes.fsa.Arrow({
        source: { id: a.id },
        target: { id: b.id }
    });
}

function makeRegion(name) {
    return new joint.shapes.basic.Rect({
        size: {
            width: 300,
            height: 200
        },
        attrs: {
            text: {
                text: name
            }
        }
    });
}

这是 Dagre-D3 的一个已知问题:自动布局不适用于具有父级链接的分层图 https://github.com/clientIO/joint/issues/455.

作为解决方法,您可以省略区域之间的链接(在您的问题版本中建议),或者您可以做一些额外的工作,这对于任意数量的节点都可以很好地工作:

  1. 分别布局每组子节点:

    var fooChildren = [nodes[0], nodes[1], nodes[2]];
    var barChildren = [nodes[3], nodes[4], nodes[5]];
    var hmmChildren = [nodes[6], nodes[7], nodes[8]];
    var children = [fooChildren, barChildren, hmmChildren];
    
    for(var i = 0; i < children.length; i++)
        joint.layout.DirectedGraph.layout(children[i]);
    
  2. 对于每个区域,创建一个辅助克隆区域。

    var clones = [];
    for(var i = 0; i < regions.length; i++) {
        var clone = regions[i].clone();
        graph.addCell(clone);
        clones.push(clone);
    }
    
  3. 将相应的节点设置为其克隆区域。

    for(var i = 0; i < children.length; i ++)
        for(var k = 0; k < children[i].length; k++)
            clones[i].embed(children[i][k]);
    
  4. 使每个克隆区域适合其子区域的大小,并根据克隆区域的大小调整原始区域的大小。

    for(var i = 0; i < clones.length; i++) {
        clones[i].fitEmbeds(padding: { top: 30, left: 10, right: 10, bottom: 10 });
        regions[i].resize(clones[i].getBBox().width, clones[i].getBBox().height);
    }
    
  5. 布置图形。

    joint.layout.DirectedGraph.layout(graph, {
        rankDir: 'LR',
        marginX: 30,
        marginY: 30,
        clusterPadding: {
            top: 30,
            left: 10,
            right: 10,
            bottom: 10
        }
    });
    
  6. 将克隆区域平移到其原始区域的位置(子区域将相应地平移)。

    for(var i = 0; i < clones.length; i++) {
        var dx = regions[i].getBBox().x - clones[i].getBBox().x;
        var dy = regions[i].getBBox().y - clones[i].getBBox().y;
        clones[i].translate(dx, dy);
    }
    
  7. 删除克隆区域并将子区域设置为原始区域。

    for(var i = 0; i < regions.length; i++) {
        clones[i].remove();
    
        for(var j = 0; j < children[i].length; j++)
            regions[i].embed(children[i][j]);
    }
    

希望这可以帮助提供替代解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我嵌入的 JointJS 元素重叠? 的相关文章

  • 上传时自动缩小 CSS 和 Javascript

    有谁知道通过上传处理 脚本自动运行某些文件类型的好方法 当我将 CSS 和 Javascript 上传到服务器时 我试图自动缩小它们 在本地保留一个漂亮的 人类可读的版本 同时在服务器上保留一个缩小的版本 我目前在 Windows 上使用
  • 添加 Javascript 按钮来更改 iframe 的内容

    我正在尝试创建此页面 其中有一个 Iframe 并且我想添加一个按钮来显示 iframe 中的下一页 以及一个按钮来显示 iframe 中的上一页 我总共有 4 个页面要在名为 1 html 2 html 3 html 4 html 的 i
  • Javascript:将 JSON 字符串转换为 ES6 映射或其他形式以保留键的顺序

    ES6 或后续版本 Javascript 或 TypeScript 中是否有原生 内置 方法将 JSON 字符串转换为 ES6 映射 或者可以选择要实现的自制解析器 目标是保留 JSON 字符串编码对象的键顺序 Note 我故意不使用 解析
  • Google 地图上的自定义路线/路径/道路

    我需要能够使用 V2 或 V3 最好是 3 创建在某种意义上忽略建筑物的路径 我试图创建一个 kml 文件来自己绘制所有路径 然后找到某种方法根据需要打开 关闭它们 例如 用户想要从 A 点前往 B 点 这些点之间有许多建筑物 用户可以实际
  • 从平面数组创建嵌套对象

    我目前有一个对象数组 我正在尝试将其重塑为嵌套对象ID作为对象键 并将其作为目标ID与parentid 如果不是 0 我尝试了几种方法 但我很挣扎 主要绊脚石for me是超过一两层深度的任何东西 理想情况下 我需要它是动态的 这样它就可以
  • 如何检查变量是否是生成器函数? (例如函数*产量)[重复]

    这个问题在这里已经有答案了 检查函数是否是生成器的可靠方法是什么 例如 let fn function yield 100 if fn instanceof for let value in fn 我能想到的唯一方法是fn toString
  • HTML5 游戏到本机应用程序 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在用 HTML5 制作游戏 我最熟悉 HTML5 并且比 C 等更高级的语言更喜欢它 HTML5
  • 如果文本过滤器在 ng-repeat 中没有返回结果,则显示消息

    假设我们有一个带有文本过滤器的 ng repeat
  • 如何隐藏 URL 中的 ID

    我以前在 Stack Overflow 上见过这类问题 但没有一个真正有帮助 我也用谷歌搜索过 但没有骰子 我想知道如果用户单击选项卡本身是否可以隐藏 URL 中的 ID 这是网页 www planet nu dev new experia
  • Javascript:更改浏览器后退按钮的功能

    有没有办法让用户的浏览器上的后退按钮调用 JavaScript 函数而不是返回页面 您无法覆盖这样的行为 如果用户通过链接访问您的页面 则单击 后退 将使他们再次离开该页面 但是 您可以使页面上的 JavaScript 操作将条目添加到历史
  • 单击 div 中的图像时如何翻转该 Div?

    好吧 我对编写 Javascript 知之甚少 我可以对其进行一些编辑 并且涉足了 CSS3 动画 我将向您展示我正在努力实现的目标 然后在下面进行解释 网站布局将是这样的 https i stack imgur com RMb4R jpg
  • 在浏览器中打开的 .mhtml 文件中填写输入

    我想对 mhtml 文件运行 e2e 测试 即填写表格 在 mhtml 文件上查看和提取数据效果非常好 但我无法填写任何内容input字段 既不是手动也不是通过木偶操作者 你可以用这个试试 mhtml 文件 https gist githu
  • EmberJS:如何为 ember-data RESTAdapter 中的模型提供特定的 URL?

    问题一 如果我有一个名为 Company 的余烬数据模型 我如何告诉它点击 businesses and businesses id而是检索记录 有没有办法指定给定模型的 url 更好的是 像 BackboneJS 一样 我可以在运行时计算
  • 如何从 WinRT StreamSocket 读取所有可用数据并清空 inputStream?

    我想在向套接字写入新数据之前读取当前正在等待套接字的所有数据 WinRT中的读取方法都是异步的 所以我不能简单地while直到套接字为空 由于我确实想丢弃套接字上的数据 因此我不想使用读取器 而是直接从套接字读取数据IInputStream
  • 如何使用 javascript 禁用组合键?

    I would like to disable view source shortcut key for IE using JavaScript To disable Ctrl C I am using the following func
  • jQuery 更改为隐藏字段后触发重力表单中的表单更新

    简而言之 是否有 JavaScript 函数或挂钩来触发重力形式的更新 以便执行条件逻辑 原问题 我正在使用重力形式 并且创建了一个 变化时 事件 gform 1 find gfield date dropdown month select
  • Kotlin JavaScript 到 TypeScript 定义文件

    我已经找到了ts2kt 库 https github com Kotlin ts2kt这将从任意位置创建 Kotlin 头文件 d ts文件 但是 我想朝相反的方向走 我想构建一个可以编译为 JavaScript 的 Kotlin 库 但我
  • ParseFromString 在 IE 中抛出错误,但在 Chrome 中不会抛出错误

    我正在使用传单的 KML 插件 该插件在 Google Chrome 中运行良好 然而 在 IE 中 它会在以下代码中引发错误 parser new DOMParser console log url outputs path to kml
  • 如何在画布中旋转图表同时保持数字垂直?

    我正在尝试围绕其中心旋转画布中的图表 同时保持字母直立 我正在尝试使用 ctx rotate 但它使用画布的左侧作为中心来旋转整个图表 以下链接提供了视觉效果 我希望它看起来像绿色 而不是红色 就像我的代码当前所做的那样 视觉解释 http
  • 在哪里放置资源特定逻辑

    您能帮我考虑在 AngularJS 中将资源 服务 特定的业务逻辑放置在哪里吗 我觉得在我的资源上创建一些类似模型的抽象应该很棒 但我不确定如何做 API调用 gt GET customers 1 lt first name John la

随机推荐

  • 正则表达式提取由空格分隔的键值对,值中包含空格

    假设一个单行字符串具有多个连续的键值对 用空格分隔 但值内也允许有空格 不在键中 例如 key1 one two three key2 four key3 five six key4 seven eight nine ten 从上面正确提取
  • WTP HTTP 预览服务器 - 如何重新配置​​默认服务器端口?

    在 Eclipse Ganymede 下 如何重新配置 Eclipse WTP HTTP 预览服务器 的默认服务器端口 8080 Leonel 我想你从来没有看到与这个问题相关的 视图 我问的是 HTTP预览服务器 而不是端口所在的其他服务
  • WPF 绑定路径=/ 不起作用?

    我已经设置了我的DataContext像这样
  • Flutter 将两个 Firestore 流合并为一个流

    我只想执行 OR 运算并将两个查询的结果放入一个流中 这是我的带有单个流的代码 StreamBuilder stream Firestore instance collection list where id isEqualTo false
  • Python:判断字符串是否包含数学?

    给定这些字符串 1 2 apple pear 如何使用 Python 3 5 确定第一个字符串包含数学问题并且没有其他的而第二根弦没有 这是一种方法 import ast UNARY OPS ast UAdd ast USub BINARY
  • Amazon S3 托管流媒体视频 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 如果我公开提供 Amazon s3 MP4 资源 然后在该资源的 URL 周围添加 Html5 视频标
  • 如果所有变量都是 float16 而不是 float32,如何运行定义 Tensorflow 图

    默认情况下 Tensorflow 变量采用 float32 格式 为了节省内存 我尝试以 float16 运行 在我的图表中 我在每个可以将数据类型定义为 float16 的地方都这样做了 但是 当我运行代码时出现错误 下面是我的代码 im
  • 在过程触发器内动态插入记录

    我们正在寻求将我们的数据库转换为 Postgres 9 3 5 我对此没有经验 并且我正在尝试让我们的审计表启动并运行 我知道每个表都需要自己的触发器 但所有触发器都可以调用单个函数 表上的触发器正在传递需要审核的列的列表 因为我们的某些列
  • WFFM 8.0 - 缺少保存到数据库操作

    我刚刚安装了 Web Forms For Marketers 8 0 并做了一个测试表单 尝试选择Save to Database从操作列表中但它不存在 另外 我已经检查过 sitecore system Modules Web Forms
  • 哪里有指示不应写入“程序文件”区域的指南?

    许多关于SO的问题都说 Windows开发人员指南 或 Windows设计指南 说你不应该将临时数据或程序数据写入程序文件区域 但据我所知 它们都没有真正链接到文档这就是说 搜索 MSDN 没有得到任何结果 Windows 将使该区域变为只
  • clojure(带超时...宏)

    我正在寻找一个宏 如果表达式完成时间超过 X 秒 它将引发异常 这个问题在这里有更好的答案 执行具有超时功能的函数 https stackoverflow com questions 6694530 executing a function
  • Visual Studio 将项目发布到一个简单的安装程序中

    我有一个相当大的项目 包含多个类 500 多个图像以及与该项目关联的 20 多个文本文件 我一直通过右键单击来发布我的项目project gt properties 然后单击 发布 选项卡 我已将文本文件和图像包含为resources已经
  • 如何使用 CSS 使 div 上的滚动条变粗?

    如果我使用 CSS 溢出属性 overflow scroll 默认情况下我得到一个细滚动条 我如何设计它以获得宽 且平坦 的滚动条 您可以在这里找到有关如何在多个浏览器上更改滚动条设计的答案 https stackoverflow com
  • Rails activesupport 通知 - 错误的数据库运行时值

    我正在尝试记录 REST API 应用程序的请求 我为此使用 Rails 通知 如下所示http railscasts com episodes 249 notifications in rails 3 http railscasts co
  • 更改 TortoiseGit 中的存储库 url

    我们刚刚将 git 存储库更新到了新位置 我正在使用 TortoiseGit 进行一些未提交的更改 我可以在任何地方更改文件夹引用吗 我在上下文菜单中没有看到该选项 如果可以避免的话 我宁愿不重新创建和合并 因为总共大约有 14 个存储库
  • 使用现有的 Rails 应用程序添加 twitter-bootstrap-rails

    我尝试将 twitter bootstrap rails 与现有的 Rails 应用程序一起使用 并在刷新页面时收到以下错误 没有要加载的文件 less 在 app assets stylesheets bootstrap and over
  • 如何将UIScrollView的触摸事件发送到其后面的视图?

    我在另一个视图之上有一个透明的 UIScrollView 滚动视图有内容 文本和图像 用于显示信息 它后面的视图有一些用户应该能够点击的图像 并且它们上面的内容可以使用提到的滚动视图进行滚动 我希望能够正常使用滚动视图 尽管没有缩放 但是当
  • 节点检查器无法连接到节点

    我运行节点 node debug app OR node debug brk app 它回应 debugger listening on port 5858 Express server listening on port 1338 我现在
  • 将 varchar 值转换为 int,如果输入错误,不会引发异常

    有没有办法调用 Sql Server 函数 Convert Cast 而不让它们抛出异常 基本上 我有一列包含字母数字数据 我正在从字段中提取值 并且我想将数据显示为整数值 有时提取的数据不是数字 在这些情况下我希望 Sql Server
  • 为什么我嵌入的 JointJS 元素重叠?

    我正在研究 JointJS 图 使用 DirectedGraph 来处理布局 我试图实现类似于下图的效果 我需要将节点 A B C D E F G H I J 概述 或包含在单独的节点 Foo Bar Hmm 中 当我将所有元素添加到图表中