使用 React Flow 构建一个思维导图应用

242d9ec432ebcf91c101501536bfdf6b.jpeg

4f93d83082235977d4242b2bd3062fb0.jpeg

思维导图是围绕共同主题或问题将思想、概念、信息或任务分组的视觉表示。思维导图应用是一种软件应用,允许您创建、可视化和组织您的思想、想法和信息作为思维导图。本文将向您展示如何实现自己的思维导图应用程序。

在我们开始之前,我想向您展示一下我们在本教程结束时将拥有的思维导图应用程序

66c02940210259423ed562e03e1a0017.png

React Flow是什么?

React Flow是一个开源工具包,用于在React应用程序中生成交互式图表、流程图和可视化。它提供了一种强大的方式来创建和管理复杂的可视化,如思维导图、网络图和组织结构图等。React Flow基于React构建,并使用现代Web技术提供统一的用户体验。

成千上万的用户使用React Flow,从个人开源开发者到像Stripe和Typeform这样的大公司。该库已被用于数据处理工具、聊天机器人构建器、机器学习、音乐合成器和其他应用程序中。

选择一个满足你需求的库可能会很困难,因为在不断发展的行业中有太多的选择。然而,使用React Flow、思维导图以及规划和设计你的项目可能会简化这个过程,节省你的时间和烦恼。

尽管市场上有众多竞争对手,但React Flow作为最出色的思维导图和流程框架之一,仍然在大型项目的开发过程中持续为用户带来好处。

在本教程中,您将学习如何使用React Flow创建一个基本的思维导图应用程序,该应用程序可用于头脑风暴、构思想法或可视化思维。

项目设置

让我们从搭建我们的React应用开始。通过运行以下命令在您选择的目录中搭建React:

npm create vite@latest mind-mapping-app --template reactcd mind-mapping-app

Vite是一个为主要框架提供的工具,可以让您从基本模板快速启动项目。这些模板由社区维护,并针对各种框架或集成其他工具。其中一个模板可以使用类似Degit的工具来搭建您的项目。

npx degit user/project my-project
cd mind-mapping-appnpm install
npm run dev

创建组件

要创建一个组件,请在您的思维导图应用的src文件夹中导航并创建一个组件(component)文件夹。接下来,在组件文件夹中创建一个新文件, node.jsx 。

集成React Flow

将React Flow集成到您的Vite React项目中,请按照以下步骤进行操作:

首先,请确保您已经安装了React Flow。如果还没有安装,请运行以下命令:

npm install react-flow-renderer

接下来,导航到 node.jsx 目录并粘贴以下代码:

import React from "react";
import ReactFlow from "reactflow";import "reactflow/dist/style.css";const initialNodes = [{id: "1",type: "input",data: { label: "Mind Map" },position: { x: 0, y: 0 },},
];export default function MindNode() {return (<div id="container"><ReactFlow nodes={initialNodes }></ReactFlow></div>);
}

我们导入了项目所需的重要依赖项。然后,我们定义了一个名为 initialNodes 的数组。该数组包含了一个起始节点配置,每个节点都有几个属性。 MindNode 功能性的React组件返回 JSX ,用于渲染思维导图节点。

从那里,导航到 App.jsx 在 src 目录/文件夹中,并替换以下代码以渲染函数 MindNode 。

import React from "react";
import MindNode from "./components/node";function App() {return (<div className="App"><MindNode /></div>);
}export default App;

最后,在这个阶段,导航到 src/main.jsx 并粘贴下面的代码:

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import "./index.css";ReactDOM.createRoot(document.getElementById("root")).render(<React.StrictMode><App /></React.StrictMode>
);

上面的代码设置并渲染了你的主要React组件App到HTML DOM中。从目前的代码中,你应该得到下面所示的输出:

44a407d448d2f749f74a5e834cb253a0.gif

自定义节点外观

您可以通过修改React Flow应用程序中节点的外观,根据其类型或属性构建具有不同样式和视觉属性的节点。现在导航到 src/node.jsx 并将以下代码添加到其中:

