【问题标题】:D3.js update Treemap dynamicallyD3.js 动态更新 Treemap
【发布时间】:2013-06-26 14:51:44
【问题描述】:

我想用新数据动态更新 Treemap。我已阅读此article,但我没有启动并运行它。所以这是我的代码:

function buildTreemap(jVals){
    //$("#treemap").empty();

    var data = jQuery.parseJSON(jVals);

    var margin = {top: 40, right: 10, bottom: 10, left: 10},
        width = 760 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

    var treemap = d3.layout.treemap()
        .size([width, height])
        .sticky(true)
        .sort(function(a,b) { return a.anzahl - b.anzahl; })
        .round(true)
        .value(function(d) { return Math.log(d.anzahl); });

    var div = d3.select("#treemap").append("div")
        .style("position", "relative")
        .style("width", (width + margin.left + margin.right) + "px")
        .style("height", (height + margin.top + margin.bottom) + "px")
        .style("left", margin.left + "px")
        .style("top", margin.top + "px")
        .attr("id", "first");

    var node = div.datum(data).selectAll(".node")
        .data(treemap.nodes)
        .enter().append("div")
        .attr("class", "node")
        .style("left", function(d) { return d.x + "px"; })
        .style("top", function(d) { return d.y + "px"; })
        .style("width", function(d) {  return Math.max(0, d.dx - 1) + "px"; })
        .style("height", function(d) { return Math.max(0, d.dy - 1) + "px"; })
        .style("background", function(d) { return d.color ? d.color : "#ffffff";})
        .text(function(d) { return d.children ? "blue" : d.keytable + "(" + d.anzahl + "-" + Math.max(0, d.dx) + "-" + Math.max(0, d.dy) + ")"; })
        ;

};

从另一个 Js-Function 我用新数据调用 buildTreemap()。现在我想用 Transition/Duration 重绘树形图。

谁能帮帮我。 非常感谢...

更新: 我已经添加了这个:

d3.selectAll("input").on("change", function change() {
        var value = this.value === "count"
            ? function() { return 1; }
            : function(d) { return Math.log(d.anzahl); };

        node
            .data(treemap.value(value).nodes)
            .transition()
            .duration(1500)
            .call(position);
    });

如果我单击“更改”-输入,则使用此代码将重建树形图。但如果我采用这段代码:

d3.selectAll("#search").on("keyup", function change() {
        var value = function(d) { return Math.log(d.anzahl); };

        node
            .data(treemap.value(value).nodes)
            .transition()
            .duration(1500)
            .call(position);
    });

树形图保持不变,另一个带有新数据值的树形图在我的第一个下方打开。在 keyup 时,另一个 js 函数被触发并将新数据发送到 buildTreemap()。

【问题讨论】:

  • 你见过this吗?
  • 是的,但这只会重新调整具有相同数据的 div 的大小。我需要重新调整新数据。
  • 原理是一样的。它仍在将新数据传递给更改时的树形图布局。
  • 嗯,请看我的更新。
  • 你能把你的完整代码贴在某个地方吗,最好是在 jsfiddle 上?没有完整的画面,很难看到发生了什么。

标签: d3.js treemap


【解决方案1】:

我已经稍微简化并修改了您的 jsfiddle here,以便在您单击按钮时显示第二组数据。关键是在单击按钮时调用的函数内部,您可以像初始化树形图时一样传入新数据,然后相应地处理输入和更新选择,如下所示:

var node = div.datum(data2).selectAll(".node")
          .data(treemap.nodes);
node.enter().append("div")
    .attr("class", "node");

node.transition().duration(1500).call(position)
    .style("background", function(d) { return d.color ? d.color : "#ffffff"; })
    .text(function(d) { return d.children ? "blue" : d.keytable + "(" + d.anzahl + "-" + Math.max(0, d.dx) + "-" + Math.max(0, d.dy) + ")"; });

请注意,输入选择合并到更新选择中,因此只需附加节点并在更新选择上设置属性就足够了。

