javascript - 如何通过单击力导向网络中的节点来更新外部条形图

标签 javascript layout event-handling protovis

我正在尝试通过单击力导向网络中的节点来更新条形图的内容。目前,我正在尝试将主面板上的“mousemove”事件与“点”事件一起使用,该事件更新变量 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();

最佳答案

这里有几个问题,但最基本的是概念性的——当您在可视化中声明标记的属性时,您可以使用一个值,例如:

.width(10)

或者一个函数,比如:

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

不同之处在于,每次您 render() vis(或 vis 的相关部分)时,都会重新评估第二个版本。因此,例如,您有:

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

关于javascript - 如何通过单击力导向网络中的节点来更新外部条形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5775721/

相关文章:

javascript - 将代码从 PHP 移动到 .js 文件,代码不起作用

javascript - NodeJS : Cannot read property 'hide' of undefined

javascript - 使用nodejs上传大文件

java - 如何将 JButton 放置在 JFrame 中的某个坐标处

android - AlertDialog EditText 不显示软键盘

java - 将文件放置在文件系统中应触发 java 应用程序

c# - 如何使用反射将事件处理程序附加到事件?

javascript - 在提交时更改目标页面的 css 属性

c# - 具有静态和动态内容的 WinForms UserControl 的最佳布局?

javascript - 为什么只有所有其他 HTML 元素对 "click"使用react?