您现在的位置是:网站首页 > 树图(Tree Chart)实现文章详情

树图(Tree Chart)实现

树图(Tree Chart)实现

树图是一种用于展示层次结构数据的图表类型,适合表现父子级关系。ECharts提供了强大的树图支持,可以自定义节点样式、连线样式、布局方式等。下面详细介绍如何使用ECharts实现树图。

基础树图实现

最简单的树图只需要定义节点数据和层级关系。ECharts的树图使用series.type: 'tree'来声明:

option = {
    series: [{
        type: 'tree',
        data: [{
            name: '根节点',
            children: [{
                name: '子节点1',
                children: [{ name: '叶子节点1' }, { name: '叶子节点2' }]
            }, {
                name: '子节点2',
                children: [{ name: '叶子节点3' }]
            }]
        }]
    }]
};

这个例子展示了一个三层树结构,包含根节点、两个子节点和三个叶子节点。ECharts会自动计算布局并绘制连接线。

自定义节点样式

可以通过symbolitemStyle自定义节点样式:

series: [{
    type: 'tree',
    symbol: 'circle',  // 节点形状
    symbolSize: 10,    // 节点大小
    itemStyle: {
        color: '#c23531',  // 节点颜色
        borderColor: '#333',  // 边框颜色
        borderWidth: 1  // 边框宽度
    },
    data: [...]
}]

连线样式定制

树图的连接线可以通过lineStyle进行定制:

series: [{
    type: 'tree',
    lineStyle: {
        color: '#999',  // 连线颜色
        width: 2,       // 连线宽度
        curveness: 0.5  // 弯曲程度
    },
    data: [...]
}]

标签显示控制

节点标签的显示可以通过label配置项控制:

series: [{
    type: 'tree',
    label: {
        position: 'left',  // 标签位置
        verticalAlign: 'middle',  // 垂直对齐
        align: 'right',    // 水平对齐
        fontSize: 12,     // 字体大小
        color: '#333'     // 字体颜色
    },
    data: [...]
}]

交互功能

ECharts树图支持丰富的交互功能:

series: [{
    type: 'tree',
    expandAndCollapse: true,  // 允许展开折叠
    initialTreeDepth: 2,     // 初始展开层级
    roam: true,              // 允许缩放平移
    data: [...]
}]

径向树图

除了常规的从左到右布局,还可以实现径向布局的树图:

series: [{
    type: 'tree',
    layout: 'radial',  // 径向布局
    symbol: 'emptyCircle',
    symbolSize: 7,
    roam: true,
    label: {
        position: 'right',
        rotate: true,
        verticalAlign: 'middle',
        align: 'left'
    },
    leaves: {
        label: {
            position: 'right',
            verticalAlign: 'middle',
            align: 'left'
        }
    },
    data: [...]
}]

大数据量优化

当处理大量节点时,可以使用以下优化策略:

series: [{
    type: 'tree',
    animationDurationUpdate: 1500,  // 动画时长
    animationEasingUpdate: 'quinticInOut',  // 动画缓动
    emphasis: {
        focus: 'ancestor'  // 高亮祖先节点
    },
    data: [...]
}]

自定义节点内容

通过rich配置可以创建复杂的节点内容:

series: [{
    type: 'tree',
    label: {
        formatter: function(params) {
            return `{name|${params.name}}\n{value|${params.value || ''}}`;
        },
        rich: {
            name: {
                fontSize: 14,
                color: '#333'
            },
            value: {
                fontSize: 12,
                color: '#999'
            }
        }
    },
    data: [...]
}]

动态更新数据

树图支持动态数据更新:

// 初始化图表
const myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);

// 更新数据
function updateData(newData) {
    myChart.setOption({
        series: [{
            data: newData
        }]
    });
}

事件处理

可以为树图添加交互事件:

myChart.on('click', function(params) {
    console.log('点击了节点:', params.name);
});

