圆包装图 - 两组值之间的转换 [英] Circle-packing diagram - transition between two set of values

查看:186
本文介绍了圆包装图 - 两组值之间的转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常类似于。



这里是处理平滑圆包转换的整个代码(除了数据定义和按钮创建):

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

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

var circles = vis.append(circle)
.attr(stroke,black)
.style(fill,function returnd.children?tan:beige;})
.attr(cx,function(d){return dx;})
.attr d){return dy;})
.attr(r,function(d){return dr;});

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 dx;})
.attr(y,function(d){return dy;})
.text(function(d){return d.name +
(d.children?::+ format(d.value));});

circle.transition()
.duration(5000)
.attr(cx,function(d){return dx;})
.attr cy,function(d){return dy;})
.attr(r,function(d){return dr;});
};


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.

解决方案

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

这篇关于圆包装图 - 两组值之间的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