<p>为了创建您想要的精确嵌套对象,我们将使用纯JavaScript和名为<a href="https://github.com/d3/d3-hierarchy#stratify" rel="noreferrer">^{<cd1>}</a>的D3方法的混合。但是,请记住,700万行(请参见下面的<em>post scriptum</em>)需要大量计算。在</p>
<p>值得一提的是,对于这个提议的解决方案,您必须<strong>在不同的数据数组中(例如,使用<code>Array.prototype.filter</code>)将王国</strong>分开。这种限制的发生是因为我们需要一个根节点,在林奈分类法中,王国之间没有任何关系(除非你创建一个顶级的<em>“Domain”</em>,这将是所有真核生物的根,但是对于古生菌和细菌,你会有同样的问题)。在</p>
<p>所以,假设您有这个CSV(我添加了一些行)和一个王国:</p>
<pre><code>RecordID,kingdom,phylum,class,order,family,genus,species
1,Animalia,Chordata,Mammalia,Primates,Hominidae,Homo,Homo sapiens
2,Animalia,Chordata,Mammalia,Carnivora,Canidae,Canis,Canis latrans
3,Animalia,Chordata,Mammalia,Cetacea,Delphinidae,Tursiops,Tursiops truncatus
1,Animalia,Chordata,Mammalia,Primates,Hominidae,Pan,Pan paniscus
</code></pre>
<p>基于这个CSV,我们将在这里创建一个名为<code>tableOfRelationships</code>的数组,顾名思义,它具有列组之间的关系:</p>
^{pr2}$
<p>对于上面的数据,这是<code>tableOfRelationships</code>:</p>
<pre><code>+---------+----------------------+---------------+
| (Index) | name | parent |
+---------+----------------------+---------------+
| 0 | "Animalia" | null |
| 1 | "Chordata" | "Animalia" |
| 2 | "Mammalia" | "Chordata" |
| 3 | "Primates" | "Mammalia" |
| 4 | "Hominidae" | "Primates" |
| 5 | "Homo" | "Hominidae" |
| 6 | "Homo sapiens" | "Homo" |
| 7 | "Carnivora" | "Mammalia" |
| 8 | "Canidae" | "Carnivora" |
| 9 | "Canis" | "Canidae" |
| 10 | "Canis latrans" | "Canis" |
| 11 | "Cetacea" | "Mammalia" |
| 12 | "Delphinidae" | "Cetacea" |
| 13 | "Tursiops" | "Delphinidae" |
| 14 | "Tursiops truncatus" | "Tursiops" |
| 15 | "Pan" | "Hominidae" |
| 16 | "Pan paniscus" | "Pan" |
+---------+----------------------+---------------+
</code></pre>
<p>请看一下<code>null</code>作为<code>Animalia</code>的父级:这就是为什么我告诉过您需要按王国来分隔数据集,整个表中只能有一个<code>null</code>值。在</p>
<p>最后,基于该表,我们使用<code>d3.stratify()</code>创建层次结构:</p>
<pre><code>const stratify = d3.stratify()
.id(function(d) { return d.name; })
.parentId(function(d) { return d.parent; });
const hierarchicalData = stratify(tableOfRelationships);
</code></pre>
<p>这是演示。打开浏览器的控制台(代码段的控制台不适合此任务),检查对象的几个级别(<code>children</code>):</p>
<p/><div^{cl1}$&13;
<div^{cl2}$&13;
<pre class="snippet-code-js lang-js prettyprint-override"><code>const csv = `RecordID,kingdom,phylum,class,order,family,genus,species
1,Animalia,Chordata,Mammalia,Primates,Hominidae,Homo,Homo sapiens
2,Animalia,Chordata,Mammalia,Carnivora,Canidae,Canis,Canis latrans
3,Animalia,Chordata,Mammalia,Cetacea,Delphinidae,Tursiops,Tursiops truncatus
1,Animalia,Chordata,Mammalia,Primates,Hominidae,Pan,Pan paniscus`;
const data = d3.csvParse(csv);
const taxonomicRanks = data.columns.filter(d => d !== "RecordID");
const tableOfRelationships = [];
data.forEach(row => {
taxonomicRanks.forEach((d, i) => {
if (!tableOfRelationships.find(e => e.name === row[d])) tableOfRelationships.push({
name: row[d],
parent: row[taxonomicRanks[i - 1]] || null
})
})
});
const stratify = d3.stratify()
.id(function(d) {
return d.name;
})
.parentId(function(d) {
return d.parent;
});
const hierarchicalData = stratify(tableOfRelationships);
console.log(hierarchicalData);</code></pre>
;
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script></code></pre>
;
</div>和13;
</div>和13;
<hr/>
<p><strong><em>PS</em></strong>:我不知道您将创建什么样的dataviz,但您确实应该避免分类级别。整个林奈分类法已经过时了,我们不再使用等级:因为系统发生系统学是在60年代中期发展起来的,我们只使用分类单元,没有任何分类等级(这里是进化生物学老师)。另外,我对这700万行很好奇,因为我们已经描述了100多万种物种!在</p>