mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-19 23:08:32 +08:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bb349b2df | ||
|
|
b262336f08 | ||
|
|
2b59087461 | ||
|
|
66c9805efc | ||
|
|
710128901a | ||
|
|
61be0f7ac4 | ||
|
|
7289b3a0ad | ||
|
|
25243e2053 | ||
|
|
060a448cd5 | ||
|
|
bdb6078df6 | ||
|
|
749a4d0e81 | ||
|
|
1749705694 |
@@ -92,6 +92,8 @@ MIT
|
||||
|
||||
<img src="./qrcode.jpg" style="width: 300px" />
|
||||
|
||||
如果已过期,可以微信添加`wanglinguanfang`拉你入群。
|
||||
|
||||
# 请作者喝杯咖啡
|
||||
|
||||
> 厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds
|
||||
|
||||
File diff suppressed because one or more lines are too long
BIN
qrcode.jpg
BIN
qrcode.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
@@ -11,127 +11,7 @@ import { layoutValueList, CONSTANTS } from './src/constants/constant'
|
||||
import { SVG } from '@svgdotjs/svg.js'
|
||||
import { simpleDeepClone } from './src/utils'
|
||||
import defaultTheme, { checkIsNodeSizeIndependenceConfig } from './src/themes/default'
|
||||
|
||||
// 默认选项配置
|
||||
const defaultOpt = {
|
||||
// 是否只读
|
||||
readonly: false,
|
||||
// 布局
|
||||
layout: CONSTANTS.LAYOUT.LOGICAL_STRUCTURE,
|
||||
// 如果结构为鱼骨图,那么可以通过该选项控制倾斜角度
|
||||
fishboneDeg: 45,
|
||||
// 主题
|
||||
theme: 'default', // 内置主题:default(默认主题)
|
||||
// 主题配置,会和所选择的主题进行合并
|
||||
themeConfig: {},
|
||||
// 放大缩小的增量比例
|
||||
scaleRatio: 0.1,
|
||||
// 最多显示几个标签
|
||||
maxTag: 5,
|
||||
// 导出图片时的内边距
|
||||
exportPadding: 20,
|
||||
// 展开收缩按钮尺寸
|
||||
expandBtnSize: 20,
|
||||
// 节点里图片和文字的间距
|
||||
imgTextMargin: 5,
|
||||
// 节点里各种文字信息的间距,如图标和文字的间距
|
||||
textContentMargin: 2,
|
||||
// 多选节点时鼠标移动到边缘时的画布移动偏移量
|
||||
selectTranslateStep: 3,
|
||||
// 多选节点时鼠标移动距边缘多少距离时开始偏移
|
||||
selectTranslateLimit: 20,
|
||||
// 自定义节点备注内容显示
|
||||
customNoteContentShow: null,
|
||||
/*
|
||||
{
|
||||
show(){},
|
||||
hide(){}
|
||||
}
|
||||
*/
|
||||
// 是否开启节点自由拖拽
|
||||
enableFreeDrag: false,
|
||||
// 水印配置
|
||||
watermarkConfig: {
|
||||
text: '',
|
||||
lineSpacing: 100,
|
||||
textSpacing: 100,
|
||||
angle: 30,
|
||||
textStyle: {
|
||||
color: '#999',
|
||||
opacity: 0.5,
|
||||
fontSize: 14
|
||||
}
|
||||
},
|
||||
// 达到该宽度文本自动换行
|
||||
textAutoWrapWidth: 500,
|
||||
// 自定义鼠标滚轮事件处理
|
||||
// 可以传一个函数,回调参数为事件对象
|
||||
customHandleMousewheel: null,
|
||||
// 鼠标滚动的行为,如果customHandleMousewheel传了自定义函数,这个属性不生效
|
||||
mousewheelAction: CONSTANTS.MOUSE_WHEEL_ACTION.ZOOM,// zoom(放大缩小)、move(上下移动)
|
||||
// 当mousewheelAction设为move时,可以通过该属性控制鼠标滚动一下视图移动的步长,单位px
|
||||
mousewheelMoveStep: 100,
|
||||
// 默认插入的二级节点的文字
|
||||
defaultInsertSecondLevelNodeText: '二级节点',
|
||||
// 默认插入的二级以下节点的文字
|
||||
defaultInsertBelowSecondLevelNodeText: '分支主题',
|
||||
// 展开收起按钮的颜色
|
||||
expandBtnStyle: {
|
||||
color: '#808080',
|
||||
fill: '#fff'
|
||||
},
|
||||
// 自定义展开收起按钮的图标
|
||||
expandBtnIcon: {
|
||||
open: '',// svg字符串
|
||||
close: ''
|
||||
},
|
||||
// 是否只有当鼠标在画布内才响应快捷键事件
|
||||
enableShortcutOnlyWhenMouseInSvg: true,
|
||||
// 是否开启节点动画过渡
|
||||
enableNodeTransitionMove: true,
|
||||
// 如果开启节点动画过渡,可以通过该属性设置过渡的时间,单位ms
|
||||
nodeTransitionMoveDuration: 300,
|
||||
// 初始根节点的位置
|
||||
initRootNodePosition: null,
|
||||
// 导出png、svg、pdf时的图形内边距
|
||||
exportPaddingX: 10,
|
||||
exportPaddingY: 10,
|
||||
// 节点文本编辑框的z-index
|
||||
nodeTextEditZIndex: 3000,
|
||||
// 节点备注浮层的z-index
|
||||
nodeNoteTooltipZIndex: 3000,
|
||||
// 是否在点击了画布外的区域时结束节点文本的编辑状态
|
||||
isEndNodeTextEditOnClickOuter: true,
|
||||
// 最大历史记录数
|
||||
maxHistoryCount: 1000,
|
||||
// 是否一直显示节点的展开收起按钮,默认为鼠标移上去和激活时才显示
|
||||
alwaysShowExpandBtn: false,
|
||||
// 扩展节点可插入的图标
|
||||
iconList: [
|
||||
// {
|
||||
// name: '',// 分组名称
|
||||
// type: '',// 分组的值
|
||||
// list: [// 分组下的图标列表
|
||||
// {
|
||||
// name: '',// 图标名称
|
||||
// icon:''// 图标,可以传svg或图片
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
],
|
||||
// 节点最大缓存数量
|
||||
maxNodeCacheCount: 1000,
|
||||
// 关联线默认文字
|
||||
defaultAssociativeLineText: '关联',
|
||||
// 思维导图适应画布大小时的内边距
|
||||
fitPadding: 50,
|
||||
// 是否开启按住ctrl键多选节点功能
|
||||
enableCtrlKeyNodeSelection: true,
|
||||
// 设置为左键多选节点,右键拖动画布
|
||||
useLeftKeySelectionRightKeyDrag: false,
|
||||
// 节点即将进入编辑前的回调方法,如果该方法返回true以外的值,那么将取消编辑,函数可以返回一个值,或一个Promise,回调参数为节点实例
|
||||
beforeTextEdit: null
|
||||
}
|
||||
import { defaultOpt } from './src/constants/defaultOptions'
|
||||
|
||||
// 思维导图
|
||||
class MindMap {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "simple-mind-map",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"description": "一个简单的web在线思维导图",
|
||||
"authors": [
|
||||
{
|
||||
|
||||
126
simple-mind-map/src/constants/defaultOptions.js
Normal file
126
simple-mind-map/src/constants/defaultOptions.js
Normal file
@@ -0,0 +1,126 @@
|
||||
import { CONSTANTS } from './constant'
|
||||
|
||||
// 默认选项配置
|
||||
export const defaultOpt = {
|
||||
// 是否只读
|
||||
readonly: false,
|
||||
// 布局
|
||||
layout: CONSTANTS.LAYOUT.LOGICAL_STRUCTURE,
|
||||
// 如果结构为鱼骨图,那么可以通过该选项控制倾斜角度
|
||||
fishboneDeg: 45,
|
||||
// 主题
|
||||
theme: 'default', // 内置主题:default(默认主题)
|
||||
// 主题配置,会和所选择的主题进行合并
|
||||
themeConfig: {},
|
||||
// 放大缩小的增量比例
|
||||
scaleRatio: 0.1,
|
||||
// 最多显示几个标签
|
||||
maxTag: 5,
|
||||
// 导出图片时的内边距
|
||||
exportPadding: 20,
|
||||
// 展开收缩按钮尺寸
|
||||
expandBtnSize: 20,
|
||||
// 节点里图片和文字的间距
|
||||
imgTextMargin: 5,
|
||||
// 节点里各种文字信息的间距,如图标和文字的间距
|
||||
textContentMargin: 2,
|
||||
// 多选节点时鼠标移动到边缘时的画布移动偏移量
|
||||
selectTranslateStep: 3,
|
||||
// 多选节点时鼠标移动距边缘多少距离时开始偏移
|
||||
selectTranslateLimit: 20,
|
||||
// 自定义节点备注内容显示
|
||||
customNoteContentShow: null,
|
||||
/*
|
||||
{
|
||||
show(){},
|
||||
hide(){}
|
||||
}
|
||||
*/
|
||||
// 是否开启节点自由拖拽
|
||||
enableFreeDrag: false,
|
||||
// 水印配置
|
||||
watermarkConfig: {
|
||||
text: '',
|
||||
lineSpacing: 100,
|
||||
textSpacing: 100,
|
||||
angle: 30,
|
||||
textStyle: {
|
||||
color: '#999',
|
||||
opacity: 0.5,
|
||||
fontSize: 14
|
||||
}
|
||||
},
|
||||
// 达到该宽度文本自动换行
|
||||
textAutoWrapWidth: 500,
|
||||
// 自定义鼠标滚轮事件处理
|
||||
// 可以传一个函数,回调参数为事件对象
|
||||
customHandleMousewheel: null,
|
||||
// 鼠标滚动的行为,如果customHandleMousewheel传了自定义函数,这个属性不生效
|
||||
mousewheelAction: CONSTANTS.MOUSE_WHEEL_ACTION.ZOOM, // zoom(放大缩小)、move(上下移动)
|
||||
// 当mousewheelAction设为move时,可以通过该属性控制鼠标滚动一下视图移动的步长,单位px
|
||||
mousewheelMoveStep: 100,
|
||||
// 默认插入的二级节点的文字
|
||||
defaultInsertSecondLevelNodeText: '二级节点',
|
||||
// 默认插入的二级以下节点的文字
|
||||
defaultInsertBelowSecondLevelNodeText: '分支主题',
|
||||
// 展开收起按钮的颜色
|
||||
expandBtnStyle: {
|
||||
color: '#808080',
|
||||
fill: '#fff'
|
||||
},
|
||||
// 自定义展开收起按钮的图标
|
||||
expandBtnIcon: {
|
||||
open: '', // svg字符串
|
||||
close: ''
|
||||
},
|
||||
// 是否只有当鼠标在画布内才响应快捷键事件
|
||||
enableShortcutOnlyWhenMouseInSvg: true,
|
||||
// 是否开启节点动画过渡
|
||||
enableNodeTransitionMove: true,
|
||||
// 如果开启节点动画过渡,可以通过该属性设置过渡的时间,单位ms
|
||||
nodeTransitionMoveDuration: 300,
|
||||
// 初始根节点的位置
|
||||
initRootNodePosition: null,
|
||||
// 导出png、svg、pdf时的图形内边距
|
||||
exportPaddingX: 10,
|
||||
exportPaddingY: 10,
|
||||
// 节点文本编辑框的z-index
|
||||
nodeTextEditZIndex: 3000,
|
||||
// 节点备注浮层的z-index
|
||||
nodeNoteTooltipZIndex: 3000,
|
||||
// 是否在点击了画布外的区域时结束节点文本的编辑状态
|
||||
isEndNodeTextEditOnClickOuter: true,
|
||||
// 最大历史记录数
|
||||
maxHistoryCount: 1000,
|
||||
// 是否一直显示节点的展开收起按钮,默认为鼠标移上去和激活时才显示
|
||||
alwaysShowExpandBtn: false,
|
||||
// 扩展节点可插入的图标
|
||||
iconList: [
|
||||
// {
|
||||
// name: '',// 分组名称
|
||||
// type: '',// 分组的值
|
||||
// list: [// 分组下的图标列表
|
||||
// {
|
||||
// name: '',// 图标名称
|
||||
// icon:''// 图标,可以传svg或图片
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
],
|
||||
// 节点最大缓存数量
|
||||
maxNodeCacheCount: 1000,
|
||||
// 关联线默认文字
|
||||
defaultAssociativeLineText: '关联',
|
||||
// 思维导图适应画布大小时的内边距
|
||||
fitPadding: 50,
|
||||
// 是否开启按住ctrl键多选节点功能
|
||||
enableCtrlKeyNodeSelection: true,
|
||||
// 设置为左键多选节点,右键拖动画布
|
||||
useLeftKeySelectionRightKeyDrag: false,
|
||||
// 节点即将进入编辑前的回调方法,如果该方法返回true以外的值,那么将取消编辑,函数可以返回一个值,或一个Promise,回调参数为节点实例
|
||||
beforeTextEdit: null,
|
||||
// 是否开启自定义节点内容
|
||||
isUseCustomNodeContent: false,
|
||||
// 自定义返回节点内容的方法
|
||||
customCreateNodeContent: null
|
||||
}
|
||||
@@ -425,6 +425,9 @@ class Render {
|
||||
let { defaultInsertSecondLevelNodeText, defaultInsertBelowSecondLevelNodeText } = this.mindMap.opt
|
||||
let list = appointNodes.length > 0 ? appointNodes : this.activeNodeList
|
||||
let first = list[0]
|
||||
if (first.isGeneralization) {
|
||||
return
|
||||
}
|
||||
if (first.isRoot) {
|
||||
this.insertChildNode(openEdit, appointNodes, appointData)
|
||||
} else {
|
||||
@@ -455,6 +458,9 @@ class Render {
|
||||
let { defaultInsertSecondLevelNodeText, defaultInsertBelowSecondLevelNodeText } = this.mindMap.opt
|
||||
let list = appointNodes.length > 0 ? appointNodes : this.activeNodeList
|
||||
list.forEach(node => {
|
||||
if (node.isGeneralization) {
|
||||
return
|
||||
}
|
||||
if (!node.nodeData.children) {
|
||||
node.nodeData.children = []
|
||||
}
|
||||
|
||||
@@ -66,10 +66,15 @@ export default class TextEdit {
|
||||
|
||||
// 显示文本编辑框
|
||||
async show(node) {
|
||||
if (typeof this.mindMap.opt.beforeTextEdit === 'function') {
|
||||
// 使用了自定义节点内容那么不响应编辑事件
|
||||
if (node.isUseCustomNodeContent()) {
|
||||
return
|
||||
}
|
||||
let { beforeTextEdit } = this.mindMap.opt
|
||||
if (typeof beforeTextEdit === 'function') {
|
||||
let isShow = false
|
||||
try {
|
||||
isShow = await this.mindMap.opt.beforeTextEdit(node)
|
||||
isShow = await beforeTextEdit(node)
|
||||
} catch (error) {
|
||||
isShow = false
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Style from './Style'
|
||||
import Shape from './Shape'
|
||||
import { asyncRun } from '../../../utils'
|
||||
import { G, Rect } from '@svgdotjs/svg.js'
|
||||
import { asyncRun, nodeToHTML } from '../../../utils'
|
||||
import { G, Rect, ForeignObject, SVG } from '@svgdotjs/svg.js'
|
||||
import nodeGeneralizationMethods from './nodeGeneralization'
|
||||
import nodeExpandBtnMethods from './nodeExpandBtn'
|
||||
import nodeCommandWrapsMethods from './nodeCommandWraps'
|
||||
@@ -59,6 +59,7 @@ class Node {
|
||||
this.group = null
|
||||
this.shapeNode = null // 节点形状节点
|
||||
// 节点内容对象
|
||||
this._customNodeContent = null
|
||||
this._imgData = null
|
||||
this._iconData = null
|
||||
this._textData = null
|
||||
@@ -154,6 +155,13 @@ class Node {
|
||||
|
||||
// 创建节点的各个内容对象数据
|
||||
createNodeData() {
|
||||
// 自定义节点内容
|
||||
let { isUseCustomNodeContent, customCreateNodeContent } = this.mindMap.opt
|
||||
if (isUseCustomNodeContent && customCreateNodeContent) {
|
||||
this._customNodeContent = customCreateNodeContent(this)
|
||||
}
|
||||
// 如果没有返回内容,那么还是使用内置的节点内容
|
||||
if (this._customNodeContent) return
|
||||
this._imgData = this.createImgNode()
|
||||
this._iconData = this.createIconNode()
|
||||
this._textData = this.createTextNode()
|
||||
@@ -176,6 +184,14 @@ class Node {
|
||||
|
||||
// 计算节点尺寸信息
|
||||
getNodeRect() {
|
||||
// 自定义节点内容
|
||||
if (this.isUseCustomNodeContent()) {
|
||||
let rect = this.measureCustomNodeContentSize(this._customNodeContent)
|
||||
return {
|
||||
width: rect.width,
|
||||
height: rect.height
|
||||
}
|
||||
}
|
||||
// 宽高
|
||||
let imgContentWidth = 0
|
||||
let imgContentHeight = 0
|
||||
@@ -266,6 +282,15 @@ class Node {
|
||||
if (this.isGeneralization && this.generalizationBelongNode) {
|
||||
this.group.addClass('generalization_' + this.generalizationBelongNode.uid)
|
||||
}
|
||||
// 如果存在自定义节点内容,那么使用自定义节点内容
|
||||
if (this.isUseCustomNodeContent()) {
|
||||
let foreignObject = new ForeignObject()
|
||||
foreignObject.width(width)
|
||||
foreignObject.height(height)
|
||||
foreignObject.add(SVG(this._customNodeContent))
|
||||
this.group.add(foreignObject)
|
||||
return
|
||||
}
|
||||
// 图片节点
|
||||
let imgHeight = 0
|
||||
if (this._imgData) {
|
||||
|
||||
@@ -280,6 +280,32 @@ function createNoteNode() {
|
||||
}
|
||||
}
|
||||
|
||||
// 测量自定义节点内容元素的宽高
|
||||
let warpEl = null
|
||||
function measureCustomNodeContentSize (content) {
|
||||
if (!warpEl) {
|
||||
warpEl = document.createElement('div')
|
||||
warpEl.style.cssText = `
|
||||
position: fixed;
|
||||
left: -99999px;
|
||||
top: -99999px;
|
||||
`
|
||||
this.mindMap.el.appendChild(warpEl)
|
||||
}
|
||||
warpEl.innerHTML = ''
|
||||
warpEl.appendChild(content)
|
||||
let rect = warpEl.getBoundingClientRect()
|
||||
return {
|
||||
width: rect.width,
|
||||
height: rect.height
|
||||
}
|
||||
}
|
||||
|
||||
// 是否使用的是自定义节点内容
|
||||
function isUseCustomNodeContent() {
|
||||
return !!this._customNodeContent
|
||||
}
|
||||
|
||||
export default {
|
||||
createImgNode,
|
||||
getImgShowSize,
|
||||
@@ -288,5 +314,7 @@ export default {
|
||||
createTextNode,
|
||||
createHyperlinkNode,
|
||||
createTagNode,
|
||||
createNoteNode
|
||||
createNoteNode,
|
||||
measureCustomNodeContentSize,
|
||||
isUseCustomNodeContent
|
||||
}
|
||||
@@ -170,8 +170,8 @@ class View {
|
||||
// 应用变换
|
||||
transform() {
|
||||
this.mindMap.draw.transform({
|
||||
origin: [0, 0],
|
||||
scale: this.scale,
|
||||
// origin: 'center center',
|
||||
translate: [this.x, this.y]
|
||||
})
|
||||
this.mindMap.emit('view_data_change', this.getTransformData())
|
||||
@@ -191,22 +191,36 @@ class View {
|
||||
|
||||
// 缩小
|
||||
narrow() {
|
||||
let scale
|
||||
if (this.scale - this.mindMap.opt.scaleRatio > 0.1) {
|
||||
this.scale -= this.mindMap.opt.scaleRatio
|
||||
scale = this.scale - this.mindMap.opt.scaleRatio
|
||||
} else {
|
||||
this.scale = 0.1
|
||||
scale = 0.1
|
||||
}
|
||||
this.scaleInCenter(this.mindMap.width / 2, this.mindMap.height / 2, scale)
|
||||
this.transform()
|
||||
this.mindMap.emit('scale', this.scale)
|
||||
}
|
||||
|
||||
// 放大
|
||||
enlarge() {
|
||||
this.scale += this.mindMap.opt.scaleRatio
|
||||
const scale = this.scale + this.mindMap.opt.scaleRatio
|
||||
this.scaleInCenter(this.mindMap.width / 2, this.mindMap.height / 2, scale)
|
||||
this.transform()
|
||||
this.mindMap.emit('scale', this.scale)
|
||||
}
|
||||
|
||||
// 基于画布中心进行缩放
|
||||
scaleInCenter(cx, cy, scale) {
|
||||
const prevScale = this.scale
|
||||
const dx = (cx - this.x) * (1 - scale / prevScale)
|
||||
const dy = (cy - this.y) * (1 - scale / prevScale)
|
||||
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
this.scale = scale
|
||||
}
|
||||
|
||||
// 设置缩放
|
||||
setScale(scale) {
|
||||
this.scale = scale
|
||||
|
||||
@@ -356,4 +356,15 @@ export const readBlob = (blob) => {
|
||||
}
|
||||
reader.readAsDataURL(blob)
|
||||
})
|
||||
}
|
||||
|
||||
// 将dom节点转换成html字符串
|
||||
let nodeToHTMLWrapEl = null
|
||||
export const nodeToHTML = (node) => {
|
||||
if (!nodeToHTMLWrapEl) {
|
||||
nodeToHTMLWrapEl = document.createElement('div')
|
||||
}
|
||||
nodeToHTMLWrapEl.innerHTML = ''
|
||||
nodeToHTMLWrapEl.appendChild(node)
|
||||
return nodeToHTMLWrapEl.innerHTML
|
||||
}
|
||||
BIN
web/src/assets/avatar/小土渣的宇宙.jpeg
Normal file
BIN
web/src/assets/avatar/小土渣的宇宙.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
@@ -11,7 +11,7 @@ let langList = [
|
||||
}
|
||||
]
|
||||
let StartList = ['introduction', 'start', 'deploy', 'client', 'translate', 'changelog']
|
||||
let CourseList = new Array(19).fill(0).map((_, index) => {
|
||||
let CourseList = new Array(20).fill(0).map((_, index) => {
|
||||
return 'course' + (index + 1)
|
||||
})
|
||||
let APIList = [
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 0.6.3
|
||||
|
||||
Fix: 1.Fix the issue where the summary node will respond to inserting node shortcuts.
|
||||
|
||||
New: 1.Support custom node content.
|
||||
|
||||
## 0.6.2
|
||||
|
||||
Fix: 1.Fixed the problem that the new node does not change with the theme in rich Text mode.
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.6.3</h2>
|
||||
<p>Fix: 1.Fix the issue where the summary node will respond to inserting node shortcuts.</p>
|
||||
<p>New: 1.Support custom node content.</p>
|
||||
<h2>0.6.2</h2>
|
||||
<p>Fix: 1.Fixed the problem that the new node does not change with the theme in rich Text mode.</p>
|
||||
<h2>0.6.1</h2>
|
||||
|
||||
@@ -67,6 +67,8 @@ const mindMap = new MindMap({
|
||||
| enableCtrlKeyNodeSelection(v0.6.0+) | Boolean | true | Whether to enable the function of holding down the Ctrl key to select multiple nodes | |
|
||||
| useLeftKeySelectionRightKeyDrag(v0.6.0+) | Boolean | false | Setting to left click to select multiple nodes and right click to drag the canvas. | |
|
||||
| beforeTextEdit(v0.6.0+) | Function/null | null | The callback method before the node is about to enter editing. If the method returns a value other than true, the editing will be canceled. The function can return a value or a promise, and the callback parameter is the node instance | |
|
||||
| isUseCustomNodeContent(v0.6.3+) | Boolean | false | Whether to customize node content | |
|
||||
| customCreateNodeContent(v0.6.3+) | Function/null | null | If `isUseCustomNodeContent` is set to `true`, then this option needs to be used to pass in a method that receives the node instance `node` as a parameter (if you want to obtain data for that node, you can use `node.nodeData.data`). You need to return the custom node content element, which is the DOM node. If a node does not require customization, you can return `null` | |
|
||||
|
||||
### Watermark config
|
||||
|
||||
|
||||
@@ -329,6 +329,20 @@
|
||||
<td>The callback method before the node is about to enter editing. If the method returns a value other than true, the editing will be canceled. The function can return a value or a promise, and the callback parameter is the node instance</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>isUseCustomNodeContent(v0.6.3+)</td>
|
||||
<td>Boolean</td>
|
||||
<td>false</td>
|
||||
<td>Whether to customize node content</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>customCreateNodeContent(v0.6.3+)</td>
|
||||
<td>Function/null</td>
|
||||
<td>null</td>
|
||||
<td>If <code>isUseCustomNodeContent</code> is set to <code>true</code>, then this option needs to be used to pass in a method that receives the node instance <code>node</code> as a parameter (if you want to obtain data for that node, you can use <code>node.nodeData.data</code>). You need to return the custom node content element, which is the DOM node. If a node does not require customization, you can return <code>null</code></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Watermark config</h3>
|
||||
|
||||
@@ -77,7 +77,7 @@ If you need a file in the format of `umd` module, such as `CDN` in the browser,
|
||||
<script scr="simpleMindMap.umd.min.js"></script>
|
||||
```
|
||||
|
||||
A global variable `window.simpleMindMap` will be created.
|
||||
A global variable `window.simpleMindMap` will be created. you can get `MindMap` constructor by `window.simpleMindMap.default`, for more detail info you can log `window.simpleMindMap`.
|
||||
|
||||
The disadvantage of this method is that it will contain all the content, including the plugins you have not registered, so the overall volume will be relatively large.
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ compile this dependency:</p>
|
||||
<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"simpleMindMap.css"</span>></span>
|
||||
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">scr</span>=<span class="hljs-string">"simpleMindMap.umd.min.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
|
||||
</code></pre>
|
||||
<p>A global variable <code>window.simpleMindMap</code> will be created.</p>
|
||||
<p>A global variable <code>window.simpleMindMap</code> will be created. you can get <code>MindMap</code> constructor by <code>window.simpleMindMap.default</code>, for more detail info you can log <code>window.simpleMindMap</code>.</p>
|
||||
<p>The disadvantage of this method is that it will contain all the content, including the plugins you have not registered, so the overall volume will be relatively large.</p>
|
||||
<p>(v0.5.4+)If you want to use the <code>ES</code> module directly on the browser side, you can find the <code>simpleMindMap.esm.js</code> and <code>simpleMindMap.esm.css</code> files in the <code>/simple-mind-map/dist/</code> directory.</p>
|
||||
<h2>Development</h2>
|
||||
|
||||
@@ -26,6 +26,7 @@ export default [
|
||||
{ path: 'course17', title: '导入和导出' },
|
||||
{ path: 'course18', title: '如何持久化数据' },
|
||||
{ path: 'course19', title: '插入和扩展节点图标' },
|
||||
{ path: 'course20', title: '如何自定义节点内容' },
|
||||
{ path: 'doExport', title: 'Export 插件' },
|
||||
{ path: 'drag', title: 'Drag插件' },
|
||||
{ path: 'introduction', title: '简介' },
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 0.6.3
|
||||
|
||||
修复:1.修复概要节点会响应插入节点快捷键的问题。
|
||||
|
||||
新增:1.支持自定义节点内容。
|
||||
|
||||
## 0.6.2
|
||||
|
||||
修复:1.修复富文本模式下,新建节点不随主题变化而变化的问题。
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.6.3</h2>
|
||||
<p>修复:1.修复概要节点会响应插入节点快捷键的问题。</p>
|
||||
<p>新增:1.支持自定义节点内容。</p>
|
||||
<h2>0.6.2</h2>
|
||||
<p>修复:1.修复富文本模式下,新建节点不随主题变化而变化的问题。</p>
|
||||
<h2>0.6.1</h2>
|
||||
|
||||
@@ -67,6 +67,8 @@ const mindMap = new MindMap({
|
||||
| enableCtrlKeyNodeSelection(v0.6.0+) | Boolean | true | 是否开启按住ctrl键多选节点的功能 | |
|
||||
| useLeftKeySelectionRightKeyDrag(v0.6.0+) | Boolean | false | 设置为左键多选节点,右键拖动画布 | |
|
||||
| beforeTextEdit(v0.6.0+) | Function/null | null | 节点即将进入编辑前的回调方法,如果该方法返回true以外的值,那么将取消编辑,函数可以返回一个值,或一个Promise,回调参数为节点实例 | |
|
||||
| isUseCustomNodeContent(v0.6.3+) | Boolean | false | 是否自定义节点内容 | |
|
||||
| customCreateNodeContent(v0.6.3+) | Function/null | null | 如果`isUseCustomNodeContent`设为`true`,那么需要使用该选项传入一个方法,接收节点实例`node`为参数(如果要获取该节点的数据,可以通过`node.nodeData.data`),需要返回自定义节点内容元素,也就是DOM节点,如果某个节点不需要自定义,那么返回`null`即可 | |
|
||||
|
||||
### 水印配置
|
||||
|
||||
|
||||
@@ -329,6 +329,20 @@
|
||||
<td>节点即将进入编辑前的回调方法,如果该方法返回true以外的值,那么将取消编辑,函数可以返回一个值,或一个Promise,回调参数为节点实例</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>isUseCustomNodeContent(v0.6.3+)</td>
|
||||
<td>Boolean</td>
|
||||
<td>false</td>
|
||||
<td>是否自定义节点内容</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>customCreateNodeContent(v0.6.3+)</td>
|
||||
<td>Function/null</td>
|
||||
<td>null</td>
|
||||
<td>如果<code>isUseCustomNodeContent</code>设为<code>true</code>,那么需要使用该选项传入一个方法,接收节点实例<code>node</code>为参数(如果要获取该节点的数据,可以通过<code>node.nodeData.data</code>),需要返回自定义节点内容元素,也就是DOM节点,如果某个节点不需要自定义,那么返回<code>null</code>即可</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>水印配置</h3>
|
||||
|
||||
119
web/src/pages/Doc/zh/course20/index.md
Normal file
119
web/src/pages/Doc/zh/course20/index.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# 如何自定义节点内容
|
||||
|
||||
> 该特性v0.6.3+版本支持
|
||||
|
||||
如果你想自定义节点的内容,那么可以在实例化`simple-mind-map`时传入以下选项:
|
||||
|
||||
```js
|
||||
new MindMap({
|
||||
isUseCustomNodeContent: true,
|
||||
customCreateNodeContent: (node) => {
|
||||
// return你的自定义DOM节点
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
`customCreateNodeContent`方法会接收当前遍历到的节点实例作为参数,一般而言你会需要该节点的数据,这可以通过如下方式获取:
|
||||
|
||||
```js
|
||||
node.nodeData.data
|
||||
```
|
||||
|
||||
其他节点实例属性你可以自行打印出来看看。
|
||||
|
||||
`customCreateNodeContent`方法需要返回`DOM`节点,如果某个节点你不想自定义,那么可以返回`null`,那么还是会走内置的节点渲染逻辑。
|
||||
|
||||
返回的`DOM`节点的宽高需要是确定的,如果是动态的那么会导致宽高获取错误,最终导致节点定位错误和发生重叠等问题。
|
||||
|
||||
如果使用了自定义节点内容,那么内置的插入节点内容的相关方法你都不应该再使用,因为相当于整个节点内容都由你自己控制,另外,节点样式设置也不会再生效,切换主题也只会切换非节点内容的样式,最后,双击节点也不会再进入编辑,所以这个功能一般用于展示性的需求。
|
||||
|
||||
## 示例1:渲染自定义DOM节点
|
||||
|
||||
```js
|
||||
{
|
||||
customCreateNodeContent: (node) => {
|
||||
let div = document.createElement('div')
|
||||
div.className = 'xxx'
|
||||
div.style.cssText = `xxx`
|
||||
div.innerHTML = `
|
||||
<h1>我是自定义节点</h1>
|
||||
${ node.nodeData.text }
|
||||
`
|
||||
return div
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 示例2:渲染Vue2组件
|
||||
|
||||
如果想要使用一个相对简单的`Vue`组件,那么可以通过如下方式:
|
||||
|
||||
```js
|
||||
import CustomNodeContent from 'CustomNodeContent.vue'
|
||||
import Vue from 'vue'
|
||||
|
||||
{
|
||||
customCreateNodeContent: (node) => {
|
||||
let el = document.createElement('div')
|
||||
let Comp = Vue.extend(CustomNodeContent)
|
||||
let comp = new Comp({
|
||||
// props
|
||||
propsData: {
|
||||
html: node.nodeData.data.text
|
||||
}
|
||||
})
|
||||
comp.$mount(el)
|
||||
return comp.$el
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
如果你的`Vue`组件比较复杂,里面用到了`vueRouter`、`vuex`、`i18n`等,那么要和你项目的入口组件一样,在实例化时要把这些内容也加载到组件内,不然会报错。
|
||||
|
||||
```js
|
||||
import CustomNodeContent from 'CustomNodeContent.vue'
|
||||
import Vue from 'vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import i18n from './i18n'
|
||||
|
||||
{
|
||||
customCreateNodeContent: (node) => {
|
||||
let el = document.createElement('div')
|
||||
let Comp = Vue.extend(CustomNodeContent)
|
||||
let comp = new Comp({
|
||||
// props
|
||||
propsData: {
|
||||
html: node.nodeData.data.text
|
||||
},
|
||||
router,
|
||||
store,
|
||||
i18n
|
||||
})
|
||||
comp.$mount(el)
|
||||
return comp.$el
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 示例3:渲染Vue3组件
|
||||
|
||||
```js
|
||||
import { createApp } from "vue"
|
||||
import CustomNodeContent from './CustomNodeContent.vue'
|
||||
|
||||
{
|
||||
customCreateNodeContent: (node) => {
|
||||
let el = document.createElement('div')
|
||||
const app = createApp(CustomNodeContent, {// props
|
||||
html: node.nodeData.data.text
|
||||
})
|
||||
app.mount(el)
|
||||
return el
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 示例4:渲染react组件
|
||||
|
||||
如果你成功渲染了`react`组件,欢迎[提交](https://github.com/wanglin2/mind-map/issues/new)示例代码给我~
|
||||
110
web/src/pages/Doc/zh/course20/index.vue
Normal file
110
web/src/pages/Doc/zh/course20/index.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>如何自定义节点内容</h1>
|
||||
<blockquote>
|
||||
<p>该特性v0.6.3+版本支持</p>
|
||||
</blockquote>
|
||||
<p>如果你想自定义节点的内容,那么可以在实例化<code>simple-mind-map</code>时传入以下选项:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">new</span> MindMap({
|
||||
<span class="hljs-attr">isUseCustomNodeContent</span>: <span class="hljs-literal">true</span>,
|
||||
<span class="hljs-attr">customCreateNodeContent</span>: <span class="hljs-function">(<span class="hljs-params">node</span>) =></span> {
|
||||
<span class="hljs-comment">// return你的自定义DOM节点</span>
|
||||
}
|
||||
})
|
||||
</code></pre>
|
||||
<p><code>customCreateNodeContent</code>方法会接收当前遍历到的节点实例作为参数,一般而言你会需要该节点的数据,这可以通过如下方式获取:</p>
|
||||
<pre class="hljs"><code>node.nodeData.data
|
||||
</code></pre>
|
||||
<p>其他节点实例属性你可以自行打印出来看看。</p>
|
||||
<p><code>customCreateNodeContent</code>方法需要返回<code>DOM</code>节点,如果某个节点你不想自定义,那么可以返回<code>null</code>,那么还是会走内置的节点渲染逻辑。</p>
|
||||
<p>返回的<code>DOM</code>节点的宽高需要是确定的,如果是动态的那么会导致宽高获取错误,最终导致节点定位错误和发生重叠等问题。</p>
|
||||
<p>如果使用了自定义节点内容,那么内置的插入节点内容的相关方法你都不应该再使用,因为相当于整个节点内容都由你自己控制,另外,节点样式设置也不会再生效,切换主题也只会切换非节点内容的样式,最后,双击节点也不会再进入编辑,所以这个功能一般用于展示性的需求。</p>
|
||||
<h2>示例1:渲染自定义DOM节点</h2>
|
||||
<pre class="hljs"><code>{
|
||||
<span class="hljs-attr">customCreateNodeContent</span>: <span class="hljs-function">(<span class="hljs-params">node</span>) =></span> {
|
||||
<span class="hljs-keyword">let</span> div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>)
|
||||
div.className = <span class="hljs-string">'xxx'</span>
|
||||
div.style.cssText = <span class="hljs-string">`xxx`</span>
|
||||
div.innerHTML = <span class="hljs-string">`
|
||||
<h1>我是自定义节点</h1>
|
||||
<span class="hljs-subst">${ node.nodeData.text }</span>
|
||||
`</span>
|
||||
<span class="hljs-keyword">return</span> div
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<h2>示例2:渲染Vue2组件</h2>
|
||||
<p>如果想要使用一个相对简单的<code>Vue</code>组件,那么可以通过如下方式:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> CustomNodeContent <span class="hljs-keyword">from</span> <span class="hljs-string">'CustomNodeContent.vue'</span>
|
||||
<span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>
|
||||
|
||||
{
|
||||
<span class="hljs-attr">customCreateNodeContent</span>: <span class="hljs-function">(<span class="hljs-params">node</span>) =></span> {
|
||||
<span class="hljs-keyword">let</span> el = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>)
|
||||
<span class="hljs-keyword">let</span> Comp = Vue.extend(CustomNodeContent)
|
||||
<span class="hljs-keyword">let</span> comp = <span class="hljs-keyword">new</span> Comp({
|
||||
<span class="hljs-comment">// props</span>
|
||||
<span class="hljs-attr">propsData</span>: {
|
||||
<span class="hljs-attr">html</span>: node.nodeData.data.text
|
||||
}
|
||||
})
|
||||
comp.$mount(el)
|
||||
<span class="hljs-keyword">return</span> comp.$el
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>如果你的<code>Vue</code>组件比较复杂,里面用到了<code>vueRouter</code>、<code>vuex</code>、<code>i18n</code>等,那么要和你项目的入口组件一样,在实例化时要把这些内容也加载到组件内,不然会报错。</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> CustomNodeContent <span class="hljs-keyword">from</span> <span class="hljs-string">'CustomNodeContent.vue'</span>
|
||||
<span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>
|
||||
<span class="hljs-keyword">import</span> router <span class="hljs-keyword">from</span> <span class="hljs-string">'./router'</span>
|
||||
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">'./store'</span>
|
||||
<span class="hljs-keyword">import</span> i18n <span class="hljs-keyword">from</span> <span class="hljs-string">'./i18n'</span>
|
||||
|
||||
{
|
||||
<span class="hljs-attr">customCreateNodeContent</span>: <span class="hljs-function">(<span class="hljs-params">node</span>) =></span> {
|
||||
<span class="hljs-keyword">let</span> el = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>)
|
||||
<span class="hljs-keyword">let</span> Comp = Vue.extend(CustomNodeContent)
|
||||
<span class="hljs-keyword">let</span> comp = <span class="hljs-keyword">new</span> Comp({
|
||||
<span class="hljs-comment">// props</span>
|
||||
<span class="hljs-attr">propsData</span>: {
|
||||
<span class="hljs-attr">html</span>: node.nodeData.data.text
|
||||
},
|
||||
router,
|
||||
store,
|
||||
i18n
|
||||
})
|
||||
comp.$mount(el)
|
||||
<span class="hljs-keyword">return</span> comp.$el
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<h2>示例3:渲染Vue3组件</h2>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> { createApp } <span class="hljs-keyword">from</span> <span class="hljs-string">"vue"</span>
|
||||
<span class="hljs-keyword">import</span> CustomNodeContent <span class="hljs-keyword">from</span> <span class="hljs-string">'./CustomNodeContent.vue'</span>
|
||||
|
||||
{
|
||||
<span class="hljs-attr">customCreateNodeContent</span>: <span class="hljs-function">(<span class="hljs-params">node</span>) =></span> {
|
||||
<span class="hljs-keyword">let</span> el = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>)
|
||||
<span class="hljs-keyword">const</span> app = createApp(CustomNodeContent, {<span class="hljs-comment">// props</span>
|
||||
<span class="hljs-attr">html</span>: node.nodeData.data.text
|
||||
})
|
||||
app.mount(el)
|
||||
<span class="hljs-keyword">return</span> el
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<h2>示例4:渲染react组件</h2>
|
||||
<p>如果你成功渲染了<code>react</code>组件,欢迎<a href="https://github.com/wanglin2/mind-map/issues/new">提交</a>示例代码给我~</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -125,4 +125,8 @@
|
||||
<img src="../../../../assets/avatar/志斌.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>志斌</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/小土渣的宇宙.jpeg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>小土渣的宇宙</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -8,19 +8,19 @@
|
||||
</blockquote>
|
||||
<h2>特性</h2>
|
||||
<ul>
|
||||
<li><input type="checkbox" id="checkbox36" checked="true" /><label for="checkbox36">插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小整体体积</label></li>
|
||||
<li><input type="checkbox" id="checkbox37" checked="true" /><label for="checkbox37">支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴、鱼骨图六种结构</label></li>
|
||||
<li><input type="checkbox" id="checkbox38" checked="true" /><label for="checkbox38">内置多种主题,允许高度自定义样式,支持注册新主题</label></li>
|
||||
<li><input type="checkbox" id="checkbox39" checked="true" /><label for="checkbox39">支持快捷键</label></li>
|
||||
<li><input type="checkbox" id="checkbox40" checked="true" /><label for="checkbox40">节点内容支持图片、图标、超链接、备注、标签、概要</label></li>
|
||||
<li><input type="checkbox" id="checkbox41" checked="true" /><label for="checkbox41">支持前进后退</label></li>
|
||||
<li><input type="checkbox" id="checkbox42" checked="true" /><label for="checkbox42">支持拖动、缩放</label></li>
|
||||
<li><input type="checkbox" id="checkbox43" checked="true" /><label for="checkbox43">支持右键和Ctrl+左键两种多选方式</label></li>
|
||||
<li><input type="checkbox" id="checkbox44" checked="true" /><label for="checkbox44">支持节点自由拖拽、拖拽调整</label></li>
|
||||
<li><input type="checkbox" id="checkbox45" checked="true" /><label for="checkbox45">支持多种节点形状</label></li>
|
||||
<li><input type="checkbox" id="checkbox46" checked="true" /><label for="checkbox46">支持导出为</label><code>json</code>、<code>png</code>、<code>svg</code>、<code>pdf</code>、<code>markdown</code>,支持从<code>json</code>、<code>xmind</code>、<code>markdown</code>导入</li>
|
||||
<li><input type="checkbox" id="checkbox47" checked="true" /><label for="checkbox47">支持小地图、支持水印</label></li>
|
||||
<li><input type="checkbox" id="checkbox48" checked="true" /><label for="checkbox48">支持关联线</label></li>
|
||||
<li><input type="checkbox" id="checkbox18" checked="true" /><label for="checkbox18">插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小整体体积</label></li>
|
||||
<li><input type="checkbox" id="checkbox19" checked="true" /><label for="checkbox19">支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴、鱼骨图六种结构</label></li>
|
||||
<li><input type="checkbox" id="checkbox20" checked="true" /><label for="checkbox20">内置多种主题,允许高度自定义样式,支持注册新主题</label></li>
|
||||
<li><input type="checkbox" id="checkbox21" checked="true" /><label for="checkbox21">支持快捷键</label></li>
|
||||
<li><input type="checkbox" id="checkbox22" checked="true" /><label for="checkbox22">节点内容支持图片、图标、超链接、备注、标签、概要</label></li>
|
||||
<li><input type="checkbox" id="checkbox23" checked="true" /><label for="checkbox23">支持前进后退</label></li>
|
||||
<li><input type="checkbox" id="checkbox24" checked="true" /><label for="checkbox24">支持拖动、缩放</label></li>
|
||||
<li><input type="checkbox" id="checkbox25" checked="true" /><label for="checkbox25">支持右键和Ctrl+左键两种多选方式</label></li>
|
||||
<li><input type="checkbox" id="checkbox26" checked="true" /><label for="checkbox26">支持节点自由拖拽、拖拽调整</label></li>
|
||||
<li><input type="checkbox" id="checkbox27" checked="true" /><label for="checkbox27">支持多种节点形状</label></li>
|
||||
<li><input type="checkbox" id="checkbox28" checked="true" /><label for="checkbox28">支持导出为</label><code>json</code>、<code>png</code>、<code>svg</code>、<code>pdf</code>、<code>markdown</code>,支持从<code>json</code>、<code>xmind</code>、<code>markdown</code>导入</li>
|
||||
<li><input type="checkbox" id="checkbox29" checked="true" /><label for="checkbox29">支持小地图、支持水印</label></li>
|
||||
<li><input type="checkbox" id="checkbox30" checked="true" /><label for="checkbox30">支持关联线</label></li>
|
||||
</ul>
|
||||
<h2>仓库目录介绍</h2>
|
||||
<p>1.<code>simple-mind-map</code></p>
|
||||
@@ -28,11 +28,11 @@
|
||||
<p>2.<code>web</code></p>
|
||||
<p>使用<code>simple-mind-map</code>库,基于<code>vue2.x</code>、<code>ElementUI</code>搭建的在线思维导图。特性:</p>
|
||||
<ul>
|
||||
<li><input type="checkbox" id="checkbox49" checked="true" /><label for="checkbox49">工具栏,支持插入节点、删除节点;编辑节点图片、图标、超链接、备注、标签、概要</label></li>
|
||||
<li><input type="checkbox" id="checkbox50" checked="true" /><label for="checkbox50">侧边栏,基础样式设置面板、节点样式设置面板、大纲面板、主题选择面板、结构选择面板</label></li>
|
||||
<li><input type="checkbox" id="checkbox51" checked="true" /><label for="checkbox51">导入导出功能;数据默认保存在浏览器本地存储,也支持直接创建、打开、编辑电脑本地文件</label></li>
|
||||
<li><input type="checkbox" id="checkbox52" checked="true" /><label for="checkbox52">右键菜单,支持展开、收起、整理布局等操作</label></li>
|
||||
<li><input type="checkbox" id="checkbox53" checked="true" /><label for="checkbox53">底部栏,支持节点数量、字数统计;支持切换编辑和只读模式;支持放大缩小;支持全屏切换;支持小地图</label></li>
|
||||
<li><input type="checkbox" id="checkbox31" checked="true" /><label for="checkbox31">工具栏,支持插入节点、删除节点;编辑节点图片、图标、超链接、备注、标签、概要</label></li>
|
||||
<li><input type="checkbox" id="checkbox32" checked="true" /><label for="checkbox32">侧边栏,基础样式设置面板、节点样式设置面板、大纲面板、主题选择面板、结构选择面板</label></li>
|
||||
<li><input type="checkbox" id="checkbox33" checked="true" /><label for="checkbox33">导入导出功能;数据默认保存在浏览器本地存储,也支持直接创建、打开、编辑电脑本地文件</label></li>
|
||||
<li><input type="checkbox" id="checkbox34" checked="true" /><label for="checkbox34">右键菜单,支持展开、收起、整理布局等操作</label></li>
|
||||
<li><input type="checkbox" id="checkbox35" checked="true" /><label for="checkbox35">底部栏,支持节点数量、字数统计;支持切换编辑和只读模式;支持放大缩小;支持全屏切换;支持小地图</label></li>
|
||||
</ul>
|
||||
<p>提供文档页面服务。</p>
|
||||
<p>3.<code>dist</code></p>
|
||||
@@ -84,6 +84,10 @@
|
||||
<img src="../../../../assets/avatar/志斌.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>志斌</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/小土渣的宇宙.jpeg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>小土渣的宇宙</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -72,7 +72,7 @@ const mindMap = new MindMap({
|
||||
<script scr="simpleMindMap.umd.min.js"></script>
|
||||
```
|
||||
|
||||
会创建一个全局变量`window.simpleMindMap`。
|
||||
会创建一个全局变量`window.simpleMindMap`,可以通过`window.simpleMindMap.default`获取到`MindMap`构造函数,详细信息可以把`window.simpleMindMap`打印出来看一下。
|
||||
|
||||
这种方式的缺点是会包含所有的内容,包括你没有注册的插件,所以整体体积会比较大。
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<pre class="hljs"><code><span class="hljs-tag"><<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"simpleMindMap.css"</span>></span>
|
||||
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">scr</span>=<span class="hljs-string">"simpleMindMap.umd.min.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
|
||||
</code></pre>
|
||||
<p>会创建一个全局变量<code>window.simpleMindMap</code>。</p>
|
||||
<p>会创建一个全局变量<code>window.simpleMindMap</code>,可以通过<code>window.simpleMindMap.default</code>获取到<code>MindMap</code>构造函数,详细信息可以把<code>window.simpleMindMap</code>打印出来看一下。</p>
|
||||
<p>这种方式的缺点是会包含所有的内容,包括你没有注册的插件,所以整体体积会比较大。</p>
|
||||
<p>(v0.5.4+)如果你想直接在浏览器端通过<code>ES</code>模块的方式来使用,你可以在<code>/simple-mind-map/dist/</code>目录中找到<code>simpleMindMap.esm.js</code>和<code>simpleMindMap.esm.css</code>文件。</p>
|
||||
<h2>开发</h2>
|
||||
|
||||
36
web/src/pages/Edit/components/CustomNodeContent.vue
Normal file
36
web/src/pages/Edit/components/CustomNodeContent.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div class="customNodeContent">
|
||||
<p>{{ title }}</p>
|
||||
<p v-html="html"></p>
|
||||
<p :style="{ backgroundColor: color }" @click="onClick">点击我会变色</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
html: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '我是自定义节点',
|
||||
color: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
this.color = 'red'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.customNodeContent {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -48,8 +48,14 @@ import Navigator from './Navigator.vue'
|
||||
import NodeImgPreview from './NodeImgPreview.vue'
|
||||
import SidebarTrigger from './SidebarTrigger.vue'
|
||||
import { mapState } from 'vuex'
|
||||
import customThemeList from '@/customThemes'
|
||||
import icon from '@/config/icon'
|
||||
import customThemeList from '@/customThemes'
|
||||
import CustomNodeContent from './CustomNodeContent.vue'
|
||||
import Color from './Color.vue'
|
||||
import Vue from 'vue'
|
||||
import router from '../../../router'
|
||||
import store from '../../../store'
|
||||
import i18n from '../../../i18n'
|
||||
|
||||
// 注册插件
|
||||
MindMap
|
||||
@@ -293,7 +299,32 @@ export default {
|
||||
},
|
||||
...(config || {}),
|
||||
iconList: icon,
|
||||
useLeftKeySelectionRightKeyDrag: this.useLeftKeySelectionRightKeyDrag
|
||||
useLeftKeySelectionRightKeyDrag: this.useLeftKeySelectionRightKeyDrag,
|
||||
// isUseCustomNodeContent: true,
|
||||
// 示例1:组件里用到了router、store、i18n等实例化vue组件时需要用到的东西
|
||||
// customCreateNodeContent: (node) => {
|
||||
// let el = document.createElement('div')
|
||||
// let Comp = Vue.extend(Color)
|
||||
// let comp = new Comp({
|
||||
// router,
|
||||
// store,
|
||||
// i18n
|
||||
// })
|
||||
// comp.$mount(el)
|
||||
// return comp.$el
|
||||
// },
|
||||
// 示例2:组件里没有用到示例1的东西
|
||||
// customCreateNodeContent: (node) => {
|
||||
// let el = document.createElement('div')
|
||||
// let Comp = Vue.extend(CustomNodeContent)
|
||||
// let comp = new Comp({
|
||||
// propsData: {
|
||||
// html: node.nodeData.data.text
|
||||
// }
|
||||
// })
|
||||
// comp.$mount(el)
|
||||
// return comp.$el
|
||||
// }
|
||||
})
|
||||
if (this.openNodeRichText) this.addRichTextPlugin()
|
||||
this.mindMap.keyCommand.addShortcut('Control+s', () => {
|
||||
|
||||
Reference in New Issue
Block a user