jsMind
jsMind
是一个用于显示和编辑思维导图的纯 JavaScript
类库。它基于 Canvas
和 SVG
进行设计,能够在现代浏览器中高效地运行。jsMind
以 BSD
协议开源,这意味着可以在遵守该协议的前提下,将其嵌入到任何项目中使用。
功能特点
jsMind
提供了强大的脑图编辑功能,支持节点的添加、删除、移动等操作。它内置了多种主题,用户可以根据需要选择合适的主题,或者自定义主题。此外,通过 CSS 可以自定义节点的样式,包括背景色、字体颜色、鼠标悬停效果等。jsMind
还提供了丰富的 API,方便开发者进行二次开发和功能扩展。
效果图
接下来我会重新构建一个react项目,然后实现jsmind思维导图功能
代码结构
项目的入口文件是index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
);
之后在App
组件实现对应功能
import React from 'react';
import 'jsmind/style/jsmind.css';
import jsMind from 'jsmind';
import './index.css';
class App extends React.Component {
componentDidMount() {
var mind = {
meta: {
name: 'demo',
author: 'yang',
version: '0.2',
},
format: 'node_tree',
data: {
id: "root",
topic: "city",
children: [
{
id: "easy", // [必选] ID, 所有节点的ID不应有重复,否则ID重复的结节将被忽略
topic: "杭州", // [必选] 节点上显示的内容
direction: "right", // [可选] 节点的方向,此数据仅在第一层节点上有效,目前仅支持 left 和 right 两种,默认为 right
// expanded: false, // [可选] 该节点是否是展开状态,默认为 true
children: [
{
id: "easy8",
topic: "滨江",
children: [
{ id: "open7", topic: "海康威视" },
{ id: "easy7", topic: "浙江大华" },
],
},
{ id: "easy2", topic: "上城" },
],
},
{
id: "open",
topic: "上海",
direction: "right",
// expanded: false,
children: [
{ id: "open1", topic: "嘉定" ,
children: [
{ id: "open45", topic: "阿里巴巴" },
{ id: "easy56", topic: "斯凯孚" },
],
},
{ id: "open2", topic: "浦东" },
{ id: "open3", topic: "徐汇" },
],
},
{
id: "powerful",
topic: "南京",
direction: "right",
// expanded: false,
children: [
{ id: "powerful2", topic: "建邺" },
{ id: "powerful3", topic: "雨花台" },
],
},
{
id: "other",
topic: "苏州",
direction: "right",
// expanded: false,
children: [
{ id: "other1", topic: "姑苏" },
{ id: "other2", topic: "吴中" },
],
},
],
},
}
const options = {
container: 'jsmind_container',
editable: true,
theme: 'primary',
mode: 'side',
view: {
line_width: 2, // 思维导图线条的粗细
line_color: '#black' // 思维导图线条的颜色
},
};
const jm = jsMind.show(options, mind);
jm.add_event_listener(async (type, dat) => {
if (type === 4 && dat.node !== 'root') {
console.log('点击了这个节点');
}
});
}
render(){
return <div style={{ width: '100%', height: '100%', position: 'absolute', top: 0, left: 0 }}>
<div id="jsmind_container" style={{ width: '100%', height: '100%'}} />
</div>
}
}
export default App;
这里jsmind
我直接从npm
库安装并引入,省去了自己下载的麻烦
npm install jsmind
引入
import 'jsmind/style/jsmind.css';
import jsMind from 'jsmind';
在点击不同的jsmind
节点时,可以使用这个代码进行逻辑书写
jm.add_event_listener(async (type, dat) => {
if (type === 4 && dat.node !== 'root') {
console.log('点击了这个节点');
}
});
因为在jsmind
源码里面
jm.event_type = { show: 1, resize: 2, edit: 3, select: 4 };
所以这么操作
但是修改样式有一些需要在node
里面的jsmind.css
里修改,但是我修改后不生效,可能是权重不够
所以我新建一个css文件,直接将要改的样式写在css里面,并加上!important
jmnode.root {
font-size: 20px !important;
font-family: "Times New Roman", sans-serif !important;
}
jmnode.selected {
background-color: rgb(222, 160, 35) !important;
color: #fff;
box-shadow: 2px 2px 8px #000;
}
jmexpander {
position: absolute;
width: 13px;
height: 11px;
display: block;
overflow: hidden;
line-height: 10px;
font-size: 20px !important;
text-align: center !important;
border-radius: 13px !important;
border-width: 1px;
border-style: solid;
cursor: pointer;
}
之后在App组件中引入
import './index.css';
但是还有一个坑,就是StrictMode
引发的组件重复执行
如果你的index.js
文件中是这样的
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
那么组件就会被渲染两次
这是因为在开发者模式中,StrictMode
会将相应组件执行两次,所以删掉即可