Javascript NetworkX D3用于mpld3的强制布局插件
我正在创建一个mpld3插件,用于将NetworkX图形转换为Force布局。我在理解mpld3中轴上的缩放是如何工作的以及如何将其转换为力布局图时遇到了一些问题Javascript NetworkX D3用于mpld3的强制布局插件,javascript,python,d3.js,mpld3,Javascript,Python,D3.js,Mpld3,我正在创建一个mpld3插件,用于将NetworkX图形转换为Force布局。我在理解mpld3中轴上的缩放是如何工作的以及如何将其转换为力布局图时遇到了一些问题 import matplotlib import matplotlib.pyplot as plt import numpy as np import mpld3 from mpld3 import plugins, utils from networkx.readwrite.json_graph import node_link_
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import mpld3
from mpld3 import plugins, utils
from networkx.readwrite.json_graph import node_link_data
class NetworkXD3ForceLayoutView(plugins.PluginBase):
"""A simple plugin showing how multiple axes can be linked"""
JAVASCRIPT = """
mpld3.register_plugin("networkxd3forcelayoutview", NetworkXD3ForceLayoutViewPlugin);
NetworkXD3ForceLayoutViewPlugin.prototype = Object.create(mpld3.Plugin.prototype);
NetworkXD3ForceLayoutViewPlugin.prototype.constructor = NetworkXD3ForceLayoutViewPlugin;
NetworkXD3ForceLayoutViewPlugin.prototype.requiredProps = ["graph", "charge", "linkDistance", "gravity"];
function NetworkXD3ForceLayoutViewPlugin(fig, props){
mpld3.Plugin.call(this, fig, props);
};
var color = d3.scale.category20();
NetworkXD3ForceLayoutViewPlugin.prototype.draw = function(){
var zoom = d3.behavior.zoom();
var height = this.fig.height
var width = this.fig.width
var graph = this.props.graph
var gravity = this.props.gravity.toFixed()
var charge = this.props.charge.toFixed()
var linkDistance = this.props.linkDistance.toFixed()
console.log(graph)
var ax = this.fig.axes[0] // axis required for zoomx and zoomy presumably?
var g = d3.select('.mpld3-axes').append('g') // This is right?
var vis = g.append('svg')
.attr('width', this.width)
.attr('height', this.height);
force = d3.layout.force()
.gravity(gravity)
.charge(charge)
.linkDistance(linkDistance)
.nodes(graph.nodes)
.links(graph.links)
.size([width, height])
.start()
var link = vis.selectAll("line.link")
.data(graph.links)
.enter().append("svg:line")
.attr("class", "link")
.attr("stroke", "black")
.style("stroke-width", function(d) { return Math.sqrt(d.value); })
.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; });
var node = vis.selectAll("circle.node")
.data(graph.nodes)
.enter().append("svg:circle")
.attr("class", "node")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", 5)
.style("fill", function(d) { return d.color; })
.call(force.drag);
node.append("svg:title")
.text(function(d) { return d.name; });
vis.style("opacity", 1e-6)
.transition()
.duration(1000)
.style("opacity", 1);
force.on("tick", function() {
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("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
zoom.on("zoom", function() {
g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
})
g.call(zoom)
};
"""
def __init__(self, G, gravity=0.5, link_distance=20, charge=-10):
self.dict_ = {"type": "networkxd3forcelayoutview",
"graph": node_link_data(G),
"gravity": gravity,
"charge": charge,
"linkDistance": link_distance}
fig, ax = plt.subplots(1, 1)
# scatter periods and amplitudes
np.random.seed(0)
import networkx as nx
G=nx.Graph()
G.add_node(1, color='red')
G.add_edge(1,2)
plugins.connect(fig, NetworkXD3ForceLayoutView(G))
mpld3.display()
以上是我能够在笔记本上运行的一个最低限度的工作示例。我已经向当前包含图形的group元素添加了一个缩放回调,因此如果鼠标移动到节点上,图形将缩放。当我使用自定义工具栏上的缩放时,如何使其工作。这是创建force布局插件的正确方法吗?我也发过帖子,但这可能是一个更好的回答这个问题的地方。我发了一个工作示例,供任何搜索类似内容的人使用。哦,酷,我一直想要这个!缩放对象非常复杂,我不记得它们是如何工作的。您可以在
ax
对象中找到它们,如ax.zoom
、ax.zoom\u x
和ax.zoom\u y
。我希望我能更好地记住他们所做的事情,但是为了找到答案,我会在这里开始挖掘js代码:谢谢你的回复!我开始深入研究代码,我碰到了一些障碍。一旦我对正在发生的事情有了更好的了解,我会在这里发表评论。这将是很好的有这个在mpld3:)好的,我有一个版本的工作!:)还有几个弯折需要熨平,应该可以走了。你认为应该在主要回购协议中这样做吗?我认为如果我们在组织中创建一个用户创建的插件repo,那将是一件好事。想法?酷,我喜欢!以main repo为例,或者作为一个附加插件,这取决于它的复杂程度和通用性。我现在肯定会为一个示例提交一个pull请求,一旦它变得更加模块化,我会为插件提交另一个请求。谢谢你的帮助!仅链接答案应在答案正文中包含链接内容的相关摘要。该图也可用。感谢链接到该图。我想在我写了这篇博文之后,我把那个PR提交给了他们的例子。