Merge branch 'feature' into main

This commit is contained in:
wanglin2
2023-08-18 14:55:15 +08:00
29 changed files with 374 additions and 65 deletions

View File

@@ -1,7 +1,7 @@
<!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,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1"><link rel="icon" href="dist/logo.ico"><title>思绪思维导图</title><script>// 自定义静态资源的路径
window.externalPublicPath = './dist/'
// 接管应用
window.takeOverApp = false</script><link href="dist/css/chunk-vendors.css?62e50ee743f683426238" rel="stylesheet"><link href="dist/css/app.css?62e50ee743f683426238" 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>const getDataFromBackend = () => {
window.takeOverApp = false</script><link href="dist/css/chunk-vendors.css?52a2b3d5d127c467a055" rel="stylesheet"><link href="dist/css/app.css?52a2b3d5d127c467a055" 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>const getDataFromBackend = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
@@ -66,4 +66,4 @@
// 可以通过window.$bus.$on()来监听应用的一些事件
// 实例化页面
window.initApp()
}</script><script src="dist/js/chunk-vendors.js?62e50ee743f683426238"></script><script src="dist/js/app.js?62e50ee743f683426238"></script></body></html>
}</script><script src="dist/js/chunk-vendors.js?52a2b3d5d127c467a055"></script><script src="dist/js/app.js?52a2b3d5d127c467a055"></script></body></html>

View File

