D3树形图调用导致NaN x0,x1,y0,y1值

时间:2017-02-11 06:17:47

标签: javascript d3.js

我正在构建一个D3 treemap可视化,而且我遇到了麻烦。

我已经能够填充我的初始树形图,但我想通过点击互动对其进行修改。为了做到这一点,我需要每次点击重新计算一个新的布局(然后再用它做一些事情),使用我之前(当前显示的)数据的子集来做到这一点。

我已经编写了sum函数,可以按照我的意愿运行,并填充value对象中每个Node的{​​{1}}属性。据我所知,这是在new_root上运行d3.treemap的唯一先决条件。这是代码片段:

new_root

填充let treemap = d3.treemap() .tile(d3.treemapResquarify) .size([800, 400]) .round(true) .paddingInner(1); // later... function object_is_direct_child(root, obj) { return (root.children.filter(child => (child.id === obj.name)).length > 0); } // ...much later... // Create and bind the click event. let click = function(d) { if (d.data.children.length > 0) { // Use the hover ID to get the underlying name attr (e.g. "Noise-hover" -> "Noise") let name = this.getAttribute("id").slice(0,-6); // Select the new root node. let new_root = root.children.find(c => c.id === name); // Sum. new_root = new_root.sum(node => ((object_is_direct_child(new_root, node)) ? node.n : 0)); // Here is the problem area. This doesn't work as expected. treemap(new_root); } } hover_rects.on("click", click); 及其所有子子的计算出的x0, x1, y0, y1值。相反,new_node及其所有孩子都是NaN。

我已经上传了我的要点,accessible here

1 个答案:

答案 0 :(得分:0)

我能够使用以下MWE脚本对其进行调试,在Node中运行:

'use strict';

// Load data.
const tree = require('../threshold-tree');
const d3 = require('d3');
const assert = require('assert');

// Load in the data file as it would be loaded in the browser.
const fs = require('fs');
const csvString = fs.readFileSync('data/complaint_types.csv').toString();
const raw_data = d3.csvParse(csvString);

let tr = new tree.ThresholdTree(raw_data);
let hr = tr.as_hierarchy();
let root = d3.stratify().id(d => d.name).parentId(d => d.parent)(hr);

function object_is_direct_child(root, obj) {
    return (root.children.filter(child => (child.id === obj.name)).length > 0);
}

// Now the sum function itself.
function nodal_summer(node) {
    return ((object_is_direct_child(root, node)) ? node.n : 0);
}

root = root.sum(nodal_summer);

// Create our treemap layout factory function.
let treemap = d3.treemap()
    .tile(d3.treemapResquarify)
    .size([800, 400])
    .round(true)
    .paddingInner(1);

// Apply our treemap function to our data.
debugger;
treemap(root);

// Again...this is where it fails!
let new_root = root.children[0];
new_root.parent = null;
new_root = new_root.sum(node => ((object_is_direct_child(new_root, node)) ? node.n : 0));

debugger;
new_root = treemap(new_root);
console.log(treemap(new_root));

罪魁祸首是positionNode内的d3回调:

  function positionNode(node) {
    var p = paddingStack[node.depth],
    ...

paddingStack被初始化为长度为1的列表,但node.depth1,因此p被初始化为NaN,从那里传播

两个有效的修复方法是:

  1. 使用node.copy()
  2. new_root.eachBefore(function(node) { node.depth--; })