mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-19 23:08:32 +08:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b7b41597f | ||
|
|
e56ff8fdf2 | ||
|
|
3f9da8940f | ||
|
|
26d5f69af2 | ||
|
|
6efe4a3fd6 | ||
|
|
2b4ab4a322 | ||
|
|
cca42d1f89 | ||
|
|
724fef87b1 | ||
|
|
d50c0e4cd5 | ||
|
|
c18c037642 | ||
|
|
cda1da5fd0 | ||
|
|
eba1aa3a37 | ||
|
|
81018bb615 | ||
|
|
5fa0ff7b5c | ||
|
|
cabe286ebb |
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="./dist/logo.png"><title>一个简单的web思维导图实现</title><link href="dist/js/chunk-2d0a3179.05d77cdf.js" rel="prefetch"><link href="dist/js/chunk-2d0aa579.0b1c8d8d.js" rel="prefetch"><link href="dist/js/chunk-2d0aa978.040c6f5c.js" rel="prefetch"><link href="dist/js/chunk-2d0ab10b.4d871bf6.js" rel="prefetch"><link href="dist/js/chunk-2d0abe0f.ae972b36.js" rel="prefetch"><link href="dist/js/chunk-2d0b1c6f.7fcfc285.js" rel="prefetch"><link href="dist/js/chunk-2d0b361e.b094b87c.js" rel="prefetch"><link href="dist/js/chunk-2d0b91e5.34207f33.js" rel="prefetch"><link href="dist/js/chunk-2d0b92c3.ade5a7e0.js" rel="prefetch"><link href="dist/js/chunk-2d0ba309.c9a9ab22.js" rel="prefetch"><link href="dist/js/chunk-2d0bd54e.db6065c6.js" rel="prefetch"><link href="dist/js/chunk-2d0be174.1ffa155d.js" rel="prefetch"><link href="dist/js/chunk-2d0c0a44.e44018ef.js" rel="prefetch"><link href="dist/js/chunk-2d0c14fc.17d4f60a.js" rel="prefetch"><link href="dist/js/chunk-2d0c18d8.0921c70f.js" rel="prefetch"><link href="dist/js/chunk-2d0c191e.52b68dc1.js" rel="prefetch"><link href="dist/js/chunk-2d0c1a01.7cb4182f.js" rel="prefetch"><link href="dist/js/chunk-2d0c20be.57f5b62e.js" rel="prefetch"><link href="dist/js/chunk-2d0d5cb9.c67e6ecf.js" rel="prefetch"><link href="dist/js/chunk-2d0d9fbc.cd8db1ee.js" rel="prefetch"><link href="dist/js/chunk-2d0da701.6c0d2c1e.js" rel="prefetch"><link href="dist/js/chunk-2d0dad5f.2fd89008.js" rel="prefetch"><link href="dist/js/chunk-2d0db0f2.32d1bf7e.js" rel="prefetch"><link href="dist/js/chunk-2d0dddce.836132f8.js" rel="prefetch"><link href="dist/js/chunk-2d0ddf37.7b4a470a.js" rel="prefetch"><link href="dist/js/chunk-2d0de01b.00dad103.js" rel="prefetch"><link href="dist/js/chunk-2d0e2326.3c894463.js" rel="prefetch"><link href="dist/js/chunk-2d0e268c.95aec9d1.js" rel="prefetch"><link href="dist/js/chunk-2d0e5089.a4640577.js" rel="prefetch"><link href="dist/js/chunk-2d0e9742.bd5197f5.js" rel="prefetch"><link href="dist/js/chunk-2d0f026c.c3ec62ff.js" rel="prefetch"><link href="dist/js/chunk-2d2082b9.c7c6517f.js" rel="prefetch"><link href="dist/js/chunk-2d208ffa.af7fe897.js" rel="prefetch"><link href="dist/js/chunk-2d20ec02.917aff76.js" rel="prefetch"><link href="dist/js/chunk-2d20f68f.7639ecc2.js" rel="prefetch"><link href="dist/js/chunk-2d210a7a.e60ccf9b.js" rel="prefetch"><link href="dist/js/chunk-2d216004.fde7548f.js" rel="prefetch"><link href="dist/js/chunk-2d217907.3772894a.js" rel="prefetch"><link href="dist/js/chunk-2d226d0a.5947204c.js" rel="prefetch"><link href="dist/js/chunk-2d2299c3.0bdd83ab.js" rel="prefetch"><link href="dist/js/chunk-2d22bd06.1447b6d2.js" rel="prefetch"><link href="dist/js/chunk-2d2308b0.4fa18681.js" rel="prefetch"><link href="dist/js/chunk-2d238428.61fffbf5.js" rel="prefetch"><link href="dist/js/chunk-3a2f3e67.13278516.js" rel="prefetch"><link href="dist/css/app.2f2d473c.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.c097b26d.css" rel="preload" as="style"><link href="dist/js/app.e8192153.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.f9723ab8.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.c097b26d.css" rel="stylesheet"><link href="dist/css/app.2f2d473c.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="dist/js/chunk-vendors.f9723ab8.js"></script><script src="dist/js/app.e8192153.js"></script></body></html>
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="./dist/logo.png"><title>一个简单的web思维导图实现</title><link href="dist/js/chunk-2d0a3179.3b27bed0.js" rel="prefetch"><link href="dist/js/chunk-2d0a514a.64cc7822.js" rel="prefetch"><link href="dist/js/chunk-2d0aa579.61afd8c1.js" rel="prefetch"><link href="dist/js/chunk-2d0aa978.84fc06da.js" rel="prefetch"><link href="dist/js/chunk-2d0ab10b.4d405645.js" rel="prefetch"><link href="dist/js/chunk-2d0abe0f.a9abff6a.js" rel="prefetch"><link href="dist/js/chunk-2d0b1c6f.b8417307.js" rel="prefetch"><link href="dist/js/chunk-2d0b361e.d657e190.js" rel="prefetch"><link href="dist/js/chunk-2d0b91e5.433fdc5c.js" rel="prefetch"><link href="dist/js/chunk-2d0b92c3.9d7f8382.js" rel="prefetch"><link href="dist/js/chunk-2d0ba309.a3915823.js" rel="prefetch"><link href="dist/js/chunk-2d0bd54e.906e86ec.js" rel="prefetch"><link href="dist/js/chunk-2d0be174.0cf53d60.js" rel="prefetch"><link href="dist/js/chunk-2d0c0a44.0f9ebf1b.js" rel="prefetch"><link href="dist/js/chunk-2d0c14fc.7163274e.js" rel="prefetch"><link href="dist/js/chunk-2d0c18d8.2e6ddc70.js" rel="prefetch"><link href="dist/js/chunk-2d0c191e.cd5e6df3.js" rel="prefetch"><link href="dist/js/chunk-2d0c1a01.2e73bf0a.js" rel="prefetch"><link href="dist/js/chunk-2d0c20be.dab092ff.js" rel="prefetch"><link href="dist/js/chunk-2d0d5cb9.2e73ab77.js" rel="prefetch"><link href="dist/js/chunk-2d0d9fbc.4800807d.js" rel="prefetch"><link href="dist/js/chunk-2d0da701.80759043.js" rel="prefetch"><link href="dist/js/chunk-2d0dad5f.f670c26a.js" rel="prefetch"><link href="dist/js/chunk-2d0db0f2.b5ce4946.js" rel="prefetch"><link href="dist/js/chunk-2d0dd3b1.c4647d07.js" rel="prefetch"><link href="dist/js/chunk-2d0dddce.3eea98de.js" rel="prefetch"><link href="dist/js/chunk-2d0ddf37.d960b122.js" rel="prefetch"><link href="dist/js/chunk-2d0de01b.a2a047cf.js" rel="prefetch"><link href="dist/js/chunk-2d0e2326.5072607c.js" rel="prefetch"><link href="dist/js/chunk-2d0e268c.ed75c510.js" rel="prefetch"><link href="dist/js/chunk-2d0e5089.10135360.js" rel="prefetch"><link href="dist/js/chunk-2d0e9742.9abceada.js" rel="prefetch"><link href="dist/js/chunk-2d0f026c.4757f6bb.js" rel="prefetch"><link href="dist/js/chunk-2d2082b9.f52387a2.js" rel="prefetch"><link href="dist/js/chunk-2d208ffa.766e8fa6.js" rel="prefetch"><link href="dist/js/chunk-2d20ec02.917aff76.js" rel="prefetch"><link href="dist/js/chunk-2d20f68f.6c1b14e1.js" rel="prefetch"><link href="dist/js/chunk-2d210a7a.6a4911c4.js" rel="prefetch"><link href="dist/js/chunk-2d216004.704073c5.js" rel="prefetch"><link href="dist/js/chunk-2d217907.32a00939.js" rel="prefetch"><link href="dist/js/chunk-2d226d0a.6b1238d2.js" rel="prefetch"><link href="dist/js/chunk-2d2299c3.8f3151dd.js" rel="prefetch"><link href="dist/js/chunk-2d22bd06.9f7bbd4c.js" rel="prefetch"><link href="dist/js/chunk-2d2308b0.2797f6b4.js" rel="prefetch"><link href="dist/js/chunk-2d238428.7c9ae7c7.js" rel="prefetch"><link href="dist/js/chunk-3a2f3e67.13278516.js" rel="prefetch"><link href="dist/css/app.3b1827be.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.c097b26d.css" rel="preload" as="style"><link href="dist/js/app.e9e06d36.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.49b07a77.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.c097b26d.css" rel="stylesheet"><link href="dist/css/app.3b1827be.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="dist/js/chunk-vendors.49b07a77.js"></script><script src="dist/js/app.e9e06d36.js"></script></body></html>
|
||||
BIN
qrcode.jpg
BIN
qrcode.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 49 KiB |
@@ -5,9 +5,13 @@ import KeyboardNavigation from './src/KeyboardNavigation.js'
|
||||
import Export from './src/Export.js'
|
||||
import Drag from './src/Drag.js'
|
||||
import Select from './src/Select.js'
|
||||
import AssociativeLine from './src/AssociativeLine'
|
||||
import RichText from './src/RichText'
|
||||
import xmind from './src/parse/xmind.js'
|
||||
import markdown from './src/parse/markdown.js'
|
||||
|
||||
MindMap.xmind = xmind
|
||||
MindMap.markdown = markdown
|
||||
|
||||
MindMap
|
||||
.usePlugin(MiniMap)
|
||||
@@ -16,5 +20,7 @@ MindMap
|
||||
.usePlugin(KeyboardNavigation)
|
||||
.usePlugin(Export)
|
||||
.usePlugin(Select)
|
||||
.usePlugin(AssociativeLine)
|
||||
.usePlugin(RichText)
|
||||
|
||||
export default MindMap
|
||||
@@ -68,7 +68,11 @@ const defaultOpt = {
|
||||
// 鼠标滚动的行为,如果customHandleMousewheel传了自定义函数,这个属性不生效
|
||||
mousewheelAction: 'zoom',// zoom(放大缩小)、move(上下移动)
|
||||
// 当mousewheelAction设为move时,可以通过该属性控制鼠标滚动一下视图移动的步长,单位px
|
||||
mousewheelMoveStep: 100
|
||||
mousewheelMoveStep: 100,
|
||||
// 默认插入的二级节点的文字
|
||||
defaultInsertSecondLevelNodeText: '二级节点',
|
||||
// 默认插入的二级以下节点的文字
|
||||
defaultInsertBelowSecondLevelNodeText: '分支主题'
|
||||
}
|
||||
|
||||
// 思维导图
|
||||
|
||||
914
simple-mind-map/package-lock.json
generated
914
simple-mind-map/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "simple-mind-map",
|
||||
"version": "0.4.6",
|
||||
"version": "0.4.7",
|
||||
"description": "一个简单的web在线思维导图",
|
||||
"authors": [
|
||||
{
|
||||
@@ -31,6 +31,7 @@
|
||||
"html2canvas": "^1.4.1",
|
||||
"jspdf": "^2.5.1",
|
||||
"jszip": "^3.10.1",
|
||||
"mdast-util-from-markdown": "^1.3.0",
|
||||
"quill": "^1.3.6",
|
||||
"uuid": "^9.0.0",
|
||||
"xml-js": "^1.6.11"
|
||||
|
||||
@@ -1,33 +1,4 @@
|
||||
// 在下一个事件循环里执行任务
|
||||
const nextTick = function (fn, ctx) {
|
||||
let pending = false
|
||||
let timerFunc = null
|
||||
let handle = () => {
|
||||
pending = false
|
||||
ctx ? fn.call(ctx) : fn()
|
||||
}
|
||||
// 支持MutationObserver接口的话使用MutationObserver
|
||||
if (typeof MutationObserver !== 'undefined') {
|
||||
let counter = 1
|
||||
let observer = new MutationObserver(handle)
|
||||
let textNode = document.createTextNode(counter)
|
||||
observer.observe(textNode, {
|
||||
characterData: true // 设为 true 表示监视指定目标节点或子节点树中节点所包含的字符数据的变化
|
||||
})
|
||||
timerFunc = function () {
|
||||
counter = (counter + 1) % 2 // counter会在0和1两者循环变化
|
||||
textNode.data = counter // 节点变化会触发回调handle,
|
||||
}
|
||||
} else {
|
||||
// 否则使用定时器
|
||||
timerFunc = setTimeout
|
||||
}
|
||||
return function () {
|
||||
if (pending) return
|
||||
pending = true
|
||||
timerFunc(handle, 0)
|
||||
}
|
||||
}
|
||||
import { nextTick } from './utils'
|
||||
|
||||
// 批量执行
|
||||
class BatchExecution {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { copyRenderTree, simpleDeepClone } from './utils'
|
||||
import { copyRenderTree, simpleDeepClone, nextTick } from './utils'
|
||||
|
||||
// 命令类
|
||||
class Command {
|
||||
@@ -11,6 +11,7 @@ class Command {
|
||||
this.activeHistoryIndex = 0
|
||||
// 注册快捷键
|
||||
this.registerShortcutKeys()
|
||||
this.addHistory = nextTick(this.addHistory, this)
|
||||
}
|
||||
|
||||
// 清空历史数据
|
||||
@@ -36,7 +37,7 @@ class Command {
|
||||
this.commands[name].forEach(fn => {
|
||||
fn(...args)
|
||||
})
|
||||
if (name === 'BACK' || name === 'FORWARD') {
|
||||
if (['BACK', 'FORWARD', 'SET_NODE_ACTIVE', 'CLEAR_ACTIVE_NODE'].includes(name)) {
|
||||
return
|
||||
}
|
||||
this.addHistory()
|
||||
@@ -80,6 +81,8 @@ class Command {
|
||||
if (this.history.length > 0 && JSON.stringify(this.history[this.history.length - 1]) === JSON.stringify(data)) {
|
||||
return
|
||||
}
|
||||
// 删除当前历史指针后面的数据
|
||||
this.history = this.history.slice(0, this.activeHistoryIndex + 1)
|
||||
this.history.push(simpleDeepClone(data))
|
||||
this.activeHistoryIndex = this.history.length - 1
|
||||
this.mindMap.emit('data_change', data)
|
||||
@@ -125,7 +128,7 @@ class Command {
|
||||
|
||||
// 获取渲染树数据副本
|
||||
getCopyData() {
|
||||
return copyRenderTree({}, this.mindMap.renderer.renderTree)
|
||||
return copyRenderTree({}, this.mindMap.renderer.renderTree, true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { imgToDataUrl, downloadFile } from './utils'
|
||||
import JsPDF from 'jspdf'
|
||||
import { SVG } from '@svgdotjs/svg.js'
|
||||
import drawBackgroundImageToCanvas from './utils/simulateCSSBackgroundInCanvas'
|
||||
import { transformToMarkdown } from './parse/toMarkdown'
|
||||
const URL = window.URL || window.webkitURL || window
|
||||
|
||||
// 导出类
|
||||
@@ -40,8 +41,10 @@ class Export {
|
||||
let nodeWithDomToImg = null
|
||||
if (domToImage && this.mindMap.richText) {
|
||||
let res = await this.mindMap.richText.handleSvgDomElements(svg)
|
||||
nodeWithDomToImg = res.svg
|
||||
svgHTML = res.svgHTML
|
||||
if (res) {
|
||||
nodeWithDomToImg = res.svg
|
||||
svgHTML = res.svgHTML
|
||||
}
|
||||
}
|
||||
return {
|
||||
node: svg,
|
||||
@@ -236,6 +239,14 @@ class Export {
|
||||
smm(name, withConfig) {
|
||||
return this.json(name, withConfig)
|
||||
}
|
||||
|
||||
// markdown文件
|
||||
md() {
|
||||
let data = this.mindMap.getData()
|
||||
let content = transformToMarkdown(data)
|
||||
let blob = new Blob([content])
|
||||
return URL.createObjectURL(blob)
|
||||
}
|
||||
}
|
||||
|
||||
Export.instanceName = 'doExport'
|
||||
|
||||
@@ -353,17 +353,26 @@ class Render {
|
||||
}
|
||||
}
|
||||
|
||||
// 规范指定节点数据
|
||||
formatAppointNodes(appointNodes) {
|
||||
if (!appointNodes) return []
|
||||
return Array.isArray(appointNodes) ? appointNodes: [appointNodes]
|
||||
}
|
||||
|
||||
// 插入同级节点,多个节点只会操作第一个节点
|
||||
|
||||
insertNode(openEdit = true) {
|
||||
if (this.activeNodeList.length <= 0) {
|
||||
insertNode(openEdit = true, appointNodes = [], appointData = null) {
|
||||
appointNodes = this.formatAppointNodes(appointNodes)
|
||||
if (this.activeNodeList.length <= 0 && appointNodes.length <= 0) {
|
||||
return
|
||||
}
|
||||
let first = this.activeNodeList[0]
|
||||
let { defaultInsertSecondLevelNodeText, defaultInsertBelowSecondLevelNodeText } = this.mindMap.opt
|
||||
let list = appointNodes.length > 0 ? appointNodes : this.activeNodeList
|
||||
let first = list[0]
|
||||
if (first.isRoot) {
|
||||
this.insertChildNode()
|
||||
this.insertChildNode(openEdit, appointNodes, appointData)
|
||||
} else {
|
||||
let text = first.layerIndex === 1 ? '二级节点' : '分支主题'
|
||||
let text = first.layerIndex === 1 ? defaultInsertSecondLevelNodeText : defaultInsertBelowSecondLevelNodeText
|
||||
if (first.layerIndex === 1) {
|
||||
first.parent.initRender = true
|
||||
}
|
||||
@@ -372,7 +381,8 @@ class Render {
|
||||
inserting: openEdit,
|
||||
data: {
|
||||
text: text,
|
||||
expand: true
|
||||
expand: true,
|
||||
...(appointData || {})
|
||||
},
|
||||
children: []
|
||||
})
|
||||
@@ -382,20 +392,24 @@ class Render {
|
||||
|
||||
// 插入子节点
|
||||
|
||||
insertChildNode(openEdit = true) {
|
||||
if (this.activeNodeList.length <= 0) {
|
||||
insertChildNode(openEdit = true, appointNodes = [], appointData = null) {
|
||||
appointNodes = this.formatAppointNodes(appointNodes)
|
||||
if (this.activeNodeList.length <= 0 && appointNodes.length <= 0) {
|
||||
return
|
||||
}
|
||||
this.activeNodeList.forEach(node => {
|
||||
let { defaultInsertSecondLevelNodeText, defaultInsertBelowSecondLevelNodeText } = this.mindMap.opt
|
||||
let list = appointNodes.length > 0 ? appointNodes : this.activeNodeList
|
||||
list.forEach(node => {
|
||||
if (!node.nodeData.children) {
|
||||
node.nodeData.children = []
|
||||
}
|
||||
let text = node.isRoot ? '二级节点' : '分支主题'
|
||||
let text = node.isRoot ? defaultInsertSecondLevelNodeText : defaultInsertBelowSecondLevelNodeText
|
||||
node.nodeData.children.push({
|
||||
inserting: openEdit,
|
||||
data: {
|
||||
text: text,
|
||||
expand: true
|
||||
expand: true,
|
||||
...(appointData || {})
|
||||
},
|
||||
children: []
|
||||
})
|
||||
@@ -548,11 +562,14 @@ class Render {
|
||||
|
||||
// 移除节点
|
||||
|
||||
removeNode() {
|
||||
if (this.activeNodeList.length <= 0) {
|
||||
removeNode(appointNodes = []) {
|
||||
appointNodes = this.formatAppointNodes(appointNodes)
|
||||
if (this.activeNodeList.length <= 0 && appointNodes.length <= 0) {
|
||||
return
|
||||
}
|
||||
let root = this.activeNodeList.find((node) => {
|
||||
let isAppointNodes = appointNodes.length > 0
|
||||
let list = isAppointNodes ? appointNodes : this.activeNodeList
|
||||
let root = list.find((node) => {
|
||||
return node.isRoot
|
||||
})
|
||||
if (root) {
|
||||
@@ -563,8 +580,9 @@ class Render {
|
||||
root.children = []
|
||||
root.nodeData.children = []
|
||||
} else {
|
||||
for (let i = 0; i < this.activeNodeList.length; i++) {
|
||||
let node = this.activeNodeList[i]
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let node = list[i]
|
||||
if (isAppointNodes) list.splice(i, 1)
|
||||
if (node.isGeneralization) {
|
||||
// 删除概要节点
|
||||
this.setNodeData(node.generalizationBelongNode, {
|
||||
@@ -580,8 +598,7 @@ class Render {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.activeNodeList = []
|
||||
this.mindMap.emit('node_active', null, [])
|
||||
this.mindMap.emit('node_active', null, this.activeNodeList)
|
||||
this.mindMap.render()
|
||||
}
|
||||
|
||||
|
||||
@@ -97,13 +97,16 @@ class RichText {
|
||||
this.mindMap.renderer.textEdit.registerTmpShortcut()
|
||||
if (!this.textEditNode) {
|
||||
this.textEditNode = document.createElement('div')
|
||||
this.textEditNode.style.cssText = `position:fixed;box-sizing: border-box;background-color:#fff;box-shadow: 0 0 20px rgba(0,0,0,.5);outline: none; word-break: break-all;`
|
||||
this.textEditNode.style.cssText = `position:fixed;box-sizing: border-box;box-shadow: 0 0 20px rgba(0,0,0,.5);outline: none; word-break: break-all;`
|
||||
document.body.appendChild(this.textEditNode)
|
||||
}
|
||||
// 原始宽高
|
||||
let g = node._textData.node
|
||||
let originWidth = g.attr('data-width')
|
||||
let originHeight = g.attr('data-height')
|
||||
// 使用节点的填充色,否则如果节点颜色是白色的话编辑时看不见
|
||||
let bgColor = node.style.merge('fillColor')
|
||||
this.textEditNode.style.backgroundColor = bgColor === 'transparent' ? '#fff' : bgColor
|
||||
this.textEditNode.style.minWidth = originWidth + 'px'
|
||||
this.textEditNode.style.minHeight = originHeight + 'px'
|
||||
this.textEditNode.style.left =
|
||||
@@ -126,7 +129,7 @@ class RichText {
|
||||
this.initQuillEditor()
|
||||
document.querySelector('.ql-editor').style.minHeight = originHeight + 'px'
|
||||
this.showTextEdit = true
|
||||
this.selectAll()
|
||||
this.focus()
|
||||
if (!node.nodeData.data.richText) {
|
||||
// 如果是非富文本的情况,需要手动应用文本样式
|
||||
this.setTextStyleIfNotRichText(node)
|
||||
@@ -228,6 +231,12 @@ class RichText {
|
||||
this.quill.setSelection(0, this.quill.getLength())
|
||||
}
|
||||
|
||||
// 聚焦
|
||||
focus() {
|
||||
let len = this.quill.getLength()
|
||||
this.quill.setSelection(len, len)
|
||||
}
|
||||
|
||||
// 格式化当前选中的文本
|
||||
formatText(config = {}, clear = false) {
|
||||
if (!this.range && !this.lastRange) return
|
||||
@@ -407,7 +416,11 @@ class RichText {
|
||||
reject(error)
|
||||
}
|
||||
}
|
||||
if (len > 0) transform()
|
||||
if (len > 0) {
|
||||
transform()
|
||||
} else {
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -429,6 +442,9 @@ class RichText {
|
||||
0,
|
||||
0
|
||||
)
|
||||
// 清空历史数据,并且触发数据变化
|
||||
this.mindMap.command.clearHistory()
|
||||
this.mindMap.command.addHistory()
|
||||
this.mindMap.reRender()
|
||||
}
|
||||
|
||||
|
||||
7
simple-mind-map/src/parse/markdown.js
Normal file
7
simple-mind-map/src/parse/markdown.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { transformToMarkdown } from './toMarkdown'
|
||||
import { transformMarkdownTo } from './markdownTo'
|
||||
|
||||
export default {
|
||||
transformToMarkdown,
|
||||
transformMarkdownTo
|
||||
}
|
||||
98
simple-mind-map/src/parse/markdownTo.js
Normal file
98
simple-mind-map/src/parse/markdownTo.js
Normal file
@@ -0,0 +1,98 @@
|
||||
import { fromMarkdown } from 'mdast-util-from-markdown'
|
||||
|
||||
// 处理list的情况
|
||||
const handleList = node => {
|
||||
let list = []
|
||||
let walk = (arr, newArr) => {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let cur = arr[i]
|
||||
let node = {}
|
||||
node.data = {
|
||||
// 节点内容
|
||||
text: cur.children[0].children[0].value
|
||||
}
|
||||
node.children = []
|
||||
newArr.push(node)
|
||||
if (cur.children.length > 1) {
|
||||
for (let j = 1; j < cur.children.length; j++) {
|
||||
let cur2 = cur.children[j]
|
||||
if (cur2.type === 'list') {
|
||||
walk(cur2.children, node.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
walk(node.children, list)
|
||||
return list
|
||||
}
|
||||
|
||||
// 将markdown转换成节点树
|
||||
export const transformMarkdownTo = async md => {
|
||||
const tree = fromMarkdown(md)
|
||||
let root = {
|
||||
children: []
|
||||
}
|
||||
let childrenQueue = [root.children]
|
||||
let currentChildren = root.children
|
||||
let depthQueue = [-1]
|
||||
let currentDepth = -1
|
||||
for (let i = 0; i < tree.children.length; i++) {
|
||||
let cur = tree.children[i]
|
||||
if (cur.type === 'heading') {
|
||||
if (!cur.children[0]) continue
|
||||
// 创建新节点
|
||||
let node = {}
|
||||
node.data = {
|
||||
// 节点内容
|
||||
text: cur.children[0].value
|
||||
}
|
||||
node.children = []
|
||||
// 如果当前的层级大于上一个节点的层级,那么是其子节点
|
||||
if (cur.depth > currentDepth) {
|
||||
// 添加到上一个节点的子节点列表里
|
||||
currentChildren.push(node)
|
||||
// 更新当前栈和数据
|
||||
childrenQueue.push(node.children)
|
||||
currentChildren = node.children
|
||||
depthQueue.push(cur.depth)
|
||||
currentDepth = cur.depth
|
||||
} else if (cur.depth === currentDepth) {
|
||||
// 如果当前层级等于上一个节点的层级,说明它们是同级节点
|
||||
// 将上一个节点出栈
|
||||
childrenQueue.pop()
|
||||
currentChildren = childrenQueue[childrenQueue.length - 1]
|
||||
depthQueue.pop()
|
||||
currentDepth = depthQueue[depthQueue.length - 1]
|
||||
// 追加到上上个节点的子节点列表里
|
||||
currentChildren.push(node)
|
||||
// 更新当前栈和数据
|
||||
childrenQueue.push(node.children)
|
||||
currentChildren = node.children
|
||||
depthQueue.push(cur.depth)
|
||||
currentDepth = cur.depth
|
||||
} else {
|
||||
// 如果当前层级小于上一个节点的层级,那么一直出栈,直到遇到比当前层级小的节点
|
||||
while (depthQueue.length) {
|
||||
childrenQueue.pop()
|
||||
currentChildren = childrenQueue[childrenQueue.length - 1]
|
||||
depthQueue.pop()
|
||||
currentDepth = depthQueue[depthQueue.length - 1]
|
||||
if (currentDepth < cur.depth) {
|
||||
// 追加到该节点的子节点列表里
|
||||
currentChildren.push(node)
|
||||
// 更新当前栈和数据
|
||||
childrenQueue.push(node.children)
|
||||
currentChildren = node.children
|
||||
depthQueue.push(cur.depth)
|
||||
currentDepth = cur.depth
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (cur.type === 'list') {
|
||||
currentChildren.push(...handleList(cur))
|
||||
}
|
||||
}
|
||||
return root.children[0]
|
||||
}
|
||||
53
simple-mind-map/src/parse/toMarkdown.js
Normal file
53
simple-mind-map/src/parse/toMarkdown.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import { walk } from '../utils'
|
||||
|
||||
let el = null
|
||||
const getText = str => {
|
||||
if (!el) {
|
||||
el = document.createElement('div')
|
||||
}
|
||||
el.innerHTML = str
|
||||
return el.textContent
|
||||
}
|
||||
|
||||
const getTitleMark = level => {
|
||||
return new Array(level).fill('#').join('')
|
||||
}
|
||||
|
||||
const getIndentMark = level => {
|
||||
return new Array(level - 6).fill(' ').join('') + '*'
|
||||
}
|
||||
|
||||
// 转换成markdown格式
|
||||
export const transformToMarkdown = root => {
|
||||
let content = ''
|
||||
walk(
|
||||
root,
|
||||
null,
|
||||
(node, parent, isRoot, layerIndex) => {
|
||||
let level = layerIndex + 1
|
||||
let text = node.data.richText ? getText(node.data.text) : node.data.text
|
||||
if (level <= 6) {
|
||||
content += getTitleMark(level)
|
||||
} else {
|
||||
content += getIndentMark(level)
|
||||
}
|
||||
content += ' ' + text
|
||||
// 概要
|
||||
let generalization = node.data.generalization
|
||||
if (generalization && generalization.text) {
|
||||
let generalizationText = generalization.richText
|
||||
? getText(generalization.text)
|
||||
: generalization.text
|
||||
content += `[${generalizationText}]`
|
||||
}
|
||||
content += '\n\n'
|
||||
// 备注
|
||||
if (node.data.note) {
|
||||
content += node.data.note + '\n\n'
|
||||
}
|
||||
},
|
||||
() => {},
|
||||
true
|
||||
)
|
||||
return content
|
||||
}
|
||||
@@ -122,12 +122,15 @@ export const simpleDeepClone = data => {
|
||||
}
|
||||
|
||||
// 复制渲染树数据
|
||||
export const copyRenderTree = (tree, root) => {
|
||||
export const copyRenderTree = (tree, root, removeActiveState = false) => {
|
||||
tree.data = simpleDeepClone(root.data)
|
||||
if (removeActiveState) {
|
||||
tree.data.isActive = false
|
||||
}
|
||||
tree.children = []
|
||||
if (root.children && root.children.length > 0) {
|
||||
root.children.forEach((item, index) => {
|
||||
tree.children[index] = copyRenderTree({}, item)
|
||||
tree.children[index] = copyRenderTree({}, item, removeActiveState)
|
||||
})
|
||||
}
|
||||
return tree
|
||||
@@ -267,4 +270,35 @@ export const measureText = (text, { italic, bold, fontSize, fontFamily }) => {
|
||||
// 拼接font字符串
|
||||
export const joinFontStr = ({ italic, bold, fontSize, fontFamily }) => {
|
||||
return `${italic ? 'italic ' : ''} ${bold ? 'bold ' : ''} ${fontSize}px ${fontFamily} `
|
||||
}
|
||||
|
||||
// 在下一个事件循环里执行任务
|
||||
export const nextTick = function (fn, ctx) {
|
||||
let pending = false
|
||||
let timerFunc = null
|
||||
let handle = () => {
|
||||
pending = false
|
||||
ctx ? fn.call(ctx) : fn()
|
||||
}
|
||||
// 支持MutationObserver接口的话使用MutationObserver
|
||||
if (typeof MutationObserver !== 'undefined') {
|
||||
let counter = 1
|
||||
let observer = new MutationObserver(handle)
|
||||
let textNode = document.createTextNode(counter)
|
||||
observer.observe(textNode, {
|
||||
characterData: true // 设为 true 表示监视指定目标节点或子节点树中节点所包含的字符数据的变化
|
||||
})
|
||||
timerFunc = function () {
|
||||
counter = (counter + 1) % 2 // counter会在0和1两者循环变化
|
||||
textNode.data = counter // 节点变化会触发回调handle,
|
||||
}
|
||||
} else {
|
||||
// 否则使用定时器
|
||||
timerFunc = setTimeout
|
||||
}
|
||||
return function () {
|
||||
if (pending) return
|
||||
pending = true
|
||||
timerFunc(handle, 0)
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2479351 */
|
||||
src: url('iconfont.woff2?t=1678955183884') format('woff2'),
|
||||
url('iconfont.woff?t=1678955183884') format('woff'),
|
||||
url('iconfont.ttf?t=1678955183884') format('truetype');
|
||||
src: url('iconfont.woff2?t=1679621707211') format('woff2'),
|
||||
url('iconfont.woff?t=1679621707211') format('woff'),
|
||||
url('iconfont.ttf?t=1679621707211') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@@ -13,6 +13,30 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.iconwenjian:before {
|
||||
content: "\e607";
|
||||
}
|
||||
|
||||
.iconpdf:before {
|
||||
content: "\e740";
|
||||
}
|
||||
|
||||
.iconPNG:before {
|
||||
content: "\ec18";
|
||||
}
|
||||
|
||||
.iconSVG:before {
|
||||
content: "\e621";
|
||||
}
|
||||
|
||||
.iconmarkdown:before {
|
||||
content: "\ec04";
|
||||
}
|
||||
|
||||
.iconjson:before {
|
||||
content: "\ea42";
|
||||
}
|
||||
|
||||
.iconlianjiexian:before {
|
||||
content: "\e75b";
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -369,3 +369,43 @@ export const sidebarTriggerList = [
|
||||
icon: 'iconjianpan'
|
||||
}
|
||||
]
|
||||
|
||||
// 下载类型列表
|
||||
export const downTypeList = [
|
||||
{
|
||||
name: 'Dedicated file',
|
||||
type: 'smm',
|
||||
icon: 'iconwenjian',
|
||||
desc: 'Available for import'
|
||||
},
|
||||
{
|
||||
name: 'JSON',
|
||||
type: 'json',
|
||||
icon: 'iconjson',
|
||||
desc: 'Popular data exchange formats, Available for import'
|
||||
},
|
||||
{
|
||||
name: 'Image',
|
||||
type: 'png',
|
||||
icon: 'iconPNG',
|
||||
desc: 'Suitable for viewing and sharing'
|
||||
},
|
||||
{
|
||||
name: 'SVG',
|
||||
type: 'svg',
|
||||
icon: 'iconSVG',
|
||||
desc: 'Scalable Vector Graphics'
|
||||
},
|
||||
{
|
||||
name: 'PDF',
|
||||
type: 'pdf',
|
||||
icon: 'iconpdf',
|
||||
desc: 'Suitable for printing'
|
||||
},
|
||||
{
|
||||
name: 'Markdown',
|
||||
type: 'md',
|
||||
icon: 'iconmarkdown',
|
||||
desc: 'Easy for other software to open'
|
||||
}
|
||||
]
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
shortcutKeyList as shortcutKeyListZh,
|
||||
shapeList as shapeListZh,
|
||||
sidebarTriggerList as sidebarTriggerListZh,
|
||||
backgroundSizeList as backgroundSizeListZh
|
||||
backgroundSizeList as backgroundSizeListZh,
|
||||
downTypeList as downTypeListZh
|
||||
} from './zh'
|
||||
import {
|
||||
fontFamilyList as fontFamilyListEn,
|
||||
@@ -26,7 +27,8 @@ import {
|
||||
shortcutKeyList as shortcutKeyListEn,
|
||||
shapeList as shapeListEn,
|
||||
sidebarTriggerList as sidebarTriggerListEn,
|
||||
backgroundSizeList as backgroundSizeListEn
|
||||
backgroundSizeList as backgroundSizeListEn,
|
||||
downTypeList as downTypeListEn
|
||||
} from './en'
|
||||
|
||||
const fontFamilyList = {
|
||||
@@ -74,6 +76,11 @@ const sidebarTriggerList = {
|
||||
en: sidebarTriggerListEn
|
||||
}
|
||||
|
||||
const downTypeList = {
|
||||
zh: downTypeListZh,
|
||||
en: downTypeListEn
|
||||
}
|
||||
|
||||
export {
|
||||
fontSizeList,
|
||||
lineHeightList,
|
||||
@@ -91,5 +98,6 @@ export {
|
||||
backgroundSizeList,
|
||||
shortcutKeyList,
|
||||
shapeList,
|
||||
sidebarTriggerList
|
||||
sidebarTriggerList,
|
||||
downTypeList
|
||||
}
|
||||
|
||||
@@ -441,3 +441,43 @@ export const sidebarTriggerList = [
|
||||
icon: 'iconjianpan'
|
||||
}
|
||||
]
|
||||
|
||||
// 下载类型列表
|
||||
export const downTypeList = [
|
||||
{
|
||||
name: '专有文件',
|
||||
type: 'smm',
|
||||
icon: 'iconwenjian',
|
||||
desc: '可用于导入'
|
||||
},
|
||||
{
|
||||
name: 'JSON',
|
||||
type: 'json',
|
||||
icon: 'iconjson',
|
||||
desc: '流行的数据交换格式,可用于导入'
|
||||
},
|
||||
{
|
||||
name: '图片',
|
||||
type: 'png',
|
||||
icon: 'iconPNG',
|
||||
desc: '适合查看分享'
|
||||
},
|
||||
{
|
||||
name: 'SVG',
|
||||
type: 'svg',
|
||||
icon: 'iconSVG',
|
||||
desc: '可缩放矢量图形'
|
||||
},
|
||||
{
|
||||
name: 'PDF',
|
||||
type: 'pdf',
|
||||
icon: 'iconpdf',
|
||||
desc: '适合打印'
|
||||
},
|
||||
{
|
||||
name: 'Markdown',
|
||||
type: 'md',
|
||||
icon: 'iconmarkdown',
|
||||
desc: '便于其他软件打开'
|
||||
}
|
||||
]
|
||||
@@ -88,6 +88,7 @@ export default {
|
||||
imageFile: 'Image file',
|
||||
svgFile: 'svg file',
|
||||
pdfFile: 'pdf file',
|
||||
markdownFile: 'markdown file',
|
||||
tips: 'tips: .smm and .json file can be import',
|
||||
domToImage: 'Whether to convert rich text nodes in svg into pictures',
|
||||
pngTips: 'tips: Exporting pictures in rich text mode is time-consuming. It is recommended to export to svg format',
|
||||
@@ -103,7 +104,7 @@ export default {
|
||||
import: {
|
||||
title: 'Import',
|
||||
selectFile: 'Select file',
|
||||
supportFile: 'Support .smm、.json、.xmind、.xlsx file'
|
||||
supportFile: 'Support .smm、.json、.xmind、.xlsx、.md file'
|
||||
},
|
||||
navigatorToolbar: {
|
||||
openMiniMap: 'Open mini map',
|
||||
|
||||
@@ -88,6 +88,7 @@ export default {
|
||||
imageFile: '图片文件',
|
||||
svgFile: 'svg文件',
|
||||
pdfFile: 'pdf文件',
|
||||
markdownFile: 'markdown文件',
|
||||
tips: 'tips:.smm和.json文件可用于导入',
|
||||
domToImage: '是否将svg中富文本节点转换成图片',
|
||||
pngTips: 'tips:富文本模式导出图片非常耗时,建议导出为svg格式',
|
||||
@@ -103,7 +104,7 @@ export default {
|
||||
import: {
|
||||
title: '导入',
|
||||
selectFile: '选取文件',
|
||||
supportFile: '支持.smm、.json、.xmind、.xlsx文件'
|
||||
supportFile: '支持.smm、.json、.xmind、.xlsx、.md文件'
|
||||
},
|
||||
navigatorToolbar: {
|
||||
openMiniMap: '开启小地图',
|
||||
|
||||
@@ -28,6 +28,7 @@ let APIList = [
|
||||
'watermark',
|
||||
'associativeLine',
|
||||
'xmind',
|
||||
'markdown',
|
||||
'utils'
|
||||
]
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 0.4.7
|
||||
|
||||
optimization: 1.During rich text editing, when initially focusing, all are no longer selected by default; 2.When editing rich text, use the node fill color as the background color to avoid being invisible when the node color is white. 3.Node activation state switching no longer triggers history. 4.Triggering history multiple times in a short time will only add the last data. 5.Optimize the addition of historical records. When there is a rollback, delete the historical data after the current pointer when adding a new record again.
|
||||
|
||||
New: 1.Support for importing and exporting Markdown format files. 2.Support for configuring initial text when inserting nodes. 3.Expand the commands for inserting and deleting nodes to support specifying nodes.
|
||||
|
||||
## 0.4.6
|
||||
|
||||
New: 1.Associated lines support adjusting control points.
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.4.7</h2>
|
||||
<p>optimization: 1.During rich text editing, when initially focusing, all are no longer selected by default; 2.When editing rich text, use the node fill color as the background color to avoid being invisible when the node color is white. 3.Node activation state switching no longer triggers history. 4.Triggering history multiple times in a short time will only add the last data. 5.Optimize the addition of historical records. When there is a rollback, delete the historical data after the current pointer when adding a new record again.</p>
|
||||
<p>New: 1.Support for importing and exporting Markdown format files. 2.Support for configuring initial text when inserting nodes. 3.Expand the commands for inserting and deleting nodes to support specifying nodes.</p>
|
||||
<h2>0.4.6</h2>
|
||||
<p>New: 1.Associated lines support adjusting control points.</p>
|
||||
<p>optimization: 1.When adding historical data, filter data that has not changed compared to the previous time.</p>
|
||||
|
||||
@@ -44,6 +44,8 @@ const mindMap = new MindMap({
|
||||
| customHandleMousewheel(v0.4.3+) | Function | null | User-defined mouse wheel event processing can pass a function, and the callback parameter is the event object | |
|
||||
| mousewheelAction(v0.4.3+) | String | zoom | The behavior of the mouse wheel, `zoom`(Zoom in and out)、`move`(Move up and down). If `customHandleMousewheel` passes a custom function, this property will not take effect | |
|
||||
| mousewheelMoveStep(v0.4.3+) | Number | 100 | When the `mousewheelAction` is set to `move`, you can use this attribute to control the step length of the view movement when the mouse scrolls. The unit is `px` | |
|
||||
| defaultInsertSecondLevelNodeText(v0.4.7+) | String | 二级节点 | Text of the default inserted secondary node | |
|
||||
| defaultInsertBelowSecondLevelNodeText(v0.4.7+) | String | 分支主题 | Text for nodes below the second level inserted by default | |
|
||||
|
||||
### Watermark config
|
||||
|
||||
@@ -269,11 +271,11 @@ redo. All commands are as follows:
|
||||
| SELECT_ALL | Select all | |
|
||||
| BACK | Go back a specified number of steps | step (the number of steps to go back, default is 1) |
|
||||
| FORWARD | Go forward a specified number of steps | step (the number of steps to go forward, default is 1) |
|
||||
| INSERT_NODE | Insert a sibling node, the active node will be the operation node. If there are multiple active nodes, only the first one will be effective | openEdit(v0.4.6+, Whether to activate the newly inserted node and enter editing mode, default is `true`) |
|
||||
| INSERT_CHILD_NODE | Insert a child node, the active node will be the operation node | openEdit(v0.4.6+, Whether to activate the newly inserted node and enter editing mode, default is `true`) |
|
||||
| INSERT_NODE | Insert a sibling node, the active node or appoint node will be the operation node. If there are multiple active nodes, only the first one will be effective | openEdit(v0.4.6+, Whether to activate the newly inserted node and enter editing mode, default is `true`) 、 appointNodes(v0.4.7+, Optional, appoint node, Specifying multiple nodes can pass an array)、 appointData(Optional, Specify the data for the newly created node, Such as {text: 'xxx', ...}, Detailed structure can be referred to [https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js) ) |
|
||||
| INSERT_CHILD_NODE | Insert a child node, the active node or appoint node will be the operation node | openEdit(v0.4.6+, Whether to activate the newly inserted node and enter editing mode, default is `true`)、 appointNodes(v0.4.7+, Optional, appoint node, Specifying multiple nodes can pass an array)、 appointData(Optional, Specify the data for the newly created node, Such as {text: 'xxx', ...}, Detailed structure can be referred to [https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js) ) |
|
||||
| UP_NODE | Move node up, the active node will be the operation node. If there are multiple active nodes, only the first one will be effective. Using this command on the root node or the first node in the list will be invalid | |
|
||||
| DOWN_NODE | Move node down, the active node will be the operation node. If there are multiple active nodes, only the first one will be effective. Using this command on the root node or the last node in the list will be invalid | |
|
||||
| REMOVE_NODE | Remove node, the active node will be the operation node | |
|
||||
| REMOVE_NODE | Remove node, the active node or appoint node will be the operation node | appointNodes(v0.4.7+, Optional, appoint node, Specifying multiple nodes can pass an array) |
|
||||
| PASTE_NODE | Paste node to a node, the active node will be the operation node | data (the node data to paste, usually obtained through the renderer.copyNode() and renderer.cutNode() methods) |
|
||||
| SET_NODE_STYLE | Modify node style | node (the node to set the style of), prop (style property), value (style property value), isActive (boolean, whether the style being set is for the active state) |
|
||||
| SET_NODE_ACTIVE | Set whether the node is active | node (the node to set), active (boolean, whether to activate) |
|
||||
|
||||
@@ -168,6 +168,20 @@
|
||||
<td>When the <code>mousewheelAction</code> is set to <code>move</code>, you can use this attribute to control the step length of the view movement when the mouse scrolls. The unit is <code>px</code></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>defaultInsertSecondLevelNodeText(v0.4.7+)</td>
|
||||
<td>String</td>
|
||||
<td>二级节点</td>
|
||||
<td>Text of the default inserted secondary node</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>defaultInsertBelowSecondLevelNodeText(v0.4.7+)</td>
|
||||
<td>String</td>
|
||||
<td>分支主题</td>
|
||||
<td>Text for nodes below the second level inserted by default</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Watermark config</h3>
|
||||
@@ -530,13 +544,13 @@ redo. All commands are as follows:</p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>INSERT_NODE</td>
|
||||
<td>Insert a sibling node, the active node will be the operation node. If there are multiple active nodes, only the first one will be effective</td>
|
||||
<td>openEdit(v0.4.6+, Whether to activate the newly inserted node and enter editing mode, default is <code>true</code>)</td>
|
||||
<td>Insert a sibling node, the active node or appoint node will be the operation node. If there are multiple active nodes, only the first one will be effective</td>
|
||||
<td>openEdit(v0.4.6+, Whether to activate the newly inserted node and enter editing mode, default is <code>true</code>) 、 appointNodes(v0.4.7+, Optional, appoint node, Specifying multiple nodes can pass an array)、 appointData(Optional, Specify the data for the newly created node, Such as {text: 'xxx', ...}, Detailed structure can be referred to <a href="https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js">https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js</a> )</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>INSERT_CHILD_NODE</td>
|
||||
<td>Insert a child node, the active node will be the operation node</td>
|
||||
<td>openEdit(v0.4.6+, Whether to activate the newly inserted node and enter editing mode, default is <code>true</code>)</td>
|
||||
<td>Insert a child node, the active node or appoint node will be the operation node</td>
|
||||
<td>openEdit(v0.4.6+, Whether to activate the newly inserted node and enter editing mode, default is <code>true</code>)、 appointNodes(v0.4.7+, Optional, appoint node, Specifying multiple nodes can pass an array)、 appointData(Optional, Specify the data for the newly created node, Such as {text: 'xxx', ...}, Detailed structure can be referred to <a href="https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js">https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js</a> )</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UP_NODE</td>
|
||||
@@ -550,8 +564,8 @@ redo. All commands are as follows:</p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>REMOVE_NODE</td>
|
||||
<td>Remove node, the active node will be the operation node</td>
|
||||
<td></td>
|
||||
<td>Remove node, the active node or appoint node will be the operation node</td>
|
||||
<td>appointNodes(v0.4.7+, Optional, appoint node, Specifying multiple nodes can pass an array)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PASTE_NODE</td>
|
||||
|
||||
35
web/src/pages/Doc/en/markdown/index.md
Normal file
35
web/src/pages/Doc/en/markdown/index.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Markdown parse
|
||||
|
||||
> v0.4.7+
|
||||
|
||||
Provides methods for importing and exporting `Markdown` files.
|
||||
|
||||
## Import
|
||||
|
||||
```js
|
||||
import markdown from 'simple-mind-map/src/parse/markdown.js'
|
||||
```
|
||||
|
||||
If you are using the file in the format of `umd`, you can obtain it in the following way:
|
||||
|
||||
```html
|
||||
<script src="simple-mind-map/dist/simpleMindMap.umd.min.js"></script>
|
||||
```
|
||||
|
||||
```js
|
||||
MindMap.markdown
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
### transformToMarkdown(data)
|
||||
|
||||
- `data`: Mind map data can be obtained using the `mindMap.getData()` method.
|
||||
|
||||
Convert mind map data into `Markdown` format data, and the returned data is a string.
|
||||
|
||||
### transformMarkdownTo(mdContent)
|
||||
|
||||
- `mdContent`: The `Markdown` data to convert, string type.
|
||||
|
||||
Convert the `Markdown` string into node tree data and return a `Promise` instance. You can use the `mindMap.setData()` method to render the converted data onto the canvas.
|
||||
39
web/src/pages/Doc/en/markdown/index.vue
Normal file
39
web/src/pages/Doc/en/markdown/index.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Markdown parse</h1>
|
||||
<blockquote>
|
||||
<p>v0.4.7+</p>
|
||||
</blockquote>
|
||||
<p>Provides methods for importing and exporting <code>Markdown</code> files.</p>
|
||||
<h2>Import</h2>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> markdown <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/parse/markdown.js'</span>
|
||||
</code></pre>
|
||||
<p>If you are using the file in the format of <code>umd</code>, you can obtain it in the following way:</p>
|
||||
<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"simple-mind-map/dist/simpleMindMap.umd.min.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
|
||||
</code></pre>
|
||||
<pre class="hljs"><code>MindMap.markdown
|
||||
</code></pre>
|
||||
<h2>Methods</h2>
|
||||
<h3>transformToMarkdown(data)</h3>
|
||||
<ul>
|
||||
<li><code>data</code>: Mind map data can be obtained using the <code>mindMap.getData()</code> method.</li>
|
||||
</ul>
|
||||
<p>Convert mind map data into <code>Markdown</code> format data, and the returned data is a string.</p>
|
||||
<h3>transformMarkdownTo(mdContent)</h3>
|
||||
<ul>
|
||||
<li><code>mdContent</code>: The <code>Markdown</code> data to convert, string type.</li>
|
||||
</ul>
|
||||
<p>Convert the <code>Markdown</code> string into node tree data and return a <code>Promise</code> instance. You can use the <code>mindMap.setData()</code> method to render the converted data onto the canvas.</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -65,6 +65,12 @@ Replace the built-in font size list during rich text editing. The built-in list
|
||||
|
||||
Select All. When the node is being edited, you can select all the text in the node through this method.
|
||||
|
||||
### focus()
|
||||
|
||||
> v0.4.7+
|
||||
|
||||
Focus.
|
||||
|
||||
### formatText(config = {})
|
||||
|
||||
- `config`:Object. The key is the style attribute and the value is the style value. The complete configuration is as follows:
|
||||
|
||||
@@ -50,6 +50,11 @@ MindMap.usePlugin(RichText, opt?)
|
||||
<h2>Method</h2>
|
||||
<h3>selectAll()</h3>
|
||||
<p>Select All. When the node is being edited, you can select all the text in the node through this method.</p>
|
||||
<h3>focus()</h3>
|
||||
<blockquote>
|
||||
<p>v0.4.7+</p>
|
||||
</blockquote>
|
||||
<p>Focus.</p>
|
||||
<h3>formatText(config = {})</h3>
|
||||
<ul>
|
||||
<li><code>config</code>:Object. The key is the style attribute and the value is the style value. The complete configuration is as follows:</li>
|
||||
|
||||
@@ -12,9 +12,11 @@ import xmind from 'simple-mind-map/src/parse/xmind.js'
|
||||
|
||||
If you are using the file in the format of `umd`, you can obtain it in the following way:
|
||||
|
||||
```js
|
||||
import MindMap from "simple-mind-map/dist/simpleMindMap.umd.min"
|
||||
```html
|
||||
<script src="simple-mind-map/dist/simpleMindMap.umd.min.js"></script>
|
||||
```
|
||||
|
||||
```js
|
||||
MindMap.xmind
|
||||
```
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> xmind <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/parse/xmind.js'</span>
|
||||
</code></pre>
|
||||
<p>If you are using the file in the format of <code>umd</code>, you can obtain it in the following way:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">"simple-mind-map/dist/simpleMindMap.umd.min"</span>
|
||||
|
||||
MindMap.xmind
|
||||
<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"simple-mind-map/dist/simpleMindMap.umd.min.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
|
||||
</code></pre>
|
||||
<pre class="hljs"><code>MindMap.xmind
|
||||
</code></pre>
|
||||
<h2>Methods</h2>
|
||||
<h3>xmind.parseXmindFile(file)</h3>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
|
||||
export default [{"lang":"zh","children":[{"path":"associativeLine","title":"AssociativeLine 插件"},{"path":"batchExecution","title":"BatchExecution实例"},{"path":"changelog","title":"Changelog"},{"path":"command","title":"Command实例"},{"path":"constructor","title":"构造函数"},{"path":"doExport","title":"Export 插件"},{"path":"drag","title":"Drag插件"},{"path":"introduction","title":"简介"},{"path":"keyboardNavigation","title":"KeyboardNavigation插件"},{"path":"keyCommand","title":"KeyCommand实例"},{"path":"miniMap","title":"MiniMap插件"},{"path":"node","title":"Node实例"},{"path":"render","title":"Render实例"},{"path":"richText","title":"RichText插件"},{"path":"select","title":"Select 插件 "},{"path":"start","title":"开始"},{"path":"translate","title":"参与翻译"},{"path":"utils","title":"内置工具方法"},{"path":"view","title":"View实例"},{"path":"watermark","title":"Watermark插件"},{"path":"xmind","title":"XMind解析"}]},{"lang":"en","children":[{"path":"associativeLine","title":"AssociativeLine plugin"},{"path":"batchExecution","title":"batchExecution instance"},{"path":"changelog","title":"Changelog"},{"path":"command","title":"command instance"},{"path":"constructor","title":"Constructor"},{"path":"doExport","title":"Export plugin"},{"path":"drag","title":"Drag plugin"},{"path":"introduction","title":"Introduction"},{"path":"keyboardNavigation","title":"KeyboardNavigation plugin"},{"path":"keyCommand","title":"KeyCommand instance"},{"path":"miniMap","title":"MiniMap plugin"},{"path":"node","title":"Node instance"},{"path":"render","title":"Render instance"},{"path":"richText","title":"RichText plugin"},{"path":"select","title":"Select plugin"},{"path":"start","title":"Start"},{"path":"translate","title":"Participate in translation"},{"path":"utils","title":"Utility Methods"},{"path":"view","title":"View instance"},{"path":"watermark","title":"Watermark plugin"},{"path":"xmind","title":"XMind parse"}]}]
|
||||
export default [{"lang":"zh","children":[{"path":"associativeLine","title":"AssociativeLine 插件"},{"path":"batchExecution","title":"BatchExecution实例"},{"path":"changelog","title":"Changelog"},{"path":"command","title":"Command实例"},{"path":"constructor","title":"构造函数"},{"path":"doExport","title":"Export 插件"},{"path":"drag","title":"Drag插件"},{"path":"introduction","title":"简介"},{"path":"keyboardNavigation","title":"KeyboardNavigation插件"},{"path":"keyCommand","title":"KeyCommand实例"},{"path":"miniMap","title":"MiniMap插件"},{"path":"node","title":"Node实例"},{"path":"render","title":"Render实例"},{"path":"richText","title":"RichText插件"},{"path":"select","title":"Select 插件 "},{"path":"start","title":"开始"},{"path":"translate","title":"参与翻译"},{"path":"utils","title":"内置工具方法"},{"path":"view","title":"View实例"},{"path":"watermark","title":"Watermark插件"},{"path":"xmind","title":"XMind解析"},{"path":"markdown","title":"Markdown解析"}]},{"lang":"en","children":[{"path":"associativeLine","title":"AssociativeLine plugin"},{"path":"batchExecution","title":"batchExecution instance"},{"path":"changelog","title":"Changelog"},{"path":"command","title":"command instance"},{"path":"constructor","title":"Constructor"},{"path":"doExport","title":"Export plugin"},{"path":"drag","title":"Drag plugin"},{"path":"introduction","title":"Introduction"},{"path":"keyboardNavigation","title":"KeyboardNavigation plugin"},{"path":"keyCommand","title":"KeyCommand instance"},{"path":"miniMap","title":"MiniMap plugin"},{"path":"node","title":"Node instance"},{"path":"render","title":"Render instance"},{"path":"richText","title":"RichText plugin"},{"path":"select","title":"Select plugin"},{"path":"start","title":"Start"},{"path":"translate","title":"Participate in translation"},{"path":"utils","title":"Utility Methods"},{"path":"view","title":"View instance"},{"path":"watermark","title":"Watermark plugin"},{"path":"xmind","title":"XMind parse"},{"path":"markdown","title":"Markdown parse"}]}]
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 0.4.7
|
||||
|
||||
优化:1.富文本编辑时初始聚焦时不再默认全选;2.富文本编辑时使用节点填充色作为背景色,避免节点颜色为白色时看不见。 3.节点激活状态切换不再触发历史记录。 4.短时间多次触发历史记录,只会添加最后一次的数据。 5.优化历史记录添加,当有回退时,再次添加新记录时删除当前指针后面的历史数据。
|
||||
|
||||
新增:1.支持导入和导出Markdown格式文件。 2.支持配置插入节点时的初始文字。 3.扩展插入节点和删除节点的命令,支持指定节点。
|
||||
|
||||
## 0.4.6
|
||||
|
||||
新增:1.关联线支持调整控制点。
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.4.7</h2>
|
||||
<p>优化:1.富文本编辑时初始聚焦时不再默认全选;2.富文本编辑时使用节点填充色作为背景色,避免节点颜色为白色时看不见。 3.节点激活状态切换不再触发历史记录。 4.短时间多次触发历史记录,只会添加最后一次的数据。 5.优化历史记录添加,当有回退时,再次添加新记录时删除当前指针后面的历史数据。</p>
|
||||
<p>新增:1.支持导入和导出Markdown格式文件。 2.支持配置插入节点时的初始文字。 3.扩展插入节点和删除节点的命令,支持指定节点。</p>
|
||||
<h2>0.4.6</h2>
|
||||
<p>新增:1.关联线支持调整控制点。</p>
|
||||
<p>优化:1.添加历史数据时过滤和上一次相比没有改变的数据。</p>
|
||||
|
||||
@@ -44,6 +44,8 @@ const mindMap = new MindMap({
|
||||
| customHandleMousewheel(v0.4.3+) | Function | null | 自定义鼠标滚轮事件处理,可以传一个函数,回调参数为事件对象 | |
|
||||
| mousewheelAction(v0.4.3+) | String | zoom | 鼠标滚轮的行为,`zoom`(放大缩小)、`move`(上下移动)。如果`customHandleMousewheel`传了自定义函数,这个属性不生效 | |
|
||||
| mousewheelMoveStep(v0.4.3+) | Number | 100 | 当`mousewheelAction`设为`move`时,可以通过该属性控制鼠标滚动一下视图移动的步长,单位`px` | |
|
||||
| defaultInsertSecondLevelNodeText(v0.4.7+) | String | 二级节点 | 默认插入的二级节点的文字 | |
|
||||
| defaultInsertBelowSecondLevelNodeText(v0.4.7+) | String | 分支主题 | 默认插入的二级以下节点的文字 | |
|
||||
|
||||
### 水印配置
|
||||
|
||||
@@ -263,11 +265,11 @@ mindMap.updateConfig({
|
||||
| SELECT_ALL | 全选 | |
|
||||
| BACK | 回退指定的步数 | step(要回退的步数,默认为1) |
|
||||
| FORWARD | 前进指定的步数 | step(要前进的步数,默认为1) |
|
||||
| INSERT_NODE | 插入同级节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效 | openEdit(v0.4.6+,是否激活新插入的节点并进入编辑模式,默认为`true`) |
|
||||
| INSERT_CHILD_NODE | 插入子节点,操作节点为当前激活的节点 | openEdit(v0.4.6+,是否激活新插入的节点并进入编辑模式,默认为`true`) |
|
||||
| INSERT_NODE | 插入同级节点,操作节点为当前激活的节点或指定节点,如果有多个激活节点,只会对第一个有效 | openEdit(v0.4.6+,是否激活新插入的节点并进入编辑模式,默认为`true`)、 appointNodes(v0.4.7+,可选,指定节点,指定多个节点可以传一个数组)、 appointData(可选,指定新创建节点的数据,比如{text: 'xxx', ...},详细结构可以参考[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js)) |
|
||||
| INSERT_CHILD_NODE | 插入子节点,操作节点为当前激活的节点或指定节点 | openEdit(v0.4.6+,是否激活新插入的节点并进入编辑模式,默认为`true`)、 appointNodes(v0.4.7+,可选,指定节点,指定多个节点可以传一个数组)、 appointData(可选,指定新创建节点的数据,比如{text: 'xxx', ...},详细结构可以参考[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js)) |
|
||||
| UP_NODE | 上移节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点或在列表里的第一个节点使用无效 | |
|
||||
| DOWN_NODE | 操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点或在列表里的最后一个节点使用无效 | |
|
||||
| REMOVE_NODE | 删除节点,操作节点为当前激活的节点 | |
|
||||
| REMOVE_NODE | 删除节点,操作节点为当前激活的节点或指定节点 | appointNodes(v0.4.7+,可选,指定节点,指定多个节点可以传一个数组) |
|
||||
| PASTE_NODE | 粘贴节点到节点,操作节点为当前激活的节点 | data(要粘贴的节点数据,一般通过`renderer.copyNode()`方法和`renderer.cutNode()`方法获取) |
|
||||
| CUT_NODE | 剪切节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点使用无效 | callback(回调函数,剪切的节点数据会通过调用该函数并通过参数返回) |
|
||||
| SET_NODE_STYLE | 修改节点样式 | node(要设置样式的节点)、prop(样式属性)、value(样式属性值)、isActive(布尔值,是否设置的是激活状态的样式) |
|
||||
|
||||
@@ -168,6 +168,20 @@
|
||||
<td>当<code>mousewheelAction</code>设为<code>move</code>时,可以通过该属性控制鼠标滚动一下视图移动的步长,单位<code>px</code></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>defaultInsertSecondLevelNodeText(v0.4.7+)</td>
|
||||
<td>String</td>
|
||||
<td>二级节点</td>
|
||||
<td>默认插入的二级节点的文字</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>defaultInsertBelowSecondLevelNodeText(v0.4.7+)</td>
|
||||
<td>String</td>
|
||||
<td>分支主题</td>
|
||||
<td>默认插入的二级以下节点的文字</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>水印配置</h3>
|
||||
@@ -520,13 +534,13 @@ mindMap.setTheme(<span class="hljs-string">'主题名称'</span>)
|
||||
</tr>
|
||||
<tr>
|
||||
<td>INSERT_NODE</td>
|
||||
<td>插入同级节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效</td>
|
||||
<td>openEdit(v0.4.6+,是否激活新插入的节点并进入编辑模式,默认为<code>true</code>)</td>
|
||||
<td>插入同级节点,操作节点为当前激活的节点或指定节点,如果有多个激活节点,只会对第一个有效</td>
|
||||
<td>openEdit(v0.4.6+,是否激活新插入的节点并进入编辑模式,默认为<code>true</code>)、 appointNodes(v0.4.7+,可选,指定节点,指定多个节点可以传一个数组)、 appointData(可选,指定新创建节点的数据,比如{text: 'xxx', ...},详细结构可以参考<a href="https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js">https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>INSERT_CHILD_NODE</td>
|
||||
<td>插入子节点,操作节点为当前激活的节点</td>
|
||||
<td>openEdit(v0.4.6+,是否激活新插入的节点并进入编辑模式,默认为<code>true</code>)</td>
|
||||
<td>插入子节点,操作节点为当前激活的节点或指定节点</td>
|
||||
<td>openEdit(v0.4.6+,是否激活新插入的节点并进入编辑模式,默认为<code>true</code>)、 appointNodes(v0.4.7+,可选,指定节点,指定多个节点可以传一个数组)、 appointData(可选,指定新创建节点的数据,比如{text: 'xxx', ...},详细结构可以参考<a href="https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js">https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UP_NODE</td>
|
||||
@@ -540,8 +554,8 @@ mindMap.setTheme(<span class="hljs-string">'主题名称'</span>)
|
||||
</tr>
|
||||
<tr>
|
||||
<td>REMOVE_NODE</td>
|
||||
<td>删除节点,操作节点为当前激活的节点</td>
|
||||
<td></td>
|
||||
<td>删除节点,操作节点为当前激活的节点或指定节点</td>
|
||||
<td>appointNodes(v0.4.7+,可选,指定节点,指定多个节点可以传一个数组)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PASTE_NODE</td>
|
||||
|
||||
35
web/src/pages/Doc/zh/markdown/index.md
Normal file
35
web/src/pages/Doc/zh/markdown/index.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Markdown解析
|
||||
|
||||
> v0.4.7+
|
||||
|
||||
提供导入和导出`Markdown`文件的方法。
|
||||
|
||||
## 引入
|
||||
|
||||
```js
|
||||
import markdown from 'simple-mind-map/src/parse/markdown.js'
|
||||
```
|
||||
|
||||
如果使用的是`umd`格式的文件,那么可以通过如下方式获取:
|
||||
|
||||
```html
|
||||
<script src="simple-mind-map/dist/simpleMindMap.umd.min.js"></script>
|
||||
```
|
||||
|
||||
```js
|
||||
MindMap.markdown
|
||||
```
|
||||
|
||||
## 方法
|
||||
|
||||
### transformToMarkdown(data)
|
||||
|
||||
- `data`:思维导图数据,可以通过`mindMap.getData()`方法获取。
|
||||
|
||||
将思维导图数据转换成`Markdown`格式数据,返回的是字符串。
|
||||
|
||||
### transformMarkdownTo(mdContent)
|
||||
|
||||
- `mdContent`:要转换的`Markdown`数据,字符串类型。
|
||||
|
||||
将`Markdown`字符串转换成节点树数据,返回一个`Promise`实例。可以使用`mindMap.setData()`方法将转换后的数据渲染到画布上。
|
||||
39
web/src/pages/Doc/zh/markdown/index.vue
Normal file
39
web/src/pages/Doc/zh/markdown/index.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Markdown解析</h1>
|
||||
<blockquote>
|
||||
<p>v0.4.7+</p>
|
||||
</blockquote>
|
||||
<p>提供导入和导出<code>Markdown</code>文件的方法。</p>
|
||||
<h2>引入</h2>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> markdown <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/parse/markdown.js'</span>
|
||||
</code></pre>
|
||||
<p>如果使用的是<code>umd</code>格式的文件,那么可以通过如下方式获取:</p>
|
||||
<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"simple-mind-map/dist/simpleMindMap.umd.min.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
|
||||
</code></pre>
|
||||
<pre class="hljs"><code>MindMap.markdown
|
||||
</code></pre>
|
||||
<h2>方法</h2>
|
||||
<h3>transformToMarkdown(data)</h3>
|
||||
<ul>
|
||||
<li><code>data</code>:思维导图数据,可以通过<code>mindMap.getData()</code>方法获取。</li>
|
||||
</ul>
|
||||
<p>将思维导图数据转换成<code>Markdown</code>格式数据,返回的是字符串。</p>
|
||||
<h3>transformMarkdownTo(mdContent)</h3>
|
||||
<ul>
|
||||
<li><code>mdContent</code>:要转换的<code>Markdown</code>数据,字符串类型。</li>
|
||||
</ul>
|
||||
<p>将<code>Markdown</code>字符串转换成节点树数据,返回一个<code>Promise</code>实例。可以使用<code>mindMap.setData()</code>方法将转换后的数据渲染到画布上。</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -65,6 +65,12 @@ MindMap.usePlugin(RichText, opt?)
|
||||
|
||||
选中全部。当节点正在编辑中可以通过该方法选中节点内的所有文本。
|
||||
|
||||
### focus()
|
||||
|
||||
> v0.4.7+
|
||||
|
||||
聚焦。
|
||||
|
||||
### formatText(config = {})
|
||||
|
||||
- `config`:对象,键为样式属性,值为样式值,完整的配置如下:
|
||||
|
||||
@@ -50,6 +50,11 @@ MindMap.usePlugin(RichText, opt?)
|
||||
<h2>方法</h2>
|
||||
<h3>selectAll()</h3>
|
||||
<p>选中全部。当节点正在编辑中可以通过该方法选中节点内的所有文本。</p>
|
||||
<h3>focus()</h3>
|
||||
<blockquote>
|
||||
<p>v0.4.7+</p>
|
||||
</blockquote>
|
||||
<p>聚焦。</p>
|
||||
<h3>formatText(config = {})</h3>
|
||||
<ul>
|
||||
<li><code>config</code>:对象,键为样式属性,值为样式值,完整的配置如下:</li>
|
||||
|
||||
@@ -12,9 +12,11 @@ import xmind from 'simple-mind-map/src/parse/xmind.js'
|
||||
|
||||
如果使用的是`umd`格式的文件,那么可以通过如下方式获取:
|
||||
|
||||
```js
|
||||
import MindMap from "simple-mind-map/dist/simpleMindMap.umd.min"
|
||||
```html
|
||||
<script src="simple-mind-map/dist/simpleMindMap.umd.min.js"></script>
|
||||
```
|
||||
|
||||
```js
|
||||
MindMap.xmind
|
||||
```
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> xmind <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/parse/xmind.js'</span>
|
||||
</code></pre>
|
||||
<p>如果使用的是<code>umd</code>格式的文件,那么可以通过如下方式获取:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">"simple-mind-map/dist/simpleMindMap.umd.min"</span>
|
||||
|
||||
MindMap.xmind
|
||||
<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"simple-mind-map/dist/simpleMindMap.umd.min.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
|
||||
</code></pre>
|
||||
<pre class="hljs"><code>MindMap.xmind
|
||||
</code></pre>
|
||||
<h2>方法</h2>
|
||||
<h3>xmind.parseXmindFile(file)</h3>
|
||||
|
||||
@@ -309,6 +309,20 @@ export default {
|
||||
})
|
||||
})
|
||||
this.bindSaveEvent()
|
||||
// setTimeout(() => {
|
||||
// 动态给指定节点添加子节点
|
||||
// this.mindMap.execCommand('INSERT_CHILD_NODE', false, this.mindMap.renderer.root, {
|
||||
// text: '自定义内容'
|
||||
// })
|
||||
|
||||
// 动态给指定节点添加同级节点
|
||||
// this.mindMap.execCommand('INSERT_NODE', false, this.mindMap.renderer.root, {
|
||||
// text: '自定义内容'
|
||||
// })
|
||||
|
||||
// 动态删除指定节点
|
||||
// this.mindMap.execCommand('REMOVE_NODE', this.mindMap.renderer.root.children[0])
|
||||
// }, 5000);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,23 +30,21 @@
|
||||
>{{ $t('export.domToImage') }}</el-checkbox
|
||||
>
|
||||
</div>
|
||||
<el-radio-group v-model="exportType" size="mini">
|
||||
<el-radio-button label="smm"
|
||||
>{{ $t('export.dedicatedFile') }}(.smm)</el-radio-button
|
||||
<div class="downloadTypeList">
|
||||
<div
|
||||
class="downloadTypeItem"
|
||||
v-for="item in downTypeList"
|
||||
:key="item.type"
|
||||
:class="{active: exportType === item.type}"
|
||||
@click="exportType = item.type"
|
||||
>
|
||||
<el-radio-button label="json"
|
||||
>{{ $t('export.jsonFile') }}(.json)</el-radio-button
|
||||
>
|
||||
<el-radio-button label="png"
|
||||
>{{ $t('export.imageFile') }}(.png)</el-radio-button
|
||||
>
|
||||
<el-radio-button label="svg"
|
||||
>{{ $t('export.svgFile') }}(.svg)</el-radio-button
|
||||
>
|
||||
<el-radio-button label="pdf"
|
||||
>{{ $t('export.pdfFile') }}(.pdf)</el-radio-button
|
||||
>
|
||||
</el-radio-group>
|
||||
<div class="icon iconfont" :class="[item.icon, item.type]"></div>
|
||||
<div class="info">
|
||||
<div class="name">{{ item.name }}</div>
|
||||
<div class="desc">{{ item.desc }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tip">{{ $t('export.tips') }}</div>
|
||||
<div class="tip warning" v-if="openNodeRichText && ['png', 'pdf'].includes(exportType)">{{ $t('export.pngTips') }}</div>
|
||||
<div class="tip warning" v-if="openNodeRichText && exportType === 'svg' && domToImage">{{ $t('export.svgTips') }}</div>
|
||||
@@ -62,6 +60,7 @@
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import { downTypeList } from '@/config'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -84,7 +83,11 @@ export default {
|
||||
computed: {
|
||||
...mapState({
|
||||
openNodeRichText: state => state.localConfig.openNodeRichText,
|
||||
})
|
||||
}),
|
||||
|
||||
downTypeList() {
|
||||
return downTypeList[this.$i18n.locale] || downTypeList.zh
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('showExport', () => {
|
||||
@@ -148,6 +151,10 @@ export default {
|
||||
|
||||
<style lang="less" scoped>
|
||||
.nodeDialog {
|
||||
/deep/ .el-dialog__body {
|
||||
background-color: #f2f4f7;
|
||||
}
|
||||
|
||||
.nameInputBox {
|
||||
margin-bottom: 20px;
|
||||
|
||||
@@ -163,5 +170,70 @@ export default {
|
||||
color: #F56C6C;
|
||||
}
|
||||
}
|
||||
|
||||
.downloadTypeList {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.downloadTypeItem {
|
||||
width: 200px;
|
||||
height: 88px;
|
||||
padding: 22px;
|
||||
overflow: hidden;
|
||||
margin: 10px;
|
||||
border-radius: 11px;
|
||||
box-shadow: 0 0 20px 0 rgba(0,0,0,.02);
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border: 2px solid transparent;
|
||||
|
||||
&.active {
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 30px;
|
||||
margin-right: 10px;
|
||||
|
||||
&.png {
|
||||
color: #ffc038;
|
||||
}
|
||||
|
||||
&.pdf {
|
||||
color: #ff6c4d;
|
||||
}
|
||||
|
||||
&.md {
|
||||
color: #2b2b2b;
|
||||
}
|
||||
|
||||
&.json {
|
||||
color: #12c87e;
|
||||
}
|
||||
|
||||
&.svg {
|
||||
color: #4380ff;
|
||||
}
|
||||
|
||||
&.smm {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
.name {
|
||||
color: #1a1a1a;
|
||||
font-size: 15px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
<script>
|
||||
import xmind from 'simple-mind-map/src/parse/xmind.js'
|
||||
import markdown from 'simple-mind-map/src/parse/markdown.js'
|
||||
import { fileToBuffer } from '@/utils'
|
||||
import { read, utils } from 'xlsx'
|
||||
|
||||
@@ -68,9 +69,9 @@ export default {
|
||||
* @Desc: 文件选择
|
||||
*/
|
||||
onChange(file) {
|
||||
let reg = /\.(smm|xmind|json|xlsx)$/
|
||||
let reg = /\.(smm|xmind|json|xlsx|md)$/
|
||||
if (!reg.test(file.name)) {
|
||||
this.$message.error('请选择.smm、.json、.xmind、.xlsx文件')
|
||||
this.$message.error('请选择.smm、.json、.xmind、.xlsx、.md文件')
|
||||
this.fileList = []
|
||||
} else {
|
||||
this.fileList.push(file)
|
||||
@@ -112,7 +113,9 @@ export default {
|
||||
this.handleXmind(file)
|
||||
} else if (/\.xlsx$/.test(file.name)) {
|
||||
this.handleExcel(file)
|
||||
}
|
||||
} else if (/\.md$/.test(file.name)) {
|
||||
this.handleMd(file)
|
||||
}
|
||||
this.cancel()
|
||||
},
|
||||
|
||||
@@ -220,6 +223,22 @@ export default {
|
||||
console.log(error)
|
||||
this.$message.error('文件解析失败')
|
||||
}
|
||||
},
|
||||
|
||||
// 处理markdown文件
|
||||
async handleMd(file) {
|
||||
let fileReader = new FileReader()
|
||||
fileReader.readAsText(file.raw)
|
||||
fileReader.onload = async evt => {
|
||||
try {
|
||||
let data = await markdown.transformMarkdownTo(evt.target.result)
|
||||
this.$bus.$emit('setData', data)
|
||||
this.$message.success('导入成功')
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.$message.error('文件解析失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user