2011-04-25 29 views
1

我試圖通過單擊強制定向網絡中的節點來更新條形圖的內容。目前,我試圖在主面板上使用「點」事件來更新變量activeNode,然後通知我希望訪問的行。我遇到麻煩的事實是,我的主面板中的點事件沒有更新activeNode並始終將其設置爲默認值。試圖尋找解決這個問題的地方,但我想我錯過了一些更基本的概念。如何通過單擊強制定向網絡中的節點更新外部條形圖

這裏是代碼...

var w = document.body.clientWidth, 
    h = document.body.clientHeight, 
    colors = pv.Colors.category19(), 
    activeNode = 0; 

var vis = new pv.Panel() 
    .width(w) 
    .height(h) 
    .fillStyle("white") 
    .event("mousemove", pv.Behavior.point(Infinity)); 

var force = vis.add(pv.Layout.Force) 
    .width(w-200) 
    .nodes(miserables.nodes) 
    .links(miserables.links); 

force.link.add(pv.Line); 

force.node.add(pv.Dot) 
    .def("o",-1) 
    .size(function(d) (d.linkDegree + 10) * Math.pow(this.scale, -1.5)) 
    .fillStyle(function(d) d.fix ? "brown" : colors(d.group)) 
    .strokeStyle(function() this.fillStyle().darker()) 
    .lineWidth(1) 
    .title(function(d) this.index) 
    .event("mousedown", pv.Behavior.drag()) 
    .event("drag", force) 
    .event("point", function() {activeNode = this.index; return vis;}); 

vis.add(pv.Label).top(20).left(w/2).text("activeNode = " + activeNode); 

vis.add(pv.Bar) 
    .data(topw[activeNode].splice(0)) 
    .top(function(d) this.index * 30) 
    .left(w-80) 
    .width(15) 
    .height(20) 
    .anchor("left").add(pv.Label) 
     .textAlign("right")  
     .text(function(d) d[0]); 

vis.render(); 

回答

2

有幾個問題在這裏,但基本是一個概念 - 當你在聲明可視化,您可以使用上標記屬性的值,如:

.width(10) 

或功能,如:

.width(function() { return 10; }) 

不同之處在於在S第二版本將在您每次登錄時(或相關部分)重新評估。因此,例如,你有:

vis.add(pv.Label).top(20).left(w/2).text("activeNode = " + activeNode); 

這隻會在第一次評估vis時進行評估。相反,你需要一個函數:

// assign the label to a variable, so we can refer to it later 
// this is easiest if we define the label and bar first 
var nodeLabel = vis.add(pv.Label) 
    .top(20) 
    .left(w/2) 
    .textAlign("right") // easier for my bar layout 
    // note that this has to be a function, so that it will be 
    // re-evaluated on re-render 
    .text(function() { 
     return "activeNode = " + (activeNode ? activeNode.nodeName : 'None') 
    }); 

所以你的更正後的代碼可能是這樣的(我改變了條形圖了一下,因爲我沒有訪問您引用topw數據):

var w = document.body.clientWidth, 
    h = document.body.clientHeight, 
    colors = pv.Colors.category19(), 
    activeNode = null; 

var vis = new pv.Panel() 
    .width(w) 
    .height(h) 
    .fillStyle("white") 
    .event("mousemove", pv.Behavior.point(Infinity)); 

// assign the label to a variable, so we can refer to it later 
// this is easiest if we define the label and bar first 
var nodeLabel = vis.add(pv.Label) 
    .top(20) 
    .left(w/2) 
    .textAlign("right") // easier for my bar layout 
    // note that this has to be a function, so that it will be 
    // re-evaluated on re-render 
    .text(function() { 
     return "activeNode = " + (activeNode ? activeNode.nodeName : 'None') 
    }); 

// again, assign the bar to a variable 
// I think I'm missing some data for your example, so 
// I made a single bar to show node degree 
// (only one data point, so no .data() needed) 
var nodeBar = vis.add(pv.Bar) 
    .top(0) 
    .left(w/2) 
    .height(20) 
    .width(function() { 
     // make a scale based on all nodes 
     var scale = pv.Scale.linear(
      // get the max link degree to be the upper limit of the scale 
      0, pv.max(miserables.nodes, function(d) { return d.linkDegree; }) 
     ).range(0, 200); 
     // return a value based on the active node 
     return activeNode ? scale(activeNode.linkDegree) : 0; 
    }); 

var force = vis.add(pv.Layout.Force) 
    .width(w-200) 
    .nodes(miserables.nodes) 
    .links(miserables.links); 

force.link.add(pv.Line); 

force.node.add(pv.Dot) 
    .def("o",-1) 
    .size(function(d) (d.linkDegree + 10) * Math.pow(this.scale, -1.5)) 
    .fillStyle(function(d) d.fix ? "brown" : colors(d.group)) 
    .strokeStyle(function() this.fillStyle().darker()) 
    .lineWidth(1) 
    .title(function(d) this.index) 
    .event("mousedown", pv.Behavior.drag()) 
    .event("drag", force) 
    .event("point", function(d) { 
     // set the global variable to point to the current node 
     activeNode = d; 
     // re-render the label 
     nodeLabel.render(); 
     // re-render the bar 
     nodeBar.render(); 
    }); 

vis.render(); 
+0

謝謝 - 你們或多或少都是原初大師我在很多這些問題上看到你。 – shigeta 2011-07-09 04:50:05

+0

@shigeta - 我看到你無恥的努力讓我回答你的其他Protovis問題:)。顯然它有效 - 爲奉承獲得一分。 – nrabinowitz 2011-07-09 14:59:33

相關問題