Để tạo đối tượng lồng nhau chính xác mà bạn muốn, chúng tôi sẽ sử dụng kết hợp JavaScript thuần túy và phương thức D3 có tên d3.stratify
. Tuy nhiên, có nhớ rằng 7 triệu hàng (xin vui lòng xem Scriptum bài dưới đây) là rất nhiều để tính toán.
Điều rất quan trọng là phải đề cập rằng, đối với giải pháp được đề xuất này, bạn sẽ phải tách Vương quốc trong các mảng dữ liệu khác nhau (ví dụ: bằng cách sử dụng Array.prototype.filter
). Hạn chế này xảy ra bởi vì chúng tôi cần một nút gốc và trong phân loại Linnaean, không có mối quan hệ nào giữa các Vương quốc (trừ khi bạn tạo "Miền" làm thứ hạng hàng đầu, sẽ là gốc cho tất cả các sinh vật nhân chuẩn, nhưng sau đó bạn sẽ có cùng vấn đề đối với Archaea và Vi khuẩn).
Vì vậy, giả sử bạn có CSV này (tôi đã thêm một số hàng) chỉ với một Vương quốc:
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
Dựa trên CSV đó, chúng tôi sẽ tạo một mảng ở đây có tên tableOfRelationships
, như tên ngụ ý, có mối quan hệ giữa các cấp bậc:
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
})
})
});
Đối với dữ liệu trên, đây là tableOfRelationships
:
+---------+----------------------+---------------+
| (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" |
+---------+----------------------+---------------+
Hãy xem null
như là cha mẹ của Animalia
: đó là lý do tại sao tôi nói với bạn rằng bạn cần tách dữ liệu của mình theo Kingdoms, chỉ có thể có một null
giá trị trong toàn bộ bảng.
Cuối cùng, dựa trên bảng đó, chúng tôi tạo cấu trúc phân cấp bằng cách sử dụng d3.stratify()
:
const stratify = d3.stratify()
.id(function(d) { return d.name; })
.parentId(function(d) { return d.parent; });
const hierarchicalData = stratify(tableOfRelationships);
Và đây là bản demo. Mở bảng điều khiển của trình duyệt của bạn (một đoạn mã không tốt cho nhiệm vụ này) và kiểm tra một số cấp độ ( children
) của đối tượng:
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);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Tái bút : Tôi không biết loại dataviz nào bạn sẽ tạo, nhưng bạn thực sự nên tránh xếp hạng phân loại. Toàn bộ phân loại Linnaean đã lỗi thời, chúng tôi không sử dụng các cấp bậc nữa: vì hệ thống phát sinh gen được phát triển vào giữa những năm 60, chúng tôi chỉ sử dụng phân loại, không có bất kỳ thứ hạng phân loại nào (giáo viên sinh học tiến hóa ở đây). Ngoài ra, tôi khá tò mò về 7 triệu hàng này, vì chúng tôi đã mô tả chỉ hơn 1 triệu loài!
nan
Phylum có chứa Magnoliopsida. Cái gìnan
vậy Phylum là Anthophyta hay còn gọi là Magnolia (đó là Phylum Angiospermae cũ).