import React, { useState } from "react";
import ReactFlow, { MiniMap, useNodesState } from "reactflow";import "reactflow/dist/style.css";const initialNodes = [{id: "1",type: "input",data: { label: "Mind Map" },position: { x: 0, y: 0 },},
];export default function MindNode() {const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);const [name, setName] = useState("");const addNode = () => {setNodes((e) =>e.concat({id: (e.length + 1).toString(),data: { label: `${name}` },position: {x: Math.random() * window.innerWidth,y: Math.random() * window.innerHeight,},}));};return (<div id="container"><ReactFlow nodes={nodes} onNodesChange={onNodesChange}><MiniMapnodeColor={(n) => {if (n.type === "input") return "blue";return "#FFCC00";}}/></ReactFlow><div><inputtype="text"onChange={(e) => setName(e.target.value)}name="title"/><button type="button" onClick={addNode}>Add Node</button></div></div>);
}

上面的代码创建了一个基本的思维导图应用程序。用户可以向地图添加自定义标签,并根据节点的类型改变其外观。Reactflow库包含处理思维导图状态和交互性所需的组件和钩子。 miniMap 允许您从小的视角看到整个屏幕。

添加互动性

93c4d4105d9c1d73dffa25c6b4b732c8.gif

从上面的片段中我们可以看到,我们无法连接节点。允许用户与节点和边进行交互,比如建立连接和与节点进行交互,是为思维导图应用程序增加互动性的一种方式。请将以下代码复制并粘贴到您的 src/node.jsx 中。

import React, { useState, useCallback } from "react";
import ReactFlow, {MiniMap,Controls,useNodesState,useEdgesState,addEdge,
} from "reactflow";import "reactflow/dist/style.css";const initialNodes = [{id: "1",type: "input",data: { label: "Mind Map" },position: { x: 0, y: 0 },},
];
const initialEdges = [];
const onLoad = (reactFlowInstance) => {reactFlowInstance.fitView();
};export default function MindNode() {const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);const [name, setName] = useState("");const addNode = () => {setNodes((e) =>e.concat({id: (e.length + 1).toString(),data: { label: `${name}` },position: {x: Math.random() * window.innerWidth,y: Math.random() * window.innerHeight,},}));};const onConnect = useCallback((params) => setEdges((eds) => addEdge(params, eds)),[setEdges]);return (<div id="container"><ReactFlownodes={nodes}edges={edges}onNodesChange={onNodesChange}onEdgesChange={onEdgesChange}onConnect={onConnect}onLoad={onLoad}><Controls /><MiniMapnodeColor={(n) => {if (n.type === "input") return "blue";return "#FFCC00";}}/></ReactFlow><div><inputtype="text"onChange={(e) => setName(e.target.value)}name="title"/><button type="button" onClick={addNode}>Add Node</button></div></div>);
}

上面的代码使用useEdgesState来管理边的状态,并使用useCallback定义onConnect来处理节点边(连接)的生成。之后,我们使用所需的边、事件处理程序和缩放和平移显示的控件来渲染一个ReactFlow组件。

保存和加载思维导图

在基于React Flow的应用中保存和加载思维导图是一个重要的功能,允许用户保存和恢复他们的工作。这个功能提高了您的应用的可用性和价值。

保存思维导图

保存思维导图时,您必须收集表示思维导图中节点和边的数据。这些信息应该被转换成可存储的格式,比如JSON。您可以利用元素的状态来捕捉思维导图的当前状态。导航到 src 文件夹并创建一个新文件 storage.jsx ,添加以下代码:

export const saveMindMap = (nodes, edges) => {const data = { nodes, edges };localStorage.setItem("mindMapData", JSON.stringify(data));
};

以上代码定义了 saveMindMap 函数,该函数将思维导图的数据,包括节点和边的信息,保存到浏览器的本地存储中。本地存储是一种在用户设备上存储少量数据的简单方法。

加载思维导图:

加载思维导图与保存相反。您获取保存的数据,反序列化它,然后使用加载的数据更新React Flow画布。要加载保存的思维导图,请将以下代码粘贴到您的 src/storage.jsx 中。

export const loadMindMap = () => {const data = localStorage.getItem("mindMapData");return data ? JSON.parse(data) : null;
};

上面的代码从本地存储中检索序列化数据,将其解析为对象并返回该对象。接下来,将以下函数导入到您的组件中,并使用它们来保存和加载思维导图:

