- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在他的d3 Sankey Diagram page上,Mike Bostock 说“该算法将来可以改进,比如尽量减少链接交叉”。
我想投入一些时间并做到这一点,但我不确定是否要开始。有人对如何实现这一目标有任何建议或想法吗?
我的直觉是,应用于节点以最小化链接距离的迭代松弛也可以用于重新定位相同的节点以最小化链接交叉。
即使在每个 x 位置只有一个节点的情况下,我确实需要垂直“展开”节点,这样可以大大减少链接交叉(不需要是学术级别的)结果,一个实用的、比现在更好的结果就足够了)
Here是一个 JS Fiddle 作为起点 - 节点以次优方式定位,使得边/链接从一开始就交叉:
function getData() {
return {
"nodes": [{
"node": 0,
"name": "Name0"
}, {
"node": 1,
"name": "Name1"
}, {
"node": 2,
"name": "Action2"
}, {
"node": 3,
"name": "Name3"
}, {
"node": 4,
"name": "Name4"
}, {
"node": 5,
"name": "Action5"
}, {
"node": 6,
"name": "Action6"
}, {
"node": 7,
"name": "Action7"
}, {
"node": 8,
"name": "Action8"
}],
"links": [{
"source": 0,
"target": 6,
"value": 25,
"id": "name0"
}, {
"source": 1,
"target": 2,
"value": 25,
"id": "Name1"
}, {
"source": 2,
"target": 5,
"value": 25,
"id": "Name1"
}, {
"source": 3,
"target": 6,
"value": 25,
"id": "Name3"
}, {
"source": 6,
"target": 7,
"value": 25,
"id": "name0"
}, {
"source": 4,
"target": 7,
"value": 25,
"id": "Name4"
}, {
"source": 5,
"target": 7,
"value": 25,
"id": "Name1"
}, {
"source": 6,
"target": 7,
"value": 25,
"id": "Name3",
}, {
"source": 7,
"target": 8,
"value": 25,
"id": "Name3"
}]
};
}
最佳答案
所有这些都在 updated sample 中。
// load the data
var graph_zero = getData();
在每个频段添加中间节点以保持间距
var graph = rebuild(graph_zero.nodes, graph_zero.links)
以正常方式生成间距
sankey
.nodes(graph.nodes)
.links(graph.links)
.layout(32);
删除添加的中间节点
strip_intermediate(graph.nodes, graph.links)
并正常构建图表。这适用于提供的简单案例。
// From sankey, but keep indices as indices
// Populate the sourceLinks and targetLinks for each node.
// Also, if the source and target are not objects, assume they are indices.
function computeNodeLinks(nodes, links) {
nodes.forEach(function(node) {
node.sourceLinks = [];
node.targetLinks = [];
});
links.forEach(function(link) {
var source = link.source,
target = link.target;
nodes[source].sourceLinks.push(link);
nodes[target].targetLinks.push(link);
});
}
// computeNodeBreadths from sankey re-written to use indexes
// Iteratively assign the breadth (x-position) for each node.
// Nodes are assigned the maximum breadth of incoming neighbors plus one;
// nodes with no incoming links are assigned breadth zero, while
// nodes with no outgoing links are assigned the maximum breadth.
function computeNodeBreadths(nodes,links) {
var remainingNodes = nodes.map(function(d) { return d.node })
var nextNodes
var x = 0
while (remainingNodes.length) {
nextNodes = [];
remainingNodes.forEach(function(node) {
nodes[node].x = x;
nodes[node].sourceLinks.forEach(function(link) {
if (nextNodes.indexOf(link.target) < 0) {
nextNodes.push(link.target);
}
});
});
remainingNodes = nextNodes;
++x;
}
}
// Add nodes and links as needed
function rebuild(nodes, links) {
var temp_nodes = nodes.slice()
var temp_links = links.slice()
computeNodeLinks(temp_nodes, temp_links)
computeNodeBreadths(temp_nodes, temp_links)
for (var i = 0; i < temp_links.length; i++) {
var source = temp_links[i].source
var target = temp_links[i].target
var source_x = nodes[source].x
var target_x = nodes[target].x
var dx = target_x - source_x
// Put in intermediate steps
for (var j = dx; 1 < j; j--) {
var intermediate = nodes.length
nodes.push({
node: intermediate,
name: "intermediate"
})
links.push({
source: intermediate,
target: (j == dx ? target : intermediate-1),
value: links[i].value
})
links[i].target = intermediate
}
}
return {
nodes: nodes,
links: links
}
}
function strip_intermediate(nodes, links) {
for (var i = links.length-1; i >= 0; i--) {
var link = links[i]
if (link.original_target) {
var intermediate = nodes[link.last_leg_source]
link.target = nodes[link.original_target]
link.ty = intermediate.sourceLinks[0].ty
}
}
for (var i = links.length-1; i >= 0; i--) {
var link = links[i]
if (link.source.name == "intermediate") {
links.splice(i, 1)
}
}
for (var i = nodes.length-1; i >= 0; i--) {
if (nodes[i].name == "intermediate") {
nodes.splice(i, 1)
}
}
}
更新:为了进一步减少交叉,Using PQR-trees for reducing edge crossings in layered directed acyclic graphs可能会有所帮助。
关于d3.js - D3 Sankey 最小化链路交叉,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37302958/
我想使用单个(交叉)编译器来编译不同 ARM 调用约定的代码:因为我总是想使用浮点和 NEON 指令,所以我只想选择硬浮点调用约定或软浮点(softfp)调用约定。 我的编译器默认为硬浮点,但它支持我
假设我正在构建一个依赖于两个库的 java 应用程序:A 和 B。A 和 B 都依赖于库 C。管理 A 和 B 使用相同版本的最佳方法是什么所以他们不冲突?我正在使用 Gradle。 最佳答案 从 G
我想在按钮的文本上添加图像。如果我将图像添加为按钮的背景,它就会添加到文本下方。预期结果作为图像添加。请帮忙 更新:我需要以编程方式执行此操作。 最佳答案 在 XML 中, * 在代码中
我已经开始使用 CSS3 制作动画了。 我尝试创建一个动画汉堡菜单,但结果有点难看。顶部和底部的条向右平移一点。所以旋转动画不是很流畅和正确。 这是结果 => 这是我的代码: /* HTML */
给定一个具有2条相交曲线的图像,如下图所示,我如何使用opencv或python检测和区分2条曲线? (所以我需要2条单独的曲线) 最佳答案 您可以扫描每一列,并从连接的零件中识别出簇。 伪算法: l
我正在尝试在 redhat 集群(x86_64 主机)上设置 cross-mingw。我没有 root 访问权限,并且可用的 mingw 二进制文件不起作用(坏 glibc 版本等)。我正在阅读本教程
我正在尝试在javaFX中开发一个游戏,当两个图像相交时,分数将被更新,并且障碍物将不可见。但不幸的是,在游戏中分数不断更新。 我想我无法在游戏中正确地使图像不可见。 以下是相关类的完整代码: pac
pikastar dot com 是网站,当向下滚动它然后在导航菜单展开固定位置时它 > 将穿过主 div。我该如何修复它。 #topNav.sticky { box-shadow: 0 10
我正在使用 Eclipse为 ARM 处理器交叉编译 g++ 项目。我在 Windows 环境中使用 yagarto 工具链。我对 C 项目没有问题,但是对于 C++,我一直收到错误: libc.a(
我想从两个哈希数组中获取并集/交集/差集,例如: array1 = [{:name =>'Guy1', :age => 45},{:name =>'Guy2', :age => 45}] array2
有没有办法在调用任何 Controller 操作之前执行一些代码? 我需要根据 get 参数的值设置 session 变量,而不考虑调用哪个 Controller 。 当然,一旦这个处理完成,请求需要
我刚开始使用 3D 网格,面向用于有限元分析。我想在立方体状矩阵中模拟 Material 的夹杂物(任何形状,但主要对球体和椭圆体感兴趣)。这些夹杂物不应彼此重合。 所以我想为python使用某种包,
我想知道以跨平台方式操作应用程序设置的最佳解决方案是什么。 在 iOS 中,我们可以在设置屏幕中更改应用程序外部的设置,但在 windows phone 和 android 中我们没有。 所以,我的想
var barcodeNum = ko.observable(""); VelocityMeetings.scan = function (params) { var errorMessage = k
这个问题在这里已经有了答案: Transforming data.frame in R (2 个答案) 关闭10 年前。 过去我问过一个关于如何create cross tables from a
我有两个共享同一个工厂的 Controller 。其中一个 Controller 正在更新工厂变量。其他人应该注意该变化并稍后显示。 我是这样尝试的: http://plnkr.co/edit/q1N
标题不好,但这是我发现的将我的问题与简单的表格交叉区分开来的方式,因为我之前的研究总是让我接触到这类主题。 我有几个表 - 为了简化起见,我们只用 3 个表来命名它们:A、B、C。我想将它们全部放在一
我需要做这样的事情(在 MySQL 中),我使用 UNION 的尝试直到现在才奏效。 理论上: SELECT * FROM tableA A JOIN tableB B ON A.tableAId =
注意:使用SDL 2.0,Cross header class问题 我在类之间进行交叉引用,主要是我的类初始化渲染器和我的纹理类引用渲染初始化。现在,我已经能够运行该程序,直到我开始放入纹理类,代码也
我有一个这样的字母数组 var letters = ["Y", "X", "A", "Y", "O", "H", "A", "O", "O"]; 我创建了一个循环来
我是一名优秀的程序员,十分优秀!