3

サークルパッキングに非常によく似た図があります

ある時点で、ユーザーはいくつかの異なるデータを見たいと思っています。明らかに、別のダイアグラムをすぐに表示できますが、知覚と認識の観点からは、遷移の方がはるかに優れています。注: 階層構造は同じままです。新しいノードや削除されたノードはなく、円のサイズの変更を決定する基礎となる値のみです。

構造が同じで値が異なる2 つのサークル パック グラフ間でこのようなスムーズな遷移を実装するには、どのような方法がよいでしょうか?

(もちろん、遷移中、つまり 10 秒続くとします。元のグラフのように円間の関係を維持する必要はありません。円は交差して別の円を通過できます)

treemapsにも同様の解決策があることは知っています。ただし、サークルパッキンには一切適用できません。ツリーマップには、そのような場合に役立つ特別な関数 sticky() さえあります。

編集: jsfiddleの新しいバージョンを添付しています。

一部の機能が動作するようになりました。ランダムなデータで駆動されるトランジションは美しいです。

現時点で懸念事項が 2 つあります。

  1. ツールチップを更新する方法がわかりません。これは重要です。ユーザーはツールチップを介してデータ ポイントを識別できる必要があります。一方、移行中に補間する必要がないのは良いことです。突然の変更で十分ですが、その方法がわかりません。
  2. 私は本当にコードを理解していません。コーディングはほとんど試行錯誤のプロセスでした。誰かがコードが良いか、良くないか、または異なる可能性があることを確認していただければ幸いです。

EDIT 2:私は問題を解決し、誰かがコードを必要とする場合は答えに jsfiddle を添付しました。誰もが解決策についてコメントすることを歓迎します。

ここに画像の説明を入力

コードの最も重要な部分は次のようです。

function updateVis() {
    // change pack value
    if (updateMethod == 0)
        pack.value(function(d) { return d.size; });
    if (updateMethod == 1)
        pack.value(function(d) { return 100; });
    if (updateMethod == 2)
        pack.value(function(d) { return 1 + Math.floor(Math.random()*101); });

    var data1 = pack.nodes(data);

//    titles = ?????

    circles.transition()
        .duration(2000)
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; })
        .attr("r", function(d) { return d.r; });
    return;
};

ヘルプやヒントをお寄せいただきありがとうございます。

4

1 に答える 1

1

最終的にすべての問題を解決したようです。jsfiddle はこちらです。

サークル パックのレイアウト遷移をスムーズに処理するコード全体 (データ定義とボタン作成を除く) は次のとおりです。

var diameter = 500,
    format = d3.format(",d"),
    dataSource = 2;
var pack = d3.layout.pack()
    .size([diameter - 4, diameter - 4])
    .value(function(d) { return d.size; });
var svg = d3.select("body").append("svg")
    .attr("width", diameter)
    .attr("height", diameter);

var data = getData();

var vis = svg.datum(data).selectAll(".node")
    .data(pack.nodes)
   .enter()
    .append("g");

var titles = vis.append("title")
    .attr("x", function(d) { return d.x; })
    .attr("y", function(d) { return d.y; })
    .text(function(d) { return d.name +
        (d.children ? "" : ": " + format(d.value)); });

var circles = vis.append("circle")
    .attr("stroke", "black")
    .style("fill", function(d) { return !d.children ? "tan" : "beige"; })
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .attr("r", function(d) { return d.r; });

updateVis();

function updateVis() {

    if (dataSource == 0)
        pack.value(function(d) { return d.size; });
    if (dataSource == 1)
        pack.value(function(d) { return 100; });
    if (dataSource == 2)
        pack.value(function(d) { return 1 +
                 Math.floor(Math.random()*301); });

    var data1 = pack.nodes(data);

    titles.attr("x", function(d) { return d.x; })
        .attr("y", function(d) { return d.y; })
        .text(function(d) { return d.name +
            (d.children ? "" : ": " + format(d.value)); });

    circles.transition()
        .duration(5000)
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; })
        .attr("r", function(d) { return d.r; });
};
于 2013-12-29T08:54:19.870 に答える