mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-23 18:14:10 +08:00
Compare commits
18 Commits
0.5.4
...
0.5.5-fix.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abda5b7d06 | ||
|
|
f815f71dd7 | ||
|
|
fa2c5b420c | ||
|
|
4c19bc76a7 | ||
|
|
d08a317920 | ||
|
|
bd805836cd | ||
|
|
e804a8f2f7 | ||
|
|
8bf876d446 | ||
|
|
f2521f663e | ||
|
|
e676bff453 | ||
|
|
8f2cc72d3c | ||
|
|
ec22656bee | ||
|
|
4acf8ba2ac | ||
|
|
d45a18904e | ||
|
|
9fc2dbabd4 | ||
|
|
b83b81f52e | ||
|
|
d1e2db993e | ||
|
|
ab931901e2 |
File diff suppressed because one or more lines are too long
@@ -92,7 +92,16 @@ const defaultOpt = {
|
||||
// 如果开启节点动画过渡,可以通过该属性设置过渡的时间,单位ms
|
||||
nodeTransitionMoveDuration: 300,
|
||||
// 初始根节点的位置
|
||||
initRootNodePosition: null
|
||||
initRootNodePosition: null,
|
||||
// 导出png、svg、pdf时的图形内边距
|
||||
exportPaddingX: 10,
|
||||
exportPaddingY: 10,
|
||||
// 节点文本编辑框的z-index
|
||||
nodeTextEditZIndex: 3000,
|
||||
// 节点备注浮层的z-index
|
||||
nodeNoteTooltipZIndex: 3000,
|
||||
// 是否在点击了画布外的区域时结束节点文本的编辑状态
|
||||
isEndNodeTextEditOnClickOuter: true
|
||||
}
|
||||
|
||||
// 思维导图
|
||||
@@ -272,6 +281,7 @@ class MindMap {
|
||||
layout = CONSTANTS.LAYOUT.LOGICAL_STRUCTURE
|
||||
}
|
||||
this.opt.layout = layout
|
||||
this.view.reset()
|
||||
this.renderer.setLayout()
|
||||
this.render()
|
||||
}
|
||||
@@ -359,7 +369,7 @@ class MindMap {
|
||||
}
|
||||
|
||||
// 获取svg数据
|
||||
getSvgData() {
|
||||
getSvgData({ paddingX = 0, paddingY = 0 } = {}) {
|
||||
const svg = this.svg
|
||||
const draw = this.draw
|
||||
// 保存原始信息
|
||||
@@ -371,6 +381,10 @@ class MindMap {
|
||||
draw.scale(1 / origTransform.scaleX, 1 / origTransform.scaleY)
|
||||
// 获取变换后的位置尺寸信息,其实是getBoundingClientRect方法的包装方法
|
||||
const rect = draw.rbox()
|
||||
// 内边距
|
||||
rect.width += paddingX
|
||||
rect.height += paddingY
|
||||
draw.translate(paddingX / 2, paddingY / 2)
|
||||
// 将svg设置为实际内容的宽高
|
||||
svg.size(rect.width, rect.height)
|
||||
// 把实际内容变换
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "simple-mind-map",
|
||||
"version": "0.5.4",
|
||||
"version": "0.5.5-fix.2",
|
||||
"description": "一个简单的web在线思维导图",
|
||||
"authors": [
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ class Event extends EventEmitter {
|
||||
|
||||
// 绑定函数上下文
|
||||
bindFn() {
|
||||
this.onBodyClick = this.onBodyClick.bind(this)
|
||||
this.onDrawClick = this.onDrawClick.bind(this)
|
||||
this.onMousedown = this.onMousedown.bind(this)
|
||||
this.onMousemove = this.onMousemove.bind(this)
|
||||
@@ -41,6 +42,7 @@ class Event extends EventEmitter {
|
||||
|
||||
// 绑定事件
|
||||
bind() {
|
||||
document.body.addEventListener('click', this.onBodyClick)
|
||||
this.mindMap.svg.on('click', this.onDrawClick)
|
||||
this.mindMap.el.addEventListener('mousedown', this.onMousedown)
|
||||
this.mindMap.svg.on('mousedown', this.onSvgMousedown)
|
||||
@@ -55,6 +57,7 @@ class Event extends EventEmitter {
|
||||
|
||||
// 解绑事件
|
||||
unbind() {
|
||||
document.body.removeEventListener('click', this.onBodyClick)
|
||||
this.mindMap.svg.off('click', this.onDrawClick)
|
||||
this.mindMap.el.removeEventListener('mousedown', this.onMousedown)
|
||||
window.removeEventListener('mousemove', this.onMousemove)
|
||||
@@ -71,6 +74,11 @@ class Event extends EventEmitter {
|
||||
this.emit('draw_click', e)
|
||||
}
|
||||
|
||||
// 页面的单击事件
|
||||
onBodyClick(e) {
|
||||
this.emit('body_click', e)
|
||||
}
|
||||
|
||||
// svg画布的鼠标按下事件
|
||||
onSvgMousedown(e) {
|
||||
this.emit('svg_mousedown', e)
|
||||
|
||||
@@ -28,7 +28,11 @@ class Export {
|
||||
|
||||
// 获取svg数据
|
||||
async getSvgData(domToImage) {
|
||||
let { svg, svgHTML } = this.mindMap.getSvgData()
|
||||
let { exportPaddingX, exportPaddingY } = this.mindMap.opt
|
||||
let { svg, svgHTML } = this.mindMap.getSvgData({
|
||||
paddingX: exportPaddingX,
|
||||
paddingY: exportPaddingY
|
||||
})
|
||||
// 把图片的url转换成data:url类型,否则导出会丢失图片
|
||||
let imageList = svg.find('image')
|
||||
let task = imageList.map(async item => {
|
||||
|
||||
@@ -99,6 +99,9 @@ class RichText {
|
||||
if (!this.textEditNode) {
|
||||
this.textEditNode = document.createElement('div')
|
||||
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;padding: 3px 5px;margin-left: -5px;margin-top: -3px;`
|
||||
this.textEditNode.addEventListener('click', e => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
document.body.appendChild(this.textEditNode)
|
||||
}
|
||||
// 原始宽高
|
||||
@@ -107,6 +110,7 @@ class RichText {
|
||||
let originHeight = g.attr('data-height')
|
||||
// 使用节点的填充色,否则如果节点颜色是白色的话编辑时看不见
|
||||
let bgColor = node.style.merge('fillColor')
|
||||
this.textEditNode.style.zIndex = this.mindMap.opt.nodeTextEditZIndex
|
||||
this.textEditNode.style.backgroundColor = bgColor === 'transparent' ? '#fff' : bgColor
|
||||
this.textEditNode.style.minWidth = originWidth + 'px'
|
||||
this.textEditNode.style.minHeight = originHeight + 'px'
|
||||
|
||||
@@ -17,7 +17,7 @@ class Select {
|
||||
|
||||
// 绑定事件
|
||||
bindEvent() {
|
||||
this.checkInNodes = throttle(this.checkInNodes, 500, this)
|
||||
this.checkInNodes = throttle(this.checkInNodes, 300, this)
|
||||
this.mindMap.on('mousedown', e => {
|
||||
if (this.mindMap.opt.readonly) {
|
||||
return
|
||||
@@ -146,22 +146,26 @@ class Select {
|
||||
let bottom = (top + height) * scaleY + translateY
|
||||
left = left * scaleX + translateX
|
||||
top = top * scaleY + translateY
|
||||
if (left >= minx && right <= maxx && top >= miny && bottom <= maxy) {
|
||||
this.mindMap.batchExecution.push('activeNode' + node.uid, () => {
|
||||
if ((left >= minx && left <= maxx ||
|
||||
right >= minx && right <= maxx) &&
|
||||
(top >= miny && top <= maxy ||
|
||||
bottom >= miny && bottom <= maxy)
|
||||
) {
|
||||
// this.mindMap.batchExecution.push('activeNode' + node.uid, () => {
|
||||
if (node.nodeData.data.isActive) {
|
||||
return
|
||||
}
|
||||
this.mindMap.renderer.setNodeActive(node, true)
|
||||
this.mindMap.renderer.addActiveNode(node)
|
||||
})
|
||||
// })
|
||||
} else if (node.nodeData.data.isActive) {
|
||||
this.mindMap.batchExecution.push('activeNode' + node.uid, () => {
|
||||
// this.mindMap.batchExecution.push('activeNode' + node.uid, () => {
|
||||
if (!node.nodeData.data.isActive) {
|
||||
return
|
||||
}
|
||||
this.mindMap.renderer.setNodeActive(node, false)
|
||||
this.mindMap.renderer.removeActiveNode(node)
|
||||
})
|
||||
// })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getStrWithBrFromHtml } from './utils'
|
||||
import { getStrWithBrFromHtml, checkNodeOuter } from './utils'
|
||||
|
||||
// 节点文字编辑类
|
||||
export default class TextEdit {
|
||||
@@ -23,6 +23,12 @@ export default class TextEdit {
|
||||
// 隐藏文本编辑框
|
||||
this.hideEditTextBox()
|
||||
})
|
||||
this.mindMap.on('body_click', () => {
|
||||
// 隐藏文本编辑框
|
||||
if (this.mindMap.opt.isEndNodeTextEditOnClickOuter) {
|
||||
this.hideEditTextBox()
|
||||
}
|
||||
})
|
||||
this.mindMap.on('svg_mousedown', () => {
|
||||
// 隐藏文本编辑框
|
||||
this.hideEditTextBox()
|
||||
@@ -54,6 +60,8 @@ export default class TextEdit {
|
||||
|
||||
// 显示文本编辑框
|
||||
show(node) {
|
||||
let { offsetLeft, offsetTop } = checkNodeOuter(this.mindMap, node)
|
||||
this.mindMap.view.translateXY(offsetLeft, offsetTop)
|
||||
let rect = node._textData.node.node.getBoundingClientRect()
|
||||
if (this.mindMap.richText) {
|
||||
this.mindMap.richText.showEditText(node, rect)
|
||||
@@ -73,6 +81,9 @@ export default class TextEdit {
|
||||
this.textEditNode.addEventListener('keyup', e => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
this.textEditNode.addEventListener('click', e => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
document.body.appendChild(this.textEditNode)
|
||||
}
|
||||
let scale = this.mindMap.view.scale
|
||||
@@ -80,6 +91,7 @@ export default class TextEdit {
|
||||
let fontSize = node.style.merge('fontSize')
|
||||
let textLines = node.nodeData.data.text.split(/\n/gim)
|
||||
node.style.domText(this.textEditNode, scale, textLines.length)
|
||||
this.textEditNode.style.zIndex = this.mindMap.opt.nodeTextEditZIndex
|
||||
this.textEditNode.innerHTML = textLines.join('<br>')
|
||||
this.textEditNode.style.minWidth = rect.width + 10 + 'px'
|
||||
this.textEditNode.style.minHeight = rect.height + 6 + 'px'
|
||||
|
||||
@@ -124,6 +124,13 @@ class View {
|
||||
}
|
||||
}
|
||||
|
||||
// 平移x,y方向
|
||||
translateXY(x, y) {
|
||||
this.x += x
|
||||
this.y += y
|
||||
this.transform()
|
||||
}
|
||||
|
||||
// 平移x方向
|
||||
translateX(step) {
|
||||
this.x += step
|
||||
@@ -160,10 +167,14 @@ class View {
|
||||
|
||||
// 恢复
|
||||
reset() {
|
||||
let scaleChange = this.scale !== 1
|
||||
this.scale = 1
|
||||
this.x = 0
|
||||
this.y = 0
|
||||
this.transform()
|
||||
if (scaleChange) {
|
||||
this.mindMap.emit('scale', this.scale)
|
||||
}
|
||||
}
|
||||
|
||||
// 缩小
|
||||
|
||||
@@ -8,6 +8,8 @@ class Fishbone extends Base {
|
||||
// 构造函数
|
||||
constructor(opt = {}) {
|
||||
super(opt)
|
||||
this.indent = 0.3
|
||||
this.childIndent = 0.5
|
||||
}
|
||||
|
||||
// 布局
|
||||
@@ -239,21 +241,21 @@ class Fishbone extends Base {
|
||||
maxx = item.left
|
||||
}
|
||||
// 水平线段到二级节点的连线
|
||||
let nodeLineX = item.left + item.width * 0.3
|
||||
let offset = item.height + node.height / 2
|
||||
let nodeLineX = item.left
|
||||
let offset = node.height / 2
|
||||
let offsetX = offset / Math.tan(degToRad(this.mindMap.opt.fishboneDeg))
|
||||
let line = this.draw.path()
|
||||
if (this.checkIsTop(item)) {
|
||||
line.plot(
|
||||
`M ${nodeLineX - offsetX},${item.top + offset} L ${nodeLineX},${
|
||||
item.top
|
||||
`M ${nodeLineX - offsetX},${item.top + item.height + offset} L ${item.left},${
|
||||
item.top + item.height
|
||||
}`
|
||||
)
|
||||
} else {
|
||||
line.plot(
|
||||
`M ${nodeLineX - offsetX},${
|
||||
item.top + item.height - offset
|
||||
} L ${nodeLineX},${item.top + item.height}`
|
||||
item.top - offset
|
||||
} L ${nodeLineX},${item.top}`
|
||||
)
|
||||
}
|
||||
node.style.line(line)
|
||||
@@ -277,7 +279,7 @@ class Fishbone extends Base {
|
||||
let maxy = -Infinity
|
||||
let miny = Infinity
|
||||
let maxx = -Infinity
|
||||
let x = node.left + node.width * 0.3
|
||||
let x = node.left + node.width * this.indent
|
||||
node.children.forEach((item, index) => {
|
||||
if (item.left > maxx) {
|
||||
maxx = item.left
|
||||
@@ -300,7 +302,7 @@ class Fishbone extends Base {
|
||||
if (len >= 0) {
|
||||
let line = this.draw.path()
|
||||
expandBtnSize = len > 0 ? expandBtnSize : 0
|
||||
let lineLength = maxx - node.left - node.width * 0.3
|
||||
let lineLength = maxx - node.left - node.width * this.indent
|
||||
lineLength = Math.max(lineLength, 0)
|
||||
let params = {
|
||||
node,
|
||||
|
||||
@@ -47,7 +47,7 @@ export default {
|
||||
computedLeftTopValue({ layerIndex, node, ctx }) {
|
||||
if (layerIndex >= 1 && node.children) {
|
||||
// 遍历三级及以下节点的子节点
|
||||
let startLeft = node.left + node.width * 0.5
|
||||
let startLeft = node.left + node.width * ctx.childIndent
|
||||
let totalTop =
|
||||
node.top +
|
||||
node.height +
|
||||
@@ -80,22 +80,21 @@ export default {
|
||||
// 将二级节点的子节点移到上方
|
||||
if (parent && parent.isRoot) {
|
||||
// 遍历二级节点的子节点
|
||||
let totalHeight = 0
|
||||
let totalHeight = node.expandBtnSize
|
||||
node.children.forEach(item => {
|
||||
// 调整top
|
||||
let nodeTotalHeight = ctx.getNodeAreaHeight(item)
|
||||
let _top = item.top
|
||||
let _left = item.left
|
||||
item.top =
|
||||
node.top - (item.top - node.top) - nodeTotalHeight + node.height
|
||||
// 调整left
|
||||
let offsetLeft =
|
||||
(nodeTotalHeight + totalHeight) / Math.tan(degToRad(ctx.mindMap.opt.fishboneDeg))
|
||||
item.left += offsetLeft
|
||||
item.left = node.left + node.width * ctx.indent + (nodeTotalHeight + totalHeight) / Math.tan(degToRad(ctx.mindMap.opt.fishboneDeg))
|
||||
totalHeight += nodeTotalHeight
|
||||
// 同步更新后代节点
|
||||
ctx.updateChildrenPro(item.children, {
|
||||
top: item.top - _top,
|
||||
left: offsetLeft
|
||||
left: item.left - _left
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -137,7 +136,7 @@ export default {
|
||||
computedLeftTopValue({ layerIndex, node, ctx }) {
|
||||
if (layerIndex === 1 && node.children) {
|
||||
// 遍历二级节点的子节点
|
||||
let startLeft = node.left + node.width * 0.5
|
||||
let startLeft = node.left + node.width * ctx.childIndent
|
||||
let totalTop =
|
||||
node.top +
|
||||
node.height +
|
||||
@@ -155,7 +154,7 @@ export default {
|
||||
}
|
||||
if (layerIndex > 1 && node.children) {
|
||||
// 遍历三级及以下节点的子节点
|
||||
let startLeft = node.left + node.width * 0.5
|
||||
let startLeft = node.left + node.width * ctx.childIndent
|
||||
let totalTop =
|
||||
node.top -
|
||||
(ctx.getNodeActChildrenLength(node) > 0 ? node.expandBtnSize : 0)
|
||||
@@ -187,7 +186,7 @@ export default {
|
||||
if (parent && parent.isRoot) {
|
||||
// 遍历二级节点的子节点
|
||||
let totalHeight = 0
|
||||
let totalHeight2 = 0
|
||||
let totalHeight2 = node.expandBtnSize
|
||||
node.children.forEach(item => {
|
||||
// 调整top
|
||||
let hasChildren = ctx.getNodeActChildrenLength(item) > 0
|
||||
@@ -199,17 +198,16 @@ export default {
|
||||
(hasChildren ? item.expandBtnSize : 0)
|
||||
: 0
|
||||
let _top = totalHeight + offset
|
||||
let _left = item.left
|
||||
item.top += _top
|
||||
// 调整left
|
||||
let offsetLeft =
|
||||
(totalHeight2 + nodeTotalHeight) / Math.tan(degToRad(ctx.mindMap.opt.fishboneDeg))
|
||||
item.left += offsetLeft
|
||||
item.left = node.left + node.width * ctx.indent + (nodeTotalHeight + totalHeight2) / Math.tan(degToRad(ctx.mindMap.opt.fishboneDeg))
|
||||
totalHeight += offset
|
||||
totalHeight2 += nodeTotalHeight
|
||||
// 同步更新后代节点
|
||||
ctx.updateChildrenPro(item.children, {
|
||||
top: _top,
|
||||
left: offsetLeft
|
||||
left: item.left - _left
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -302,4 +302,34 @@ export const nextTick = function (fn, ctx) {
|
||||
pending = true
|
||||
timerFunc(handle, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查节点是否超出画布
|
||||
export const checkNodeOuter = (mindMap, node) => {
|
||||
let elRect = mindMap.elRect
|
||||
let { scaleX, scaleY, translateX, translateY } = mindMap.draw.transform()
|
||||
let { left, top, width, height } = node
|
||||
let right = (left + width) * scaleX + translateX
|
||||
let bottom = (top + height) * scaleY + translateY
|
||||
left = left * scaleX + translateX
|
||||
top = top * scaleY + translateY
|
||||
let offsetLeft = 0
|
||||
let offsetTop = 0
|
||||
if (left < 0) {
|
||||
offsetLeft = -left
|
||||
}
|
||||
if (right > elRect.width) {
|
||||
offsetLeft = -(right - elRect.width)
|
||||
}
|
||||
if (top < 0) {
|
||||
offsetTop = -top
|
||||
}
|
||||
if (bottom > elRect.height) {
|
||||
offsetTop = -(bottom - elRect.height)
|
||||
}
|
||||
return {
|
||||
isOuter: offsetLeft !== 0 || offsetTop !== 0,
|
||||
offsetLeft,
|
||||
offsetTop
|
||||
}
|
||||
}
|
||||
@@ -205,13 +205,14 @@ function createNoteNode() {
|
||||
if (!this.noteEl) {
|
||||
this.noteEl = document.createElement('div')
|
||||
this.noteEl.style.cssText = `
|
||||
position: absolute;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 2px 5px rgb(0 0 0 / 10%);
|
||||
display: none;
|
||||
background-color: #fff;
|
||||
`
|
||||
position: absolute;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 2px 5px rgb(0 0 0 / 10%);
|
||||
display: none;
|
||||
background-color: #fff;
|
||||
z-index: ${ this.mindMap.opt.nodeNoteTooltipZIndex }
|
||||
`
|
||||
document.body.appendChild(this.noteEl)
|
||||
}
|
||||
this.noteEl.innerText = this.nodeData.data.note
|
||||
|
||||
2
web/package-lock.json
generated
2
web/package-lock.json
generated
@@ -18450,7 +18450,6 @@
|
||||
"integrity": "sha512-VCNRiAt2P/bLo09rYt3DLe6xXUMlhJwrvU18Ddd/lYJgC7s8+wvhgYs+MTx4OiAXdu58drGwSBO9SPx7C6J82Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.11.0",
|
||||
"@babel/helper-compilation-targets": "^7.9.6",
|
||||
"@babel/helper-module-imports": "^7.8.3",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
@@ -18463,7 +18462,6 @@
|
||||
"@vue/babel-plugin-jsx": "^1.0.3",
|
||||
"@vue/babel-preset-jsx": "^1.2.4",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||
"core-js": "^3.6.5",
|
||||
"core-js-compat": "^3.6.5",
|
||||
"semver": "^6.1.0"
|
||||
}
|
||||
|
||||
BIN
web/src/assets/avatar/Think.jpg
Normal file
BIN
web/src/assets/avatar/Think.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@@ -95,7 +95,9 @@ export default {
|
||||
svgTips: 'tips: Exporting pictures in rich text mode is time-consuming',
|
||||
transformingDomToImages: 'Converting nodes: ',
|
||||
notifyTitle: 'Info',
|
||||
notifyMessage: 'If the download is not triggered, check whether it is blocked by the browser'
|
||||
notifyMessage: 'If the download is not triggered, check whether it is blocked by the browser',
|
||||
paddingX: 'Padding x',
|
||||
paddingY: 'Padding y'
|
||||
},
|
||||
fullscreen: {
|
||||
fullscreenShow: 'Full screen show',
|
||||
|
||||
@@ -95,7 +95,9 @@ export default {
|
||||
svgTips: 'tips:富文本模式导出图片非常耗时',
|
||||
transformingDomToImages: '正在转换节点:',
|
||||
notifyTitle: '消息',
|
||||
notifyMessage: '如果没有触发下载,请检查是否被浏览器拦截了'
|
||||
notifyMessage: '如果没有触发下载,请检查是否被浏览器拦截了',
|
||||
paddingX: '水平内边距',
|
||||
paddingY: '垂直内边距'
|
||||
},
|
||||
fullscreen: {
|
||||
fullscreenShow: '全屏查看',
|
||||
|
||||
@@ -10,7 +10,7 @@ let langList = [
|
||||
path: 'en'
|
||||
}
|
||||
]
|
||||
let StartList = ['introduction', 'start', 'translate', 'changelog']
|
||||
let StartList = ['introduction', 'start', 'deploy', 'translate', 'changelog']
|
||||
let CourseList = new Array(18).fill(0).map((_, index) => {
|
||||
return 'course' + (index + 1)
|
||||
})
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## 0.5.5-fix.1
|
||||
|
||||
Fix: 1.Fix the issue where the edit box is also outside the canvas when editing nodes outside the canvas. 2.After modifying the structure, reset the transformation to prevent the problem of sudden position changes during the first drag after switching the structure during scaling.
|
||||
|
||||
optimization: 1.When multiple nodes are selected, as long as there is a cross between the node and the selection area, it is considered selected.
|
||||
|
||||
## 0.5.5
|
||||
|
||||
New: 1.Supports configuring the padding when exporting to PNG, SVG, or PDF. 2.Support the configuration of z-index for node text editing boxes and node comment floating layer elements. 3.Support clicking on areas outside the canvas to end node editing status.
|
||||
|
||||
## 0.5.4
|
||||
|
||||
New: 1.Add new themes. 2.Added timeline and fishbone structure.
|
||||
@@ -8,6 +18,10 @@ Fix: 1.Fix the conflict issue between node right-click and canvas right-click. 2
|
||||
|
||||
optimization: 1.Optimize the layout of organizational chart. 2.Optimize the layout of the directory organization chart.
|
||||
|
||||
## 0.5.4-fix.1
|
||||
|
||||
optimization: 1.Optimize fishbone layout.
|
||||
|
||||
## 0.5.3
|
||||
|
||||
Fix: 1.Fixed the issue of setting the text style when multiple nodes were selected in rich text mode, which would change the text of all selected nodes to the text of the last selected node.
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.5.5-fix.1</h2>
|
||||
<p>Fix: 1.Fix the issue where the edit box is also outside the canvas when editing nodes outside the canvas. 2.After modifying the structure, reset the transformation to prevent the problem of sudden position changes during the first drag after switching the structure during scaling.</p>
|
||||
<p>optimization: 1.When multiple nodes are selected, as long as there is a cross between the node and the selection area, it is considered selected.</p>
|
||||
<h2>0.5.5</h2>
|
||||
<p>New: 1.Supports configuring the padding when exporting to PNG, SVG, or PDF. 2.Support the configuration of z-index for node text editing boxes and node comment floating layer elements. 3.Support clicking on areas outside the canvas to end node editing status.</p>
|
||||
<h2>0.5.4</h2>
|
||||
<p>New: 1.Add new themes. 2.Added timeline and fishbone structure.</p>
|
||||
<p>Fix: 1.Fix the conflict issue between node right-click and canvas right-click. 2.Fix the bug that the line segment is not hidden when dragging nodes such as organizational chart and directory organization chart.</p>
|
||||
<p>optimization: 1.Optimize the layout of organizational chart. 2.Optimize the layout of the directory organization chart.</p>
|
||||
<h2>0.5.4-fix.1</h2>
|
||||
<p>optimization: 1.Optimize fishbone layout.</p>
|
||||
<h2>0.5.3</h2>
|
||||
<p>Fix: 1.Fixed the issue of setting the text style when multiple nodes were selected in rich text mode, which would change the text of all selected nodes to the text of the last selected node.</p>
|
||||
<p>New: 1.Support setting the position of the initial central node.</p>
|
||||
|
||||
@@ -53,6 +53,11 @@ const mindMap = new MindMap({
|
||||
| enableNodeTransitionMove(v0.5.1+) | Boolean | true | Whether to enable node animation transition | |
|
||||
| nodeTransitionMoveDuration(v0.5.1+) | Number | 300 | If node animation transition is enabled, the transition time can be set using this attribute, in milliseconds | |
|
||||
| initRootNodePosition(v0.5.3+) | Array | null | The position of the initial root node can be passed as an array, default is `['center', 'center']`, Represents the root node at the center of the canvas, In addition to `center`, keywords can also be set to `left`, `top`, `right`, and `bottom`, In addition to passing keywords, each item in the array can also pass a number representing a specific pixel, Can pass a percentage string, such as `['40%', '60%']`, Represents a horizontal position at `40%` of the canvas width, and a vertical position at `60%` of the canvas height | |
|
||||
| exportPaddingX(v0.5.5+) | Number | 10 | Horizontal padding of graphics when exporting PNG, SVG, and PDF | |
|
||||
| exportPaddingY(v0.5.5+) | Number | 10 | Vertical padding of graphics when exporting PNG, SVG, and PDF | |
|
||||
| nodeTextEditZIndex(v0.5.5+) | Number | 3000 | | z-index of node text edit box elements |
|
||||
| nodeNoteTooltipZIndex(v0.5.5+) | Number | 3000 | z-index of floating layer elements in node comments | |
|
||||
| isEndNodeTextEditOnClickOuter(v0.5.5+) | Boolean | true | Whether to end the editing status of node text when clicking on an area outside the canvas | |
|
||||
|
||||
### Watermark config
|
||||
|
||||
|
||||
@@ -231,6 +231,41 @@
|
||||
<td>The position of the initial root node can be passed as an array, default is <code>['center', 'center']</code>, Represents the root node at the center of the canvas, In addition to <code>center</code>, keywords can also be set to <code>left</code>, <code>top</code>, <code>right</code>, and <code>bottom</code>, In addition to passing keywords, each item in the array can also pass a number representing a specific pixel, Can pass a percentage string, such as <code>['40%', '60%']</code>, Represents a horizontal position at <code>40%</code> of the canvas width, and a vertical position at <code>60%</code> of the canvas height</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>exportPaddingX(v0.5.5+)</td>
|
||||
<td>Number</td>
|
||||
<td>10</td>
|
||||
<td>Horizontal padding of graphics when exporting PNG, SVG, and PDF</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>exportPaddingY(v0.5.5+)</td>
|
||||
<td>Number</td>
|
||||
<td>10</td>
|
||||
<td>Vertical padding of graphics when exporting PNG, SVG, and PDF</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nodeTextEditZIndex(v0.5.5+)</td>
|
||||
<td>Number</td>
|
||||
<td>3000</td>
|
||||
<td></td>
|
||||
<td>z-index of node text edit box elements</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nodeNoteTooltipZIndex(v0.5.5+)</td>
|
||||
<td>Number</td>
|
||||
<td>3000</td>
|
||||
<td>z-index of floating layer elements in node comments</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>isEndNodeTextEditOnClickOuter(v0.5.5+)</td>
|
||||
<td>Boolean</td>
|
||||
<td>true</td>
|
||||
<td>Whether to end the editing status of node text when clicking on an area outside the canvas</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Watermark config</h3>
|
||||
|
||||
1
web/src/pages/Doc/en/deploy/index.md
Normal file
1
web/src/pages/Doc/en/deploy/index.md
Normal file
@@ -0,0 +1 @@
|
||||
# Deploy
|
||||
@@ -41,7 +41,8 @@ export default [
|
||||
{ path: 'utils', title: '内置工具方法' },
|
||||
{ path: 'view', title: 'View实例' },
|
||||
{ path: 'watermark', title: 'Watermark插件' },
|
||||
{ path: 'xmind', title: 'XMind解析' }
|
||||
{ path: 'xmind', title: 'XMind解析' },
|
||||
{ path: 'deploy', title: '部署' }
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -68,7 +69,8 @@ export default [
|
||||
{ path: 'utils', title: 'Utility Methods' },
|
||||
{ path: 'view', title: 'View instance' },
|
||||
{ path: 'watermark', title: 'Watermark plugin' },
|
||||
{ path: 'xmind', title: 'XMind parse' }
|
||||
{ path: 'xmind', title: 'XMind parse' },
|
||||
{ path: 'deploy', title: 'Deploy' }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## 0.5.5
|
||||
|
||||
新增:1.支持配置导出为png、svg、pdf时的内边距。 2.支持配置节点文本编辑框、节点备注浮层元素的z-index。 3.支持点击画布外的区域结束节点编辑状态。
|
||||
|
||||
## 0.5.5-fix.1
|
||||
|
||||
修复:1.修复节点在画布外编辑时编辑框也在画布外的问题。 2.修改结构后复位变换,防止存在缩放时切换结构后第一次拖动时会发生位置突变的问题。
|
||||
|
||||
优化:1.节点多选时只要节点和选区存在交叉即认为被选中。
|
||||
|
||||
## 0.5.4
|
||||
|
||||
新增:1.添加新主题。 2.新增时间轴和鱼骨结构。
|
||||
@@ -8,6 +18,10 @@
|
||||
|
||||
优化:1.优化组织结构图布局。2.优化目录组织图布局。
|
||||
|
||||
## 0.5.4-fix.1
|
||||
|
||||
优化:1.优化鱼骨图布局。
|
||||
|
||||
## 0.5.3
|
||||
|
||||
修复:1.修复富文本模式下,如果选择了多个节点时设置文本样式,会将所有多选节点的文本改成最后一个多选节点的文本的问题。
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.5.5</h2>
|
||||
<p>新增:1.支持配置导出为png、svg、pdf时的内边距。 2.支持配置节点文本编辑框、节点备注浮层元素的z-index。 3.支持点击画布外的区域结束节点编辑状态。</p>
|
||||
<h2>0.5.5-fix.1</h2>
|
||||
<p>修复:1.修复节点在画布外编辑时编辑框也在画布外的问题。 2.修改结构后复位变换,防止存在缩放时切换结构后第一次拖动时会发生位置突变的问题。</p>
|
||||
<p>优化:1.节点多选时只要节点和选区存在交叉即认为被选中。</p>
|
||||
<h2>0.5.4</h2>
|
||||
<p>新增:1.添加新主题。 2.新增时间轴和鱼骨结构。</p>
|
||||
<p>修复:1.修复节点右键和画布右键的冲突问题。 2.修复组织结构图、目录组织图等节点拖拽时存在线段未隐藏的bug。</p>
|
||||
<p>优化:1.优化组织结构图布局。2.优化目录组织图布局。</p>
|
||||
<h2>0.5.4-fix.1</h2>
|
||||
<p>优化:1.优化鱼骨图布局。</p>
|
||||
<h2>0.5.3</h2>
|
||||
<p>修复:1.修复富文本模式下,如果选择了多个节点时设置文本样式,会将所有多选节点的文本改成最后一个多选节点的文本的问题。</p>
|
||||
<p>新增:1.支持设置初始中心节点的位置。</p>
|
||||
|
||||
@@ -53,6 +53,11 @@ const mindMap = new MindMap({
|
||||
| enableNodeTransitionMove(v0.5.1+) | Boolean | true | 是否开启节点动画过渡 | |
|
||||
| nodeTransitionMoveDuration(v0.5.1+) | Number | 300 | 如果开启节点动画过渡,可以通过该属性设置过渡的时间,单位ms | |
|
||||
| initRootNodePosition(v0.5.3+) | Array | null | 初始根节点的位置,可传一个数组,默认为`['center', 'center']`,代表根节点处于画布中心位置,除了`center`,关键词还可以设置`left`、`top`、`right`、`bottom`,除了可以传关键词,数组的每项还可以传递一个数字,代表具体的像素,可以传递一个百分比字符串,比如`['40%', '60%']`,代表水平位置在画布宽度的`40%`的位置,垂直位置在画布高度的`60%`的位置 | |
|
||||
| exportPaddingX(v0.5.5+) | Number | 10 | 导出png、svg、pdf时的图形水平内边距 | |
|
||||
| exportPaddingY(v0.5.5+) | Number | 10 | 导出png、svg、pdf时的图形垂直内边距 | |
|
||||
| nodeTextEditZIndex(v0.5.5+) | Number | 3000 | 节点文本编辑框元素的z-index | |
|
||||
| nodeNoteTooltipZIndex(v0.5.5+) | Number | 3000 | 节点备注浮层元素的z-index | |
|
||||
| isEndNodeTextEditOnClickOuter(v0.5.5+) | Boolean | true | 是否在点击了画布外的区域时结束节点文本的编辑状态 | |
|
||||
|
||||
### 水印配置
|
||||
|
||||
|
||||
@@ -231,6 +231,41 @@
|
||||
<td>初始根节点的位置,可传一个数组,默认为<code>['center', 'center']</code>,代表根节点处于画布中心位置,除了<code>center</code>,关键词还可以设置<code>left</code>、<code>top</code>、<code>right</code>、<code>bottom</code>,除了可以传关键词,数组的每项还可以传递一个数字,代表具体的像素,可以传递一个百分比字符串,比如<code>['40%', '60%']</code>,代表水平位置在画布宽度的<code>40%</code>的位置,垂直位置在画布高度的<code>60%</code>的位置</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>exportPaddingX(v0.5.5+)</td>
|
||||
<td>Number</td>
|
||||
<td>10</td>
|
||||
<td>导出png、svg、pdf时的图形水平内边距</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>exportPaddingY(v0.5.5+)</td>
|
||||
<td>Number</td>
|
||||
<td>10</td>
|
||||
<td>导出png、svg、pdf时的图形垂直内边距</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nodeTextEditZIndex(v0.5.5+)</td>
|
||||
<td>Number</td>
|
||||
<td>3000</td>
|
||||
<td>节点文本编辑框元素的z-index</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nodeNoteTooltipZIndex(v0.5.5+)</td>
|
||||
<td>Number</td>
|
||||
<td>3000</td>
|
||||
<td>节点备注浮层元素的z-index</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>isEndNodeTextEditOnClickOuter(v0.5.5+)</td>
|
||||
<td>Boolean</td>
|
||||
<td>true</td>
|
||||
<td>是否在点击了画布外的区域时结束节点文本的编辑状态</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>水印配置</h3>
|
||||
|
||||
66
web/src/pages/Doc/zh/deploy/index.md
Normal file
66
web/src/pages/Doc/zh/deploy/index.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# 部署
|
||||
|
||||
本项目的`web`目录下提供了一个基于`simple-mind-map`库、`Vue2.x`、`ElementUI`开发的完整项目,数据默认存储在电脑本地,此外可以操作电脑本地文件,原意是作为一个线上`demo`,但是也完全可以直接把它当做一个在线版思维导图应用使用,在线地址:[https://wanglin2.github.io/mind-map/](https://wanglin2.github.io/mind-map/)。
|
||||
|
||||
如果你的网络环境访问`GitHub`服务很慢,你也可以部署到你的服务器上。
|
||||
|
||||
## 部署到静态文件服务器
|
||||
|
||||
项目本身不依赖后端,所以完全可以部署到一个静态文件服务器上,可以依次执行如下命令:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/wanglin2/mind-map.git
|
||||
cd mind-map
|
||||
cd simple-mind-map
|
||||
npm i
|
||||
npm link
|
||||
cd ..
|
||||
cd web
|
||||
npm i
|
||||
npm link simple-mind-map
|
||||
```
|
||||
|
||||
然后你可以选择启动本地服务:
|
||||
|
||||
```bash
|
||||
npm run serve
|
||||
```
|
||||
|
||||
也可以直接打包生成构建产物:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
打包完后的入口页面`index.html`可以在项目根目录找到,对应的静态资源在根目录下的`dist`目录,`html`文件中会通过相对路径访问`dist`目录的资源,比如`dist/xxx`。你可以直接把这两个文件或目录上传到你的静态文件服务器,事实上,本项目就是这样部署到`GitHub Pages`上的。
|
||||
|
||||
如果你没有代码修改需求的话,直接从本仓库复制这些文件也是可以的。
|
||||
|
||||
如果你想把`index.html`也打包进`dist`目录,可以修改`web/package.json`文件的`scripts.build`命令,把`vue-cli-service build && node ../copy.js`中的` && node ../copy.js`删除即可。
|
||||
|
||||
如果你想修改打包输出的目录,可以修改`web/vue.config.js`文件的`outputDir`配置,改成你想要输出的路径即可。
|
||||
|
||||
如果你想修改`index.html`文件引用静态资源的路径的话可以修改`web/vue.config.js`文件的`publicPath`配置。
|
||||
|
||||
另外默认使用的是`hash`路由,也就是路径中会在`#`,如果你想使用`history`路由,可以修改`web/src/router.js`文件,将:
|
||||
|
||||
```js
|
||||
const router = new VueRouter({
|
||||
routes
|
||||
})
|
||||
```
|
||||
|
||||
改成:
|
||||
|
||||
```js
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
routes
|
||||
})
|
||||
```
|
||||
|
||||
不过这需要后台支持,因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问子路由时会返回404,所以呢你要在服务端增加一个覆盖所有情况的候选资源:如果`URL`匹配不到任何静态资源,则应该返回同一个`index.html`页面。
|
||||
|
||||
## Docker
|
||||
|
||||
编写中。。。
|
||||
55
web/src/pages/Doc/zh/deploy/index.vue
Normal file
55
web/src/pages/Doc/zh/deploy/index.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>部署</h1>
|
||||
<p>本项目的<code>web</code>目录下提供了一个基于<code>simple-mind-map</code>库、<code>Vue2.x</code>、<code>ElementUI</code>开发的完整项目,数据默认存储在电脑本地,此外可以操作电脑本地文件,原意是作为一个线上<code>demo</code>,但是也完全可以直接把它当做一个在线版思维导图应用使用,在线地址:<a href="https://wanglin2.github.io/mind-map/">https://wanglin2.github.io/mind-map/</a>。</p>
|
||||
<p>如果你的网络环境访问<code>GitHub</code>服务很慢,你也可以部署到你的服务器上。</p>
|
||||
<h2>部署到静态文件服务器</h2>
|
||||
<p>项目本身不依赖后端,所以完全可以部署到一个静态文件服务器上,可以依次执行如下命令:</p>
|
||||
<pre class="hljs"><code>git <span class="hljs-built_in">clone</span> https://github.com/wanglin2/mind-map.git
|
||||
<span class="hljs-built_in">cd</span> mind-map
|
||||
<span class="hljs-built_in">cd</span> simple-mind-map
|
||||
npm i
|
||||
npm link
|
||||
<span class="hljs-built_in">cd</span> ..
|
||||
<span class="hljs-built_in">cd</span> web
|
||||
npm i
|
||||
npm link simple-mind-map
|
||||
</code></pre>
|
||||
<p>然后你可以选择启动本地服务:</p>
|
||||
<pre class="hljs"><code>npm run serve
|
||||
</code></pre>
|
||||
<p>也可以直接打包生成构建产物:</p>
|
||||
<pre class="hljs"><code>npm run build
|
||||
</code></pre>
|
||||
<p>打包完后的入口页面<code>index.html</code>可以在项目根目录找到,对应的静态资源在根目录下的<code>dist</code>目录,<code>html</code>文件中会通过相对路径访问<code>dist</code>目录的资源,比如<code>dist/xxx</code>。你可以直接把这两个文件或目录上传到你的静态文件服务器,事实上,本项目就是这样部署到<code>GitHub Pages</code>上的。</p>
|
||||
<p>如果你没有代码修改需求的话,直接从本仓库复制这些文件也是可以的。</p>
|
||||
<p>如果你想把<code>index.html</code>也打包进<code>dist</code>目录,可以修改<code>web/package.json</code>文件的<code>scripts.build</code>命令,把<code>vue-cli-service build && node ../copy.js</code>中的<code> && node ../copy.js</code>删除即可。</p>
|
||||
<p>如果你想修改打包输出的目录,可以修改<code>web/vue.config.js</code>文件的<code>outputDir</code>配置,改成你想要输出的路径即可。</p>
|
||||
<p>如果你想修改<code>index.html</code>文件引用静态资源的路径的话可以修改<code>web/vue.config.js</code>文件的<code>publicPath</code>配置。</p>
|
||||
<p>另外默认使用的是<code>hash</code>路由,也就是路径中会在<code>#</code>,如果你想使用<code>history</code>路由,可以修改<code>web/src/router.js</code>文件,将:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">const</span> router = <span class="hljs-keyword">new</span> VueRouter({
|
||||
routes
|
||||
})
|
||||
</code></pre>
|
||||
<p>改成:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">const</span> router = <span class="hljs-keyword">new</span> VueRouter({
|
||||
<span class="hljs-attr">mode</span>: <span class="hljs-string">'history'</span>,
|
||||
routes
|
||||
})
|
||||
</code></pre>
|
||||
<p>不过这需要后台支持,因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问子路由时会返回404,所以呢你要在服务端增加一个覆盖所有情况的候选资源:如果<code>URL</code>匹配不到任何静态资源,则应该返回同一个<code>index.html</code>页面。</p>
|
||||
<h2>Docker</h2>
|
||||
<p>编写中。。。</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -99,4 +99,11 @@
|
||||
|
||||
<img src="../../../../assets/img/alipay.jpg" style="width: 300px" />
|
||||
|
||||
<img src="../../../../assets/img/wechat.jpg" style="width: 300px" />
|
||||
<img src="../../../../assets/img/wechat.jpg" style="width: 300px" />
|
||||
|
||||
<div style="display: flex;">
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/Think.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>Think</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -7,19 +7,19 @@
|
||||
</blockquote>
|
||||
<h2>特性</h2>
|
||||
<ul>
|
||||
<li><input type="checkbox" id="checkbox0" checked="true" /><label for="checkbox0">插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小整体体积</label></li>
|
||||
<li><input type="checkbox" id="checkbox1" checked="true" /><label for="checkbox1">支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴、鱼骨图六种结构</label></li>
|
||||
<li><input type="checkbox" id="checkbox2" checked="true" /><label for="checkbox2">内置多种主题,允许高度自定义样式,支持注册新主题</label></li>
|
||||
<li><input type="checkbox" id="checkbox3" checked="true" /><label for="checkbox3">支持快捷键</label></li>
|
||||
<li><input type="checkbox" id="checkbox4" checked="true" /><label for="checkbox4">节点内容支持图片、图标、超链接、备注、标签、概要</label></li>
|
||||
<li><input type="checkbox" id="checkbox5" checked="true" /><label for="checkbox5">支持前进后退</label></li>
|
||||
<li><input type="checkbox" id="checkbox6" checked="true" /><label for="checkbox6">支持拖动、缩放</label></li>
|
||||
<li><input type="checkbox" id="checkbox7" checked="true" /><label for="checkbox7">支持右键和Ctrl+左键两种多选方式</label></li>
|
||||
<li><input type="checkbox" id="checkbox8" checked="true" /><label for="checkbox8">支持节点自由拖拽、拖拽调整</label></li>
|
||||
<li><input type="checkbox" id="checkbox9" checked="true" /><label for="checkbox9">支持多种节点形状</label></li>
|
||||
<li><input type="checkbox" id="checkbox10" checked="true" /><label for="checkbox10">支持导出为</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="checkbox11" checked="true" /><label for="checkbox11">支持小地图、支持水印</label></li>
|
||||
<li><input type="checkbox" id="checkbox12" checked="true" /><label for="checkbox12">支持关联线</label></li>
|
||||
<li><input type="checkbox" id="checkbox216" checked="true" /><label for="checkbox216">插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小整体体积</label></li>
|
||||
<li><input type="checkbox" id="checkbox217" checked="true" /><label for="checkbox217">支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴、鱼骨图六种结构</label></li>
|
||||
<li><input type="checkbox" id="checkbox218" checked="true" /><label for="checkbox218">内置多种主题,允许高度自定义样式,支持注册新主题</label></li>
|
||||
<li><input type="checkbox" id="checkbox219" checked="true" /><label for="checkbox219">支持快捷键</label></li>
|
||||
<li><input type="checkbox" id="checkbox220" checked="true" /><label for="checkbox220">节点内容支持图片、图标、超链接、备注、标签、概要</label></li>
|
||||
<li><input type="checkbox" id="checkbox221" checked="true" /><label for="checkbox221">支持前进后退</label></li>
|
||||
<li><input type="checkbox" id="checkbox222" checked="true" /><label for="checkbox222">支持拖动、缩放</label></li>
|
||||
<li><input type="checkbox" id="checkbox223" checked="true" /><label for="checkbox223">支持右键和Ctrl+左键两种多选方式</label></li>
|
||||
<li><input type="checkbox" id="checkbox224" checked="true" /><label for="checkbox224">支持节点自由拖拽、拖拽调整</label></li>
|
||||
<li><input type="checkbox" id="checkbox225" checked="true" /><label for="checkbox225">支持多种节点形状</label></li>
|
||||
<li><input type="checkbox" id="checkbox226" checked="true" /><label for="checkbox226">支持导出为</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="checkbox227" checked="true" /><label for="checkbox227">支持小地图、支持水印</label></li>
|
||||
<li><input type="checkbox" id="checkbox228" checked="true" /><label for="checkbox228">支持关联线</label></li>
|
||||
</ul>
|
||||
<h2>仓库目录介绍</h2>
|
||||
<p>1.<code>simple-mind-map</code></p>
|
||||
@@ -27,11 +27,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="checkbox13" checked="true" /><label for="checkbox13">工具栏,支持插入节点、删除节点;编辑节点图片、图标、超链接、备注、标签、概要</label></li>
|
||||
<li><input type="checkbox" id="checkbox14" checked="true" /><label for="checkbox14">侧边栏,基础样式设置面板、节点样式设置面板、大纲面板、主题选择面板、结构选择面板</label></li>
|
||||
<li><input type="checkbox" id="checkbox15" checked="true" /><label for="checkbox15">导入导出功能;数据默认保存在浏览器本地存储,也支持直接创建、打开、编辑电脑本地文件</label></li>
|
||||
<li><input type="checkbox" id="checkbox16" checked="true" /><label for="checkbox16">右键菜单,支持展开、收起、整理布局等操作</label></li>
|
||||
<li><input type="checkbox" id="checkbox17" checked="true" /><label for="checkbox17">底部栏,支持节点数量、字数统计;支持切换编辑和只读模式;支持放大缩小;支持全屏切换;支持小地图</label></li>
|
||||
<li><input type="checkbox" id="checkbox229" checked="true" /><label for="checkbox229">工具栏,支持插入节点、删除节点;编辑节点图片、图标、超链接、备注、标签、概要</label></li>
|
||||
<li><input type="checkbox" id="checkbox230" checked="true" /><label for="checkbox230">侧边栏,基础样式设置面板、节点样式设置面板、大纲面板、主题选择面板、结构选择面板</label></li>
|
||||
<li><input type="checkbox" id="checkbox231" checked="true" /><label for="checkbox231">导入导出功能;数据默认保存在浏览器本地存储,也支持直接创建、打开、编辑电脑本地文件</label></li>
|
||||
<li><input type="checkbox" id="checkbox232" checked="true" /><label for="checkbox232">右键菜单,支持展开、收起、整理布局等操作</label></li>
|
||||
<li><input type="checkbox" id="checkbox233" checked="true" /><label for="checkbox233">底部栏,支持节点数量、字数统计;支持切换编辑和只读模式;支持放大缩小;支持全屏切换;支持小地图</label></li>
|
||||
</ul>
|
||||
<p>提供文档页面服务。</p>
|
||||
<p>3.<code>dist</code></p>
|
||||
@@ -67,6 +67,12 @@
|
||||
</blockquote>
|
||||
<img src="../../../../assets/img/alipay.jpg" style="width: 300px" />
|
||||
<img src="../../../../assets/img/wechat.jpg" style="width: 300px" />
|
||||
<div style="display: flex;">
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/Think.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>Think</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ export default {
|
||||
this.getData()
|
||||
this.init()
|
||||
this.$bus.$on('execCommand', this.execCommand)
|
||||
this.$bus.$on('paddingChange', this.onPaddingChange)
|
||||
this.$bus.$on('export', this.export)
|
||||
this.$bus.$on('setData', this.setData)
|
||||
this.$bus.$on('startTextEdit', () => {
|
||||
@@ -276,6 +277,8 @@ export default {
|
||||
theme: theme.template,
|
||||
themeConfig: theme.config,
|
||||
viewData: view,
|
||||
nodeTextEditZIndex: 1000,
|
||||
nodeNoteTooltipZIndex: 1000,
|
||||
customNoteContentShow: {
|
||||
show: (content, left, top) => {
|
||||
this.$bus.$emit('showNoteContent', content, left, top)
|
||||
@@ -374,6 +377,11 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// 修改导出内边距
|
||||
onPaddingChange(data) {
|
||||
this.mindMap.updateConfig(data)
|
||||
},
|
||||
|
||||
// 显示新特性提示
|
||||
showNewFeatureInfo() {
|
||||
let showed = localStorage.getItem('SIMPLE_MIND_MAP_NEW_FEATURE_TIP_1')
|
||||
|
||||
@@ -30,6 +30,22 @@
|
||||
>{{ $t('export.domToImage') }}</el-checkbox
|
||||
>
|
||||
</div>
|
||||
<div class="paddingInputBox" v-show="['svg', 'png', 'pdf'].includes(exportType)">
|
||||
<span class="name">{{ $t('export.paddingX') }}</span>
|
||||
<el-input
|
||||
style="width: 100px"
|
||||
v-model="paddingX"
|
||||
size="mini"
|
||||
@change="onPaddingChange"
|
||||
></el-input>
|
||||
<span class="name" style="margin-left: 10px;">{{ $t('export.paddingY') }}</span>
|
||||
<el-input
|
||||
style="width: 100px"
|
||||
v-model="paddingY"
|
||||
size="mini"
|
||||
@change="onPaddingChange"
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="downloadTypeList">
|
||||
<div
|
||||
class="downloadTypeItem"
|
||||
@@ -77,7 +93,9 @@ export default {
|
||||
widthConfig: true,
|
||||
domToImage: false,
|
||||
loading: false,
|
||||
loadingText: ''
|
||||
loadingText: '',
|
||||
paddingX: 10,
|
||||
paddingY: 10
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -102,6 +120,13 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
onPaddingChange() {
|
||||
this.$bus.$emit('paddingChange', {
|
||||
exportPaddingX: Number(this.paddingX),
|
||||
exportPaddingY: Number(this.paddingY)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-22 22:08:11
|
||||
@@ -163,6 +188,14 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.paddingInputBox {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.name {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.tip {
|
||||
margin-top: 10px;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user