import React, { useState, useCallback, useEffect } from "react";
import ReactFlow, {MiniMap,Controls,useNodesState,useEdgesState,addEdge,Background,
} from "reactflow";
import { saveMindMap, loadMindMap } from "./Storage";
import "reactflow/dist/style.css";const initialNodes = [{id: "1",type: "input",data: { label: "Mind Map" },position: { x: 0, y: 0 },style: { border: "20px solid #9999" },},
];
const initialEdges = [];
const onLoad = (reactFlowInstance) => {reactFlowInstance.fitView();
};export default function MindNode() {const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);const [name, setName] = useState("");const addNode = () => {setNodes((e) =>e.concat({id: (e.length + 1).toString(),data: { label: `${name}` },position: {x: Math.random() * window.innerWidth,y: Math.random() * window.innerHeight,},style: { border: "10px solid #9999" },}));};const onConnect = useCallback((params) => setEdges((eds) => addEdge(params, eds)),[setEdges]);const handleSaveClick = () => {saveMindMap(nodes, edges);console.log(nodes);};const handleLoadClick = () => {const loadedData = loadMindMap();if (loadedData) {setNodes(loadedData.nodes);setEdges(loadedData.edges);console.log(loadedData);}};const refreshPage = () => {window.location.reload();};// const nodeOrigin = [0.5, 0.5];const connectionLineStyle = {stroke: "#9999",strokeWidth: 3,};const defaultEdgeOptions = { style: connectionLineStyle, type: "mindmap" };return (<div id="container"><ReactFlownodes={nodes}edges={edges}onNodesChange={onNodesChange}onEdgesChange={onEdgesChange}connectionLineStyle={connectionLineStyle}defaultEdgeOptions={defaultEdgeOptions}onConnect={onConnect}onLoad={onLoad}><Controls /><Background variant="dots" gap={12} size={1} /><MiniMapnodeColor={(n) => {if (n.type === "input") return "blue";return "#FFCC00";}}/></ReactFlow><div><inputtype="text"onChange={(e) => setName(e.target.value)}name="title"/><button id="one" type="button" onClick={addNode}>Add Node</button></div><div><button id="two" onClick={handleSaveClick}>Save Mind Map</button><button id="three" onClick={handleLoadClick}>Load Mind Map</button><button id="four" onClick={refreshPage}>Refresh</button></div></div>);
}

通过这些更改,您现在有一个用于保存当前思维导图数据的 handleSaveClick 函数,一个用于加载先前保存的思维导图数据的 handleLoadClick 函数,以及一个用于重新加载页面到其原始形式的 refreshPage 函数。

界面设计的样式化

我们的开发过程几乎完成了。让我们根据我们的特定需求来定制我们的设计。导航到 src/index.css 并替换以下代码:

body {margin: 0;background-color: #f8f8f8;
}
#container {height: 90vh;width: 100%;
}
input {border: 1px solid rgb(203, 186, 186);padding: 4px 8px;border-radius: 5px;font-weight: 700;background: transparent;height: 100%;color: #222;
}input:focus {border: none;outline: none;background: rgba(255, 255, 255, 0.25);pointer-events: all;
}
button {padding: 6px 8px;border-radius: 5px;border: none;background-color: #008cba;color: white;
}
button:hover {background-color: rgb(69, 69, 229);
}
input[type="text"] {padding: 8px;margin-right: 10px;border: 1px solid #ccc;border-radius: 4px;
}.react-flow {border: 3px solid #9999;border-radius: 10px;
}
/* .react-flow_nodes {color: #a02828;
} */
#two {background-color: #4caf50;margin: 5px;
}
#two:hover {background-color: #63c266;
}
#three {background-color: #f44336;margin: 2px;
}
#three:hover {background-color: rgb(190, 68, 68);
}
#four {background-color: rgb(86, 86, 6);
}
#four:hover {background-color: rgb(113,

测试

我们将进行一项测试,以了解我们的ReactFlow Mind应用程序的工作原理。

79b6ce50b1bc19cd018cc99a098b2bd3.png

请注意:您可以连接不同位置的节点,并且您还可以为每个节点指定一个期望的名称,以说明您的想法或项目。

