【问题标题】:How to hide and restore custom nodes in InfoVis/JIT force directed graph?如何在 InfoVis/JIT 强制有向图中隐藏和恢复自定义节点?
【发布时间】:2013-01-19 23:16:52
【问题描述】:

我正在尝试使用 InfoVis / JIT 来呈现一个力导向图来可视化网络。 我是 java 脚本和 JIT 的新手。 我在我的 js 文件中使用以下代码创建了我自己的自定义节点类型,这让我可以在节点上显示我的图像。

$jit.ForceDirected.Plot.NodeTypes.implement({
    'icon1': { 
         'render': function(node, canvas){ 
                    var ctx = canvas.getCtx(); 
                    var img = new Image(); 
                    img.src='magnify.png'; 
                    var pos = node.pos.getc(true); 
                    img.onload = function() { 
                            ctx.drawImage(img, pos.x, pos.y); 
                    }; 

            }, 
            'contains': function(node,pos){ 
                    var npos = node.pos.getc(true); 
                    dim = node.getData('dim'); 
                    return this.nodeHelper.circle.contains(npos, pos, dim);
                    //return this.nodeHelper.square.contains(npos, pos, dim); 
            } 
     }

我在 json 数据对象中使用 "$type": "icon1" 将此自定义节点类型分配给节点。我确实在节点上获得了图像,但问题是我无法在需要时隐藏它。我可以使用以下代码隐藏内置节点类型,如圆形、方形等。

 node.setData('alpha', 0);
 node.eachAdjacency(function(adj) {
     adj.setData('alpha', 0);
 });
 fd.fx.animate({
     modes: ['node-property:alpha',
          'edge-property:alpha'],
     duration: 2000
 });

但相同的代码不适用于自定义节点。 因此,我尝试将节点类型临时更改为内置的“圆形”类型,将其隐​​藏,然后将节点类型重新设置为其原始类型,即我的自定义节点 icon1。

function hideNode( ){
  var typeOfNode = node.getData('type');
  node.setData( 'type','circle');
  node.setData('alpha', 0);
  node.eachAdjacency(function(adj) {
       adj.setData('alpha', 0);
  }); 
   fd.fx.animate({
          modes: ['node-property:alpha',
                  'edge-property:alpha'],
          duration: 2000
   });

   node.setData('type',typeOfNode );    
 }

我认为这应该可行,但自定义图像会在一段时间后在画布上返回。 如果我没有将节点的类型重置为其原始类型,即在上面的代码中并注释掉以下语句并调用隐藏函数,那么该节点将被隐藏。

  node.setData('type',typeOfNode );

我无法弄清楚如何通过仅将节点的类型设置为某种自定义类型来呈现节点。对此问题的任何帮助将不胜感激。

我需要将节点的类型重新设置为其原始类型,因为我希望在需要时通过调用取消隐藏函数来恢复节点。如果我不将节点的类型重置为原始类型,那么在恢复时它将呈现为一个圆圈。

我浏览了 JIT 的 API 和 google 组,但找不到答案。 有人可以帮忙吗?

【问题讨论】:

    标签: javascript graph html5-canvas infovis thejit


    【解决方案1】:

    下面是来自 Plot 的 plotNode 函数的 sn-p:

    var alpha = node.getData('alpha'),
        ctx = canvas.getCtx();
    ctx.save();
    ctx.globalAlpha = alpha;
    
    // snip
    
    this.nodeTypes[f].render.call(this, node, canvas, animating);
    ctx.restore();
    

    如您所见,节点的 alpha 值在调用节点的渲染函数之前立即应用于画布。渲染完节点后,画布恢复到之前的状态。

    这里的问题是您的自定义节点的render 函数没有同步渲染节点,并且在调用drawImage 之前画布状态正在恢复。因此,您可以做以下两件事之一:

    1) 预加载和缓存您的图像(首选方法,因为这也可以防止图像闪烁并有助于提高性能):

    // preload image
    var magnifyImg = new Image();
    magnifyImg.src = 'magnify.png';
    
    // 'icon1' node render function:
    'render': function(node, canvas){ 
        var ctx = canvas.getCtx(); 
        var pos = node.pos.getc(true); 
        ctx.drawImage(magnifyImg, pos.x, pos.y); 
    }
    

    2)保存画布状态,重新应用 alpha,然后在您的 onload 处理程序中绘制图像后恢复画布状态:

    // 'icon1' node render function:
    'render': function(node, canvas){ 
        var ctx = canvas.getCtx(); 
        var img = new Image(); 
        img.src='magnify.png'; 
        var pos = node.pos.getc(true); 
        img.onload = function() {
            ctx.save(); // save current canvas state
            ctx.globalAlpha = node.getData('alpha'); // apply node alpha
            ctx.drawImage(img, pos.x, pos.y); // draw image
            ctx.restore(); // revert to previous canvas state
        };
    }
    

    【讨论】:

    • 是的。两种选择都有效。感谢您的完美回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    • 1970-01-01
    • 2012-07-17
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多