【问题标题】:D3 Zoomable Treemap changing the children accessorD3 可缩放树形图更改子访问器
【发布时间】:2013-06-28 18:29:18
【问题描述】:

我正在尝试使用 Mike Bostock 的可缩放树形图 http://bost.ocks.org/mike/treemap/ 进行一次修改。我没有使用嵌套的 JSON 数据,而是有一个从父级到子级列表的简单映射。我构建了一个函数 getChildren(root),它只返回 root 的孩子,如果 root 没有任何孩子,则返回 null。

我已尝试在树形图 javascript 文件中将 d.children() 的所有实例替换为 getChildren(d),但它似乎无法正常工作。

生成的页面在顶部正常显示橙色条,但没有其他内容正确显示(即橙色条下方没有矩形,只有空白的灰色空间)。孩子们的所有文字都混杂在空白灰色空间的左上角,因此可能是坐标分配不正确。

有什么想法吗?? 谢谢!

【问题讨论】:

  • 你能告诉我们你的代码和数据吗?
  • 看起来您正在尝试在那里同时做几件事,即自定义数据格式和自定义布局算法。先让一个工作,然后另一个工作可能更容易。

标签: d3.js treemap


【解决方案1】:

这里似乎有一些问题:

  • 您的数据结构似乎没有引用子节点:

    var nMap = {};
    nMap.papa = {};
    nMap.papa["children"] = [];
    nMap.papa["children"].push({
        "name": "c1"
    });
    // snip
    nMap.c1 = {
        size: 5
    };
    

    除非我遗漏了什么,否则您的 getChildren 函数会获取 { name: "c1" } 对象,但不会查找 nMap.c1。我不确定您的替代数据结构试图实现什么,但似乎最明显的选择是使用节点的平面图,其中子节点由 id 引用,如下所示:

    var nMap = {};
    nMap.c1 = {
        name: "c1",
        value: 5
    };
    nMap.c2 = {
        name: "c2",
        value: 5
    };
    nMap.c3 = {
        name: "c3",
        value: 5
    };
    nMap.papa = {
        name: "papa",
        children: ['c1', 'c2', 'c3']
    };
    

    通过这样的结构,您可以在getChildren 函数中映射到真正的孩子:

    function getChildren(par){
         var parName = par.name,
             childNames = parName in nMap && nMap[parName].children;
         if (childNames) {
             // look up real nodes
             return childNames.map(function(name) { return nMap[name]; });
         } 
    }
    
  • 您的孩子使用size 而不是value 来表示体重,其余代码应为value(所以他们都有体重0)。

  • 因为您使用的是“可缩放”树图方法,该方法使用树图布局的专用版本,所以您无需指定树图布局的 .children 访问器。相反,请在自定义 layout 帮助器中使用您的自定义访问器:

    function layout(d) {
        // get the children with your accessor
        var children = getChildren(d);
        if (children && children.length > 0) {
            treemap.nodes({ children: children });
            children.forEach(function(c) {
                c.x = d.x + c.x * d.dx;
                c.y = d.y + c.y * d.dy;
                c.dx *= d.dx;
                c.dy *= d.dy;
                c.parent = d;
                layout(c);
            });
        }
    }
    

在这里工作:http://jsfiddle.net/nrabinowitz/WpQCy/

【讨论】:

  • 谢谢!我试图在你的小提琴中制作一个孙子(“C31”),它的行为似乎和以前一样(所有名字都集中在左上角)。你会知道为什么会这样吗?
  • 得到了解决方案 :) 添加这一行来更改默认子访问器似乎可以解决问题 .children(function(d, depth) { return depth ? null : d.children; })跨度>
猜你喜欢
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
  • 2015-01-18
  • 1970-01-01
  • 2013-06-28
  • 1970-01-01
相关资源
最近更新 更多