结束

使用React Flow创建一个思维导图应用是一个有趣且多功能的项目,可以根据不同的用例进行调整,从头脑风暴会议到项目管理等等。在本指南中,我们已经涵盖了构建一个可工作的思维导图应用的重要步骤,例如设置开发环境,集成React Flow,修改节点外观,添加交互,并实现保存、加载和刷新功能。您可以根据需要添加更多功能和功能。

由于文章内容篇幅有限,今天的内容就分享到这里,文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/195751.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ke11..--2其他界面也要提取我的locatStarage

获取浏览器里面的本地缓存 localStorage就是我们的浏览器缓存在哪都可以用 下面代码是获取打印到我们的页面上 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> …

Hessian协议详解

前言 Hessian协议是一种基于二进制的轻量级远程调用协议&#xff0c;用于在分布式系统中进行跨语言的通信。它使用简单的二进制格式来序列化和反序列化数据&#xff0c;并支持多种编程语言&#xff0c;如Java、C#、Python等。Hessian协议相对于其他协议的优势在于其简单性和高…

微服务实战系列之Token

前言 什么是“Token”&#xff1f; 它是服务端生成的一串字符串&#xff0c;以作客户端进行请求的一个令牌&#xff0c;当第一次登录后&#xff0c;服务器生成一个Token便返回给客户端&#xff1b;以后客户端只携带此Token请求数据即可。 简言之&#xff0c;Token其实就是用户身…

【2022改良版】学法减分助手PRO小程序源码

【2022改良版】学法减分助手PRO小程序源码 &#xff0c;交管推出个学法减分&#xff0c;每个驾驶员可以把被扣的6分&#xff0c;以看视频答题的形式学习回来&#xff0c;然后答题这个一共二十道题每道题60秒&#xff0c; 有好多人不会&#xff0c;用咱们的小程序就可以模拟练习…

北京君正客户应用案例:掌静脉3D人脸猫眼视屏智能锁

凯迪仕在今年4月发布了智能锁旗舰新品K70 Pro Max掌静脉3D人脸猫眼视屏智能锁&#xff0c;随即这款新品也成了行业热议的焦点。凯迪仕每次新品都力求突破精益求精&#xff0c;不仅追求科技感、高级感与品质感&#xff0c;而且赋予科技温度&#xff0c;带来人文化的关怀。K70 Pr…

OpenCV快速入门:像素操作和图像变换

文章目录 前言1. 像素操作1.1 像素统计1.2 两个图像之间的操作1.2.1 图像加法操作1.2.3 图像加权混合 1.3 二值化1.4 LUT&#xff08;查找表&#xff09;1.4.1 查找表原理1.4.2 代码演示 2 图像变换2.1 旋转操作2.1.1 旋转的基本原理2.1.2 代码实现 2.2 缩放操作2.3 平移操作2.…

使用GPT-4训练数据微调GPT-3.5 RAG管道

原文&#xff1a;使用GPT-4训练数据微调GPT-3.5 RAG管道 - 知乎 OpenAI在2023年8月22日宣布&#xff0c;现在可以对GPT-3.5 Turbo进行微调了。也就是说&#xff0c;我们可以自定义自己的模型了。然后LlamaIndex就发布了0.8.7版本&#xff0c;集成了微调OpenAI gpt-3.5 turbo的…

IIC协议保姆级教学

目录 1.IIC协议概述 2.IIC总线传输 3.IIC-51单片机应用 1.起始信号 2.终止信号 3.应答信号 4.数据发送 4.IIC-32单片机应用 用到的库函数&#xff1a; 1.IIC协议概述 IIC全称Inter-Integrated Circuit (集成电路总线)是由PHILIPS公司在80年代开发的两线式串行总线&am…

【Spring】IoC容器的一些总结与补充

文章目录 1. 创建容器的两种方式相对路径导入绝对路径导入 2. 获取Bean的三种方式getBean后强转类型getBean内写明类别根据类别获取bean 3. 容器层次结构4. BeanFactory5. bean的总结6. 注入的总结 1. 创建容器的两种方式 相对路径导入 ApplicationContext ctx new ClassPat…

