如何在 VEGA Api 中使用 D3 树数据?
How can I use D3 tree data in the VEGA Api?
我正在尝试使用 Vega 渲染 D3 树数据 API。
Vega Tree documentation 声明 Vega 使用 d3 树层次结构。这表明它应该是可能的。 Vega 页面甚至包含 D3 层次结构的 link,如下所示:
{
"name": "Eve",
"children": [
{
"name": "Cain"
},
{
"name": "Seth",
"children": [
{
"name": "Enos"
},
{
"name": "Noam"
}
]
},
{
"name": "Abel"
},
{
"name": "Awan",
"children": [
{
"name": "Enoch"
}
]
},
{
"name": "Azura"
}
]
}
但是直接在维加树图中使用这个是行不通的。
Vega's own tree example includes a data file that does work,但数据格式看起来完全不同。有没有办法将 D3 数据层次结构转换为 Vega 支持的格式? Vega 文档讨论了转换,但我找不到示例。
所需的 Vega 格式如下所示。它使用 ID 来知道父节点是谁,而不是嵌套数组。
[
{
"id": 1,
"name": "flare"
},
{
"id": 2,
"name": "analytics",
"parent": 1
},
{
"id": 3,
"name": "cluster",
"parent": 2
},
{
"id": 4,
"name": "AgglomerativeCluster",
"parent": 3,
"size": 3938
},
{
"id": 5,
"name": "CommunityStructure",
"parent": 3,
"size": 3812
}
如何在 Vega 中使用 D3 格式的树数据?
我没有在 Vega 上尝试过,但是你可以用一个小的辅助函数来转换层次结构,如下所示:
data = {
"name": "Eve",
"children": [
{
"name": "Cain"
},
{
"name": "Seth",
"children": [
{
"name": "Enos"
},
{
"name": "Noam"
}
]
},
{
"name": "Abel"
},
{
"name": "Awan",
"children": [
{
"name": "Enoch"
}
]
},
{
"name": "Azura"
}
]
};
console.log(flatten(data));
function flatten(hierarchy) {
let ar = [];
let i = 0;
let hierarchyWithID = d3.hierarchy(hierarchy).each(d => d.id = i++);
ar = hierarchyWithID.descendants().map(d => {
let obj = {};
obj.name = d.data.name;
obj.id = d.id;
if (d.parent) { obj.parent = d.parent.id;}
if (d.size) { obj.size = d.size;}
return obj;
});
return ar;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
或者,一个没有 d3.js 功能的版本(分配不同的 id):
data = {
"name": "Eve",
"children": [
{
"name": "Cain"
},
{
"name": "Seth",
"children": [
{
"name": "Enos"
},
{
"name": "Noam"
}
]
},
{
"name": "Abel"
},
{
"name": "Awan",
"children": [
{
"name": "Enoch"
}
]
},
{
"name": "Azura"
}
]
};
console.log(flatten2(data));
function flatten2(obj) {
let id = 0;
return _flatten2(obj);
function _flatten2(obj, ar = [], parentID = -1) {
let node = {};
node.id = id++;
node.name = obj.name;
if (parentID !== -1) { node.parent = parentID;}
if (obj.size) { node.size = obj.size;}
ar.push(node);
if (obj.children) {
for (let child of obj.children) {
_flatten2(child, ar, node.id);
}
}
return ar;
}
}
我正在尝试使用 Vega 渲染 D3 树数据 API。
Vega Tree documentation 声明 Vega 使用 d3 树层次结构。这表明它应该是可能的。 Vega 页面甚至包含 D3 层次结构的 link,如下所示:
{
"name": "Eve",
"children": [
{
"name": "Cain"
},
{
"name": "Seth",
"children": [
{
"name": "Enos"
},
{
"name": "Noam"
}
]
},
{
"name": "Abel"
},
{
"name": "Awan",
"children": [
{
"name": "Enoch"
}
]
},
{
"name": "Azura"
}
]
}
但是直接在维加树图中使用这个是行不通的。
Vega's own tree example includes a data file that does work,但数据格式看起来完全不同。有没有办法将 D3 数据层次结构转换为 Vega 支持的格式? Vega 文档讨论了转换,但我找不到示例。
所需的 Vega 格式如下所示。它使用 ID 来知道父节点是谁,而不是嵌套数组。
[
{
"id": 1,
"name": "flare"
},
{
"id": 2,
"name": "analytics",
"parent": 1
},
{
"id": 3,
"name": "cluster",
"parent": 2
},
{
"id": 4,
"name": "AgglomerativeCluster",
"parent": 3,
"size": 3938
},
{
"id": 5,
"name": "CommunityStructure",
"parent": 3,
"size": 3812
}
如何在 Vega 中使用 D3 格式的树数据?
我没有在 Vega 上尝试过,但是你可以用一个小的辅助函数来转换层次结构,如下所示:
data = {
"name": "Eve",
"children": [
{
"name": "Cain"
},
{
"name": "Seth",
"children": [
{
"name": "Enos"
},
{
"name": "Noam"
}
]
},
{
"name": "Abel"
},
{
"name": "Awan",
"children": [
{
"name": "Enoch"
}
]
},
{
"name": "Azura"
}
]
};
console.log(flatten(data));
function flatten(hierarchy) {
let ar = [];
let i = 0;
let hierarchyWithID = d3.hierarchy(hierarchy).each(d => d.id = i++);
ar = hierarchyWithID.descendants().map(d => {
let obj = {};
obj.name = d.data.name;
obj.id = d.id;
if (d.parent) { obj.parent = d.parent.id;}
if (d.size) { obj.size = d.size;}
return obj;
});
return ar;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
或者,一个没有 d3.js 功能的版本(分配不同的 id):
data = {
"name": "Eve",
"children": [
{
"name": "Cain"
},
{
"name": "Seth",
"children": [
{
"name": "Enos"
},
{
"name": "Noam"
}
]
},
{
"name": "Abel"
},
{
"name": "Awan",
"children": [
{
"name": "Enoch"
}
]
},
{
"name": "Azura"
}
]
};
console.log(flatten2(data));
function flatten2(obj) {
let id = 0;
return _flatten2(obj);
function _flatten2(obj, ar = [], parentID = -1) {
let node = {};
node.id = id++;
node.name = obj.name;
if (parentID !== -1) { node.parent = parentID;}
if (obj.size) { node.size = obj.size;}
ar.push(node);
if (obj.children) {
for (let child of obj.children) {
_flatten2(child, ar, node.id);
}
}
return ar;
}
}