TreeCanvas фикс: // fix root node displacement after layout recalculation. layoutCenterId must match actual root.
## Проблема: смещение корневого узла после пересчёта layout в TreeCanvas
При работе с компонентом TreeCanvas нередко возникает баг, при котором корневой узел (root node) визуально смещается после того, как происходит пересчёт раскладки (layout recalculation). Причина, как правило, одна: значение `layoutCenterId` не соответствует фактическому корневому узлу дерева.
### Почему возникает это несоответствие?
Когда TreeCanvas выполняет пересчёт позиций узлов, он использует `layoutCenterId` как опорную точку — «центр» дерева, относительно которого рассчитываются координаты всех остальных узлов. Если это значение устарело (например, дерево было перестроено, корень изменился, или узлы были добавлены/удалены), алгоритм позиционирует узлы относительно неверной точки. В результате реальный корень оказывается не там, где ожидается — он «уплывает» в сторону.
### Как исправить
**1. Синхронизация layoutCenterId с актуальным корнем**
После каждого пересчёта дерева или изменения его структуры необходимо явно обновлять `layoutCenterId`:
javascript
// После перестройки дерева
const actualRoot = tree.getRootNode();
layoutManager.layoutCenterId = actualRoot.id;
layoutManager.recalculate();
**2. Добавить проверку перед recalculate()**
Перед вызовом пересчёта всегда валидируйте, что `layoutCenterId` указывает на существующий и корневой узел:
javascript
function safeRecalculate(layoutManager, tree) {
const root = tree.getRootNode();
if (!root) {
console.error(‘Tree has no root node’);
return;
}
if (layoutManager.layoutCenterId !== root.id) {
console.warn(
`layoutCenterId mismatch: expected ${root.id}, got ${layoutManager.layoutCenterId}. Fixing…`
);
layoutManager.layoutCenterId = root.id;
}
layoutManager.recalculate();
}
**3. Подписаться на события изменения дерева**
Если дерево может изменяться динамически (например, через drag-and-drop или API), подпишитесь на события и автоматически обновляйте `layoutCenterId`:
javascript
tree.on(‘rootChanged’, (newRoot) => {
layoutManager.layoutCenterId = newRoot.id;
});
tree.on(‘nodesUpdated’, () => {
const root = tree.getRootNode();
if (root) layoutManager.layoutCenterId = root.id;
});
**4. Сброс смещения (offset) корневого узла**
Иногда помимо несоответствия `layoutCenterId` накапливается и визуальное смещение самого узла. После фикса стоит сбросить transform/offset корня:
javascript
const rootNode = tree.getRootNode();
rootNode.position = { x: 0, y: 0 }; // или canvas.centerNode(rootNode);
### Итог
Основное правило: `layoutCenterId` **всегда** должен отражать id актуального корневого узла на момент вызова пересчёта layout. Любое изменение структуры дерева — это триггер для обновления этого значения. Добавьте валидацию в pipeline пересчёта, и баг со смещением корня исчезнет.