@@ -7,10 +7,17 @@ import Style from './src/core/render/node/Style'
import KeyCommand from './src/core/command/KeyCommand'
import Command from './src/core/command/Command'
import BatchExecution from './src/utils/BatchExecution'
import { layoutValueList, CONSTANTS, commonCaches } from './src/constants/constant'
import {
layoutValueList,
CONSTANTS,
commonCaches,
ERROR_TYPES
} from './src/constants/constant'
import { SVG } from '@svgdotjs/svg.js'
import { simpleDeepClone, getType } from './src/utils'
import defaultTheme, { checkIsNodeSizeIndependenceConfig } from './src/themes/default'
import defaultTheme, {
checkIsNodeSizeIndependenceConfig
} from './src/themes/default'
import { defaultOpt } from './src/constants/defaultOptions'
// 思维导图
@@ -22,11 +29,13 @@ class MindMap {
// 容器元素
this.el = this.opt.el
if (!this.el) throw new Error('缺少容器元素el')
this.elRect = this.el.getBoundingClientRect()
// 画布宽高
this.width = this.elRect.width
this.height = this.elRect.height
if (this.width <= 0 || this.height <= 0) throw new Error('容器元素el的宽高不能为0')
// 画布
this.svg = SVG().addTo(this.el).size(this.width, this.height)
@@ -68,7 +77,7 @@ class MindMap {
this.batchExecution = new BatchExecution()
// 注册插件
MindMap.pluginList.forEach((plugin) => {
MindMap.pluginList.forEach(plugin => {
this.initPlugin(plugin)
})
@@ -136,10 +145,10 @@ class MindMap {
// 初始化缓存数据
initCache() {
Object.keys(commonCaches).forEach((key) => {
Object.keys(commonCaches).forEach(key => {
let type = getType(commonCaches[key])
let value = ''
switch(type) {
switch (type) {
case 'Boolean':
value = false
break
@@ -164,7 +173,7 @@ class MindMap {
this.renderer.clearAllActive()
this.opt.theme = theme
this.render(null, CONSTANTS.CHANGE_THEME)
this.emit('view_theme_change', theme)
this.emit('view_theme_change', theme)
}
// 获取当前主题
@@ -278,8 +287,12 @@ class MindMap {
// 导出
async export(...args) {
let result = await this.doExport.export(...args)
return result
try {
let result = await this.doExport.export(...args)
return result
} catch (error) {
this.mindMap.opt.errorHandler(ERROR_TYPES.EXPORT_ERROR, error)
}
}
// 转换位置
@@ -327,7 +340,11 @@ class MindMap {
// 克隆一份数据
let clone = svg.clone()
// 如果实际图形宽高超出了屏幕宽高,且存在水印的话需要重新绘制水印,否则会出现超出部分没有水印的问题
if ((rect.width > origWidth || rect.height > origHeight) && this.watermark && this.watermark.hasWatermark()) {
if (
(rect.width > origWidth || rect.height > origHeight) &&
this.watermark &&
this.watermark.hasWatermark()
) {
this.width = rect.width
this.height = rect.height
this.watermark.draw()
@@ -388,7 +405,7 @@ class MindMap {
// 销毁
destroy() {
// 移除插件
[...MindMap.pluginList].forEach((plugin) => {
;[...MindMap.pluginList].forEach(plugin => {
this[plugin.instanceName] = null
})
// 解绑事件
@@ -408,8 +425,8 @@ MindMap.usePlugin = (plugin, opt = {}) => {
MindMap.pluginList.push(plugin)
return MindMap
}
MindMap.hasPlugin = (plugin) => {
return MindMap.pluginList.findIndex((item) => {
MindMap.hasPlugin = plugin => {
return MindMap.pluginList.findIndex(item => {
return item === plugin
})
}

View File

@@ -1,6 +1,6 @@
{
"name": "simple-mind-map",
"version": "0.6.14",
"version": "0.6.15",
"description": "一个简单的web在线思维导图",
"authors": [
{

View File

@@ -332,4 +332,14 @@ export const nodeDataNoStylePropList = [
export const commonCaches = {
measureCustomNodeContentSizeEl: null,
measureRichtextNodeTextSizeEl: null
}
// 错误类型
export const ERROR_TYPES = {
READ_CLIPBOARD_ERROR: 'read_clipboard_error',
PARSE_PASTE_DATA_ERROR: 'parse_paste_data_error',
CUSTOM_HANDLE_CLIPBOARD_TEXT_ERROR: 'custom_handle_clipboard_text_error',
LOAD_CLIPBOARD_IMAGE_ERROR: 'load_clipboard_image_error',
BEFORE_TEXT_EDIT_ERROR: 'before_text_edit_error',
EXPORT_ERROR: 'export_error'
}

View File

@@ -149,5 +149,11 @@ export const defaultOpt = {
}
*/
// 如果你的处理逻辑存在异步逻辑也可以返回一个promise
customHandleClipboardText: null
customHandleClipboardText: null,
// 禁止鼠标滚轮缩放你仍旧可以使用api进行缩放
disableMouseWheelZoom: false,
// 错误处理函数
errorHandler: (code, error) => {
console.error(code, error)
}
}

View File

@@ -17,7 +17,7 @@ import {
} from '../../utils'
import { shapeList } from './node/Shape'
import { lineStyleProps } from '../../themes/default'
import { CONSTANTS } from '../../constants/constant'
import { CONSTANTS, ERROR_TYPES } from '../../constants/constant'
// 布局列表
const layouts = {
@@ -629,6 +629,7 @@ class Render {
// 粘贴事件
async onPaste() {
const { errorHandler } = this.mindMap.opt
// 读取剪贴板的文字和图片
let text = null
let img = null
@@ -647,7 +648,7 @@ class Render {
}
}
} catch (error) {
console.log(error)
errorHandler(ERROR_TYPES.READ_CLIPBOARD_ERROR, error)
}
}
// 检查剪切板数据是否有变化
@@ -682,7 +683,9 @@ class Render {
text = String(res)
}
}
} catch (error) {}
} catch (error) {
errorHandler(ERROR_TYPES.CUSTOM_HANDLE_CLIPBOARD_TEXT_ERROR, error)
}
}
// 默认处理
if (useDefault) {
@@ -691,7 +694,9 @@ class Render {
if (parsedData && parsedData.simpleMindMap) {
smmData = parsedData.data
}
} catch (error) {}
} catch (error) {
errorHandler(ERROR_TYPES.PARSE_PASTE_DATA_ERROR, error)
}
}
if (smmData) {
this.mindMap.execCommand(
@@ -724,7 +729,7 @@ class Render {
})
}
} catch (error) {
console.log(error)
errorHandler(ERROR_TYPES.LOAD_CLIPBOARD_IMAGE_ERROR, error)
}
}
} else {

View File

@@ -1,4 +1,5 @@
import { getStrWithBrFromHtml, checkNodeOuter } from '../../utils'
import { ERROR_TYPES } from '../../constants/constant'
// 节点文字编辑类
export default class TextEdit {
@@ -104,6 +105,7 @@ export default class TextEdit {
isShow = await beforeTextEdit(node, isInserting)
} catch (error) {
isShow = false
this.mindMap.opt.errorHandler(ERROR_TYPES.BEFORE_TEXT_EDIT_ERROR, error)
}
if (!isShow) return
}

View File

@@ -1,10 +1,11 @@
import Style from './Style'
import Shape from './Shape'
import { G, Rect, ForeignObject, SVG } from '@svgdotjs/svg.js'
import { G, ForeignObject, SVG } from '@svgdotjs/svg.js'
import nodeGeneralizationMethods from './nodeGeneralization'
import nodeExpandBtnMethods from './nodeExpandBtn'
import nodeCommandWrapsMethods from './nodeCommandWraps'
import nodeCreateContentsMethods from './nodeCreateContents'
import nodeExpandBtnPlaceholderRectMethods from './nodeExpandBtnPlaceholderRect'
import { CONSTANTS } from '../../../constants/constant'
// 节点类
@@ -107,6 +108,10 @@ class Node {
Object.keys(nodeExpandBtnMethods).forEach(item => {
this[item] = nodeExpandBtnMethods[item].bind(this)
})
// 展开收起按钮占位元素相关方法
Object.keys(nodeExpandBtnPlaceholderRectMethods).forEach(item => {
this[item] = nodeExpandBtnPlaceholderRectMethods[item].bind(this)
})
// 命令的相关方法
Object.keys(nodeCommandWrapsMethods).forEach(item => {
this[item] = nodeCommandWrapsMethods[item].bind(this)
@@ -252,9 +257,11 @@ class Node {
this.shapeInstance.getShapePadding(_width, _height, paddingX, paddingY)
this.shapePadding.paddingX = shapePaddingX
this.shapePadding.paddingY = shapePaddingY
// 边框宽度,因为边框是以中线向两端发散,所以边框会超出节点
const borderWidth = this.getBorderWidth()
return {
width: _width + paddingX * 2 + shapePaddingX * 2,
height: _height + paddingY * 2 + margin + shapePaddingY * 2
width: _width + paddingX * 2 + shapePaddingX * 2 + borderWidth,
height: _height + paddingY * 2 + margin + shapePaddingY * 2 + borderWidth
}
}
@@ -264,10 +271,12 @@ class Node {
this.group.clear()
let { width, height, textContentItemMargin } = this
let { paddingY } = this.getPaddingVale()
paddingY += this.shapePadding.paddingY
const halfBorderWidth = this.getBorderWidth() / 2
paddingY += this.shapePadding.paddingY + halfBorderWidth
// 节点形状
this.shapeNode = this.shapeInstance.createShape()
this.shapeNode.addClass('smm-node-shape')
this.shapeNode.translate(halfBorderWidth, halfBorderWidth)
this.group.add(this.shapeNode)
this.updateNodeShape()
// 渲染一个隐藏的矩形区域,用来触发展开收起按钮的显示
@@ -358,27 +367,6 @@ class Node {
this.group.add(textContentNested)
}
// 渲染展开收起按钮的隐藏占位元素
renderExpandBtnPlaceholderRect() {
if (!this.mindMap.opt.alwaysShowExpandBtn) {
let { width, height } = this
if (!this._unVisibleRectRegionNode) {
this._unVisibleRectRegionNode = new Rect()
this._unVisibleRectRegionNode.fill({
color: 'transparent'
})
}
this.group.add(this._unVisibleRectRegionNode)
this.renderer.layout.renderExpandBtnRect(
this._unVisibleRectRegionNode,
this.expandBtnSize,
width,
height,
this
)
}
}
// 给节点绑定事件
bindGroupEvent() {
// 单击事件,选中节点
@@ -588,10 +576,7 @@ class Node {
this.needLayout = false
this.layout()
}
if (this.needRerenderExpandBtnPlaceholderRect) {
this.needRerenderExpandBtnPlaceholderRect = false
this.renderExpandBtnPlaceholderRect()
}
this.updateExpandBtnPlaceholderRect()
this.update()
}
// 子节点
@@ -846,6 +831,11 @@ class Node {
) // 父级
}
// 获取节点非节点状态的边框大小
getBorderWidth() {
return this.style.merge('borderWidth', false, false) || 0
}
// 获取数据
getData(key) {
return key ? this.nodeData.data[key] || '' : this.nodeData.data

View File

@@ -62,7 +62,10 @@ export default class Shape {
// 创建形状节点
createShape() {
const shape = this.node.getShape()
const borderWidth = this.node.getBorderWidth()
let { width, height } = this.node
width -= borderWidth
height -= borderWidth
let node = null
// 矩形
if (shape === CONSTANTS.SHAPE.RECTANGLE) {

View File

@@ -0,0 +1,66 @@
import { Rect } from '@svgdotjs/svg.js'
// 渲染展开收起按钮的隐藏占位元素
function renderExpandBtnPlaceholderRect() {
// 根节点或没有子节点不需要渲染
if (
!this.nodeData.children ||
this.nodeData.children.length <= 0 ||
this.isRoot
) {
return
}
// 默认显示展开按钮的情况下也不需要渲染
if (!this.mindMap.opt.alwaysShowExpandBtn) {
let { width, height } = this
if (!this._unVisibleRectRegionNode) {
this._unVisibleRectRegionNode = new Rect()
this._unVisibleRectRegionNode.fill({
color: 'transparent'
})
}
this.group.add(this._unVisibleRectRegionNode)
this.renderer.layout.renderExpandBtnRect(
this._unVisibleRectRegionNode,
this.expandBtnSize,
width,
height,
this
)
}
}
// 删除展开收起按钮的隐藏占位元素
function clearExpandBtnPlaceholderRect() {
if (!this._unVisibleRectRegionNode) {
return
}
this._unVisibleRectRegionNode.remove()
this._unVisibleRectRegionNode = null
}
// 更新展开收起按钮的隐藏占位元素
function updateExpandBtnPlaceholderRect() {
// 布局改变需要重新渲染
if (this.needRerenderExpandBtnPlaceholderRect) {
this.needRerenderExpandBtnPlaceholderRect = false
this.renderExpandBtnPlaceholderRect()
}
// 没有子节点到有子节点需要渲染
if (this.nodeData.children && this.nodeData.children.length > 0) {
if (!this._unVisibleRectRegionNode) {
this.renderExpandBtnPlaceholderRect()
}
} else {
// 有子节点到没子节点,需要删除
if (this._unVisibleRectRegionNode) {
this.clearExpandBtnPlaceholderRect()
}
}
}
export default {
renderExpandBtnPlaceholderRect,
clearExpandBtnPlaceholderRect,
updateExpandBtnPlaceholderRect
}

View File

@@ -65,7 +65,8 @@ class View {
mousewheelAction,
mouseScaleCenterUseMousePosition,
mousewheelMoveStep,
mousewheelZoomActionReverse
mousewheelZoomActionReverse,
disableMouseWheelZoom
} = this.mindMap.opt
// 是否自定义鼠标滚轮事件
if (
@@ -76,8 +77,10 @@ class View {
}
// 鼠标滚轮事件控制缩放
if (mousewheelAction === CONSTANTS.MOUSE_WHEEL_ACTION.ZOOM) {
let cx = mouseScaleCenterUseMousePosition ? e.clientX : undefined
let cy = mouseScaleCenterUseMousePosition ? e.clientY : undefined
if (disableMouseWheelZoom) return
const { x: clientX, y: clientY } = this.mindMap.toPos(e.clientX, e.clientY)
let cx = mouseScaleCenterUseMousePosition ? clientX : undefined
let cy = mouseScaleCenterUseMousePosition ? clientY : undefined
switch (dir) {
// 鼠标滚轮,向上和向左,都是缩小
case CONSTANTS.DIR.UP:

View File

@@ -28,7 +28,7 @@ const handleList = node => {
}
// 将markdown转换成节点树
export const transformMarkdownTo = async md => {
export const transformMarkdownTo = md => {
const tree = fromMarkdown(md)
let root = {
children: []

View File

@@ -1,5 +1,41 @@
# Changelog
## 0.6.15
新增:
> 1.Export PDF supports pagination export based on image size.
>
> 2.Exporting PDF supports automatic direction adjustment based on aspect ratio.
>
> 3.Optimize the placeholder elements of the expand and collapse buttons: 1. Nodes without child nodes do not render this element; 2. Dynamically update the element based on the existence of child nodes.
>
> 4.Add a configuration that prohibits mouse wheel scaling.
>
> 5.Supports passing error handling functions.
修复:
> 1.Fix the issue of displaying exceptions when node text is empty.
>
> 2.Change the paddingX and paddingY of exported SVG graphics to single sided padding.
>
> 3.Fixed an issue where the mouse is not centered when zooming when the canvas is not 0 from the top left corner of the browser window.
>
> 4.Fix the issue of overlapping node borders.
Demo
> 1.The bottom right corner supports jumping to related links.
>
> 2.Adjust the position of the mini map to solve the problem of being blocked by side buttons.
>
> 3.Fix the issue where the prompt in the upper right corner of the open local file cannot be closed.
>
> 4.Editing the outline separately is no longer linked to the canvas, optimizing the editing experience under large data volume.
>
> 5.The sidebar involves graphical options to increase visualization effects.
## 0.6.14
New:

View File

@@ -1,6 +1,30 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.6.15</h2>
<p>新增</p>
<blockquote>
<p>1.Export PDF supports pagination export based on image size.</p>
<p>2.Exporting PDF supports automatic direction adjustment based on aspect ratio.</p>
<p>3.Optimize the placeholder elements of the expand and collapse buttons: 1. Nodes without child nodes do not render this element; 2. Dynamically update the element based on the existence of child nodes.</p>
<p>4.Add a configuration that prohibits mouse wheel scaling.</p>
<p>5.Supports passing error handling functions.</p>
</blockquote>
<p>修复</p>
<blockquote>
<p>1.Fix the issue of displaying exceptions when node text is empty.</p>
<p>2.Change the paddingX and paddingY of exported SVG graphics to single sided padding.</p>
<p>3.Fixed an issue where the mouse is not centered when zooming when the canvas is not 0 from the top left corner of the browser window.</p>
<p>4.Fix the issue of overlapping node borders.</p>
</blockquote>
<p>Demo</p>
<blockquote>
<p>1.The bottom right corner supports jumping to related links.</p>
<p>2.Adjust the position of the mini map to solve the problem of being blocked by side buttons.</p>
<p>3.Fix the issue where the prompt in the upper right corner of the open local file cannot be closed.</p>
<p>4.Editing the outline separately is no longer linked to the canvas, optimizing the editing experience under large data volume.</p>
<p>5.The sidebar involves graphical options to increase visualization effects.</p>
</blockquote>
<h2>0.6.14</h2>
<p>New:</p>
<blockquote>

View File

@@ -77,6 +77,8 @@ const mindMap = new MindMap({
| enableAutoEnterTextEditWhenKeydownv0.6.13+ | Boolean | true | Does it automatically enter text editing mode when pressing the Chinese, English, or numeric buttons when there is an activation node?| |
| richTextEditFakeInPlacev0.6.13+ | Boolean | false | Set the rich text node edit box to match the size of the node, creating a pseudo in place editing effect. It should be noted that only when there is only text within the node and the shape is rectangular, can the effect be better | |
| customHandleClipboardTextv0.6.14+ | Function | null | Customize the processing of clipboard text. When pressing ctrl+v to paste, it will read the text and images from the user's clipboard. By default, it will only determine whether the text is regular text and node data in simple mind map format. If you want to process data from other mind maps, such as process, zhixi, etc., you can pass a function that takes the text from the current clipboard as a parameter and returns the processed data, which can be of two types: 1.If a pure text is returned, a child node will be directly created with that text; 2.Returns a node object in the following format: { simpleMindMap: true, data: { data: { text: '' }, children: [] } }, The representative is data in simple bind map format, and the node data is in the same format as the simple bind map node data. If your processing logic has asynchronous logic, you can also return a promise | |
| errorHandlerv0.6.15+ | Function | | Custom error handling functions currently only throw some asynchronous logic errors. Can pass a function that takes two parameters, the first being the wrong type and the second being the wrong object | |
| disableMouseWheelZoomv0.6.15+ | Boolean | false | Prohibit mouse wheel scaling, you can still use the API for scaling | |
### Watermark config

View File

@@ -399,6 +399,20 @@
<td>Customize the processing of clipboard text. When pressing ctrl+v to paste, it will read the text and images from the user's clipboard. By default, it will only determine whether the text is regular text and node data in simple mind map format. If you want to process data from other mind maps, such as process, zhixi, etc., you can pass a function that takes the text from the current clipboard as a parameter and returns the processed data, which can be of two types: 1.If a pure text is returned, a child node will be directly created with that text; 2.Returns a node object in the following format: { simpleMindMap: true, data: { data: { text: '' }, children: [] } }, The representative is data in simple bind map format, and the node data is in the same format as the simple bind map node data. If your processing logic has asynchronous logic, you can also return a promise</td>
<td></td>
</tr>
<tr>
<td>errorHandlerv0.6.15+</td>
<td>Function</td>
<td></td>
<td>Custom error handling functions currently only throw some asynchronous logic errors. Can pass a function that takes two parameters, the first being the wrong type and the second being the wrong object</td>
<td></td>
</tr>
<tr>
<td>disableMouseWheelZoomv0.6.15+</td>
<td>Boolean</td>
<td>false</td>
<td>Prohibit mouse wheel scaling, you can still use the API for scaling</td>
<td></td>
</tr>
</tbody>
</table>
<h3>Watermark config</h3>

View File

@@ -38,12 +38,14 @@ a.download = 'xxx'
a.click()
```
### png(name, transparent = false)
### png(name, transparent = false, rotateWhenWidthLongerThenHeight)
- `name`: Name, optional
- `transparent`: v0.5.7+, Specify whether the background of the exported image is transparent
- `rotateWhenWidthLongerThenHeight`: v0.6.15+Boolean, false, Automatically rotate 90 degrees when the image has a width to height ratio
Exports as `png`.
### svg(name, plusCssText)
@@ -66,11 +68,13 @@ svg(
Exports as `svg`.
### pdf(name)
### pdf(name, useMultiPageExport)
> v0.2.1+
`name`File name
- `name`File name
- `useMultiPageExport`: v0.6.15+, Boolean, false, Whether to export multiple pages, default to single page
Export as `pdf`. Unlike other export methods, this method does not return data and directly triggers the download.

View File

@@ -27,7 +27,7 @@ a.href = <span class="hljs-string">&#x27;xxx.png&#x27;</span><span class="hljs-c
a.download = <span class="hljs-string">&#x27;xxx&#x27;</span>
a.click()
</code></pre>
<h3>png(name, transparent = false)</h3>
<h3>png(name, transparent = false, rotateWhenWidthLongerThenHeight)</h3>
<ul>
<li>
<p><code>name</code>: Name, optional</p>
@@ -35,6 +35,9 @@ a.click()
<li>
<p><code>transparent</code>: v0.5.7+, Specify whether the background of the exported image is transparent</p>
</li>
<li>
<p><code>rotateWhenWidthLongerThenHeight</code>: v0.6.15+Boolean, false, Automatically rotate 90 degrees when the image has a width to height ratio</p>
</li>
</ul>
<p>Exports as <code>png</code>.</p>
<h3>svg(name, plusCssText)</h3>
@@ -57,11 +60,18 @@ a.click()
)
</code></pre>
<p>Exports as <code>svg</code>.</p>
<h3>pdf(name)</h3>
<h3>pdf(name, useMultiPageExport)</h3>
<blockquote>
<p>v0.2.1+</p>
</blockquote>
<ul>
<li>
<p><code>name</code>File name</p>
</li>
<li>
<p><code>useMultiPageExport</code>: v0.6.15+, Boolean, false, Whether to export multiple pages, default to single page</p>
</li>
</ul>
<p>Export as <code>pdf</code>. Unlike other export methods, this method does not return data and directly triggers the download.</p>
<blockquote>
<p>After v0.6.0, an additional ExportPDF plugin needs to be registered</p>

View File

@@ -18,6 +18,8 @@ The principle of this plugin is to use [Quill](https://github.com/quilljs/quill)
`V0.6.13+` version uses [dom-to-image-more](https://github.com/1904labs/dom-to-image-more) Replaced 'html2canvas' to address the issue of ineffective color export for nodes.
> The compatibility of dom to image more is relatively poor, and exported images are empty on many browsers, so you can replace them with html2canvas according to your own needs.
## Register
```js

View File

@@ -18,6 +18,9 @@
<p>The version of <code>v0.5.7+</code> directly uses <code>html2canvas</code> to convert the entire <code>svg</code>, which is no longer an issue with speed. However, there is currently a bug where the color of the node does not take effect after export.</p>
</blockquote>
<p><code>V0.6.13+</code> version uses <a href="https://github.com/1904labs/dom-to-image-more">dom-to-image-more</a> Replaced 'html2canvas' to address the issue of ineffective color export for nodes.</p>
<blockquote>
<p>The compatibility of dom to image more is relatively poor, and exported images are empty on many browsers, so you can replace them with html2canvas according to your own needs.</p>
</blockquote>
<h2>Register</h2>
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map&#x27;</span>
<span class="hljs-keyword">import</span> RichText <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map/src/plugins/RichText.js&#x27;</span>

View File

@@ -1,5 +1,41 @@
# Changelog
## 0.6.15
新增:
> 1.导出pdf支持根据图片大小分页导出。
>
> 2.导出pdf支持根据长宽比自动调整方向。
>
> 3.优化展开收起按钮的占位元素1.没有子节点的节点不渲染该元素2.根据是否存在子节点动态更新该元素。
>
> 4.新增禁止鼠标滚轮缩放的配置。
>
> 5.支持传递错误处理函数。
修复:
> 1.修复节点文本为空时显示异常问题。
>
> 2.导出svg的图形的paddingX和paddingY改为单侧padding。
>
> 3.修复画布距浏览器窗口左上角不为0时鼠标缩放时不以鼠标为中心的问题。
>
> 4.修复节点边框会重合的问题。
Demo
> 1.右下角支持跳转相关链接。
>
> 2.调整小地图位置,解决被侧边按钮遮挡的问题。
>
> 3.修复打开本地文件右上角的提示无法关闭的问题。
>
> 4.单独编辑大纲不再和画布联动,优化大数据量下的编辑体验。
>
> 5.侧边栏涉及图形的选项增加可视化效果。
## 0.6.14
新增:

View File

@@ -1,6 +1,30 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.6.15</h2>
<p>新增</p>
<blockquote>
<p>1.导出pdf支持根据图片大小分页导出</p>
<p>2.导出pdf支持根据长宽比自动调整方向</p>
<p>3.优化展开收起按钮的占位元素1.没有子节点的节点不渲染该元素2.根据是否存在子节点动态更新该元素</p>
<p>4.新增禁止鼠标滚轮缩放的配置</p>
<p>5.支持传递错误处理函数</p>
</blockquote>
<p>修复</p>
<blockquote>
<p>1.修复节点文本为空时显示异常问题</p>
<p>2.导出svg的图形的paddingX和paddingY改为单侧padding</p>
<p>3.修复画布距浏览器窗口左上角不为0时鼠标缩放时不以鼠标为中心的问题</p>
<p>4.修复节点边框会重合的问题</p>
</blockquote>
<p>Demo</p>
<blockquote>
<p>1.右下角支持跳转相关链接</p>
<p>2.调整小地图位置解决被侧边按钮遮挡的问题</p>
<p>3.修复打开本地文件右上角的提示无法关闭的问题</p>
<p>4.单独编辑大纲不再和画布联动优化大数据量下的编辑体验</p>
<p>5.侧边栏涉及图形的选项增加可视化效果</p>
</blockquote>
<h2>0.6.14</h2>
<p>新增</p>
<blockquote>

View File

@@ -77,6 +77,8 @@ const mindMap = new MindMap({
| enableAutoEnterTextEditWhenKeydownv0.6.13+ | Boolean | true | 是否在存在一个激活节点时,当按下中文、英文、数字按键时自动进入文本编辑模式 | |
| richTextEditFakeInPlacev0.6.13+ | Boolean | false | 设置富文本节点编辑框和节点大小一致,形成伪原地编辑的效果,需要注意的是,只有当节点内只有文本、且形状是矩形才会有比较好的效果 | |
| customHandleClipboardTextv0.6.14+ | Function | null | 自定义对剪贴板文本的处理。当按ctrl+v粘贴时会读取用户剪贴板中的文本和图片默认只会判断文本是否是普通文本和simple-mind-map格式的节点数据如果你想处理其他思维导图的数据比如processon、zhixi等那么可以传递一个函数接受当前剪贴板中的文本为参数返回处理后的数据可以返回两种类型1.返回一个纯文本那么会直接以该文本创建一个子节点2.返回一个节点对象,格式如下:{ simpleMindMap: true, data: { data: { text: '' }, children: [] } }代表是simple-mind-map格式的数据节点数据同simple-mind-map节点数据格式如果你的处理逻辑存在异步逻辑也可以返回一个promise | |
| errorHandlerv0.6.15+ | Function | | 自定义错误处理函数,目前只会抛出一些异步逻辑出错的情况。可以传递一个函数,会接收两个参数,第一个为错误的类型,第二个为错误对象 | |
| disableMouseWheelZoomv0.6.15+ | Boolean | false | 禁止鼠标滚轮缩放你仍旧可以使用api进行缩放 | |
### 水印配置

View File

@@ -399,6 +399,20 @@
<td>自定义对剪贴板文本的处理当按ctrl+v粘贴时会读取用户剪贴板中的文本和图片默认只会判断文本是否是普通文本和simple-mind-map格式的节点数据如果你想处理其他思维导图的数据比如processonzhixi等那么可以传递一个函数接受当前剪贴板中的文本为参数返回处理后的数据可以返回两种类型1.返回一个纯文本那么会直接以该文本创建一个子节点2.返回一个节点对象格式如下{ simpleMindMap: true, data: { data: { text: '' }, children: [] } }代表是simple-mind-map格式的数据节点数据同simple-mind-map节点数据格式如果你的处理逻辑存在异步逻辑也可以返回一个promise</td>
<td></td>
</tr>
<tr>
<td>errorHandlerv0.6.15+</td>
<td>Function</td>
<td></td>
<td>自定义错误处理函数目前只会抛出一些异步逻辑出错的情况可以传递一个函数会接收两个参数第一个为错误的类型第二个为错误对象</td>
<td></td>
</tr>
<tr>
<td>disableMouseWheelZoomv0.6.15+</td>
<td>Boolean</td>
<td>false</td>
<td>禁止鼠标滚轮缩放你仍旧可以使用api进行缩放</td>
<td></td>
</tr>
</tbody>
</table>
<h3>水印配置</h3>

View File

@@ -38,12 +38,14 @@ a.download = 'xxx'
a.click()
```
### png(name, transparent = false)
### png(name, transparent = false, rotateWhenWidthLongerThenHeight)
- `name`:名称,可不传
- `transparent`v0.5.7+,指定导出图片的背景是否是透明的
- `rotateWhenWidthLongerThenHeight`: v0.6.15+Boolean, false, 是否在图片宽比高长时自动旋转90度
导出为`png`
### svg(name, plusCssText)
@@ -66,11 +68,13 @@ svg(
导出为`svg`
### pdf(name)
### pdf(name, useMultiPageExport)
> v0.2.1+
`name`:文件名称
- `name`:文件名称
- `useMultiPageExport`: v0.6.15+Boolean, false, 是否多页导出,默认为单页
导出为`pdf`,和其他导出方法不一样,这个方法不会返回数据,会直接触发下载。

View File

@@ -27,7 +27,7 @@ a.href = <span class="hljs-string">&#x27;xxx.png&#x27;</span><span class="hljs-c
a.download = <span class="hljs-string">&#x27;xxx&#x27;</span>
a.click()
</code></pre>
<h3>png(name, transparent = false)</h3>
<h3>png(name, transparent = false, rotateWhenWidthLongerThenHeight)</h3>
<ul>
<li>
<p><code>name</code>名称可不传</p>
@@ -35,6 +35,9 @@ a.click()
<li>
<p><code>transparent</code>v0.5.7+指定导出图片的背景是否是透明的</p>
</li>
<li>
<p><code>rotateWhenWidthLongerThenHeight</code>: v0.6.15+Boolean, false, 是否在图片宽比高长时自动旋转90度</p>
</li>
</ul>
<p>导出为<code>png</code></p>
<h3>svg(name, plusCssText)</h3>
@@ -57,11 +60,18 @@ a.click()
)
</code></pre>
<p>导出为<code>svg</code></p>
<h3>pdf(name)</h3>
<h3>pdf(name, useMultiPageExport)</h3>
<blockquote>
<p>v0.2.1+</p>
</blockquote>
<ul>
<li>
<p><code>name</code>文件名称</p>
</li>
<li>
<p><code>useMultiPageExport</code>: v0.6.15+Boolean, false, 是否多页导出默认为单页</p>
</li>
</ul>
<p>导出为<code>pdf</code>和其他导出方法不一样这个方法不会返回数据会直接触发下载</p>
<blockquote>
<p>v0.6.0版本以后需要额外注册一个ExportPDF插件</p>

View File

@@ -18,6 +18,8 @@
`v0.6.13+`版本使用[dom-to-image-more](https://github.com/1904labs/dom-to-image-more)替换了`html2canvas`,解决了节点的颜色导出后不生效的问题。
> dom-to-image-more兼容性比较差在很多浏览器上导出图片都是空的所以可以根据你自己的需求替换成html2canvas。
## 注册
```js

View File

@@ -18,6 +18,9 @@
<p><code>v0.5.7+</code>的版本直接使用<code>html2canvas</code>转换整个<code>svg</code>速度不再是问题但是目前存在一个<code>bug</code>就是节点的颜色导出后不生效</p>
</blockquote>
<p><code>v0.6.13+</code>版本使用<a href="https://github.com/1904labs/dom-to-image-more">dom-to-image-more</a>替换了<code>html2canvas</code>解决了节点的颜色导出后不生效的问题</p>
<blockquote>
<p>dom-to-image-more兼容性比较差在很多浏览器上导出图片都是空的所以可以根据你自己的需求替换成html2canvas</p>
</blockquote>
<h2>注册</h2>
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map&#x27;</span>
<span class="hljs-keyword">import</span> RichText <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map/src/plugins/RichText.js&#x27;</span>

View File

@@ -303,7 +303,24 @@ export default {
// })
// comp.$mount(el)
// return comp.$el
// }
// },
// 示例3普通元素
// customCreateNodeContent: (node) => {
// let el = document.createElement('div')
// el.style.cssText = `
// width: 203px;
// height: 78px;
// opacity: 0.8;
// background-image: linear-gradient(0deg, rgba(53,130,172,0.06) 0%, rgba(24,75,116,0.06) 100%);
// box-shadow: inset 0 1px 15px 0 rgba(119,196,255,0.40);
// border-radius: 2px;
// display: flex;
// justify-content: center;
// align-items: center;
// `
// el.innerHTML = node.nodeData.data.text
// return el
// },
})
if (this.openNodeRichText) this.addRichTextPlugin()
this.mindMap.keyCommand.addShortcut('Control+s', () => {