当用户需要展示树形结构数据时,react-echarts库提供了一个很好的解决方案:树图。除此之外,还可以为树图添加搜索和展开等交互功能,方便用户更好地查看数据。在本文中,我们将为您展示如何在react-echarts中实现这些功能。
前置条件
在进行以下步骤之前,请确保您已经安装以下依赖项:
- React:16.8.0 以上版本
- Echarts:5.0.2 以上版本
- React-echarts:7.2.1 以上版本
树图
首先,我们需要安装React-echarts组件并导入它。
import ReactECharts from 'echarts-for-react';
接下来,让我们创建一个React组件,并在该组件中初始化一个简单的树图。具体来说,我们将创建一个带有简单大小的节点的树图,并设置其相关配置。
import React from 'react'
import ReactECharts from 'echarts-for-react'
const option = {
tooltip: {},
series: [
{
type: 'tree',
data: [
{
name: 'node01',
value: 1,
children: [
{
name: 'node011',
value: 1
},
{
name: 'node012',
value: 1
}
]
},
{
name: 'node02',
value: 1,
children: [
{
name: 'node021',
value: 1
},
{
name: 'node022',
value: 1
}
]
}
],
top: '1%',
left: '7%',
bottom: '1%',
right: '20%',
symbolSize: 7,
label: {
position: 'left',
verticalAlign: 'middle',
align: 'right'
},
leaves: {
label: {
position: 'right',
verticalAlign: 'middle',
align: 'left'
}
},
expandAndCollapse: true,
animationDuration: 550,
animationDurationUpdate: 750
}
]
};
export default function Example() {
return (
<ReactECharts
option={option}
/>
)
}
现在,我们已经有了一个简单的树图。
添加搜索功能
要为树图添加搜索功能,我们需要先定义一下两个变量:
const initTreeData = [
{
name: 'node01',
value: 1,
children: [
{
name: 'node011',
value: 1
},
{
name: 'node012',
value: 1
}
]
},
{
name: 'node02',
value: 1,
children: [
{
name: 'node021',
value: 1
},
{
name: 'node022',
value: 1
}
]
}
];
const [treeData, setTreeData] = React.useState(initTreeData);
其中,initTreeData为初始化的树形数据,treeData则是用来存储当前操作过程中的树形数据。
接下来,我们需要添加一个搜索框,并将用户输入的搜索关键字保存在一个状态变量中:
const [keyword, setKeyword] = React.useState('');
return(
<div>
<input type="text" onChange={(e) => setKeyword(e.target.value)} value={keyword} placeholder="搜索树形结构"/>
</div>
)
接着,我们需要定义一个函数来处理搜索操作:
const handleSearch = (data, key) => {
let result = [];
for (let i = 0; i < data.length; i++) {
let node = data[i];
if (node.name.includes(key) || node.value.toString().includes(key)) {
result.push(node);
}
if (node.children) {
let childrenResult = handleSearch(node.children, key);
if (childrenResult.length > 0) {
result.push({
...node,
children: childrenResult
});
}
}
}
return result
}
此函数中,handleSearch接受两个参数,分别是需要搜索的节点数据和用户输入的搜索关键字。在函数中,我们将遍历节点数据,并将所有包含搜索关键字的节点过滤出来。并且,如果搜索结果有子节点,则递归查找子节点。
接下来,我们在搜索框value值发生变化时,调用该函数并将结果存入treeData中:
const handleSearchInputChange = (e) => {
setKeyword(e.target.value);
let result = handleSearch(initTreeData, e.target.value);
setTreeData(result)
};
return (
<div>
<input onChange={handleSearchInputChange} value={keyword}/>
</div>
);
至此,我们已经为树图添加了搜索功能。
添加展开功能
为树图添加展开功能,我们首先需要在每个节点上定义一个按钮,并为按钮添加点击事件。点击事件将根据节点当前的展开情况,执行相应的展开或收起操作。在每个节点上添加按钮的代码如下所示:
const onExpandButtonClick = (e, node) => {
e.stopPropagation(); // 阻止事件冒泡
if (node.children) {
node._children = node.children;
node.children = null;
} else {
node.children = node._children;
node._children = null;
}
setTreeData((prev) => {
return [...prev]
});
};
return(
<div>
{
treeNode.children ? (
<button
onClick={(e) => {
onExpandButtonClick(e, treeNode)
}}
>
{expanded ? '-' : '+'}
</button>
) : null
}
<span>{treeNode.name}</span>
</div>
)
在每个按钮上,我们添加了一个onExpandButtonClick函数,并将子节点列表的引用存储在每个节点上。然后,如果子节点列表当前是打开的,则从列表中删除子节点并将其放入另一个引用“_children”中。相反地,如果子节点列表当前是关闭的,则从“_children”中获取子节点列表并将其放回children中。最后,我们将用新的树形数据更新setTreeData。
现在,我们已经成功为树图添加了展开功能。
示例1:添加动画效果
我们可以为树图的展开动态效果添加动画效果:
const option = {
tooltip: {},
series: [
{
type: 'tree',
data: treeData,
top: '1%',
left: '7%',
bottom: '1%',
right: '20%',
symbolSize: 7,
label: {
position: 'left',
verticalAlign: 'middle',
align: 'right'
},
leaves: {
label: {
position: 'right',
verticalAlign: 'middle',
align: 'left'
}
},
expandAndCollapse: true,
animationDuration: 550,
animationDurationUpdate: 750,
emphasis: {
focus: 'descendant'
}
}
]
};
export default function Example1() {
const initTreeData = [
{
name: '我的网站',
children: [
{
name: '技术文档',
children: [
{
name: '机器学习'
},
{
name: '深度学习'
},
{
name: '自然语言处理'
}
]
},
{
name: '个人博客',
children: [
{
name: '个人日记'
},
{
name: '旅游攻略'
},
{
name: '美食评测'
}
]
}
]
},
];
const [treeData, setTreeData] = React.useState(initTreeData);
const [keyword, setKeyword] = React.useState('');
const handleSearch = (data, key) => {
let result = [];
for (let i = 0; i < data.length; i++) {
let node = data[i];
if (node.name.includes(key)) {
result.push(node);
}
if (node.children) {
let childrenResult = handleSearch(node.children, key);
if (childrenResult.length > 0) {
result.push({
...node,
children: childrenResult
});
}
}
}
return result
};
const handleSearchInputChange = (e) => {
setKeyword(e.target.value);
let result = handleSearch(initTreeData, e.target.value);
setTreeData(result)
};
const onExpandButtonClick = (e, node) => {
e.stopPropagation();
if (node.children) {
node._children = node.children;
node.children = null;
} else {
node.children = node._children;
node._children = null;
}
setTreeData((prev) => {
return [...prev]
});
};
return (
<React.Fragment>
<input onChange={handleSearchInputChange} value={keyword}/>
<ReactECharts
option={option}
/>
</React.Fragment>
)
}
示例2:树图数据异步加载展示
在树图数据较大时,为了实现更流畅的展示效果,我们可以通过异步加载树图数据的方式取得更好的体验。
const option = {
tooltip: {},
series: [
{
type: 'tree',
data: treeData,
top: '1%',
left: '7%',
bottom: '1%',
right: '20%',
symbolSize: 7,
label: {
position: 'left',
verticalAlign: 'middle',
align: 'right'
},
leaves: {
label: {
position: 'right',
verticalAlign: 'middle',
align: 'left'
}
},
expandAndCollapse: true,
animationDuration: 550,
animationDurationUpdate: 750,
emphasis: {
focus: 'descendant'
}
}
]
};
export default function Example2() {
const [treeData, setTreeData] = React.useState([]);
React.useEffect(() => {
// 模拟异步加载数据
setTimeout(() => {
const initData = [
{
name: '我的网站',
children: [
{
name: '技术文档',
children: [
{
name: '机器学习'
},
{
name: '深度学习'
},
{
name: '自然语言处理'
}
]
},
{
name: '个人博客',
children: [
{
name: '个人日记'
},
{
name: '旅游攻略'
},
{
name: '美食评测'
}
]
}
]
}
];
setTreeData(initData);
}, 2000)
}, []);
const [keyword, setKeyword] = React.useState('');
const handleSearch = (data, key) => {
let result = [];
for (let i = 0; i < data.length; i++) {
let node = data[i];
if (node.name.includes(key)) {
result.push(node);
}
if (node.children) {
let childrenResult = handleSearch(node.children, key);
if (childrenResult.length > 0) {
result.push({
...node,
children: childrenResult
});
}
}
}
return result
};
const handleSearchInputChange = (e) => {
setKeyword(e.target.value);
let result = handleSearch(treeData, e.target.value);
setTreeData(result)
};
const onExpandButtonClick = (e, node) => {
e.stopPropagation();
if (node.children) {
node._children = node.children;
node.children = null;
} else {
node.children = node._children;
node._children = null;
}
setTreeData((prev) => {
return [...prev]
});
};
return (
<React.Fragment>
<input onChange={handleSearchInputChange} value={keyword}/>
<ReactECharts
option={option}
/>
</React.Fragment>
)
}
在这个例子中,我们在useEffect钩子中异步加载了根节点数据,然后在组件初始渲染时显示空的树图。当数据加载完成之后,我们将使用setTreeData函数将其存储在树形数据中。
结论
本文在React-echarts基础上,通过示例演示了如何实现树图搜索和展开功能,并讨论树图动态效果添加和异步加载等高级技术。通过了解这些基于react-echarts库的技术,您可以创建出高度交互的树形结构,为用户提供更好的数据展示和使用体验。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:react echarts tree树图搜索展开功能示例详解 - Python技术站