【讨论】:

  • 好的非常好!但如果我采用更复杂的数据,行为就会很奇怪。看看这个:jsfiddle.net/maker23/WB5jh/4
  • 我认为旧节点保留在树形图中,新节点被推送...这样想?!!?!
  • 只需在更改函数末尾添加node.exit().remove()即可。
  • 针对您的其他问题,您似乎传递了格式错误的数据。
【解决方案2】:

我看不到任何错误的格式。

我的第一个数据是:

{
    "name": "items",
    "children": [
        {
            "id": "33447",
            "anzahl": "13",
            "color": "#ff8080",
            "keytable": "CCR",
            "bordercolor": "#B25959"
        },
        {
            "id": "33455",
            "anzahl": "4",
            "color": "#80ff80",
            "keytable": "COMMODITY",
            "bordercolor": "#59B259"
        },
        {
            "id": "2",
            "anzahl": "37",
            "color": "#80ffff",
            "keytable": "COUNTRY",
            "bordercolor": "#59B2B2"
        },
        {
            "id": "33465",
            "anzahl": "3",
            "color": "#ff0000",
            "keytable": "FUNDS",
            "bordercolor": "#B20000"
        },
        {
            "id": "67400",
            "anzahl": "22",
            "color": "#ffff00",
            "keytable": "GOVERNMENT",
            "bordercolor": "#B2B200"
        },
        {
            "id": "29",
            "anzahl": "183",
            "color": "#008080",
            "keytable": "INDEX",
            "bordercolor": "#005959"
        },
        {
            "id": "33449",
            "anzahl": "1",
            "color": "#8080ff",
            "keytable": "INTER",
            "bordercolor": "#5959B2"
        },
        {
            "id": "67422",
            "anzahl": "8",
            "color": "#800000",
            "keytable": "PARTY",
            "bordercolor": "#590000"
        },
        {
            "id": "33358",
            "anzahl": "4",
            "color": "#8000ff",
            "keytable": "PM",
            "bordercolor": "#5900B2"
        },
        {
            "id": "30",
            "anzahl": "1920",
            "color": "#f90631",
            "keytable": "SHARE",
            "bordercolor": "#AE0422"
        },
        {
            "id": "81",
            "anzahl": "70960",
            "color": "#11b1ee",
            "keytable": "WARRANT",
            "bordercolor": "#0B7BA6"
        },
        {
            "id": "1",
            "anzahl": "1",
            "color": "#004000",
            "keytable": "WORLD",
            "bordercolor": "#002C00"
        }
    ]
}

第二个数据是:

{
    "name": "items",
    "children": [
        {
            "id": "29",
            "anzahl": "12",
            "color": "#008080",
            "keytable": "INDEX",
            "bordercolor": "#005959"
        },
        {
            "id": "55645",
            "anzahl": "165",
            "color": "#11b1ee",
            "keytable": "WARRANT",
            "bordercolor": "#0B7BA6"
        }
    ]
}

好的,在控制台中它看起来不同......但为什么:

数据1:

Object {name: "items", children: Array[12]}
area: 333000
children: Array[12]
depth: 0
dx: 740
dy: 450
name: "items"
value: 39.15699051089851
x: 0
y: 0
__proto__: Object

数据2:

Object {name: "items", children: Array[2]}
children: Array[2]
name: "items"
__proto__: Object

但是孩子们也在里面……

更新:

我认为 data2 上的错误“Uncaught TypeError: Cannot read property 'children' of undefined”意味着其中一个数据集丢失。

在小提琴中,两个数据集都在函数中定义。但在我的实时示例中,数据集传递给函数。喜欢这个:

function buildTreemap(jVals_all, jVals_filtered, doRebuild){

if(doRebuild === false){
    var data1 = jQuery.parseJSON(jVals_all);
}
if(doRebuild === true){
    var data2 = jQuery.parseJSON(jVals_filtered);
}
....
}

那么如果我发送 data2 函数是否有可能因为 data1 为空而缺少 data1 的子项??

最后我只想将一个对象传递给函数...

function buildTreemap(data){}

如果这更容易解决,那么我会更喜欢这种方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-21
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多