Как реализовать ограничение по количеству отображаемых поколений вверх и вниз (ancestorDepthLimit) в генеалогическом древе?
Ограничение глубины отображаемых поколений (ancestorDepthLimit) в генеалогическом древе — это важная функция, позволяющая управлять объёмом отображаемых данных и производительностью интерфейса. Рассмотрим, как реализовать это на практике.
## Основная идея
Каждый узел дерева имеет ссылки на родителей (ancestors) и детей (descendants). При рендеринге нужно передавать текущую глубину и максимально допустимую, останавливая рекурсию при её достижении.
## Структура данных
Типичный узел генеалогического дерева:
js
{
id: 1,
name: «Иван Иванов»,
parents: [/* массив узлов */],
children: [/* массив узлов */]
}
## Алгоритм обхода с ограничением глубины
js
function buildTree(node, ancestorDepthLimit, descendantDepthLimit, currentAncestorDepth = 0, currentDescendantDepth = 0) {
const result = { id: node.id, name: node.name, parents: [], children: [] };
if (currentAncestorDepth
buildTree(parent, ancestorDepthLimit, descendantDepthLimit, currentAncestorDepth + 1, 0)
);
}
if (currentDescendantDepth
buildTree(child, ancestorDepthLimit, descendantDepthLimit, 0, currentDescendantDepth + 1)
);
}
return result;
}
Вызов: `buildTree(rootNode, 3, 2)` — отобразит 3 поколения вверх и 2 вниз.
## Визуальное скрытие vs. фильтрация данных
Есть два подхода:
1. **Фильтрация на уровне данных** — загружать с сервера только нужные узлы (экономит трафик и память).
2. **Скрытие на уровне UI** — загружать всё дерево, но отображать только нужные уровни (удобно для динамического изменения лимита без перезапросов).
Для больших деревьев рекомендуется первый подход с ленивой загрузкой (lazy loading).
## Реализация с динамическим изменением лимита
Если нужно давать пользователю возможность менять глубину «на лету»:
js
const [ancestorLimit, setAncestorLimit] = useState(3);
const [descendantLimit, setDescendantLimit] = useState(2);
const visibleTree = useMemo(
() => buildTree(rootNode, ancestorLimit, descendantLimit),
[rootNode, ancestorLimit, descendantLimit]
);
## Индикация скрытых узлов
Важно визуально показывать пользователю, что дерево не полное. Добавьте флаг `hasMoreAncestors` / `hasMoreDescendants` к узлам на граничной глубине и отображайте кнопку «Показать ещё».
## Советы по производительности
— Используйте мемоизацию для пересчёта дерева.
— При работе с большими базами данных добавляйте параметры `depth` в SQL-запросы (например, с помощью рекурсивных CTE).
— Кэшируйте результаты обхода на сервере.
Таким образом, реализация ancestorDepthLimit сводится к передаче счётчика глубины в рекурсивную функцию обхода и остановке рекурсии при достижении лимита.
