From e584081b417c1bcfe3ee773e0dd9a9fb9dd32560 Mon Sep 17 00:00:00 2001 From: wanglin2 <1013335014@qq.com> Date: Fri, 21 Apr 2023 09:32:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/pages/Doc/en/xmind/index.md | 10 +- web/src/pages/Doc/en/xmind/index.vue | 10 +- web/src/pages/Doc/zh/course11/index.md | 2 +- web/src/pages/Doc/zh/course11/index.vue | 2 +- web/src/pages/Doc/zh/course16/index.md | 100 +++++++++- web/src/pages/Doc/zh/course16/index.vue | 61 +++++- web/src/pages/Doc/zh/course17/index.md | 244 ++++++++++++++++++++++- web/src/pages/Doc/zh/course17/index.vue | 176 +++++++++++++++- web/src/pages/Doc/zh/course18/index.md | 101 +++++++++- web/src/pages/Doc/zh/course18/index.vue | 65 +++++- web/src/pages/Doc/zh/xmind/index.md | 4 +- web/src/pages/Doc/zh/xmind/index.vue | 4 +- web/src/pages/Edit/components/Import.vue | 1 + 13 files changed, 755 insertions(+), 25 deletions(-) diff --git a/web/src/pages/Doc/en/xmind/index.md b/web/src/pages/Doc/en/xmind/index.md index e4d9274e..b26a54a7 100644 --- a/web/src/pages/Doc/en/xmind/index.md +++ b/web/src/pages/Doc/en/xmind/index.md @@ -24,9 +24,8 @@ MindMap.xmind ### xmind.parseXmindFile(file) -Parsing the `.xmind` file and returning the parsed data. Note that this is -complete data, including the node tree, theme, and structure. You can use -`mindMap.setFullData(data)` to render the returned data to the canvas. +Parsing the `.xmind` file and returning the parsed data. You can use +`mindMap.setData(data)` to render the returned data to the canvas. `file`: `File` object @@ -35,9 +34,8 @@ complete data, including the node tree, theme, and structure. You can use Convert `xmind` data. The `.xmind` file is essentially a `zip` file that can be decompressed by changing the suffix to zip. Inside, there is a `content.json` file. If you have parsed this file yourself, you can pass the contents of this -file to this method for conversion. The converted data is the complete data, -including the node tree, theme, structure, etc. You can use -`mindMap.setFullData(data)` to render the returned data to the canvas. +file to this method for conversion. You can use +`mindMap.setData(data)` to render the returned data to the canvas. `content`: the contents of the `content.json` file within the `.xmind` zip package diff --git a/web/src/pages/Doc/en/xmind/index.vue b/web/src/pages/Doc/en/xmind/index.vue index a2c3af24..323a9990 100644 --- a/web/src/pages/Doc/en/xmind/index.vue +++ b/web/src/pages/Doc/en/xmind/index.vue @@ -15,17 +15,15 @@
Parsing the .xmind file and returning the parsed data. Note that this is
-complete data, including the node tree, theme, and structure. You can use
-mindMap.setFullData(data) to render the returned data to the canvas.
Parsing the .xmind file and returning the parsed data. You can use
+mindMap.setData(data) to render the returned data to the canvas.
file: File object
Convert xmind data. The .xmind file is essentially a zip file that can be
decompressed by changing the suffix to zip. Inside, there is a content.json
file. If you have parsed this file yourself, you can pass the contents of this
-file to this method for conversion. The converted data is the complete data,
-including the node tree, theme, structure, etc. You can use
-mindMap.setFullData(data) to render the returned data to the canvas.
mindMap.setData(data) to render the returned data to the canvas.
content: the contents of the content.json file within the .xmind zip
package
simple-mind-map目前支持四种结构:logicalStructure(逻辑结构图)、mindMap(思维导图)、organizationStructure(组织结构图)、catalogOrganization(目录组织图)。
simple-mind-map目前支持四种结构:logicalStructure(逻辑结构图)、mindMap(思维导图)、organizationStructure(组织结构图)、catalogOrganization(目录组织图)、timeline(时间轴)、timeline2(时间轴2)、fishbone(鱼骨图)。
可以在实例化simple-mind-map时通过选项指定使用的结构:
new MindMap({
// ...
diff --git a/web/src/pages/Doc/zh/course16/index.md b/web/src/pages/Doc/zh/course16/index.md
index 6354013c..26d07840 100644
--- a/web/src/pages/Doc/zh/course16/index.md
+++ b/web/src/pages/Doc/zh/course16/index.md
@@ -1,3 +1,101 @@
# 如何渲染富文本的悬浮工具栏
-> 要支持节点富文本编辑需要使用富文本插件
\ No newline at end of file
+> 要支持节点富文本编辑需要使用富文本插件
+
+如果开启了节点富文本编辑,那么可以对节点内的部分文本应用样式,一般当选中文本时上方会出现一个工具栏,有加粗、斜体、改变颜色等等的按钮。
+
+首先要监听`rich_text_selection_change`事件,也就是选中文本的事件:
+
+```js
+mindMap.on('rich_text_selection_change', (hasRange, rect, formatInfo) => {
+ // hasRange(是否存在选区)
+ // rectInfo(选区的尺寸和位置信息)
+ // formatInfo(选区的文本格式化信息)
+ // 显示你的工具栏
+})
+```
+
+可以通过`hasRange`来判断是否显示工具栏,工具栏的位置可以通过`rectInfo`获取,通过`formatInfo`可以获取当前选中文本的样式信息,比如已经被加粗了,那么你的加粗按钮就可以渲染为激活状态。
+
+### 工具栏定位
+
+```js
+let left = rect.left + rect.width / 2 + 'px'
+let top = rect.top - 60 + 'px'
+```
+
+计算出来的是相对于浏览器窗口左上角的位置,所以你的工具栏元素最好是添加在body元素下面,并且使用固定定位或相对定位,另外`z-index`的属性最好也设置的高一点,否则在弹窗等场景下可能会被挡住。
+
+### 加粗/取消加粗
+
+```js
+mindMap.richText.formatText({
+ bold: true/false
+})
+```
+
+### 斜体/取消斜体
+
+```js
+mindMap.richText.formatText({
+ italic: true/false
+})
+```
+
+### 下划线/取消下划线
+
+```js
+mindMap.richText.formatText({
+ underline: true/false
+})
+```
+
+### 删除线/取消删除线
+
+```js
+mindMap.richText.formatText({
+ strike: true/false
+})
+```
+
+### 设置字体
+
+```js
+mindMap.richText.formatText({
+ font: '宋体, SimSun, Songti SC'
+})
+```
+
+### 设置字号
+
+```js
+mindMap.richText.formatText({
+ font: 16 + 'px'
+})
+```
+
+### 设置文字颜色
+
+```js
+mindMap.richText.formatText({
+ color: '#fff'
+})
+```
+
+### 设置文字背景颜色
+
+```js
+mindMap.richText.formatText({
+ background: '#fff'
+})
+```
+
+### 清除样式
+
+```js
+mindMap.richText.removeFormat()
+```
+
+## 完整示例
+
+
\ No newline at end of file
diff --git a/web/src/pages/Doc/zh/course16/index.vue b/web/src/pages/Doc/zh/course16/index.vue
index 24547b16..90e80f11 100644
--- a/web/src/pages/Doc/zh/course16/index.vue
+++ b/web/src/pages/Doc/zh/course16/index.vue
@@ -4,7 +4,66 @@
要支持节点富文本编辑需要使用富文本插件
-
+如果开启了节点富文本编辑,那么可以对节点内的部分文本应用样式,一般当选中文本时上方会出现一个工具栏,有加粗、斜体、改变颜色等等的按钮。
+首先要监听rich_text_selection_change事件,也就是选中文本的事件:
+mindMap.on('rich_text_selection_change', (hasRange, rect, formatInfo) => {
+ // hasRange(是否存在选区)
+ // rectInfo(选区的尺寸和位置信息)
+ // formatInfo(选区的文本格式化信息)
+ // 显示你的工具栏
+})
+
+可以通过hasRange来判断是否显示工具栏,工具栏的位置可以通过rectInfo获取,通过formatInfo可以获取当前选中文本的样式信息,比如已经被加粗了,那么你的加粗按钮就可以渲染为激活状态。
+工具栏定位
+let left = rect.left + rect.width / 2 + 'px'
+let top = rect.top - 60 + 'px'
+
+计算出来的是相对于浏览器窗口左上角的位置,所以你的工具栏元素最好是添加在body元素下面,并且使用固定定位或相对定位,另外z-index的属性最好也设置的高一点,否则在弹窗等场景下可能会被挡住。
+加粗/取消加粗
+mindMap.richText.formatText({
+ bold: true/false
+})
+
+斜体/取消斜体
+mindMap.richText.formatText({
+ italic: true/false
+})
+
+下划线/取消下划线
+mindMap.richText.formatText({
+ underline: true/false
+})
+
+删除线/取消删除线
+mindMap.richText.formatText({
+ strike: true/false
+})
+
+设置字体
+mindMap.richText.formatText({
+ font: '宋体, SimSun, Songti SC'
+})
+
+设置字号
+mindMap.richText.formatText({
+ font: 16 + 'px'
+})
+
+设置文字颜色
+mindMap.richText.formatText({
+ color: '#fff'
+})
+
+设置文字背景颜色
+mindMap.richText.formatText({
+ background: '#fff'
+})
+
+清除样式
+mindMap.richText.removeFormat()
+
+完整示例
+
编写中。。。
+++要使用导出功能需要使用导出插件。
+
目前支持导出为.smm、.json、.svg、.png、.pdf、.md文件。
.smm是simple-mind-map自己定义的一种文件,其实就是json文件,换了一个扩展名而已。
导出直接调用export方法即可。
这两种文件的导出是一样的:
+mindMap.export(type, isDownload, fileName, withConfig)
+
+withConfig指定导出的数据中是否要包含节点数据外的配置数据,比如使用的布局、主题等,传true,导出的结构如下:
{
+ layout,
+ root,
+ theme: {
+ template,
+ config
+ },
+ view
+}
+
+如果传false,导出的数据只有root部分,也就是纯节点树。
示例:
+mindMap.export('smm', true, '文件名', true)
+mindMap.export('json', true, '文件名', false)
+
+导出这两种文件很简单:
+mindMap.export('png', true, '文件名')
+mindMap.export('pdf', true, '文件名')
+
+如果开启了节点富文本编辑,那么导出会非常慢,因为需要挨个转换节点,所以如果导出操作很频繁的话建议关闭节点非文本编辑功能。
+导出为svg可以传递的参数如下:
mindMap.export(type, isDownload, fileName, domToImage = false, plusCssText = '')
+
+如果开启了节点富文本编辑功能,那么可以通过domToImage参数控制导出的svg中是否保留html结构,还是转换成图片形式,同样,如果传了true,导出会非常耗时,建议导出为svg时domToImage传false。
如果domToImage传的是false,也就是svg中会保留节点的html结构,这就又存在一个问题,因为浏览器对每个元素默认会设置一些样式,影响最大的就是margin和padding,这就有可能会导致节点中的文字错位,所以可以通过plusCssText参数传入css样式:
mindMap.export(
+ 'svg',
+ true,
+ '文件名',
+ false,
+ `* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }`
+)
+
+导出为markdown文件只要传递默认的三个参数即可:
mindMap.export('md', true, '文件名')
+
+目前支持从.smm、.json、.xmind、.xlsx、.md格式的文件导入。
这两个文件导入很简单,直接读取文件内容,转成对象,然后调用相关方法渲染到画布即可。
+因为导出这两种类型时可以选择是否包含配置数据,所以导入的时候调用的方法也是不一样的:
+let data = JSON.parse('json数据')
+// 如果数据中存在root属性,那么代表是包含配置的完整数据,则使用setFullData方法导入数据
+if (data.root) {
+ mindMap.setFullData(data)
+} else {
+// 否则使用setData方法导入
+ mindMap.setData(data)
+}
+// 导入数据后有可能新数据渲染在可视区域外了,所以为了更好的体验,可以复位一下视图的变换
+mindMap.view.reset()
+
+要导入xmind文件,需要引入xmind的解析方法:
import xmind from 'simple-mind-map/src/parse/xmind.js'
+
+如果使用的是umd文件,可以这样获取:
MindMap.xmind
+
+如果你是通过input type=file等方式获取到的File文件对象,那么可以直接传递给parseXmindFile方法解析,注意返回的是一个Promise实例,会返回解析后的节点树数据,使用setData方法渲染到画布即可。
let data = await xmind.parseXmindFile(file)
+mindMap.setData(data)
+
+.xmind文件本质上是一个压缩包,改成zip后缀可以解压缩,里面存在一个content.json文件,如果你自己解析出了这个文件,那么可以把这个文件内容传递给这个transformXmind方法进行转换:
let data = await xmind.transformXmind(fileContent)
+mindMap.setData(data)
+
+另外如果导入的是xmind8版本的数据,需要使用transformOldXmind方法。
这个文件的导入没有内置方法,需要你自己开发,以下是一个使用xlsx库的方式:
import { read, utils } from 'xlsx'
+// 文件转buffer
+export const fileToBuffer = file => {
+ return new Promise(r => {
+ const reader = new FileReader()
+ reader.onload = () => {
+ r(reader.result)
+ }
+ reader.readAsArrayBuffer(file)
+ })
+}
+
+// File文件对象
+const transformXLSXToJson = async (file) => {
+ const wb = read(await fileToBuffer(file))
+ const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], {
+ header: 1
+ })
+ if (data.length <= 0) {
+ return
+ }
+ let max = 0
+ data.forEach(arr => {
+ if (arr.length > max) {
+ max = arr.length
+ }
+ })
+ let layers = []
+ let walk = layer => {
+ if (!layers[layer]) {
+ layers[layer] = []
+ }
+ for (let i = 0; i < data.length; i++) {
+ if (data[i][layer]) {
+ let node = {
+ data: {
+ text: data[i][layer]
+ },
+ children: [],
+ _row: i
+ }
+ layers[layer].push(node)
+ }
+ }
+ if (layer < max - 1) {
+ walk(layer + 1)
+ }
+ }
+ walk(0)
+ let getParent = (arr, row) => {
+ for (let i = arr.length - 1; i >= 0; i--) {
+ if (row >= arr[i]._row) {
+ return arr[i]
+ }
+ }
+ }
+ for (let i = 1; i < layers.length; i++) {
+ let arr = layers[i]
+ for (let j = 0; j < arr.length; j++) {
+ let item = arr[j]
+ let parent = getParent(layers[i - 1], item._row)
+ if (parent) {
+ parent.children.push(item)
+ }
+ }
+ }
+
+ return layers[0][0]
+}
+
+let data = transformXLSXToJson('xlsx文件对象')
+mindMap.setData(data)
+
+要导入markdown文件需要引入相应的解析方法:
import markdown from 'simple-mind-map/src/parse/markdown.js'
+
+如果使用的是umd格式的文件,那么可以通过如下方式获取:
+MindMap.markdown
+
+获取到md文件的内容后调用transformMarkdownTo方法转换即可,返回一个Promise实例:
let data = await markdown.transformMarkdownTo('md文件内容')
+mindMap.setData(data)
+
+编写中。。。
- +在线demo的数据是存储在电脑本地的,也就是localStorage里,当然,你也可以存储到数据库中。
保存数据,一般有两种做法,一是让用户手动保存,二是当画布上的数据改变后自动保存,显然,第二中体验更好一点。
+要获取画布的数据,可以使用getData方法,可以传递一个参数,true指定返回的数据中包含配置数据,false指定只返回节点树数据。
const data = mindMap.getData(true)
+
+包含配置的完整数据结构:
+{
+ layout,
+ root,
+ theme: {
+ template,
+ config
+ },
+ view
+}
+
+你可以直接把获取到的数据保存起来即可。
+如果要自动保存,那么肯定需要监听相关事件:
+this.$bus.$on('data_change', data => {
+ // 节点树数据改变
+ // data即完整数据中的root部分
+})
+this.$bus.$on('view_data_change', data => {
+ // 视图数据改变
+ // data即完整数据中的view部分
+})
+
+主题和结构的改变一般是开发者提供一个ui界面让用户选择,所以可以自行触发保存。
+当从数据库获取到了保存的数据,那么怎么渲染到画布上呢,首先可以直接在new一个MindMap实例时直接传入:
// 从数据中取出各个部分
+let { root, layout, theme, view } = storeData
+let mindMap = new MindMap({
+ el: container,
+ data: root,
+ layout: layout,
+ theme: theme.template,
+ themeConfig: theme.config,
+ viewData: view,
+ // ...
+})
+
+其次如果是包含配置的完整数据也可以调用setFullData方法:
mindMap.setFullData(data)
+
+如果是纯节点数据可以调用setData方法:
mindMap.setData(data)
+
+修改结构可以调用setLayout方法:
mindMap.setLayout(layout)
+
+设置主题可以调用setTheme方法:
mindMap.setTheme(theme)
+
+设置主题配置可以调用setThemeConfig方法:
mindMap.setThemeConfig(themeConfig)
+
+设置视图数据可以调用view.setTransformData方法:
mindMap.view.setTransformData(view)
+
+解析.xmind文件,返回解析后的数据,注意是完整的数据,包含节点树、主题、结构等,可以使用mindMap.setFullData(data)来将返回的数据渲染到画布上
解析.xmind文件,返回解析后的数据,可以使用mindMap.setData(data)来将返回的数据渲染到画布上
file:File对象
转换xmind数据,.xmind文件本质上是一个压缩包,改成zip后缀可以解压缩,里面存在一个content.json文件,如果你自己解析出了这个文件,那么可以把这个文件内容传递给这个方法进行转换,转换后的数据,注意是完整的数据,包含节点树、主题、结构等,可以使用mindMap.setFullData(data)来将返回的数据渲染到画布上
转换xmind数据,.xmind文件本质上是一个压缩包,改成zip后缀可以解压缩,里面存在一个content.json文件,如果你自己解析出了这个文件,那么可以把这个文件内容传递给这个方法进行转换,转换后的数据,可以使用mindMap.setData(data)来将返回的数据渲染到画布上
content:.xmind压缩包内的content.json文件内容
diff --git a/web/src/pages/Edit/components/Import.vue b/web/src/pages/Edit/components/Import.vue index e936066d..e79cdd84 100644 --- a/web/src/pages/Edit/components/Import.vue +++ b/web/src/pages/Edit/components/Import.vue @@ -150,6 +150,7 @@ export default { async handleXmind(file) { try { let data = await xmind.parseXmindFile(file.raw) + console.log(data); this.$bus.$emit('setData', data) this.$message.success('导入成功') } catch (error) {