function updateNode()

in src/chart/tree/TreeView.ts [367:518]


function updateNode(
    data: SeriesData,
    dataIndex: number,
    symbolEl: TreeSymbol,
    group: graphic.Group,
    seriesModel: TreeSeriesModel
) {
    const isInit = !symbolEl;
    const node = data.tree.getNodeByDataIndex(dataIndex);
    const itemModel = node.getModel<TreeSeriesNodeItemOption>();
    const visualColor = (node.getVisual('style') as PathStyleProps).fill;
    const symbolInnerColor = node.isExpand === false && node.children.length !== 0
            ? visualColor : '#fff';

    const virtualRoot = data.tree.root;

    const source = node.parentNode === virtualRoot ? node : node.parentNode || node;
    const sourceSymbolEl = data.getItemGraphicEl(source.dataIndex) as TreeSymbol;
    const sourceLayout = source.getLayout() as TreeNodeLayout;
    const sourceOldLayout = sourceSymbolEl
        ? {
            x: sourceSymbolEl.__oldX,
            y: sourceSymbolEl.__oldY,
            rawX: sourceSymbolEl.__radialOldRawX,
            rawY: sourceSymbolEl.__radialOldRawY
        }
        : sourceLayout;
    const targetLayout = node.getLayout();

    if (isInit) {
        symbolEl = new SymbolClz(data, dataIndex, null, {
            symbolInnerColor,
            useNameLabel: true
        }) as TreeSymbol;
        symbolEl.x = sourceOldLayout.x;
        symbolEl.y = sourceOldLayout.y;
    }
    else {
        symbolEl.updateData(data, dataIndex, null, {
            symbolInnerColor,
            useNameLabel: true
        });
    }

    symbolEl.__radialOldRawX = symbolEl.__radialRawX;
    symbolEl.__radialOldRawY = symbolEl.__radialRawY;
    symbolEl.__radialRawX = targetLayout.rawX;
    symbolEl.__radialRawY = targetLayout.rawY;

    group.add(symbolEl);
    data.setItemGraphicEl(dataIndex, symbolEl);

    symbolEl.__oldX = symbolEl.x;
    symbolEl.__oldY = symbolEl.y;

    graphic.updateProps(symbolEl, {
        x: targetLayout.x,
        y: targetLayout.y
    }, seriesModel);

    const symbolPath = symbolEl.getSymbolPath();

    if (seriesModel.get('layout') === 'radial') {
        const realRoot = virtualRoot.children[0];
        const rootLayout = realRoot.getLayout();
        const length = realRoot.children.length;
        let rad;
        let isLeft;

        if (targetLayout.x === rootLayout.x && node.isExpand === true && realRoot.children.length) {
            const center = {
                x: (realRoot.children[0].getLayout().x + realRoot.children[length - 1].getLayout().x) / 2,
                y: (realRoot.children[0].getLayout().y + realRoot.children[length - 1].getLayout().y) / 2
            };
            rad = Math.atan2(center.y - rootLayout.y, center.x - rootLayout.x);
            if (rad < 0) {
                rad = Math.PI * 2 + rad;
            }
            isLeft = center.x < rootLayout.x;
            if (isLeft) {
                rad = rad - Math.PI;
            }
        }
        else {
            rad = Math.atan2(targetLayout.y - rootLayout.y, targetLayout.x - rootLayout.x);
            if (rad < 0) {
                rad = Math.PI * 2 + rad;
            }
            if (node.children.length === 0 || (node.children.length !== 0 && node.isExpand === false)) {
                isLeft = targetLayout.x < rootLayout.x;
                if (isLeft) {
                    rad = rad - Math.PI;
                }
            }
            else {
                isLeft = targetLayout.x > rootLayout.x;
                if (!isLeft) {
                    rad = rad - Math.PI;
                }
            }
        }

        const textPosition = isLeft ? 'left' as const : 'right' as const;
        const normalLabelModel = itemModel.getModel('label');
        const rotate = normalLabelModel.get('rotate');
        const labelRotateRadian = rotate * (Math.PI / 180);

        const textContent = symbolPath.getTextContent();
        if (textContent) {
            symbolPath.setTextConfig({
                position: normalLabelModel.get('position') || textPosition,
                rotation: rotate == null ? -rad : labelRotateRadian,
                origin: 'center'
            });
            textContent.setStyle('verticalAlign', 'middle');
        }

    }

    // Handle status
    const focus = itemModel.get(['emphasis', 'focus']);
    const focusDataIndices: number[] = focus === 'relative'
        ? zrUtil.concatArray(node.getAncestorsIndices(), node.getDescendantIndices()) as number[]
        : focus === 'ancestor'
            ? node.getAncestorsIndices()
            : focus === 'descendant' ? node.getDescendantIndices() : null;

    if (focusDataIndices) {
        // Modify the focus to data indices.
        getECData(symbolEl).focus = focusDataIndices;
    }

    drawEdge(
        seriesModel, node, virtualRoot, symbolEl, sourceOldLayout,
        sourceLayout, targetLayout, group
    );

    if (symbolEl.__edge) {
        (symbolEl as ECElement).onHoverStateChange = function (toState) {
            if (toState !== 'blur') {
                // NOTE: Ensure the parent elements will been blurred firstly.
                // According to the return of getAncestorsIndices and getDescendantIndices
                // TODO: A bit tricky.
                const parentEl = node.parentNode
                    && data.getItemGraphicEl(node.parentNode.dataIndex);
                if (!(parentEl && (parentEl as ECElement).hoverState === HOVER_STATE_BLUR)) {
                    setStatesFlag(symbolEl.__edge, toState);
                }
            }
        };
    }
}