Требования
1.Все сыновья должны быть выровнены по левому краю
2.Все дочери должны быть выровнены по правому краю
3.Вся семья каждого ребенка (ребенок → супруг → потомки) должна рассматриваться как один вертикальный блок
4.Когда семья первого сына заканчивается, семья второго сына начинается непосредственно под ним
5.Та же логика вертикального стекирования применяется к дочерним элементам
6.Родители подключаются к дочерним элементам через одну среднюю точку, а затем разветвляются к дочерним узлам Примечание. Я прикрепил эталонное изображение, показывающее ожидаемый результат. Что я пробовал
Я вычисляю позиции вручную, используя рекурсию и отслеживая смещения по оси Y.
Код ниже приведен минимальный воспроизводимый пример, демонстрирующий логику макета. Минимально воспроизводимый пример
[b]Требования[/b] 1.Все сыновья должны быть выровнены по левому краю 2.Все дочери должны быть выровнены по правому краю 3.Вся семья каждого ребенка (ребенок → супруг → потомки) должна рассматриваться как один вертикальный блок 4.Когда семья первого сына заканчивается, семья второго сына начинается непосредственно под ним 5.Та же логика вертикального стекирования применяется к дочерним элементам 6.Родители подключаются к дочерним элементам через одну среднюю точку, а затем разветвляются к дочерним узлам [b]Примечание.[/b] Я прикрепил эталонное изображение, показывающее ожидаемый результат. [b]Что я пробовал[/b] Я вычисляю позиции вручную, используя рекурсию и отслеживая смещения по оси Y. Код ниже приведен минимальный воспроизводимый пример, демонстрирующий логику макета. [b]Минимально воспроизводимый пример[/b] [code]
// calculate height of an entire family block function familyHeight(person) { let h = nodeH; if (person.children) { person.children.forEach(c => { h += familyHeight(c) + vGap; }); } return h; }
// recursive layout function layoutFamily(person, x, y, parentMid) { const node = { ...person, x, y }; nodes.push(node);
if (parentMid) { links.push({ x1: parentMid.x, y1: parentMid.y, x2: x, y2: y }); }
if (!person.children) return y + nodeH + vGap;
let cy = y + nodeH + vGap; person.children.forEach(child => { cy = layoutFamily(child, x, cy, { x, y }); });