阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 树图(Tree Chart)实现

树图(Tree Chart)实现

作者:陈川 阅读数:63841人阅读 分类: ECharts

树图(Tree Chart)实现

树图是一种用于展示层级结构数据的可视化图表类型,特别适合表现父子关系或组织结构。ECharts提供了强大的树图支持,能够通过简单的配置实现复杂的树形结构展示。

基本树图配置

ECharts中实现树图需要准备层级结构的数据,并通过series.type指定为'tree'。以下是一个最基本的树图配置示例:

option = {
    series: [{
        type: 'tree',
        data: [{
            name: '根节点',
            children: [{
                name: '子节点1',
                children: [
                    { name: '子节点1.1' },
                    { name: '子节点1.2' }
                ]
            }, {
                name: '子节点2',
                children: [
                    { name: '子节点2.1' },
                    { name: '子节点2.2' }
                ]
            }]
        }],
        symbol: 'circle',
        symbolSize: 7,
        orient: 'vertical',
        label: {
            position: 'top',
            verticalAlign: 'middle',
            align: 'center'
        },
        leaves: {
            label: {
                position: 'right',
                verticalAlign: 'middle',
                align: 'left'
            }
        }
    }]
};

数据格式要求

树图数据必须符合特定的嵌套结构,每个节点可以包含以下属性:

  • name: 节点显示名称
  • value: 节点数值(可选)
  • children: 子节点数组(可选)
  • itemStyle: 节点样式(可选)
  • label: 标签样式(可选)
// 复杂数据示例
const treeData = {
    name: '公司架构',
    value: 100,
    itemStyle: {
        color: '#5470c6'
    },
    children: [
        {
            name: '技术部',
            value: 40,
            children: [
                { name: '前端组', value: 15 },
                { name: '后端组', value: 20 },
                { name: '测试组', value: 5 }
            ]
        },
        {
            name: '市场部',
            value: 30,
            children: [
                { name: '推广组', value: 10 },
                { name: '销售组', value: 20 }
            ]
        }
    ]
};

布局方向控制

ECharts树图支持多种布局方向,通过orient属性控制:

// 水平布局
orient: 'horizontal'

// 垂直布局(默认)
orient: 'vertical'

// 径向布局
orient: 'radial'

径向布局示例:

option = {
    series: [{
        type: 'tree',
        data: [treeData],
        orient: 'radial',
        symbol: 'emptyCircle',
        symbolSize: 7,
        expandAndCollapse: true,
        initialTreeDepth: 3,
        label: {
            rotate: 0,
            position: 'left'
        },
        leaves: {
            label: {
                position: 'right'
            }
        }
    }]
};

交互功能实现

ECharts树图支持丰富的交互功能,包括节点展开/折叠、缩放和平移等:

option = {
    series: [{
        type: 'tree',
        data: [treeData],
        roam: true,  // 开启缩放和平移
        expandAndCollapse: true,  // 允许展开折叠
        initialTreeDepth: 2,  // 初始展开层级
        itemStyle: {
            borderColor: '#999'
        },
        emphasis: {  // 高亮样式
            focus: 'ancestor',
            itemStyle: {
                borderColor: '#333'
            }
        }
    }],
    tooltip: {
        trigger: 'item',
        formatter: '{b}: {c}'
    }
};

自定义样式

可以通过多种方式自定义树图样式:

option = {
    series: [{
        type: 'tree',
        data: [treeData],
        lineStyle: {
            color: '#ccc',
            width: 2,
            curveness: 0.5  // 连接线弯曲度
        },
        itemStyle: {
            color: function(params) {
                // 根据层级设置不同颜色
                const depth = params.data.depth;
                const colorList = ['#c23531','#2f4554','#61a0a8','#d48265'];
                return colorList[depth % colorList.length];
            },
            borderWidth: 1
        },
        label: {
            fontSize: 12,
            color: '#333',
            formatter: function(params) {
                // 自定义标签显示
                return `${params.name} (${params.value || 0})`;
            }
        }
    }]
};

高级功能:动画效果

ECharts树图支持丰富的动画效果:

option = {
    series: [{
        type: 'tree',
        data: [treeData],
        animationDuration: 800,
        animationDurationUpdate: 500,
        animationEasing: 'elasticOut',
        expandAndCollapse: true,
        symbol: 'path://M10,10 L50,10 L50,50 L10,50 Z',  // 自定义节点形状
        symbolSize: [20, 20],
        itemStyle: {
            opacity: 0.8,
            shadowBlur: 10,
            shadowColor: 'rgba(0, 0, 0, 0.3)'
        }
    }]
};

