let nodeList = [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 },
{ id: 6 },
{ id: 7 },
{ id: 8 },
{ id: 9 },
{ id: 10 },
{ id: 11 },
{ id: 12 },
{ id: 13 },
];
let linkList = [
{ source: 1, target: 2 },
{ source: 1, target: 8 },
{ source: 2, target: 3 },
{ source: 3, target: 4 },
{ source: 3, target: 5 },
{ source: 3, target: 6 },
{ source: 4, target: 7 },
{ source: 5, target: 7 },
{ source: 6, target: 7 },
{ source: 8, target: 9 },
{ source: 8, target: 12 },
{ source: 9, target: 10 },
{ source: 12, target: 13 },
{ source: 10, target: 11 },
{ source: 13, target: 11 },
]
let linkMap = {};
for (let i = 0; i < linkList.length; i++) {
const source = linkList[i].source;
const target = linkList[i].target;
if (linkMap[source]) {
linkMap[source].push(target);
} else {
linkMap[source] = [target]
}
if (linkMap[target]) {
linkMap[target].push(source);
} else {
linkMap[target] = [source]
}
}
let rootId = 1;
let tree = { id: 1, children: [], level: 0 }
let sameLevelNodeListMap = {
0: [tree]
};
let queue = [tree];
let visited = new Set([tree.id]);
while(queue.length > 0) {
let queueHead = queue.shift();
let queueHeadId = queueHead.id;
let adjIdList1 = linkList.filter(item => item.source === queueHeadId).map(item => item.target);
let adjIdList2 = linkList.filter(item => item.target === queueHeadId).map(item => item.source);
// let adjIdList = [...adjIdList1, ...adjIdList2];
let adjIdList = linkMap[queueHeadId];
for (let i = 0; i < adjIdList.length; i++) {
const adjId = adjIdList[i];
if (!visited.has(adjId)) {
visited.add(adjId);
let tempChild = {
id: adjId,
children: [],
level: queueHead.level + 1
};
queueHead.children.push(tempChild);
queue.push(tempChild);
if (!sameLevelNodeListMap[queueHead.level + 1]) {
sameLevelNodeListMap[queueHead.level + 1] = [tempChild]
} else {
sameLevelNodeListMap[queueHead.level + 1].push(tempChild)
}
}
}
}
console.log(tree);
console.log(sameLevelNodeListMap);
// miji
let maxBlood = 1;
tree.blood = 1;
queue = [tree];
while(queue.length > 0) {
let queueHead = queue.shift();
let childrenList = queueHead.children;
let childBlood = queueHead.blood * childrenList.length;
for (let i = 0; i < childrenList.length; i++) {
const child = childrenList[i];
child.blood = childBlood;
maxBlood = Math.max(maxBlood, childBlood);
queue.push(child);
}
}
console.log(tree);
tree.yArea = maxBlood * tree.blood;
tree.x = tree.level;
tree.y = 0;
queue = [tree];
while(queue.length > 0) {
let queueHead = queue.shift();
let childrenList = queueHead.children;
// // 推恩令
if (childrenList.length === 1) {
let onlyChild = childrenList[0];
let prevNodeList = sameLevelNodeListMap[onlyChild.level - 1];
let parentNodeList = prevNodeList.filter(item => linkMap[onlyChild.id].includes(item.id));
let sumY = parentNodeList.reduce((total, curNode) => total + curNode.y, 0);
let sumBlood = parentNodeList.reduce((total, curNode) => total + 1 / curNode.blood, 0);
onlyChild.yArea = maxBlood * sumBlood;
onlyChild.x = onlyChild.level;
onlyChild.y = sumY / parentNodeList.length;
queue.push(onlyChild);
} else {
let yUnit = queueHead.yArea / (childrenList.length + 1);
let yStart = queueHead.y + queueHead.yArea / 2;
for (let i = 0; i < childrenList.length; i++) {
const child = childrenList[i];
child.yArea = maxBlood * (queueHead.blood / childrenList.length);
child.x = child.level;
child.y = yStart - yUnit * ( i + 1);
queue.push(child);
}
}
}
console.log(sameLevelNodeListMap);
for (const level in sameLevelNodeListMap) {
if (Object.prototype.hasOwnProperty.call(sameLevelNodeListMap, level)) {
sameLevelNodeListMap[level].forEach(element => {
document.getElementById(`item_${element.id}`).style.left = element.x * 100 + 500 + 'px'
document.getElementById(`item_${element.id}`).style.top = element.y * 100 + 500 + 'px'
})
}
}
布局
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- <font color = #FF8C00>1.computer architecture</font> 1.1w...