问题描述
My JsFiddle 使用优秀的 Dagre 动态创建网络图。完整代码如下,以满足发帖要求。
我的问题是,当我添加节点时,我无法让它自动缩放以使节点适合图形(的 SVG 画布)。
添加几个节点,然后...
嗯,经过一定程度的缩放后,可能会变得难以阅读,所以我想我应该在一定程度后限制缩放并将其留给用户滚动,而不是所有时间都可以看到所有图形( ?).
如果只有 Dagre 处理这个(和自动布局(我强烈希望将一个节点居中,将其锁定在中心并让其他节点出现在它周围 - 我不关心排序,但某种形式的权重,虽然不是绝对必要的,但不会伤害))。想,也许我使用了错误的库,但搜索,甚至 a quarion on S/W reccomendations 都没有帮助,而 Dagre 在其他方面非常出色。
好了,我离题了。以及如何让它自动缩放?
这是 HTML:
<!doctype html>
<headd>
<Meta charset="utf-8">
<title>Dynamic social network</title>
<link rel="stylesheet" href="style.css">
<script src="https://d3js.org/d3.v5.min.js" charset="utf-8"></script>
<script src="https://dagrejs.github.io/project/dagre-d3/latest/dagre-d3.js"></script>
</head>
<body>
<!-- based loosely on https://dagrejs.github.io/project/dagre-d3/latest/demo/clusters.html -->
<!-- docs at https://npmdoc.github.io/node-npmdoc-dagre/build/apidoc.html-->
<h1>Social network demo</h1>
<style id="css">
.clusters rect {
fill: whitesmoke;
stroke: #999;
stroke-width: 1.5px;
margin: auto;
}
text {
font-weight: 300;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serf;
font-size: 14px;
}
.node rect {
stroke: #999;
fill: #fff;
stroke-width: 1.5px;
}
.edgePath path {
stroke: #333;
stroke-width: 1.5px;
}
</style>
<a href="javascript:AddGroup()">Add a group</a>
<span> </span>
<a href="javascript:AddPerson()">Add a person (to a random group,at a random level)</a>
<br>
<br>
<svg id="svg-canvas" width=600 height=6000></svg>
<script id="js">
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
let forenames = [];
forenames.push("Michael");
forenames.push("David");
forenames.push("John");
forenames.push("James");
forenames.push("Robert");
forenames.push("Mark");
forenames.push("William");
forenames.push("Richard");
forenames.push("Thomas");
forenames.push("Jeffrey");
forenames.push("Steven");
forenames.push("Joseph");
forenames.push("Timothy");
forenames.push("Kevin");
forenames.push("Scott");
forenames.push("Brian");
forenames.push("Charles");
forenames.push("Paul");
forenames.push("Daniel");
forenames.push("Christopher");
forenames.push("Anthony");
forenames.push("Kenneth");
forenames.push("Gregory");
forenames.push("Ronald");
forenames.push("Donald");
forenames.push("Lisa");
forenames.push("Mary");
forenames.push("Susan");
forenames.push("Karen");
forenames.push("Margaret");
forenames.push("Patricia");
forenames.push("Linda");
forenames.push("Donna");
forenames.push("Michelle");
forenames.push("Cynthia");
forenames.push("Sandra");
forenames.push("Deborah");
forenames.push("Tammy");
forenames.push("Pamela");
forenames.push("Christine");
forenames.push("Laura");
forenames.push("Elizabeth");
forenames.push("Julie");
forenames.push("Brenda");
forenames.push("Jennifer");
forenames.push("Barbara");
forenames.push("Angela");
forenames.push("Sharon");
forenames.push("Debra");
forenames.push("Teresa");
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
let surnames = [];
surnames.push("Smith");
surnames.push("Jones");
surnames.push("Williams");
surnames.push("Taylor");
surnames.push("brown");
surnames.push("Davies");
surnames.push("Evans");
surnames.push("Wilson");
surnames.push("Thomas");
surnames.push("Johnson");
surnames.push("Roberts");
surnames.push("Robinson");
surnames.push("Thompson");
surnames.push("Wright");
surnames.push("Walker");
surnames.push("White");
surnames.push("Edwards");
surnames.push("Hughes");
surnames.push("Green");
surnames.push("Hall");
surnames.push("Lewis");
surnames.push("Harris");
surnames.push("Clarke");
surnames.push("Jackson");
surnames.push("Wood");
surnames.push("Turner");
surnames.push("Martin");
surnames.push("Cooper");
surnames.push("Hill");
surnames.push("Ward");
const initalNodeName = 'Hiro protaganist';
let groupNumber = 0;
let lastAddedGroupName = '';
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
function Rendergraph()
{
// Round the corners of the nodes
g.nodes().forEach(function(v) {
let node = g.node(v);
node.rx = node.ry = 5;
});
// Run the renderer. This is what draws the final graph.
render(d3.select("svg g"),g);
// Set up an SVG group so that we can translate the final graph.
let svg = d3.select("svg"),svgGroup = svg.append("g");
// Center the graph
let xCenterOffset = (svg.attr("width") - g.graph().width) / 2;
svgGroup.attr("transform","translate(" + xCenterOffset + ",20)");
svg.attr("height",g.graph().height + 40);
let selections = inner.selectAll("g.node");
selections
.on('mouSEOver',function(d) {
console.log('mouSEOver ' + d);
})
// .on('mouSEOut',function(d) {
// console.log('mouSEOut ' + d);
// })
// .on('mousedown',function(d) {
// console.log('mousedown ' + d);
// })
// .on('mouseup',function(d) {
// console.log('mouseup ' + d);
// })
.on('click',function (d) {
alert('You clicked "' + d + '"');
});
}
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
function AddGroup()
{
let groupName = 'Group_' + ++groupNumber;
lastAddedGroupName = groupName;
console.log('Added ' + groupName);
g.setNode(groupName,{ label: groupName,clusterLabelPos: 'bottom' });
Rendergraph();
}
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
function AddPerson()
{
let numChildrenInGroup = 0;
if (groupNumber === 0) // No groups,so create one,to add the new person to
{
AddGroup();
}
else
{
numChildrenInGroup = g.children(lastAddedGroupName).length;
// 1 chance in 4 to add a new group & switch to that
if ((Math.floor(Math.random() * 4) + 1) === 1)
{
AddGroup();
numChildrenInGroup = g.children(lastAddedGroupName).length;
}
else
{
if (numChildrenInGroup == 4)
{
AddGroup();
numChildrenInGroup = 0;
}
}
}
let forname = forenames[Math.floor(Math.random() * forenames.length)];
let suname = surnames[Math.floor(Math.random() * surnames.length)];
let name = forname + ' ' + suname;
let level = 1; // FixMe:
if (numChildrenInGroup > 0)
{
level = Math.floor(Math.random() * 2) + 1;
}
let borderColour = 'green';
if (level === 2)
borderColour = 'blue';
g.setNode(name,{label: name,style: 'stroke: ' + borderColour,level: level});
g.setParent(name,lastAddedGroupName);
g.setEdge(initalNodeName,name,{ arrowhead: 'undirected',label: level} );
console.log('Added ' + name);
Rendergraph();
} // AddPerson()
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
// Create the input graph
let g = new dagreD3.graphlib.Graph({compound:true})
.setGraph({})
.setDefaultEdgeLabel(function() { return {}; });
// Here we're setting the initial,central node
g.setNode(initalNodeName,{label: initalNodeName,style: 'stroke: red',level: 2});
// Create the renderer
let render = new dagreD3.render();
// // Set up an SVG group so that we can translate the final graph.
let svg = d3.select("svg"),inner = svg.append("g");
// Todo: Look at https://github.com/dagrejs/dagre-d3/issues/144
// // Set up zoom support
// let zoom = d3.behavior.zoom().on("zoom",function() {
// inner.attr("transform","translate(" + d3.event.translate + ")" +
// "scale(" + d3.event.scale + ")");
// });
// svg.call(zoom);
Rendergraph();
</script>
</body>
</html>
这里是 CSS:
body {
width: 960px;
margin: 0 auto;
color: #333;
font-weight: 300;
font-family: "Helvetica Neue",sans-serf;
}
h1 {
font-size: 3em;
font-weight: 300;
}
h2 {
font-size: 1.5em;
font-weight: 300;
}
section {
margin-bottom: 3em;
}
section p {
text-align: justify;
}
svg {
border: 1px solid #ccc;
overflow: hidden;
margin: 0 auto;
}
pre {
border: 1px solid #ccc;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)