0

作成したツリーマップがあります。今、私はホバーオーバーを適切に機能させようとしています。ユーザーがその特定の葉の上にカーソルを置いたときにのみ、各 treemap.leaf のテキストが表示されるようにします。

私はこの例に従おうとしましたが無駄でした http://mbostock.github.com/protovis/docs/interaction.html

私がこれまでに持っているコードは次のとおりです。

var json = {
    "sectors":{
        "electronics": { "Sony": 85, "AMD": 70, "Techtronics": 20, "Apple": 220, "Microsoft": 340},
        "automotive": {"Chevy": 43, "Audi":120, "BMW": 200}},
    "ids":{"Sony":72833,"AMD":582926,"Techtronics":839261, "Apple":822463, "Microsoft":242512, "Chevy":627363, "Audi":524362,"BMW":25143}   
};

var tree = json.sectors;
var ids = json.ids;

var nodes = pv.dom(tree).root("tree").nodes();
color = pv.Colors.category10().by(function(d){return  d.parentNode.nodeName});

var vis = new pv.Panel()
 .width(400)
 .height(400)
 .canvas("test");
var treemap = vis.add(pv.Layout.Treemap)
 .nodes(nodes)
 .round(true);  

treemap.leaf.add(pv.Panel)
 .def("active", false)
 .fillStyle(function(d) d.active ? "lightcoral" : color(d))
 .strokeStyle("#fff")
 .lineWidth(1)
 .antialias(false)
 .cursor("pointer")
 .event("mouseover", function(d) { return this.active(true)});

treemap.label.add(pv.Label)
 .visible(function() {return this.parent.children[0].active()})
 .textStyle(function(d) {return pv.rgb(0, 0, 0, 1)});

vis.render();
4

1 に答える 1

1

ここにはいくつかの問題があります。

  • .event()メソッドを使用し、渡す関数が のインスタンスを返す場合pv.Mark、Protovis はマークとその子を再レンダリングします。(ドキュメントは、再レンダリングしたいマークを返すという要件についてかなり不透明です。)

  • ツリーマップ レイアウト内では、ラベルはノードの子ではなく、レイアウトの子の別のグループです。そのため、ノードを更新すると、対応するラベルを再レンダリングすることはできません。

  • 次の行にタイプミスがあります。

    .fillStyle(function(d) d.active ? "lightcoral" : color(d))
    

    dインスタンスではなくデータです。そのはず:

    .fillStyle(function() this.active() ? "lightcoral" : color(d))
    

    しかし、上で述べたように、これはまだラベルを更新しません (そして、私はこれをあまりいじりませんでしたが、この行を修正するだけで、終わったノードだけでなく、すべてのノードが強調表示されるようです)。

したがって、これらすべてを修正するには、定義をノードではなく に設定する必要がactiveありtreemapます。true/false を使用する代わりに、アクティブ ノードのインデックスを設定し、同じインデックスを使用してラベルを参照できます。

var treemap = vis.add(pv.Layout.Treemap)
 .nodes(nodes)
 .round(true)
 // define the active node on the layout
 .def("active", -1);  

treemap.leaf.add(pv.Panel)
 .fillStyle(function(d) { 
     return treemap.active() == this.index ? "lightcoral" : color(d) 
 })
 // ...
 .event("mouseover", function() { 
     return treemap.active(this.index);
 })
 .event("mouseout", function() { 
     return treemap.active(-1);
 });

treemap.label.add(pv.Label)
 .visible(function() {
     return treemap.active() == this.index;
 });

ここで jsFiddle を使用します。

ここでの欠点は、毎回ツリーマップ全体を再レンダリングすることです。おそらく特定のノードとラベルのみを再レンダリングする方法があると思いますが、より複雑になるため、パフォーマンスが問題にならないようであれば気にしません。

于 2011-09-26T18:59:05.400 に答える