myChart.on('dblclick', function(params) {
    console.log('双击了节点:', params.name);
});

复杂样式示例

一个综合样式配置的示例:

option = {
    series: [{
        type: 'tree',
        orient: 'vertical',
        symbol: 'roundRect',
        symbolSize: [60, 30],
        edgeShape: 'polyline',
        edgeForkPosition: '50%',
        initialTreeDepth: 3,
        lineStyle: {
            width: 2,
            curveness: 0.2
        },
        label: {
            backgroundColor: '#fff',
            borderColor: '#999',
            borderWidth: 1,
            borderRadius: 4,
            padding: [4, 8],
            position: 'inside',
            formatter: '{b}'
        },
        leaves: {
            label: {
                position: 'right'
            }
        },
        emphasis: {
            focus: 'descendant',
            label: {
                show: true
            }
        },
        expandAndCollapse: true,
        animationDuration: 800,
        data: [{
            name: '根节点',
            itemStyle: {
                color: '#c23531'
            },
            children: [...]
        }]
    }]
};

与其他图表组合

树图可以与其他图表类型组合使用:

option = {
    tooltip: {
        trigger: 'item',
        triggerOn: 'mousemove'
    },
    series: [
        {
            type: 'tree',
            data: [...],
            left: '5%',
            right: '50%',
            top: '10%',
            bottom: '10%'
        },
        {
            type: 'pie',
            data: [...],
            left: '55%',
            right: '5%',
            top: '10%',
            bottom: '10%'
        }
    ]
};

性能优化技巧

处理大型树结构时的优化方法:

  1. 使用animation: false关闭动画
  2. 设置合理的initialTreeDepth减少初始渲染节点
  3. 使用progressive渐进式渲染
  4. 简化节点样式和标签内容
series: [{
    type: 'tree',
    animation: false,
    initialTreeDepth: 2,
    progressive: 200,
    data: [...]
}]

响应式设计

使树图适应不同屏幕尺寸:

window.addEventListener('resize', function() {
    myChart.resize();
});

// 或者在option中配置
option = {
    series: [{
        type: 'tree',
        left: '10%',
        right: '10%',
        top: '10%',
        bottom: '10%',
        data: [...]
    }]
};

自定义交互行为

实现自定义的展开/折叠逻辑:

myChart.on('click', function(params) {
    if (params.data.collapsed) {
        // 展开节点
        params.data.collapsed = false;
    } else {
        // 折叠节点
        params.data.collapsed = true;
    }
    myChart.setOption({
        series: [{
            data: option.series[0].data
        }]
    });
});

高级布局配置

控制树图的详细布局参数:

series: [{
    type: 'tree',
    layout: 'orthogonal',
    orient: 'vertical',
    nodePadding: 20,
    layerPadding: 100,
    expandAndCollapse: true,
    symbolKeepAspect: true,
    data: [...]
}]

数据格式转换

将扁平数据转换为树形结构:

function convertToTree(flatData) {
    const map = {};
    const roots = [];
    
    flatData.forEach(item => {
        map[item.id] = { ...item, children: [] };
    });
    
    flatData.forEach(item => {
        if (item.parentId) {
            map[item.parentId].children.push(map[item.id]);
        } else {
            roots.push(map[item.id]);
        }
    });
    
    return roots;
}

const treeData = convertToTree([
    { id: 1, name: '根节点' },
    { id: 2, name: '子节点1', parentId: 1 },
    { id: 3, name: '子节点2', parentId: 1 },
    { id: 4, name: '叶子节点1', parentId: 2 }
]);

我的名片

网名:~川~

岗位:console.log 调试员

坐标:重庆市-九龙坡区

邮箱:cc@qdcc.cn

沙漏人生

站点信息

  • 建站时间:2013/03/16
  • 本站运行
  • 文章数量
  • 总访问量
微信公众号
每次关注
都是向财富自由迈进的一步