ant-mind是一款基于html5的svg进行设计与开发的一个包含文档模式与思维导图模式的一个纯js类库,支持在当前主流的前端框架中接入。
效果图:

官网地址:https://www.aim.link/h5/KA.html
将下载到的sdk拷贝至项目工程目录,如拷贝至:
externalSdk/ant-mind/index.js
externalSdk/ant-mind/index.css
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#ant-mind {
width: 100%;
height: 100%;
}
</style>
<link rel="stylesheet" type="text/css" href="/externalSdk/ant-mind/index.css"/>
<script type="text/javascript" src="/externalSdk/ant-mind/index.js" defer></script>
</head>
<body>
<div id="ant-mind"></div>
</body>
</html>
const config = { mode: 'mind' };
const mIns = new AntMind('#ant-mind', config);
const mProps = {
onAtSearch: (val) => {
const userList = [
{ id: '1', name: '张三', photo: '' },
{ id: '2', name: '李四', photo: '' }
];
return Promise.resolve(userList);
}
};
mIns.render([{
id: '1',
name: '主要主题',
type: 'p', // 根节点
}], mProps);
import './externalSdk/ant-mind/index.css';
import React from 'react';
import AntMind from './externalSdk/ant-mind';
const MindView = () => {
const mindRef = React.useRef(null);
React.useLayoutEffect(() => {
mindRef.current = new AntMind('#ant-mind', { mode: 'mind' });
}, []);
React.useEffect(() => {
const mIns = mindRef.current;
const mProps = {
onAtSearch: (val) => getUserList(val),
};
mIns.render([{
id: '1',
name: '主要主题',
type: 'p', // 根节点
}], mProps);
return () => {
mIns?.destroy();
};
}, []);
const getUserList = (searchValue) => {
const userList = [
{ id: '1', name: '张三', photo: '' },
{ id: '2', name: '李四', photo: '' }
];
return Promise.resolve(userList);
};
return <div id="ant-mind"></div>
};
export default MindView;
<template>
<div id="ant-mind" class="m-mind"></div>
</template>
<style scoped>
.m-mind {
width: 100%;
height: 100%;
}
</style>
<script>
import AntMind from '@/externalSdk/ant-mind';
import '@/externalSdk/ant-mind/index.css';
export default {
data() {
return {
config: {
mode: 'mind'
}
}
},
mounted() {
this.init()
},
beforeDestroy() {
this.mIns?.destroy();
},
methods: {
init() {
this.mIns = new AntMind('#ant-mind', this.config);
this.getData().then(data => {
this.mIns.render(data, {
onAtSearch: (val) => this.getUserList(val)
});
});
},
getData() {
return Promise.resolve([
{
id: 'task.1',
editable: true,
wbs: '2',
milestone:"1",
name: '任务01',
fzr: 'x先生',
type: 't',
status: 2,
beginTime: "2021-06-02",
children: []
},
]);
},
getUserList(searchValue) {
const userList = [
{ id: '1', name: '张三', photo: '' },
{ id: '2', name: '李四', photo: '' }
];
return Promise.resolve(userList);
},
}
}
</script>
type为p、i、t时,通用的节点字段
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| id | 节点id - 必填 | string | 必填项 |
| name | 节点名称 | string | 必填项 |
| type | 节点类型 | p - 根节点、i - 二级根节点、t - 标准节点 | 必填项 |
| childCount | 一级子节点数量 | number | - |
| children | 子节点列表 | dataItem[] | - |
| excludes | 需过滤的不可操作项 | NodeOprKey[] | [] |
| parentId | 父节点id | string | - |
NodeOprKey:‘child’ | ‘sibling’ | ‘detail’ | ‘delete’ | ‘enter’ | ‘user’ | ‘move’ | ‘copy’ | ‘edit’;
特殊性:
特殊性:
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| isNew | 是否是新增节点 | boolean | true |
特殊性:
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| status | 节点状态 | string | - |
| milestone | 是否里程碑 | boolean | false |
| user | 人员 | object<{id, name}> | - |
| time | 日期 | YYYY/MM/DD HH:mm | - |
| timeStatus | 日期状态,当值为0时,当前日期临近截止日期时,日期显示橙色,超过截止日期时,日期显示红色;为当值为1时,日期颜色不随当前日期变化,显示灰色; | number | 0 |
| isNew | 是否是新增节点 | boolean | true |
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| mode | 视图类型,mind - 思维导图,outline - 大纲视图 | string | mind |
| locale | 显示语言 - zh-CN、en-US、zh-TW | string | zh-CN |
| locales | 自定义语言包 | LocalesType | 详细配置 |
| eventDom | 键盘事件触发容器,容器内的键盘事件可监听 | HTMLElement|string | - |
| fullDom | 全屏容器,全屏时的元素 | HTMLElement|string | - |
| platform | 第三方平台,用于在企业微信下显示人名 | wx|dingtalk | - |
| status | 节点状态 | StatusAttributes[] | 详细配置 |
| pngSize | 导出图片的最大尺寸,建议设置为20M以内 | number | - |
| theme | 主题属性 | ThemeAttributes | 详细配置 |
| wrapper | 画布属性 | WrapperAttributes | 详细配置 |
| operation | 操作栏 | OperationAttributes | 详细配置 |
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| key | 状态的唯一值,必填项 | string | - |
| name | 状态名称 | string | - |
| color | 状态颜色,用于显示节点的图标颜色,必填项 | string | - |
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| backgroundColor | 背景色 | string | #F7F7F7 |
| color | 主题颜色,思维导图模式下,节点与子节点间收起展开的节点颜色 | string | #4983FF |
| maxWidth | 节点最大宽度 | number | 500 |
| line | 连线配置 | LineType | - |
| +color | 线条颜色 | string | #4983FF |
| +width | 线条宽度 | [number, number] | [2, 1] |
| +radius | 线条转角弧度 | number | 4 |
| p | 根节点主题 | PNode | - |
| +maxLength | 最大长度 | number | 100 |
| i | 二级根节点主题 | INode | - |
| +maxLength | 最大长度 | number | 30 |
| t | 子节点主题 | TNode | - |
| +maxLength | 最大长度 | number | 100 |
| +defaultTime | 默认结束时间 | HH:mm | 18:00 |
| nodes | 节点样式 | NodeStyle[] | 详细配置 |
// 一个长度为3的数组,[p, i, t]分别代表3种不同节点的绘制样式
[
// 根节点
{
// 节点间距
space: {
x: 60,
y: 16
},
// 节点样式
style: {
wrap: true,
color: '#333333',
placeholderColor: '#CCCCCC',
fontSize: 18,
fontFamily: 'PingFang SC, Microsoft YaHei',
fontWeight: 500,
borderRadius: 6,
borderWidth: 2,
borderColor: '#CCCCCC',
borderFocusColor: '#4983FF',
borderHoverColor: '#92B5FF',
backgroundColor: '#FFFFFF',
}
},
// 二级根节点
{
space: {
x: 40,
y: 16
},
style: {
wrap: true,
color: '#333333',
placeholderColor: '#CCCCCC',
fontSize: 14,
fontFamily: 'PingFang SC, Microsoft YaHei',
fontWeight: 400,
borderRadius: 4,
borderWidth: 1,
borderColor: '#CCCCCC',
borderFocusColor: '#2867EC',
borderHoverColor: '#92B5FF',
backgroundColor: '#FFFFFF',
}
},
// 子节点样式
{
// 节点文本偏移量,x,y为无icon情况的偏移量
transform: {
x: 8,
y: 8,
icon: {
size: 20,
margin: 4
}
},
space: {
x: 40,
y: 8
},
style: {
wrap: true,
color: '#333333',
placeholderColor: '#CCCCCC',
fontSize: 14,
fontFamily: 'PingFang SC, Microsoft YaHei',
fontWeight: 400,
borderRadius: 2,
borderWidth: 1,
borderColor: 'transparent',
borderFocusColor: '#2867EC',
borderHoverColor: '#92B5FF',
backgroundColor: 'transparent',
}
}
]
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| scale | 画布缩放配置 | ScaleType | - |
| +min | 缩放的最小值 | number | 25 |
| +max | 缩放的最大值 | number | 200 |
| +size | 画布缩放值 | number | 100 |
| +step | 每次缩放的跨度 | number | 10 |
| +map | 画布缩放的可选项 | number[] | [25, 50, 75, 100, 125, 150, 175, 200] |
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| header | 顶部操作栏 | HeaderType | - |
| +show | 是否显示 | boolean | true |
| +excludes | 不显示的操作项 | HeaderAction[] | [] |
| node | 节点操作栏 | NodeType | - |
| +show | 是否显示 | boolean | true |
| batch | 批量操作栏 | BatchType | - |
| +show | 是否显示 | boolean | true |
| +excludes | 不显示的操作项 | BatchAction | [] |
| footer | 底部操作栏 | FooterType | - |
| +show | 是否显示 | boolean | true |
| +excludes | 不显示的操作项 | FooterAction | [] |
HeaderAction
mind - 脑图|outline - 大纲 |search - 搜索 |export - 导出 |shortcut - 快捷键
BatchAction
delete - 删除 | user - 人员
FooterAction
expand - 展开 | thumbnail - 缩略图 | center - 中心定位 | fullscreen - 全屏 | scale - 缩放
{
'shortcut': '快捷键',
'opr': '操作',
'opr.mind': '脑图模式',
'opr.outline': '文档模式',
'opr.undo': '撤回',
'opr.redo': '重做',
'opr.search': '查找',
'opr.export': '导出',
'opr.shortcut': '快捷键',
'opr.expand': '一键展开',
'opr.thumbnail': '导航器',
'opr.center': '定位到中心主题',
'opr.fullscreen': '全屏',
'opr.scale': '缩放比例',
'opr.reduce': '缩小',
'opr.enlarge': '放大',
'opr.user': '添加负责人',
'node': '节点',
'node.sibling': '插入同级节点',
'node.child': '插入子节点',
'node.delete': '删除节点',
'node.navigation': '任务导航',
'node.expand': '节点展开',
'node.fold': '节点折叠',
'node.edit': '编辑',
'node.cut': '剪切',
'node.copy': '复制',
'node.paste': '粘贴',
'canvas': '画布',
'canvas.reduce': '画布缩小',
'canvas.enlarge': '画布放大',
'expand.label': '展开至${num}级节点',
'search.placeholder': '搜索关键词',
'search.empty': '无搜索结果',
'empty.title': '无标题',
'p.placeholder': '项目名称',
'i.placeholder': '清单名称',
't.placeholder': '任务名称@负责人#计划截止时间',
't.detail': '任务详情',
't.delete': '删除任务',
'i.detail': '清单详情',
'i.delete': '删除清单',
'p.detail': '项目详情',
'p.delete': '删除项目',
'p.create': '新建清单',
'i.create': '新建任务',
't.create': '新建子任务',
'i.default': '默认清单',
't.default': '默认任务',
}
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| maxChildCount | 最大子节点数,超过该数则不支持默认展开 | number | Infinity |
| foldKeys | 折叠的节点 | id[] | [] |
| limit | 每类节点的最小数量,小于或等于该数量不可删除 | LimitType | - |
| level | 数据层级,超过该层级后不可添加子节点 | number | Infinity |
| onAtSearch | 输入@时的,回调函数,用于搜索人员 | val => Promise<{id, name}[]> | - |
| onCopyData | 复制粘贴时触发, dataArr为复制后的节点列表,dataMap为复制后节点的<key, value>对象。 | ({ ids, pid }) => Promise<{dataArr, dataMap?}> | - |
| onDelete | 在删除节点时触发 | (dataItem[]) => Promise.resolve(reject) | - |
| onDetail | 在查看详情时触发 | (dataItem) => void | - |
| onEnter | 在切换根节点时触发 | (id) => void | - |
| onError | 复制移动过程中,在当前节点不能插入子节点时触发 | (type: ‘move’ | ‘copy’) => void | - |
| onExport | 在导出图片时触发,fn接收opts参数({ name, bgColor, maxSize }),并返回一个Promise,用以标记导出成功或失败的状态 | (fn) => void; | - |
| onItemChange | 在节点发生变化时触发 | (params, data) => Promise | - |
| onLoadData | 当节点的子节点数(childCount)大于0,但不存在children时,点击展开时触发 | (data) => Promise<{ dataArr, dataMap}> | - |
| onModeChange | 在切换视图模式时触发,可用于控制视图显示权限 | (mode: ‘mind’ |‘outline’) => Promise | - |
| onMoveData | 在移动节点时触发 | ({ ids, pid }) => Promise.resolve(reject) | - |
| onMultipleUser | 在批量操作中,需要修改节点的@人员时,可通过此方法来调用外部组件修改 | (ids) => void | - |
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| i | 描述根节点下子节点的最小数量 | number | - |
| t | 描述除根节点外其他节点下子节点的最小数量 | number | - |
// 组件实例化
const config = { mode: 'mind' };
const mIns = new AntMind('#app', config);
const props = {
limit: { 'i': 1 },
// 该参数设置,需要render后才能生效
foldKeys: [],
// 其他参数
};
mIns.initProps(props);
// 浅更新
mIns.setConfig({ mode: 'outline' });
// 更新配置后,如果需要更新视图,则需要调用renderView方法
mIns.renderView();
const props = {
limit: { 'i': 1 },
foldKeys: [],
// 其他回调方法
};
const data = [];
mIns.render(data, props);
// id => 更新节点的id
// type => 更新方式:delete、move、update
// data => 最新的节点数据,在type === 'delete'时,可不传
mindIns.handleUpdate(id, type, data);
// 在思维导图模式下,用于更新视图的偏移位置
mIns.updateMatrix({
a: 1, // x轴缩放
b: 0, // 倾斜角度
c: 0, // 旋转角度
d: 1, // y轴缩放
e: 0, // x轴偏移量
f: 0 // y轴偏移量
});
// 在组件卸载时调用,用于注销组件涉及的浏览器事件
mIns.destroy();
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
IntrductionLibwebsocketsisasimple-to-use,MIT-license,pureClibraryprovidingclientandserverforhttp/1,http/2,websockets,MQTTandotherprotocolsinasecurity-minded,lightweight,configurable,scalableandflexibleway.It’seasytobuildandcross-buildviacmakeandissuitablefortasksfromembeddedRTOSthroughmasscloudservi
安全产品安全网关类防火墙Firewall防火墙防火墙主要用于边界安全防护的权限控制和安全域的划分。防火墙•信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。防火墙是一个由软件和硬件设备组合而成,在内外网之间、专网与公网之间的界面上构成的保护屏障。下一代防火墙•下一代防火墙,NextGenerationFirewall,简称NGFirewall,是一款可以全面应对应用层威胁的高性能防火墙,提供网络层应用层一体化安全防护。生产厂家•联想网御、CheckPoint、深信服、网康、天融信、华为、H3C等防火墙部署部署于内、外网编辑额,用于权限访问控制和安全域划分。UTM统一威胁管理(Un
在Rails3.x应用程序中,我正在使用net::ssh并向远程pc运行一些命令。我想向用户的浏览器显示实时日志。比如,如果两个命令在net中运行::ssh执行即echo"Hello",echo"Bye"被传递然后"Hello"应该在执行后立即显示在浏览器中。这是代码我在rubyonrails应用程序中使用ssh连接和运行命令Net::SSH.start(@servers['local'],@machine_name,:password=>@machine_pwd,:timeout=>30)do|ssh|ssh.open_channeldo|channel|channel.requ
我正在为Jekyll编写一个转换器插件,需要访问一些页眉(YAML前端)属性。只有内容被传递给主要的转换器方法,似乎无法访问上下文。例子:moduleJekyllclassUpcaseConverter关于如何在转换器插件中访问页眉数据有什么想法吗? 最佳答案 基于Jekyll源代码,无法在转换器中检索YAML前端内容。根据您的情况,我看到了两种可行的解决方案。您的文件扩展名可以具有足够的描述性,以提供您本应包含在前言中的信息。看起来Converter插件的设计就是这么基本的。如果修改Jekyll是一个选项,您可以更改Convert
一、简介之前在Vue项目中使用过element的上传组件,实现了点击上传+拖拽上传的两种上传功能。然后我就在想是否可以通过原生的html+js来实现文件的点击上传和拖拽上传,说干就干。首先是点击获取上传文件自然没的说,只需要借助input标签即可,但原生的点击上传按钮,实在是过于简陋,所以我的想法是通过一个div,模拟成上传按钮,然后监听其点击事件,通过input.click()去模拟点击真正的上传元素。然后是拖拽获取上传文件,这个稍有难度,我的想法是通过HTML5新增的drag拖放API+dataTransfer来实现文件的拖拽获取,但是由于是html5新增的,所以可能在某些低版本IE浏览器
我在使用rails3.0.7时遇到问题,这导致我提出了这个子问题:我在哪里可以找到3.0的Rails版本列表,例如3.0.0,3.0.1,3.0.11,.等等?我用谷歌搜索并查看了维基百科和SO以及各种主要的ruby站点,但找不到这个“版本列表”信息。 最佳答案 $gemlist-r--allrailsrails(3.2.2、3.2.1、3.2.0、3.1.4、3.1.3、3.1.2、3.1.1、3.1.0、3.0.12、3.0.11、3.0。10,3.0.9,3.0.8,3.0.7,3.0.6,3.0.5,3.0.4,3.0.
一、介绍一下vercelvercel是一个站点托管平台,提供CDN加速,同类的平台有Netlify和GithubPages,相比之下,vercel国内的访问速度更快,并且提供Production环境和development环境,对于项目开发非常的有用的,并且支持持续集成,一次push或者一次PR会自动化构建发布,发布在development环境,都会生成不一样的链接可供预览。但是vercel只是针对个人用户免费,teams是收费的首先vercel零配置部署,第二访问速度比github-page好很多,并且构建很快,还是免费使用的,对于部署个人前端项目路、接口服务非常方便vercel类似于git
🐱个人主页:不叫猫先生🙋♂️作者简介:前端领域新星创作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀!💫系列专栏:vue3从入门到精通、TypeScript从入门到实践📢资料领取:前端进阶资料以及文中源码可以找我免费领取🔥前端学习交流:博主建立了一个前端交流群,汇集了各路大神,一起交流学习,期待你的加入!(文末有我wx或者私信)目录前言一、vue自定义指令directive讲解二、基于DOM的实现方式1.思路整理2.新建index.vue3.新建`directives`文件4.在`directives`文件下创建`index.ts`文件5.在`main.ts`中全局引
GPT-4是OpenAI发布的最新一代语言模型,于2023年3月14日正式发布,并通过API和ChatGPTPlus平台向用户开放。微软也证实,在GPT-4正式发布之前,就已经在部分版本的Bing中使用GPT-4技术。本文旨在对使用GPT-4技术的NewBing进行中立、专业的使用评测,探讨其使用体验的变化。界面与限额早于2月26日小编获得Newbing试用资格,届时Newbing初体验并不理想,限制多,例如对话只能持续5条自动终止,对话字符受限,生成效果不尽如人意。然而今日对接GPT-4全新bing额度扩充至15条,且对话字数扩容至2000字。Newbing提供了三种模式选项,即创造力、平衡