0

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

これはうまくいくはずですが、カスタムイメージがしばらくするとキャンバスに戻ってきます。ノードのタイプを元のタイプにリセットしない場合、つまり上記のコードで次のステートメントをコメントアウトしてhide関数を呼び出すと、ノードは非表示になります。

  node.setData('type',typeOfNode );

ノードのタイプをカスタムタイプに設定するだけでは、ノードがどのようにレンダリングされるのか理解できません。この質問の助けをいただければ幸いです。

unhide関数を呼び出して必要なときにノードを復元したいので、ノードのタイプを元にリセットする必要があります。ノードのタイプを元にリセットしないと、復元時に円としてレンダリングされます。

APIとJITのGoogleグループを調べましたが、答えが見つかりませんでした。誰か助けてもらえますか?

4

1 に答える 1

1

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

ご覧のとおり、ノードのレンダリング関数が呼び出される直前に、ノードのアルファ値がキャンバスに適用されます。ノードをレンダリングした後、キャンバスは前の状態に復元されます。

ここでの問題は、カスタムノードのrender関数がノードを同期的にレンダリングせず、への呼び出しの前にキャンバスの状態が復元されていることdrawImageです。したがって、次の2つのいずれかを実行できます。

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)キャンバスの状態を保存し、アルファを再適用して、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
    };
}
于 2013-02-12T04:26:23.523 に答える