一些RLHF的平替汇总

卷友们好&#xff0c;我是rumor。 众所周知&#xff0c;RLHF十分玄学且令人望而却步。我听过有的小道消息说提升很大&#xff0c;也有小道消息说效果不明显&#xff0c;究其根本还是系统链路太长自由度太高&#xff0c;不像SFT一样可以通过数据配比、prompt、有限的超参数来可控…

电压跟随器

电压跟随器即输入多大电压就输出多大的电压&#xff0c;那其起什么作用呢&#xff0c;直接用导线不行吗&#xff1f; 下图为Multisim软件仿真结果&#xff0c;很明显输入电压6.5V输出电压使用万用表测得同为6.5V&#xff0c;验证了电压跟随器的作用。 在同相放大电路的基础上&a…

快速入门ESP32——开发环境配置PlatformIO IDE

相关文章 快速入门ESP32——开发环境配置Arduino IDE 快速入门ESP32——开发环境配置PlatformIO IDE 一、下载安装二、验证 一、下载安装 下载安装 vscode 安装PlatformIO插件 创建工程 二、验证 写一个简单的函数来验证一下功能 void setup() {// put your setup cod…

DevExpress WinForms HeatMap组件,一个高度可自定义热图控件!

通过DevExpress WinForms可以为Windows Forms桌面平台提供的高度可定制的热图UI组件&#xff0c;体验DevExpress的不同之处。 DevExpress WinForms有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。同时能完美构建流畅、美观且易于使用的应用程…

JVM类加载机制详解

JVM类加载运行全过程 运行Math类的main函数&#xff0c;启动程序时&#xff0c;首先需要通过类加载器把类加载到JVM。 package com.cold;public class Math {public int compute() {int a 1;int b 2;int c (a b) * 10;return c;}public static void main(String[] args) …

vue2 tinymce富文本插件

一、介绍 TinyMCE是一款易用、且功能强大的所见即所得的富文本编辑器。同类程序有&#xff1a;UEditor、Kindeditor、Simditor、CKEditor、wangEditor、Suneditor、froala等等。 TinyMCE的优势&#xff1a; 开源可商用&#xff0c;基于LGPL2.1插件丰富&#xff0c;自带插件基…

4核8G服务器价格选择轻量还是CVM合适?

腾讯云服务器4核8G配置优惠价格表&#xff0c;轻量应用服务器和CVM云服务器均有活动&#xff0c;云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元&#xff0c;5年6490.44元&#xff0c;轻量应用服务器4核8G12M带宽一年446元、529元15个月&#xff0c;腾讯云百科txybk.com分…

【论文解读】CP-SLAM: Collaborative Neural Point-based SLAM System_神经点云协同SLAM系统(下)

目录 4 CP-SLAM实验 4.1 两个智能体协作&#xff08; Two-agent Collaboration&#xff09; 4.2 单智能体回环&#xff08;Single Agent with Loop&#xff09; 4.3 地图构建&#xff08;Map Reconstruction&#xff09; 4.4 消融实验 姿态图优化&#xff08;Pose Graph …

JUC工具类_CyclicBarrier与CountDownLatch

最近被问到CyclicBarrier和CountDownLatch相关的面试题&#xff0c;CountDownLatch平时工作中经常用到&#xff0c;但是CyclicBarrier没有用过&#xff0c;一时答不上来&#xff0c;因此简单总结记录一下 1.什么是CyclicBarrier&#xff1f; 1.1 概念 CyclicBarrier&#xff…

简单漂亮的首页

效果图 说明 这个首页我也是构思了很久&#xff0c;才想出这个界面&#xff0c;大家喜欢的话&#xff0c;可以拿走去使用 技术的话&#xff0c;采用的就是vue的语法&#xff0c;但是不影响&#xff0c;很多样式我都是直接手敲出来的 代码实现 标语 <!-- 标语 start-->&…

hive sql 取当周周一 str_to_date(DATE_FORMAT(biz_date, ‘%Y%v‘), ‘%Y%v‘)

select str_to_date(DATE_FORMAT(biz_date, %Y%v), %Y%v)方法拆解 select DATE_FORMAT(now(), %Y%v), str_to_date(202346, %Y%v)