2011-04-25 3 views
1

강제 지정 네트워크에서 노드를 클릭하여 막 대형 차트의 내용을 업데이트하려고합니다. 현재, 메인 패널에서 "mousemove"이벤트를 사용하여 변수 "activeNode"를 업데이트하는 "point"이벤트를 사용하여 어떤 행에 액세스하려고하는지 알려줍니다. 메인 패널의 포인트 이벤트가 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이고 econd 버전은 vis (또는 vis의 관련된 부분) render() 때마다 재평가 될 것이다. 예를 들어, 가지고있는 곳 :

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

이것은 vis가 렌더링 된 최초의 시간에만 평가됩니다. 그래서 수정 된 코드가 (난 당신이 참조하는 topw 데이터에 액세스 할 수 없습니다 때문에 내가 바는 조금 차트 변경) 다음과 같을 수

// 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') 
    }); 

: 대신, 당신은 기능을 필요

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

감사합니다 - 당신은 더 많은 또는 덜 protovis 마스터 그래서 나는이 질문들을 많이 보았다. – shigeta

+0

@shigeta - 나는 다른 Protovis 질문에 대한 답변을 얻기 위해 당신의 뻔뻔한 노력을 보았습니다 :). 명백하게 그것은 효과가있었습니다 - 아첨에 하나를 얻으십시오. – nrabinowitz

관련 문제