圆形包装图 - 两组值之间的转换

时间:2013-12-28 11:34:11

标签: svg d3.js tooltip transition circle-pack

我的图表与circle packing

非常相似

在某些时候,用户想要查看一些不同的数据。显然,可以立即显示不同的图表,但从感知和认知的角度来看,过渡会更好。注意:层次结构保持不变,没有新的或删除的节点,只有确定圆周大小变化的基础值。

在相同结构但价值不同的两个圆包图之间实现平滑过渡的好方法是什么?

(当然,在过渡期间,可以说持续10秒,没有必要保持像原始图形一样的圆圈之间的关系,圆圈可以交叉并传递一个在另一个之上)

我知道treemaps有类似的解决方案。但是,它根本不能应用于圆形包装。树形图甚至还有一个特殊的功能sticky(),在这种情况下有帮助。

编辑:我正在附加新版jsfiddle

现在有些功能开始运作了。用随机数据驱动的转换非常漂亮。

此刻我有两个问题:

  1. 我不知道如何更新工具提示。这很重要,用户应该能够通过工具提示识别数据点。另一方面,好处是它们不需要在转换期间进行插值,突然改变就足够了,但我不知道该怎么做。
  2. 我真的不明白代码。编码主要是试错过程。如果有人验证代码是好的,或者可能不好,或者它可能不同,我将不胜感激。
  3. 编辑2:我解决了问题,如果有人需要代码,我会在答案中附上jsfiddle。欢迎大家对解决方案发表评论。

    enter image description here

    代码中最关键的部分似乎是:

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

    提前感谢任何帮助或提示。

1 个答案:

答案 0 :(得分:1)

看来我终于解决了所有问题。 jsfiddle是here

以下是处理平滑圆包布局转换的整个代码(数据定义和按钮创建除外):

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