D3でバンドルレイアウトを作ろうとしています。ただし、エッジノード間にギャップがないように、非階層化(または疑似非階層化)したいと考えています。下の画像は、削除したいギャップの良い例として役立つことを願っています (異なる色のテキストの間の画像の上部を参照してください)。
私はこの 2 つの方法で解決しようとしました。ノード タイプを区別するタイプを一般的なタイプに置き換えることと、ノード タイプを作成者の名前に置き換えることです (これにより、すべてのノードを異なるタイプにし、等間隔にすることを強制します)。これらの試みの前者は、このクエリに応じて提案された提案に似ています。
ただし、ラインを実行すると
var nodes = cluster.nodes(packageHierarchy(theArr, id_to_user_dict));
必然的に「Uncaught TypeError: Undefined のプロパティ 'parent' を読み取れません」というエラーが表示されます。コードが正しく機能するように、このデータにジェネリック ルートを強制するにはどうすればよいですか?
含まれている図のコード構造を生成するための私のコードは以下のとおりです。上記で提案した 2 つの解決策は、「パッケージ階層」機能内でコメント化されています。これは、 Bostock の階層的エッジ バンドリングのサンプルから派生したものであることに注意してください。
function packageHierarchy(classes, dictionary) {
for (var i = 0; i < classes.length; i++){
var imports = [];
// classes[i].name = "root" + "^" + classes[i]["author"];
// classes[i].name = classes[i]["author"] + "^" + classes[i]["author"];
classes[i].name = classes[i]["type"] + "^" + classes[i]["author"];
for (var j = 0; j < classes[i]["values"].length; j++){
if (classes[i]["values"][j]["type"] == "comments"){
var responseObj = classes[i]["values"][j]["in_response_to"];
var responseAuthor = dictionary[classes[i]["values"][j]["in_response_to"]];
if (responseAuthor != undefined){
imports.push(responseAuthor);
}
}
}
classes[i].imports = imports;
}
var map = {};
function find(name, data) {
var node = map[name], i;
if (!node) {
node = map[name] = data || {name: name, children: [] };
if (name.length) {
node.parent = find(name.substring(0, i = name.indexOf("^")));
node.parent.children.push(node);
node.key = name.substring(i + 1);
}
}
return node;
}
classes.forEach(function(d) {
find(d.name, d);
});
return map[""];
}