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 пересчёта, и баг со смещением корня исчезнет.


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.