大数据量优化

当处理大型树结构时,需要进行性能优化:

option = {
    series: [{
        type: 'tree',
        data: [largeTreeData],
        layout: 'orthogonal',  // 正交布局,性能更好
        symbolSize: 6,
        label: {
            show: false  // 关闭标签提升性能
        },
        leaves: {
            label: {
                show: true  // 只显示叶子节点标签
            }
        },
        emphasis: {
            disabled: true  // 禁用高亮效果
        },
        animation: false  // 禁用动画
    }]
};

与其他图表类型结合

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

option = {
    tooltip: {
        trigger: 'item',
        triggerOn: 'mousemove'
    },
    series: [
        {
            type: 'tree',
            data: [treeData],
            top: '5%',
            left: '7%',
            bottom: '5%',
            right: '60%',
            symbolSize: 10,
            label: {
                position: 'left',
                verticalAlign: 'middle',
                align: 'right'
            },
            leaves: {
                label: {
                    position: 'right',
                    verticalAlign: 'middle',
                    align: 'left'
                }
            }
        },
        {
            type: 'pie',
            radius: ['15%', '30%'],
            center: ['75%', '50%'],
            data: pieData,
            label: {
                position: 'inner'
            }
        }
    ]
};

动态更新数据

树图支持动态数据更新:

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

// 动态更新数据
function updateTreeData(newData) {
    myChart.setOption({
        series: [{
            type: 'tree',
            data: [newData]
        }]
    });
}

// 示例:展开所有节点
function expandAll() {
    const option = myChart.getOption();
    option.series[0].initialTreeDepth = Infinity;
    myChart.setOption(option);
}

事件处理

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

myChart.on('click', function(params) {
    console.log('点击节点:', params.name);
    if (params.data.children) {
        // 处理有子节点的点击逻辑
    }
});

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

myChart.on('mouseover', function(params) {
    // 鼠标悬停处理
});

myChart.on('globalout', function() {
    // 鼠标移出图表处理
});

响应式设计

实现树图的响应式布局:

function resizeChart() {
    myChart.resize();
}

window.addEventListener('resize', resizeChart);

// 响应式配置示例
option = {
    series: [{
        type: 'tree',
        data: [treeData],
        layout: function() {
            // 根据窗口宽度决定布局方向
            return window.innerWidth < 768 ? 'vertical' : 'horizontal';
        }(),
        label: {
            fontSize: function() {
                return window.innerWidth < 768 ? 10 : 12;
            }()
        }
    }]
};

导出与打印

实现树图的导出功能:

// 导出为图片
document.getElementById('export-btn').addEventListener('click', function() {
    const imgData = myChart.getDataURL({
        type: 'png',
        pixelRatio: 2,
        backgroundColor: '#fff'
    });
    const link = document.createElement('a');
    link.href = imgData;
    link.download = 'tree-chart.png';
    link.click();
});

// 打印图表
document.getElementById('print-btn').addEventListener('click', function() {
    const printWindow = window.open('', '_blank');
    printWindow.document.write('<html><head><title>树图打印</title></head><body>');
    printWindow.document.write('<img src="' + myChart.getDataURL() + '">');
    printWindow.document.write('</body></html>');
    printWindow.document.close();
    printWindow.focus();
    printWindow.print();
});

主题定制

通过主题定制统一树图样式:

// 注册主题
echarts.registerTheme('myTheme', {
    color: ['#c12e34', '#e6b600', '#0098d9', '#2b821d'],
    tree: {
        itemStyle: {
            borderColor: '#555'
        },
        lineStyle: {
            color: '#888',
            width: 1
        }
    }
});

// 使用主题
const myChart = echarts.init(document.getElementById('main'), 'myTheme');

无障碍访问

提升树图的无障碍访问能力:

option = {
    series: [{
        type: 'tree',
        data: [treeData],
        aria: {
            enabled: true,
            label: {
                description: '树图展示公司组织架构,包含{depth}层,当前节点{name}'
            }
        },
        label: {
            show: true,
            color: '#333',
            fontSize: 14,
            fontWeight: 'bold'
        },
        itemStyle: {
            color: '#4e79a7',
            borderColor: '#333'
        }
    }]
};

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