Circle-packing diagram - transition between two set of values

☆樱花仙子☆ 提交于 2019-12-01 05:51:57

问题


I have a diagram very similar to circle packing

At some point, a user wants to see some different data. Obviously, a different diagram can be displayed immediately, but transition would be much better from perception and cognition point of view. NOTE: The hierarchical structure remains the same, there is no new or deleted nodes, just underlying values that determine circle size change.

What would be the good way to implement such smooth transition between two circle pack graphs of the same structure but different values?

(Of course, during transition, that lets say lasts 10 sec, there is no need to keep relation between circles like in original graph, circles can intersect and pass one over another)

I know there is similar solution for treemaps. However, it can't be applied on circle packing at all. Treemaps even have a special function sticky() that helps in such cases.

EDIT: I am attaching new version of jsfiddle.

Some functionality now started working. Transitions driven with random data are beautiful.

I have two concerns at this moment:

  1. I don't know how to update tooltips. This is important, user should be able to identify data points via tooltips. On teh other hand, good thing is they don't need to be interpolated during transition, abrupt change is sufficient, but I don't know how to do it.
  2. I really don't understand the code. Coding was mostly trial/error process. I would appreciate if somebody verifies the code is good, or maybe not good, or it could be different.

EDIT 2: I resolved problems, and attached jsfiddle in the answer if somebody needs the code. Everybody is still welcome to comment on solution.

Most critical part of the code, it seems is:

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

Thanks in advance for any help or hint.


回答1:


It looks that I finally resolved all issues. jsfiddle is here.

Here is the whole code (except data definition and button creation) that handles smooth circle pack layout transition:

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


来源:https://stackoverflow.com/questions/20814073/circle-packing-diagram-transition-between-two-set-of-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!