react echarts tree树图搜索展开功能示例详解

yizhihongxing

当用户需要展示树形结构数据时,react-echarts库提供了一个很好的解决方案:树图。除此之外,还可以为树图添加搜索和展开等交互功能,方便用户更好地查看数据。在本文中,我们将为您展示如何在react-echarts中实现这些功能。

前置条件

在进行以下步骤之前,请确保您已经安装以下依赖项:

  1. React:16.8.0 以上版本
  2. Echarts:5.0.2 以上版本
  3. 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技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • JavaScript弹出对话框的三种方式

    当我们想向用户展示一些提示信息时,经常会使用JavaScript弹出对话框。JavaScript弹出对话框有三种方式,分别为alert()、confirm()和prompt()。 alert() 使用alert()方法弹出对话框可以显示警告信息,警告信息通常只需要用户确认即可。下面是alert()的语法: alert("警告信息"); 下…

    JavaScript 2023年5月27日
    00
  • Rxjs 中处理错误和抓取错误的代码案例

    Rxjs 是一款强大的响应式编程库,它能够非常方便地处理各种异步任务。但是在实际项目中,难免会遇到各种错误以及异常情况。Rxjs 提供了很多处理错误和抓取错误的方法,接下来我们将详细讲解。 错误处理方法 catchError catchError 是 Rxjs 提供的一个异常处理方法,它可以用来捕捉 Observable 序列中的错误,并将错误转化为一个新的…

    JavaScript 2023年5月28日
    00
  • JavaScript面向对象之七大基本原则实例详解

    JavaScript面向对象之七大基本原则实例详解 本文将向大家介绍面向对象编程的七大基本原则,并结合示例详细讲解这些原则的实现方法。 七大基本原则 单一职责原则(SRP) 单一职责原则是指一个类只应该有一个单一的功能。如果一个类承担了过多的职责,那么这个类就会变得不可控,难以维护,并且不易复用。 开放封闭原则(OCP) 开放封闭原则是指软件实体(类、模块、…

    JavaScript 2023年5月27日
    00
  • JS实现两周内自动登录功能

    实现两周内自动登录的功能需要涉及到一些技术点,下面是完整的攻略: 技术点 Cookie / LocalStorage:用于保存登录状态和用户信息,以及判断用户是否已登录。 路由拦截:在用户未登录的情况下,将其重定向至登录页面。可以通过 Vue Router 的全局前置守卫实现。 Token 认证:为了保证用户信息的安全性,一般需要在后台生成一个 Token,…

    JavaScript 2023年6月11日
    00
  • JavaScript字符串对象replace方法实例(用于字符串替换或正则替换)

    JavaScript字符串对象replace方法是用来替换文本的,并可以通过正则表达式进行更精确的匹配和替换。下面是关于该方法的完整攻略: 一. 标准语法 JavaScript字符串对象replace方法的标准语法如下: str.replace(regexp|substr, newSubstr|function) 其中,str是要进行替换的字符串;regex…

    JavaScript 2023年5月28日
    00
  • uniapp实现横屏签字版

    实现横屏签字版可以利用uniapp中的canvas以及第三方的canvas插件实现。 步骤一:安装canvas插件 在uniapp中使用canvas需要下载并安装canvas插件,下载地址为:https://ext.dcloud.net.cn/plugin?id=127 下载完成后,在uniapp项目的根目录下,打开cmd或者终端并输入如下命令: npm i…

    JavaScript 2023年6月11日
    00
  • js split 的用法和定义 js split分割字符串成数组的实例代码

    下面是关于JS的split函数的详细讲解: 定义 split是JavaScript中的字符串方法,可以将一个字符串分割成一个字符串数组。分割的标准可以是一个固定字符串,也可以是一个正则表达式。返回的字符串数组包含原始字符串中分割出的子字符串。 用法 split方法的语法格式如下: str.split(separator,limit) 参数说明: separa…

    JavaScript 2023年5月28日
    00
  • Element-Plus el-col、el-row快速布局及使用方法

    Element-Plus el-col、el-row快速布局及使用方法 Element-Plus是一套基于Vue3的UI框架,其中包含了el-col、el-row等快速布局组件。在本攻略中,我们将详细讲解Element-Plus中el-col、el-row的使用方法,以及如何快速进行页面布局。 el-col组件 基本用法 el-col组件用于将页面水平分成2…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部