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

当用户需要展示树形结构数据时,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日

相关文章

  • P3P 和 跨域 (cross-domain) cookie 访问(读取和设置)

    P3P(Platform for Privacy Preferences)是一个Internet标准,它在Web服务器和浏览器之间传递标准格式的隐私策略。P3P帮助网站明确并公开其隐私政策,并允许用户在浏览网站时了解网站将如何使用其个人信息。跨域cookie指的是在某个域名下,通过设置cookie使得另一个域名下的网站也可以共享这个cookie,即跨域共享c…

    JavaScript 2023年6月11日
    00
  • JavaScript使用localStorage存储数据

    以下是使用localStorage存储数据的完整攻略。 什么是localStorage? localStorage是一种客户端存储数据的方式,它可以在客户端本地存储数据,是一个只有浏览器端可以访问的本地存储器。localStorage可以使网页在下一次访问时获取我们之前保存的数据。 localStorage的使用步骤 1. 存储数据 在JavaScript中…

    JavaScript 2023年6月11日
    00
  • jquery获取URL中参数解决中文乱码问题的两种方法

    接下来我将详细讲解“jquery获取URL中参数解决中文乱码问题的两种方法”的完整攻略。 问题描述 由于中国所有的编码都是基于 Unicode,因此 UTF-8 编码也经过传递被应用在了 URL 地址中。而浏览器在向服务器传递请求的时候,会自动将请求参数进行编码(包括中文),所以在 URL 中看起来是一堆乱码,而我们在使用 jQuery 获取 URL 中的参…

    JavaScript 2023年5月19日
    00
  • JS立即执行函数功能与用法分析

    下面是关于JS立即执行函数功能与用法分析的完整攻略。 一、什么是立即执行函数 立即执行函数(Immediately Invoked Function Expression, IIFE)是函数表达式的一种形式,它可以在定义后直接调用执行,不需要进行额外的函数调用。通常使用括号将函数表达式包裹起来,然后在最后加上一个括号,用于立即执行该函数。 代码示例: (fu…

    JavaScript 2023年6月11日
    00
  • canvas压缩图片转换成base64格式输出文件流

    下面是使用canvas压缩图片并转换为base64格式输出文件流的完整攻略: 步骤一:html文件部分 首先,我们需要在html文件中添加一个input元素,用于选择要上传的图片。代码如下: <label for="image_upload">选择图片:</label> <input type="f…

    JavaScript 2023年5月19日
    00
  • JavaScript初学者容易犯的几个错误

    JavaScript初学者容易犯的几个错误 在学习JavaScript的过程中,初学者常常会犯一些基础错误,本文将介绍几个常见的错误并提供解决方案。 错误1:变量命名不规范 初学者经常会犯变量命名不规范的错误,这会导致代码难以阅读和维护。正确的变量命名应该具有描述性和表现力,同时应该遵循驼峰命名法或者下划线命名法。 // 不规范的变量命名 var a = 5…

    JavaScript 2023年6月10日
    00
  • JS对象和字符串之间互换操作实例分析

    下面我会详细讲解如何在JavaScript中实现JS对象和字符串之间的互换操作。 JS对象和字符串之间互换操作实例分析 JS对象和字符串是JavaScript编程中最常见的数据类型之一。有时候,我们需要将JS对象转换为字符串,或者将字符串转换为JS对象。下面分别介绍如何实现这两种操作。 将JS对象转换为字符串 在JavaScript中,可以使用JSON.st…

    JavaScript 2023年5月28日
    00
  • 使用JS动态显示文本

    下面是使用JS动态显示文本的完整攻略: 1. 编写HTML代码 首先,在HTML代码中需要创建一个用于显示文本内容的元素,可以是<span>、<div>或者其他你想要的元素。例如,下面代码创建了一个<div>元素: <div id="my-text"></div> 2. 写JS代…

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