- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是否可以为 d3 强制布局提供某种结构?我想展示员工和用户之间的关系,员工可以有很多用户。
然而,最初的布局虽然正确,但却难以理解。
红色轮廓的节点是员工,蓝色轮廓的是用户,理想情况下,让用户在员工下方会很好,如果存在的话,几乎处于强制层次结构布局中?
var width = document.querySelector('.visualisation').clientWidth,
height = 500;
var svg = d3.select(".visualisation").append("svg")
.attr("width", width)
.attr("height", height);
var force = d3.layout.force()
.gravity(.05)
.linkDistance(100)
.charge(-300)
.size([width, height]);
var sw = [],
su = [],
workbase = [],
links = [],
edges = [],
simplified = [];
d3.json("test_example.json", function(error, json) {
if (error) throw error;
console.log(json);
var users = [];
json.forEach(function(data){
if(data.workbase == "Cherry Tree Lodge") {
data.weight = 1;
links.push({
target : data.user_id,
source : data.staff_id,
});
users.push(data);
}
});
console.log(nodes);
// json.forEach(function(data) {
// console.log(json);
users.forEach(function(d) {
if(_.findWhere(sw, { name: d.staff_name}) == undefined) {
sw.push({
name : d.staff_name,
id : d.staff_id,
role : d.role,
weight:1,
type : "worker"
});
}
if(_.findWhere(su, { name: d.service_user}) == undefined) {
su.push({
name : d.service_user,
type : "user",
id : d.user_id,
weight:1
});
}
});
var nodes = sw.concat(su);
console.log(nodes);
nodes.forEach(function(data){
if(typeof data.linked_to != "undefined") {
links.push({
target: _.findIndex(nodes, function(user) {
return user.id == data.linked_to;
}),
source: data.id
});
}
});
console.log(links);
// //console.log(json);console.log(links)
links.forEach(function(e){
var sourceNode = nodes.filter(function(n) { return n.id === e.source})[0];
var targetNode = nodes.filter(function(n) { return n.id === e.target})[0];
edges.push({ source: sourceNode, target: targetNode });
});
console.log(edges);
// console.log(nodes);
force
.nodes(nodes)
.links(edges)
.on("tick", tick)
.start();
var link = svg.selectAll(".link")
.data(edges)
.enter().append("line")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);
// node.append("defs")
// .append("pattern")
// .attr("id", function(d){
// return "image-" + d.id;
// })
// .attr("height", 50)
// .attr("width", 50)
// .attr("x", 0)
// .attr("y", 0)
// .append("image")
// .attr("xlink:href", function(d) {
// return d.image;
// })
// .attr('height',60)
// .attr('width',60)
// .attr('x',0)
// .attr('y',0);
node.append("circle")
.attr("class", function(d){
return d.type;
})
.attr("r", 25);
// .on("mouseover", showDetails)
// .on("mouseout", removeDetails);
node.append("text")
.attr("x", 0)
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d){
//return d.name;
});
// // node.append("svg:a")
// // .attr("xlink:href", function(d){ return "" })
// // .append("text")
// // .attr("dx", 12)
// // .attr("dy", ".35em")
// // .text(function(d) { return d.name})
function tick(e) {
var k = 6 * e.alpha;
// Push sources up and targets down to form a weak tree.
link
.each(function(d) { d.source.y -= k, d.target.y += k; })
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}
});
最佳答案
您可以通过使用 d3.forceY()
设置沿 y 轴的位置来实现此目的。根据API :
Creates a new positioning force along the y-axis towards the given position y.
因此,我使用 type
创建了一个数组来指定用户和员工:
var nodes = [
{"id": 1, "name": "staff1", "type": "staff"},
{"id": 2, "name": "staff2", "type": "staff"},
{"id": 3, "name": "user1", "type": "user"},
{"id": 4, "name": "user2", "type": "user"},
{"id": 5, "name": "user3", "type": "user"},
{"id": 6, "name": "staff3", "type": "staff"},
{"id": 7, "name": "user4", "type": "user"},
{"id": 8, "name": "user5", "type": "user"},
{"id": 9, "name": "user6", "type": "user"},
{"id": 10, "name": "user7", "type": "user"},
{"id": 11, "name": "user8", "type": "user"},
{"id": 12, "name": "user19", "type": "user"}
];
然后,我使用类型
来设置位置:
var simulation = d3.forceSimulation()
.force('y', d3.forceY((d) => d.type === "staff" ? height/5 : 4*height/5).strength(2))
这是一个演示:
var nodes = [
{"id": 1, "name": "staff1", "type": "staff"},
{"id": 2, "name": "staff2", "type": "staff"},
{"id": 3, "name": "user1", "type": "user"},
{"id": 4, "name": "user2", "type": "user"},
{"id": 5, "name": "user3", "type": "user"},
{"id": 6, "name": "staff3", "type": "staff"},
{"id": 7, "name": "user4", "type": "user"},
{"id": 8, "name": "user5", "type": "user"},
{"id": 9, "name": "user6", "type": "user"},
{"id": 10, "name": "user7", "type": "user"},
{"id": 11, "name": "user8", "type": "user"},
{"id": 12, "name": "user19", "type": "user"}
];
var links = [
{source: 1, target: 8},
{source: 1, target: 3},
{source: 1, target: 4},
{source: 1, target: 9},
{source: 1, target: 10},
{source: 1, target: 11},
{source: 2, target: 5},
{source: 2, target: 6},
{source: 2, target: 7},
{source: 2, target: 12},
{source: 2, target: 4},
{source: 2, target: 8},
{source: 6, target: 7},
{source: 6, target: 8},
{source: 6, target: 9},
{source: 6, target: 5},
{source: 6, target: 3},
{source: 6, target: 9},
]
var index = 10;
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
node,
link;
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.id; }))
.force('y', d3.forceY((d) => d.type === "staff" ? height/5 : 4*height/5).strength(2))
.force("charge", d3.forceManyBody())
.force("collide", d3.forceCollide(30))
.force("center", d3.forceCenter(width / 2, height / 2));
update();
function update() {
link = svg.selectAll(".link")
.data(links, function(d) { return d.target.id; })
link = link.enter()
.append("line")
.attr("class", "link");
node = svg.selectAll(".node")
.data(nodes, function(d) { return d.id; })
node = node.enter()
.append("g")
.attr("class", "node")
.on("click", click)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
node.append("circle")
.attr("r", 6)
.attr("fill", (d)=> d.type === "user" ? "blue" : "red")
node.append("title")
.text(function(d) { return d.id; });
node.append("text")
.attr("dx", 10)
.text(function(d) { return d.name; });
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
}
function click(d) {
nodes.push({id: index, name: "server " + index});
links.push({source: d.id, target: index});
index++;
update();
}
function ticked() {
link
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node
.attr("transform", function(d) { return "translate(" + d.x + ", " + d.y + ")"; });
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart()
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = undefined;
d.fy = undefined;
}
.link {
stroke: #aaa;
}
.node {
pointer-events: all;
stroke: none;
stroke-width: 40px;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="400" height="400"></svg>
关于javascript - d3力布局初始结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40523107/
我为 S3 做了一个额外的布局(所有布局的反叛),人们说,使用 layout-sw320dp 对 s3 有好处。一切正常,s3 选择了这个文件夹,布局在 s3 上看起来很棒。 但是当我尝试在 10"平
我是 CSS 的新手,我正在尝试创建一个 3 列布局。也应该有一个居中的页脚。页面的总高度应该填满当前的屏幕。宽度似乎不对。 目前,页脚在尺寸和位置上似乎都没有对齐。 I have attached
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
有没有办法确定设备是从右到左的语言(比如阿拉伯语)而不是从左到右的语言(英语)? 需要与旧 API 级别(低至 10)兼容的东西 解决方案 我最终在接受的答案中使用了 xml 方法。更进一步,我还添加
我是 QT 的新手。我试图通过实现下面看到的这个小窗口来理解布局机制。它在作为主窗口的 QWidget 下具有以下元素: 一个延伸到所有客户区域的大型 QWidget。 窗口顶部的两个 QWidget
Accordion 布局是堆叠面板布局,因为此时只有一个面板可见,但我想同时显示两个面板可见,所以我们可以使用 Accordion 面板来做到这一点吗?? 最佳答案 您不能扩展现有的 Accordio
我只是想知道,作为一个假设示例,针对以下场景布局表格的最佳方式是什么: 假设我正在编写一个用于跟踪学生出勤的应用程序。每年年初,我都想添加所有学生(我将手动执行此操作 - 现在,是否应该为这里的每个学
在 CVS 中,我们的项目中有多个目录。 有一个夜间构建,它必须从同一个 CVS 项目的不同目录中提取东西才能构建夜间构建。所以我应该记住这一点,如果我们迁移到 SVN,我必须修改构建脚本以从不同的存
我在 WPF Windows 上有几个列表框,带有 Height="Auto" Width="Auto"在表格上设置 表单大小在不同分辨率下完美匹配,但问题是当我按下最大化按钮时,在表单调整大小时会看
仅供引用,我是 WPF 的新手。 我正在我的 WPF 应用程序中创建一个侧边栏并想要圆角。我学到的不是可以附加到网格的属性。另外,我尝试将文本块放在边框控件中,但我收到的错误消息说“ child 只能
我是CodeIgniter的新手。我想使用包含菜单,页脚等的基本样式创建母版页或布局。我不想在所有页面中编写重复的内容并为所有页面自动加载。例如,我可以在asp.net中创建母版页,或者在asp.ne
我正在使用它来调试应用程序。调试的时候发现底部显示了一个窗口中变量的值,如图- 但是,当我显示表达式时,我得到这样的布局 - 我的问题是,是否可以更改变量窗口的布局也可以在右侧显示值,因为这对我来说很
上面的代码中,放置“as=”footer_links”是什么意思? 最佳答案 as="x" 语法定义模板可用来调用 block 的名称。因此,对于以下内容: 在outer_block.p
我试图编写一个检查注册表值的功能,以查看Windows上的控制台是否启用了颜色。 Computer\HKEY_CURRENT_USER\Console\VirtualTerminalLevel 如果您
我有一个布局,但无法提前定义其所有区域,因为它们是未知的。 稍后创建了 ItemView,我想使用 View 的 ID 作为区域名称在布局中创建一个新区域,这样我就可以说: layout.dynami
我们有一个相当复杂的 gulp 构建过程,涉及多个模块,每个模块都有一个或两个 watch 。我想在一个仪表板中监控这一点,如下所示: 每一列都是一个模块,列内的每一行都是后续的构建步骤。一旦第 1
这就是问题所在,我有一个 MainWindow 类,它在一个设置例程中扩展了 JFrame,我将该类的布局设置为新的 CardLayout()。这一切都工作正常,但是当我从 JFrame 请求布局并将
我正在制作一个简单的迷宫程序,用户可以在其中创建墙壁、路径、起点和终点,单击“解决”,迷宫将被解决。为此,我有一个大小为 640x480 的 java JFrame。在 JFrame 的左侧,我有一个
我正在使用它来调试应用程序。调试的时候发现底部显示了一个窗口中变量的值,如图- 但是,当我显示表达式时,我得到这样的布局 - 我的问题是,是否可以更改变量窗口的布局也可以在右侧显示值,因为这对我来说很
我已经编写了使用 VBox 作为布局的代码。我希望按钮出现在顶行,然后绘制 2 条水平线,在 400x400 场景中应位于 y=200 和 300 处。但输出显示了我给出的不同坐标处的线条。 我知道这
我是一名优秀的程序员,十分优秀!