svg - 如何创建一个拖动和克隆网络 d3
问题描述
我正在尝试创建一个创建网络访问的区域。从这个区域,我想将一个节点拖放到另一个区域。我的当前代码有两个问题。
(1) 我有拖放工作,但不知道如何为网络 vis 创建一个容器,这样它就不会溢出到其他区域。
这是一个带有工作示例的可观察笔记本。在此示例中,网络包含不是一个大问题,因为它是一个小型网络,但我想知道如何为更大的网络创建一个容器。
(2) 另外,一个节点一旦被拖放,就不能再被拖放,这是为什么呢?
const w = 600, h = 600;
//Create SVG element
const svg = d3.select("body")
.append("svg")
.attr("id", "#network")
.attr("viewBox", [0, 0, w, h]);
svg
.append("rect") // Schema Box
.attr("id", "network")
.attr("width", w)
.attr("height", h / 4 * 3)
.attr("stroke", "black")
.attr("fill", "none");
let network = svg.append("g");
const scale = d3.scaleOrdinal(d3.schemeCategory10)
const colors = d => scale(d.group);
//SET UP MOTIF
let motifSVG = svg
.append("svg")
.attr("width", w)
.attr("height", h / 4);
let motifRect = motifSVG.append("rect")
.attr("id", "motif")
.attr("width", w)
.attr("height", h / 4)
motifRect
.attr("stroke", "black")
.attr("fill", "none")
.attr("transform", `translate(0, ${h - (h/4)})`);
d3.json("https://static.observableusercontent.com/files/a54fa5363b4035634b31bda01f902f2620a54a6366986631347558458e2484388de6575e5015e38bccc7db6637d87f80ad4ed7bdcab81ec3f31b75908a22a42d?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27miserables%2520(1).json").then((dataset) => {
const linksData = dataset.links
const nodesData = dataset.nodes
//Initialize a simple force layout, using the nodes and edges in dataset
const force = d3.forceSimulation(nodesData)
.force("charge", d3.forceManyBody())
.force("link", d3.forceLink(linksData).id(d => d.id))
.force("center", d3.forceCenter().x(w / 2).y(h / 2));
//Create edges as lines
var edges = network
.append("g")
.attr("class", "link")
.selectAll("line")
.data(linksData)
.enter()
.append("line")
.style("stroke", "#ccc")
.style("stroke-width", 1);
//Create nodes as circles
var nodes = network.selectAll("circle")
.data(nodesData)
.enter()
.append("circle")
.attr("r", 10)
.style("fill", colors)
.attr("id", d => d.id)
//Add a simple tooltip
nodes.append("title")
.text((d) => d.id);
nodes.call(
d3
.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended)
);
//Every time the simulation "ticks", this will be called
force.on("tick", function() {
edges.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;
});
nodes.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
});
});
function dragstarted(d) {
d3.select(this).clone()
d3.select(this).raise().attr("stroke", "black").classed("clone", true);
}
function dragged(d) {
d3.select(this)
.attr("cx", (d.x = d3.event.x))
.attr("cy", (d.y = d3.event.y));
}
function dragended(d) {
var mouseCoordinates = d3.mouse(this);
let networkHeight = d3.select("#network").attr("height");
if (mouseCoordinates[1] > networkHeight) {
d3.select(this)
.attr("r", 20);
} else {
d3.select(this).remove();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
解决方案
推荐阅读
- python - Python - Selenium 节点不启动 Chrome 浏览器
- json - 反转 JSON 文件
- c# - 如何在我的 DataGrid 中合并相同的值?
- javascript - this.canvas.call 不是函数(vue.js + d3.js)
- flutter - 如何替换下面的路线,以便我的导航器堆栈中没有重复的路线?
- python - anchor = link.find('a').get('href') AttributeError: 'NoneType' 对象没有属性 'get'
- javascript - 更新部分页面
- django - 使用 Django ORM 将已上传文件的路径修改为 S3
- sharepoint - SharePoint 内部部署到 SharePoint 在线迁移
- security - 如果用户单击取消按钮,为什么 pam_faildelay.so 不生效?