Skip to content

Commit 9d037c5

Browse files
committed
feat:space saving
1 parent 51fbe06 commit 9d037c5

File tree

1 file changed

+85
-23
lines changed

1 file changed

+85
-23
lines changed

src/component/treeDiagram.vue

Lines changed: 85 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default {
1313
methods: {
1414
handleNodePosition() {
1515
this.$nextTick(() => {
16-
const nodePad = 0;
16+
const nodePad = 33;
1717
const levelPad = 33;
1818
const {
1919
list, PIDMap, ChildIDMap, levelID, maxLevel,
@@ -29,36 +29,98 @@ export default {
2929
});
3030
}
3131
};
32-
for (let level = maxLevel; level >= 0; level -= 1) {
33-
const thisLevelIDArr = levelID[level];
34-
let nodeToLeft = 0;
35-
let childPadLeft = 0;
36-
let thisLevelMaxHeight = 0;
37-
thisLevelIDArr.forEach((id) => {
38-
const {
32+
let scaleW = null;
33+
let scaleH = null;
34+
const getNodeSize = (id) => {
35+
if (!nodeStyleMap[id]) {
36+
let {
3937
width, height,
4038
} = this.$refs[`node-${id}`].getBoundingClientRect();
41-
thisLevelMaxHeight = Math.max(thisLevelMaxHeight, height);
39+
if (scaleW === null && width > 0 && height > 0) {
40+
const offsetW = this.$refs[`node-${id}`].offsetWidth;
41+
const offsetH = this.$refs[`node-${id}`].offsetHeight;
42+
scaleW = offsetW / width;
43+
scaleH = offsetH / height;
44+
}
45+
if (scaleW) {
46+
width *= scaleW;
47+
height *= scaleH;
48+
}
49+
nodeStyleMap[id] = { width, height };
50+
}
51+
return nodeStyleMap[id];
52+
};
53+
const getNodeOffsetWidth = (id) => {
54+
if (!nodeOffsetWidth[id]) {
4255
let thisNodeOffsetWidth = 0;
4356
if (ChildIDMap[id] && ChildIDMap[id].length) {
4457
ChildIDMap[id].forEach((cid) => {
45-
thisNodeOffsetWidth += nodeOffsetWidth[cid];
58+
thisNodeOffsetWidth += getNodeOffsetWidth(cid);
4659
});
47-
nodeOffsetWidth[id] = Math.max(width, thisNodeOffsetWidth);
48-
} else {
49-
thisNodeOffsetWidth = width;
60+
}
61+
nodeOffsetWidth[id] = Math.max(getNodeSize(id).width, thisNodeOffsetWidth);
62+
}
63+
return nodeOffsetWidth[id];
64+
};
65+
for (let level = maxLevel; level >= 0; level -= 1) {
66+
const thisLevelIDArr = levelID[level];
67+
let nodeToLeft = 0;
68+
let childPadLeft = 0;
69+
let thisLevelMaxHeight = 0;
70+
let spaceForPrey = 0;
71+
for (let levelIDIndex = 0; levelIDIndex < thisLevelIDArr.length; levelIDIndex += 1) {
72+
const id = thisLevelIDArr[levelIDIndex];
73+
const nextId = thisLevelIDArr[levelIDIndex + 1];
74+
const prevId = thisLevelIDArr[levelIDIndex - 1];
75+
const { width, height } = getNodeSize(id);
76+
thisLevelMaxHeight = Math.max(thisLevelMaxHeight, height);
77+
const thisNodeOffsetWidth = getNodeOffsetWidth(id);
78+
let preyPrevSpace = 0;
79+
let preyNextSpace = 0;
80+
if (!ChildIDMap[id] || ChildIDMap[id].length === 0) {
5081
childPadLeft += width + nodePad;
82+
spaceForPrey += width + nodePad;
83+
if (prevId !== undefined && ChildIDMap[prevId] && ChildIDMap[prevId].length) {
84+
const prevNodeOffsetWidth = getNodeOffsetWidth(prevId);
85+
const prevNodeWidth = getNodeSize(prevId).width;
86+
const space = (prevNodeOffsetWidth - prevNodeWidth) / 2;
87+
if (space > 0) {
88+
preyPrevSpace = Math.min(spaceForPrey, space);
89+
spaceForPrey -= preyPrevSpace;
90+
childPadLeft -= preyPrevSpace;
91+
nodeToLeft -= preyPrevSpace;
92+
}
93+
}
94+
if (spaceForPrey && nextId !== undefined && ChildIDMap[nextId] && ChildIDMap[nextId].length) {
95+
const nextNodeOffsetWidth = getNodeOffsetWidth(nextId);
96+
const nextNodeWidth = getNodeSize(nextId).width;
97+
const space = (nextNodeOffsetWidth - nextNodeWidth) / 2;
98+
if (space > 0) {
99+
preyNextSpace = Math.min(spaceForPrey, space);
100+
childPadLeft -= preyNextSpace;
101+
}
102+
spaceForPrey = 0;
103+
}
104+
nodeStyleMap[id].left = nodeToLeft;
105+
nodeToLeft += thisNodeOffsetWidth + nodePad - preyNextSpace;
106+
} else {
107+
doChildPadLeft(id, childPadLeft);
108+
const childIDArr = ChildIDMap[id];
109+
const lastChildInfo = getNodeSize(childIDArr[childIDArr.length - 1]);
110+
const childSpaceStart = getNodeSize(childIDArr[0]).left;
111+
const childSpaceEnd = lastChildInfo.left + lastChildInfo.width;
112+
const childSpace = childSpaceEnd - childSpaceStart;
113+
const gapSpace = Math.abs((childSpace - width) / 2)
114+
if (childSpace > width) {
115+
nodeStyleMap[id].left = childSpaceStart + gapSpace;
116+
nodeToLeft = childSpaceEnd;
117+
} else {
118+
nodeStyleMap[id].left = childSpaceStart - gapSpace;
119+
nodeToLeft += childSpaceEnd + gapSpace;
120+
}
51121
}
52-
nodeOffsetWidth[id] = thisNodeOffsetWidth;
53-
nodeStyleMap[id] = {
54-
top: 0,
55-
left: nodeToLeft + (thisNodeOffsetWidth - width) / 2,
56-
width,
57-
height,
58-
};
59-
nodeToLeft += thisNodeOffsetWidth + nodePad;
60-
doChildPadLeft(id, childPadLeft);
61-
});
122+
nodeStyleMap[id].top = 0;
123+
}
62124
levelMaxHeightMap[level] = thisLevelMaxHeight;
63125
}
64126
for (let level = 0, thisLevelToTop = 0; level <= maxLevel; level += 1) {

0 commit comments

Comments
 (0)