如何在InfoVis/JIT强制定向图中隐藏和恢复自定义节点



我正在尝试使用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 );

我不知道如何通过仅将节点的类型设置为某个自定义类型来渲染节点。如有任何帮助,我们将不胜感激。

我需要将节点的类型重新设置为其原始类型,因为我希望在需要时通过调用unhide函数来恢复节点。如果不将节点的类型重置为原始类型,则在恢复时会将其渲染为圆形。

我已经浏览了API和JIT的谷歌小组,但找不到答案。有人能帮忙吗?

下面是Plot的plotNode函数的一个片段:

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
    };
}

相关内容

  • 没有找到相关文章

最新更新