2016-09-30 4 views
1

NetworkXグラフをForce Layoutに変換するためのmpld3プラグインを作成中です。 Axesのズームがmpld3でどのように機能するのか、フォースレイアウトグラフに変換する方法を理解する上で問題があります。mpld3用NetworkX D3 Force Layout Plugin

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() 

上記は、私がノートブックで実行できる最小の実例です。私は現在、グラフを含むグループ要素にズームコールバックを追加していたので、ノードがマウスの場合はグラフがズームされます。カスタムツールバーのズームを使用すると、どのように機能するのですか。これは、強制レイアウトプラグインを作成する正しい方法ですか?私はまたhereを掲示したが、それは、この質問のためのよりよい場所であるかもしれないかもしれない。

+0

おっと、クール、私はいつもこれが欲しかった! 'zoom'オブジェクトは本当に複雑で、どうやって動作するのか覚えていません。 'ax'オブジェクトの中で、' ax.zoom'、 'ax.zoom_x'、' ax.zoom_y'のように見つけられます。私は彼らが何をしているのか覚えていればいいと思いますが、ここでjsコードを掘り起こすことにします:https://github.com/mpld3/mpld3/blob/73473c9ffd8ea36a1912244e664fdb7ce391fd8b/src/core/axes.js#L171 –

+0

ありがとう返信のために!私はコードを掘り始め、いくつかの壁に当っています。私はここで何が起こっているの良いアイデアを持っているコメントします。これはmpld3で持っていると良いでしょう:) – kdheepak

+0

私はバージョンが動作しているよ! :)アイロンをかけるためにもう少しキンクがあり、それは良いことでなければなりません。あなたはそれがメインのレポですべきだと思いますか?私は組織でユーザーが作成したプラグインレポを作成した方がいいと思う。思考? – kdheepak

答えて

0

類似のものを探している人のために、実例hereを投稿しました。

関連する問題