Compare commits

..

9 Commits

Author SHA1 Message Date
wanglin2
745531f20f 打包0.7.3-fix.1 2023-10-08 09:45:25 +08:00
wanglin2
3acd425c09 Demo:优化超链接输入 2023-10-08 09:37:54 +08:00
wanglin2
8dcc7c985d Doc: update 2023-10-08 09:33:06 +08:00
wanglin2
253ded33bf Demo:超链接输入框增加协议选择功能 2023-10-08 09:32:07 +08:00
wanglin2
2c6b8294f4 Fix:修复多次粘贴节点时由于节点uid重复造成的渲染异常问题 2023-10-08 09:10:14 +08:00
wanglin2
83a5ef8e2e Fix:修复多选节点时在节点上松开鼠标时框选区域不会消失的问题 2023-10-06 14:08:45 +08:00
wanglin2
b959e90723 Fix:修复一些情况下多选节点时的框选区域没有消失的问题 2023-10-06 13:47:47 +08:00
wanglin2
89ebc9a1fa 打包 2023-10-06 10:20:54 +08:00
wanglin2
56d2e34fbd Doc: update 2023-10-06 09:52:03 +08:00
45 changed files with 595 additions and 368 deletions

View File

@@ -39,6 +39,7 @@ Github[releases](https://github.com/wanglin2/mind-map/releases)。
- [x] 支持导出为`json``png``svg``pdf``markdown``xmind`,支持从`json``xmind``markdown`导入
- [x] 支持快捷键、前进后退、关联线、搜索替换、小地图、水印、滚动条
- [x] 提供丰富的配置,满足各种场景各种使用习惯
- [x] 支持协同编辑
# 安装
@@ -93,11 +94,11 @@ const mindMap = new MindMap({
# 请作者喝杯咖啡
开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡~
开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡~
> 厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds
> 推荐使用支付宝,微信获取不到头像。转账请备注【思维导图】。你的头像和名字将会出现在下面和[文档页面](https://wanglin2.github.io/mind-map/#/doc/zh/introduction/%E8%AF%B7%E4%BD%9C%E8%80%85%E5%96%9D%E6%9D%AF%E5%92%96%E5%95%A1)
> 推荐使用支付宝,微信获取不到头像。转账请备注【思维导图】。
<p>
<img src="./web/src/assets/img/alipay.jpg" style="width: 300px" />

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?29889d7ca2f7c720050d" rel="stylesheet"><link href="dist/css/app.css?29889d7ca2f7c720050d" 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?ceeef97326ffc3ea9cba" rel="stylesheet"><link href="dist/css/app.css?ceeef97326ffc3ea9cba" 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?29889d7ca2f7c720050d"></script><script src="dist/js/app.js?29889d7ca2f7c720050d"></script></body></html>
}</script><script src="dist/js/chunk-vendors.js?ceeef97326ffc3ea9cba"></script><script src="dist/js/app.js?ceeef97326ffc3ea9cba"></script></body></html>

View File

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

View File

@@ -512,7 +512,7 @@ class Render {
uid: createUid(),
...(appointData || {})
},
children: [...createUidForAppointNodes(appointChildren)]
children: [...createUidForAppointNodes(appointChildren, true)]
}
parent.nodeData.children.splice(index + 1, 0, newNodeData)
})
@@ -558,7 +558,7 @@ class Render {
const index = parent.nodeData.children.findIndex(item => {
return item.data.uid === node.uid
})
const newNodeList = createUidForAppointNodes(simpleDeepClone(nodeList))
const newNodeList = createUidForAppointNodes(simpleDeepClone(nodeList), true)
parent.nodeData.children.splice(
index + 1,
0,
@@ -619,7 +619,7 @@ class Render {
...params,
...(appointData || {})
},
children: [...createUidForAppointNodes(appointChildren)]
children: [...createUidForAppointNodes(appointChildren, true)]
}
node.nodeData.children.push(newNode)
// 插入子节点时自动展开子节点
@@ -659,7 +659,7 @@ class Render {
if (!node.nodeData.children) {
node.nodeData.children = []
}
childList = createUidForAppointNodes(childList)
childList = createUidForAppointNodes(childList, true)
node.nodeData.children.push(...childList)
// 插入子节点时自动展开子节点
node.nodeData.data.expand = true
@@ -1071,7 +1071,9 @@ class Render {
this.activeNodeList.forEach(node => {
node.nodeData.children.push(
...data.map(item => {
return simpleDeepClone(item)
const newData = simpleDeepClone(item)
createUidForAppointNodes([newData], true)
return newData
})
)
})

View File

@@ -89,23 +89,28 @@ class Select {
}
)
})
this.mindMap.on('mouseup', () => {
if (this.mindMap.opt.readonly) {
return
}
if (!this.isMousedown) {
return
}
this.checkTriggerNodeActiveEvent()
clearTimeout(this.autoMoveTimer)
this.isMousedown = false
this.cacheActiveList = []
if (this.rect) this.rect.remove()
this.rect = null
setTimeout(() => {
this.isSelecting = false
}, 0)
})
this.onMouseup = this.onMouseup.bind(this)
this.mindMap.on('mouseup', this.onMouseup)
this.mindMap.on('node_mouseup', this.onMouseup)
}
// 结束框选
onMouseup() {
if (this.mindMap.opt.readonly) {
return
}
if (!this.isMousedown) {
return
}
this.checkTriggerNodeActiveEvent()
clearTimeout(this.autoMoveTimer)
this.isMousedown = false
this.cacheActiveList = []
if (this.rect) this.rect.remove()
this.rect = null
setTimeout(() => {
this.isSelecting = false
}, 0)
}
// 如果激活节点改变了,那么触发事件
@@ -184,6 +189,7 @@ class Select {
// 创建矩形
createRect(x, y) {
if (this.rect) this.rect.remove()
this.rect = this.mindMap.svg
.polygon()
.stroke({

View File

@@ -167,11 +167,13 @@ export const copyNodeTree = (
tree,
root,
removeActiveState = false,
keepId = false
removeId = true
) => {
tree.data = simpleDeepClone(root.nodeData ? root.nodeData.data : root.data)
// 重新创建节点uid因为节点uid不能重复
if (!keepId) {
// 移除节点uid
if (removeId) {
delete tree.data.uid
} else if (!tree.data.uid) {// 否则保留或生成
tree.data.uid = createUid()
}
if (removeActiveState) {
@@ -180,7 +182,7 @@ export const copyNodeTree = (
tree.children = []
if (root.children && root.children.length > 0) {
root.children.forEach((item, index) => {
tree.children[index] = copyNodeTree({}, item, removeActiveState, keepId)
tree.children[index] = copyNodeTree({}, item, removeActiveState, removeId)
})
} else if (
root.nodeData &&
@@ -188,7 +190,7 @@ export const copyNodeTree = (
root.nodeData.children.length > 0
) {
root.nodeData.children.forEach((item, index) => {
tree.children[index] = copyNodeTree({}, item, removeActiveState, keepId)
tree.children[index] = copyNodeTree({}, item, removeActiveState, removeId)
})
}
return tree
@@ -766,14 +768,15 @@ export const addDataToAppointNodes = (appointNodes, data = {}) => {
return appointNodes
}
// 给指定的节点列表树数据添加uid如果不存在的话,会修改原数据
export const createUidForAppointNodes = appointNodes => {
// 给指定的节点列表树数据添加uid会修改原数据
// createNewId默认为false即如果节点不存在uid的话会创建新的uid。如果传true那么无论节点数据原来是否存在uid都会创建新的uid
export const createUidForAppointNodes = (appointNodes, createNewId = false) => {
const walk = list => {
list.forEach(node => {
if (!node.data) {
node.data = {}
}
if (isUndef(node.data.uid)) {
if (createNewId || isUndef(node.data.uid)) {
node.data.uid = createUid()
}
if (node.children && node.children.length > 0) {

View File

@@ -95,6 +95,10 @@ declare class MindMap {
beingDragNodeOpacity: number;
};
tagsColorMap: {};
cooperateStyle: {
avatarSize: number;
fontSize: number;
};
});
opt: any;
el: any;
@@ -159,14 +163,14 @@ declare class MindMap {
destroy(): void;
}
declare namespace MindMap {
let pluginList: any[];
const pluginList: any[];
function usePlugin(plugin: any, opt?: {}): typeof MindMap;
function hasPlugin(plugin: any): number;
function defineTheme(name: any, config?: {}): Error;
}
import Event from './src/core/event/Event';
import KeyCommand from './src/core/command/KeyCommand';
import Command from './src/core/command/Command';
import Render from './src/core/render/Render';
import View from './src/core/view/View';
import BatchExecution from './src/utils/BatchExecution';
import Event from "./src/core/event/Event";
import KeyCommand from "./src/core/command/KeyCommand";
import Command from "./src/core/command/Command";
import Render from "./src/core/render/Render";
import View from "./src/core/view/View";
import BatchExecution from "./src/utils/BatchExecution";

View File

@@ -4,81 +4,81 @@ export const themeList: {
dark: boolean;
}[];
export namespace CONSTANTS {
let CHANGE_THEME: string;
let CHANGE_LAYOUT: string;
let SET_DATA: string;
let TRANSFORM_TO_NORMAL_NODE: string;
const CHANGE_THEME: string;
const CHANGE_LAYOUT: string;
const SET_DATA: string;
const TRANSFORM_TO_NORMAL_NODE: string;
namespace MODE {
let READONLY: string;
let EDIT: string;
const READONLY: string;
const EDIT: string;
}
namespace LAYOUT {
let LOGICAL_STRUCTURE: string;
let MIND_MAP: string;
let ORGANIZATION_STRUCTURE: string;
let CATALOG_ORGANIZATION: string;
let TIMELINE: string;
let TIMELINE2: string;
let FISHBONE: string;
let VERTICAL_TIMELINE: string;
const LOGICAL_STRUCTURE: string;
const MIND_MAP: string;
const ORGANIZATION_STRUCTURE: string;
const CATALOG_ORGANIZATION: string;
const TIMELINE: string;
const TIMELINE2: string;
const FISHBONE: string;
const VERTICAL_TIMELINE: string;
}
namespace DIR {
let UP: string;
let LEFT: string;
let DOWN: string;
let RIGHT: string;
const UP: string;
const LEFT: string;
const DOWN: string;
const RIGHT: string;
}
namespace KEY_DIR {
let LEFT_1: string;
const LEFT_1: string;
export { LEFT_1 as LEFT };
let UP_1: string;
const UP_1: string;
export { UP_1 as UP };
let RIGHT_1: string;
const RIGHT_1: string;
export { RIGHT_1 as RIGHT };
let DOWN_1: string;
const DOWN_1: string;
export { DOWN_1 as DOWN };
}
namespace SHAPE {
let RECTANGLE: string;
let DIAMOND: string;
let PARALLELOGRAM: string;
let ROUNDED_RECTANGLE: string;
let OCTAGONAL_RECTANGLE: string;
let OUTER_TRIANGULAR_RECTANGLE: string;
let INNER_TRIANGULAR_RECTANGLE: string;
let ELLIPSE: string;
let CIRCLE: string;
const RECTANGLE: string;
const DIAMOND: string;
const PARALLELOGRAM: string;
const ROUNDED_RECTANGLE: string;
const OCTAGONAL_RECTANGLE: string;
const OUTER_TRIANGULAR_RECTANGLE: string;
const INNER_TRIANGULAR_RECTANGLE: string;
const ELLIPSE: string;
const CIRCLE: string;
}
namespace MOUSE_WHEEL_ACTION {
let ZOOM: string;
let MOVE: string;
const ZOOM: string;
const MOVE: string;
}
namespace INIT_ROOT_NODE_POSITION {
let LEFT_2: string;
const LEFT_2: string;
export { LEFT_2 as LEFT };
export let TOP: string;
let RIGHT_2: string;
export const TOP: string;
const RIGHT_2: string;
export { RIGHT_2 as RIGHT };
export let BOTTOM: string;
export let CENTER: string;
export const BOTTOM: string;
export const CENTER: string;
}
namespace LAYOUT_GROW_DIR {
let LEFT_3: string;
const LEFT_3: string;
export { LEFT_3 as LEFT };
let TOP_1: string;
const TOP_1: string;
export { TOP_1 as TOP };
let RIGHT_3: string;
const RIGHT_3: string;
export { RIGHT_3 as RIGHT };
let BOTTOM_1: string;
const BOTTOM_1: string;
export { BOTTOM_1 as BOTTOM };
}
namespace PASTE_TYPE {
let CLIP_BOARD: string;
let CANVAS: string;
const CLIP_BOARD: string;
const CANVAS: string;
}
namespace SCROLL_BAR_DIR {
let VERTICAL: string;
let HORIZONTAL: string;
const VERTICAL: string;
const HORIZONTAL: string;
}
}
export const initRootNodePositionMap: {
@@ -91,19 +91,19 @@ export const layoutList: {
export const layoutValueList: string[];
export const nodeDataNoStylePropList: string[];
export namespace commonCaches {
let measureCustomNodeContentSizeEl: any;
let measureRichtextNodeTextSizeEl: any;
const measureCustomNodeContentSizeEl: any;
const measureRichtextNodeTextSizeEl: any;
}
export namespace ERROR_TYPES {
let READ_CLIPBOARD_ERROR: string;
let PARSE_PASTE_DATA_ERROR: string;
let CUSTOM_HANDLE_CLIPBOARD_TEXT_ERROR: string;
let LOAD_CLIPBOARD_IMAGE_ERROR: string;
let BEFORE_TEXT_EDIT_ERROR: string;
let EXPORT_ERROR: string;
const READ_CLIPBOARD_ERROR: string;
const PARSE_PASTE_DATA_ERROR: string;
const CUSTOM_HANDLE_CLIPBOARD_TEXT_ERROR: string;
const LOAD_CLIPBOARD_IMAGE_ERROR: string;
const BEFORE_TEXT_EDIT_ERROR: string;
const EXPORT_ERROR: string;
}
export namespace a4Size {
let width: number;
let height: number;
const width: number;
const height: number;
}
export const cssContent: "\n /* 鼠标hover和激活时渲染的矩形 */\n .smm-hover-node{\n display: none;\n opacity: 0.6;\n stroke-width: 1;\n }\n\n .smm-node:not(.smm-node-dragging):hover .smm-hover-node{\n display: block;\n }\n\n .smm-node.active .smm-hover-node{\n display: block;\n opacity: 1;\n stroke-width: 2;\n }\n";

View File

@@ -1,95 +1,100 @@
export namespace defaultOpt {
let readonly: boolean;
let layout: string;
let fishboneDeg: number;
let theme: string;
let themeConfig: {};
let scaleRatio: number;
let mouseScaleCenterUseMousePosition: boolean;
let maxTag: number;
let expandBtnSize: number;
let imgTextMargin: number;
let textContentMargin: number;
let selectTranslateStep: number;
let selectTranslateLimit: number;
let customNoteContentShow: any;
let enableFreeDrag: boolean;
const readonly: boolean;
const layout: string;
const fishboneDeg: number;
const theme: string;
const themeConfig: {};
const scaleRatio: number;
const mouseScaleCenterUseMousePosition: boolean;
const maxTag: number;
const expandBtnSize: number;
const imgTextMargin: number;
const textContentMargin: number;
const selectTranslateStep: number;
const selectTranslateLimit: number;
const customNoteContentShow: any;
const enableFreeDrag: boolean;
namespace watermarkConfig {
let text: string;
let lineSpacing: number;
let textSpacing: number;
let angle: number;
const text: string;
const lineSpacing: number;
const textSpacing: number;
const angle: number;
namespace textStyle {
let color: string;
let opacity: number;
let fontSize: number;
const color: string;
const opacity: number;
const fontSize: number;
}
}
let textAutoWrapWidth: number;
let customHandleMousewheel: any;
let mousewheelAction: string;
let mousewheelMoveStep: number;
let mousewheelZoomActionReverse: boolean;
let defaultInsertSecondLevelNodeText: string;
let defaultInsertBelowSecondLevelNodeText: string;
const textAutoWrapWidth: number;
const customHandleMousewheel: any;
const mousewheelAction: string;
const mousewheelMoveStep: number;
const mousewheelZoomActionReverse: boolean;
const defaultInsertSecondLevelNodeText: string;
const defaultInsertBelowSecondLevelNodeText: string;
namespace expandBtnStyle {
let color_1: string;
const color_1: string;
export { color_1 as color };
export let fill: string;
let fontSize_1: number;
export const fill: string;
const fontSize_1: number;
export { fontSize_1 as fontSize };
export let strokeColor: string;
export const strokeColor: string;
}
namespace expandBtnIcon {
let open: string;
let close: string;
const open: string;
const close: string;
}
function expandBtnNumHandler(num: any): any;
let isShowExpandNum: boolean;
let enableShortcutOnlyWhenMouseInSvg: boolean;
let initRootNodePosition: any;
let exportPaddingX: number;
let exportPaddingY: number;
let nodeTextEditZIndex: number;
let nodeNoteTooltipZIndex: number;
let isEndNodeTextEditOnClickOuter: boolean;
let maxHistoryCount: number;
let alwaysShowExpandBtn: boolean;
let iconList: any[];
let maxNodeCacheCount: number;
let defaultAssociativeLineText: string;
let fitPadding: number;
let enableCtrlKeyNodeSelection: boolean;
let useLeftKeySelectionRightKeyDrag: boolean;
let beforeTextEdit: any;
let isUseCustomNodeContent: boolean;
let customCreateNodeContent: any;
let customInnerElsAppendTo: any;
let nodeDragPlaceholderMaxSize: number;
let enableAutoEnterTextEditWhenKeydown: boolean;
let richTextEditFakeInPlace: boolean;
let customHandleClipboardText: any;
let disableMouseWheelZoom: boolean;
const isShowExpandNum: boolean;
const enableShortcutOnlyWhenMouseInSvg: boolean;
const initRootNodePosition: any;
const exportPaddingX: number;
const exportPaddingY: number;
const nodeTextEditZIndex: number;
const nodeNoteTooltipZIndex: number;
const isEndNodeTextEditOnClickOuter: boolean;
const maxHistoryCount: number;
const alwaysShowExpandBtn: boolean;
const iconList: any[];
const maxNodeCacheCount: number;
const defaultAssociativeLineText: string;
const fitPadding: number;
const enableCtrlKeyNodeSelection: boolean;
const useLeftKeySelectionRightKeyDrag: boolean;
const beforeTextEdit: any;
const isUseCustomNodeContent: boolean;
const customCreateNodeContent: any;
const customInnerElsAppendTo: any;
const nodeDragPlaceholderMaxSize: number;
const enableAutoEnterTextEditWhenKeydown: boolean;
const richTextEditFakeInPlace: boolean;
const customHandleClipboardText: any;
const disableMouseWheelZoom: boolean;
function errorHandler(code: any, error: any): void;
let resetCss: string;
let enableDblclickReset: boolean;
let minExportImgCanvasScale: number;
let hoverRectColor: string;
let hoverRectPadding: number;
let selectTextOnEnterEditText: boolean;
let deleteNodeActive: boolean;
let autoMoveWhenMouseInEdgeOnDrag: boolean;
let fit: boolean;
const resetCss: string;
const enableDblclickReset: boolean;
const minExportImgCanvasScale: number;
const hoverRectColor: string;
const hoverRectPadding: number;
const selectTextOnEnterEditText: boolean;
const deleteNodeActive: boolean;
const autoMoveWhenMouseInEdgeOnDrag: boolean;
const fit: boolean;
namespace dragMultiNodeRectConfig {
export let width: number;
export let height: number;
let fill_1: string;
export const width: number;
export const height: number;
const fill_1: string;
export { fill_1 as fill };
}
let dragPlaceholderRectFill: string;
const dragPlaceholderRectFill: string;
namespace dragOpacityConfig {
let cloneNodeOpacity: number;
let beingDragNodeOpacity: number;
const cloneNodeOpacity: number;
const beingDragNodeOpacity: number;
}
const tagsColorMap: {};
namespace cooperateStyle {
export const avatarSize: number;
const fontSize_2: number;
export { fontSize_2 as fontSize };
}
let tagsColorMap: {};
}

View File

@@ -22,6 +22,7 @@ declare class Render {
currentBeingPasteType: string;
setLayout(): void;
layout: MindMap | CatalogOrganization | OrganizationStructure | Timeline | VerticalTimeline;
setData(data: any): void;
bindEvent(): void;
registerCommands(): void;
selectAll(): void;
@@ -87,9 +88,9 @@ declare class Render {
expandToNodeUid(uid: any, callback?: () => void): void;
findNodeByUid(uid: any): any;
}
import TextEdit from './TextEdit';
import MindMap from '../../layouts/MindMap';
import CatalogOrganization from '../../layouts/CatalogOrganization';
import OrganizationStructure from '../../layouts/OrganizationStructure';
import Timeline from '../../layouts/Timeline';
import VerticalTimeline from '../../layouts/VerticalTimeline';
import TextEdit from "./TextEdit";
import MindMap from "../../layouts/MindMap";
import CatalogOrganization from "../../layouts/CatalogOrganization";
import OrganizationStructure from "../../layouts/OrganizationStructure";
import Timeline from "../../layouts/Timeline";
import VerticalTimeline from "../../layouts/VerticalTimeline";

View File

@@ -25,6 +25,7 @@ declare class Node {
isDrag: boolean;
parent: any;
children: any;
userList: any[];
group: any;
shapeNode: any;
hoverNode: any;
@@ -42,6 +43,7 @@ declare class Node {
_openExpandNode: any;
_closeExpandNode: any;
_fillExpandNode: any;
_userListGroup: any;
_lines: any[];
_generalizationLine: any;
_generalizationNode: any;
@@ -114,5 +116,5 @@ declare class Node {
getData(key: any): any;
hasCustomStyle(): boolean;
}
import Style from './Style';
import Shape from './Shape';
import Style from "./Style";
import Shape from "./Shape";

View File

@@ -32,5 +32,5 @@ declare class Style {
hoverNode(node: any): void;
}
declare namespace Style {
let cacheStyle: any;
const cacheStyle: any;
}

View File

@@ -0,0 +1,18 @@
declare namespace _default {
export { createUserListNode };
export { updateUserListNode };
export { createTextAvatar };
export { createImageAvatar };
export { addUser };
export { removeUser };
}
export default _default;
declare function createUserListNode(): void;
declare class createUserListNode {
_userListGroup: any;
}
declare function updateUserListNode(): void;
declare function createTextAvatar(item: any): any;
declare function createImageAvatar(item: any): any;
declare function addUser(userInfo: any): void;
declare function removeUser(userInfo: any): void;

View File

@@ -29,4 +29,4 @@ declare class removeGeneralization {
}
declare function hideGeneralization(): void;
declare function showGeneralization(): void;
import Node from './Node';
import Node from "./Node";

View File

@@ -40,4 +40,4 @@ declare class Base {
};
getNodeActChildrenLength(node: any): any;
}
import Lru from '../utils/Lru';
import Lru from "../utils/Lru";

View File

@@ -1,15 +1,11 @@
export default CatalogOrganization;
declare class CatalogOrganization extends Base {
constructor(opt?: {});
doLayout(callback: any): void;
computedBaseValue(): void;
computedLeftTopValue(): void;
adjustLeftTopValue(): void;
updateBrothersLeft(node: any, addWidth: any): void;
updateBrothersTop(node: any, addHeight: any): void;
renderLine(node: any, lines: any, style: any): any[];
renderExpandBtn(node: any, btn: any): void;
renderGeneralization(node: any, gLine: any, gNode: any): void;
renderExpandBtnRect(rect: any, expandBtnSize: any, width: any, height: any, node: any): void;
}
import Base from './Base';
import Base from "./Base";

View File

@@ -3,7 +3,6 @@ declare class Fishbone extends Base {
constructor(opt?: {});
indent: number;
childIndent: number;
doLayout(callback: any): void;
computedBaseValue(): void;
computedLeftTopValue(): void;
adjustLeftTopValue(): void;
@@ -11,9 +10,6 @@ declare class Fishbone extends Base {
updateBrothersLeft(node: any): void;
updateBrothersTop(node: any, addHeight: any): void;
checkIsTop(node: any): boolean;
renderLine(node: any, lines: any, style: any): any[];
renderExpandBtn(node: any, btn: any): void;
renderGeneralization(node: any, gLine: any, gNode: any): void;
renderExpandBtnRect(rect: any, expandBtnSize: any, width: any, height: any, node: any): void;
}
import Base from './Base';
import Base from "./Base";

View File

@@ -1,17 +1,13 @@
export default LogicalStructure;
declare class LogicalStructure extends Base {
constructor(opt?: {});
doLayout(callback: any): void;
computedBaseValue(): void;
computedTopValue(): void;
adjustTopValue(): void;
updateBrothers(node: any, addHeight: any): void;
renderLine(node: any, lines: any, style: any, lineStyle: any): void;
renderLineStraight(node: any, lines: any, style: any): any[];
renderLineDirect(node: any, lines: any, style: any): any[];
renderLineCurve(node: any, lines: any, style: any): any[];
renderExpandBtn(node: any, btn: any): void;
renderGeneralization(node: any, gLine: any, gNode: any): void;
renderExpandBtnRect(rect: any, expandBtnSize: any, width: any, height: any, node: any): void;
}
import Base from './Base';
import Base from "./Base";

View File

@@ -1,17 +1,13 @@
export default MindMap;
declare class MindMap extends Base {
constructor(opt?: {});
doLayout(callback: any): void;
computedBaseValue(): void;
computedTopValue(): void;
adjustTopValue(): void;
updateBrothers(node: any, leftAddHeight: any, rightAddHeight: any): void;
renderLine(node: any, lines: any, style: any, lineStyle: any): void;
renderLineStraight(node: any, lines: any, style: any): any[];
renderLineDirect(node: any, lines: any, style: any): any[];
renderLineCurve(node: any, lines: any, style: any): any[];
renderExpandBtn(node: any, btn: any): void;
renderGeneralization(node: any, gLine: any, gNode: any): void;
renderExpandBtnRect(rect: any, expandBtnSize: any, width: any, height: any, node: any): void;
}
import Base from './Base';
import Base from "./Base";

View File

@@ -1,16 +1,12 @@
export default OrganizationStructure;
declare class OrganizationStructure extends Base {
constructor(opt?: {});
doLayout(callback: any): void;
computedBaseValue(): void;
computedLeftValue(): void;
adjustLeftValue(): void;
updateBrothers(node: any, addWidth: any): void;
renderLine(node: any, lines: any, style: any, lineStyle: any): void;
renderLineDirect(node: any, lines: any, style: any): any[];
renderLineStraight(node: any, lines: any, style: any): any[];
renderExpandBtn(node: any, btn: any): void;
renderGeneralization(node: any, gLine: any, gNode: any): void;
renderExpandBtnRect(rect: any, expandBtnSize: any, width: any, height: any, node: any): void;
}
import Base from './Base';
import Base from "./Base";

View File

@@ -2,16 +2,12 @@ export default Timeline;
declare class Timeline extends Base {
constructor(opt: {}, layout: any);
layout: any;
doLayout(callback: any): void;
computedBaseValue(): void;
computedLeftTopValue(): void;
adjustLeftTopValue(): void;
getNodeAreaHeight(node: any): number;
updateBrothersLeft(node: any): void;
updateBrothersTop(node: any, addHeight: any): void;
renderLine(node: any, lines: any, style: any): any[];
renderExpandBtn(node: any, btn: any): void;
renderGeneralization(node: any, gLine: any, gNode: any): void;
renderExpandBtnRect(rect: any, expandBtnSize: any, width: any, height: any, node: any): void;
}
import Base from './Base';
import Base from "./Base";

View File

@@ -2,18 +2,14 @@ export default VerticalTimeline;
declare class VerticalTimeline extends Base {
constructor(opt: {}, layout: any);
layout: any;
doLayout(callback: any): void;
computedBaseValue(): void;
computedTopValue(): void;
adjustLeftTopValue(): void;
updateBrothers(node: any, addHeight: any): void;
updateBrothersTop(node: any, addHeight: any): void;
renderLine(node: any, lines: any, style: any, lineStyle: any): void;
renderLineStraight(node: any, lines: any, style: any): any[];
renderLineDirect(node: any, lines: any, style: any): any[];
renderLineCurve(node: any, lines: any, style: any): any[];
renderExpandBtn(node: any, btn: any): void;
renderGeneralization(node: any, gLine: any, gNode: any): void;
renderExpandBtnRect(rect: any, expandBtnSize: any, width: any, height: any, node: any): void;
}
import Base from './Base';
import Base from "./Base";

View File

@@ -1,5 +1,14 @@
declare namespace _default {
namespace top {
function renderExpandBtn({ node, btn, expandBtnSize, translateX, translateY, width, height }: {
node: any;
btn: any;
expandBtnSize: any;
translateX: any;
translateY: any;
width: any;
height: any;
}): void;
function renderExpandBtn({ node, btn, expandBtnSize, translateX, translateY, width, height }: {
node: any;
btn: any;
@@ -20,11 +29,33 @@ declare namespace _default {
maxy: any;
ctx: any;
}): void;
function renderLine({ node, line, top, x, lineLength, height, expandBtnSize, maxy, ctx }: {
node: any;
line: any;
top: any;
x: any;
lineLength: any;
height: any;
expandBtnSize: any;
maxy: any;
ctx: any;
}): void;
function computedLeftTopValue({ layerIndex, node, ctx }: {
layerIndex: any;
node: any;
ctx: any;
}): void;
function computedLeftTopValue({ layerIndex, node, ctx }: {
layerIndex: any;
node: any;
ctx: any;
}): void;
function adjustLeftTopValueBefore({ node, parent, ctx, layerIndex }: {
node: any;
parent: any;
ctx: any;
layerIndex: any;
}): void;
function adjustLeftTopValueBefore({ node, parent, ctx, layerIndex }: {
node: any;
parent: any;
@@ -36,8 +67,22 @@ declare namespace _default {
node: any;
ctx: any;
}): void;
function adjustLeftTopValueAfter({ parent, node, ctx }: {
parent: any;
node: any;
ctx: any;
}): void;
}
namespace bottom {
function renderExpandBtn({ node, btn, expandBtnSize, translateX, translateY, width, height }: {
node: any;
btn: any;
expandBtnSize: any;
translateX: any;
translateY: any;
width: any;
height: any;
}): void;
function renderExpandBtn({ node, btn, expandBtnSize, translateX, translateY, width, height }: {
node: any;
btn: any;
@@ -57,11 +102,31 @@ declare namespace _default {
miny: any;
ctx: any;
}): void;
function renderLine({ node, line, top, x, lineLength, height, miny, ctx }: {
node: any;
line: any;
top: any;
x: any;
lineLength: any;
height: any;
miny: any;
ctx: any;
}): void;
function computedLeftTopValue({ layerIndex, node, ctx }: {
layerIndex: any;
node: any;
ctx: any;
}): void;
function computedLeftTopValue({ layerIndex, node, ctx }: {
layerIndex: any;
node: any;
ctx: any;
}): void;
function adjustLeftTopValueBefore({ node, ctx, layerIndex }: {
node: any;
ctx: any;
layerIndex: any;
}): void;
function adjustLeftTopValueBefore({ node, ctx, layerIndex }: {
node: any;
ctx: any;
@@ -72,6 +137,11 @@ declare namespace _default {
node: any;
ctx: any;
}): void;
function adjustLeftTopValueAfter({ parent, node, ctx }: {
parent: any;
node: any;
ctx: any;
}): void;
}
}
export default _default;

View File

@@ -1,139 +1,139 @@
declare namespace _default {
let paddingX: number;
let paddingY: number;
let imgMaxWidth: number;
let imgMaxHeight: number;
let iconSize: number;
let lineWidth: number;
let lineColor: string;
let lineDasharray: string;
let lineStyle: string;
let rootLineKeepSameInCurve: boolean;
let generalizationLineWidth: number;
let generalizationLineColor: string;
let generalizationLineMargin: number;
let generalizationNodeMargin: number;
let associativeLineWidth: number;
let associativeLineColor: string;
let associativeLineActiveWidth: number;
let associativeLineActiveColor: string;
let associativeLineTextColor: string;
let associativeLineTextFontSize: number;
let associativeLineTextLineHeight: number;
let associativeLineTextFontFamily: string;
let backgroundColor: string;
let backgroundImage: string;
let backgroundRepeat: string;
let backgroundPosition: string;
let backgroundSize: string;
let nodeUseLineStyle: boolean;
const paddingX: number;
const paddingY: number;
const imgMaxWidth: number;
const imgMaxHeight: number;
const iconSize: number;
const lineWidth: number;
const lineColor: string;
const lineDasharray: string;
const lineStyle: string;
const rootLineKeepSameInCurve: boolean;
const generalizationLineWidth: number;
const generalizationLineColor: string;
const generalizationLineMargin: number;
const generalizationNodeMargin: number;
const associativeLineWidth: number;
const associativeLineColor: string;
const associativeLineActiveWidth: number;
const associativeLineActiveColor: string;
const associativeLineTextColor: string;
const associativeLineTextFontSize: number;
const associativeLineTextLineHeight: number;
const associativeLineTextFontFamily: string;
const backgroundColor: string;
const backgroundImage: string;
const backgroundRepeat: string;
const backgroundPosition: string;
const backgroundSize: string;
const nodeUseLineStyle: boolean;
namespace root {
let shape: string;
let fillColor: string;
let fontFamily: string;
let color: string;
let fontSize: number;
let fontWeight: string;
let fontStyle: string;
let lineHeight: number;
let borderColor: string;
let borderWidth: number;
let borderDasharray: string;
let borderRadius: number;
let textDecoration: string;
const shape: string;
const fillColor: string;
const fontFamily: string;
const color: string;
const fontSize: number;
const fontWeight: string;
const fontStyle: string;
const lineHeight: number;
const borderColor: string;
const borderWidth: number;
const borderDasharray: string;
const borderRadius: number;
const textDecoration: string;
}
namespace second {
let shape_1: string;
const shape_1: string;
export { shape_1 as shape };
export let marginX: number;
export let marginY: number;
let fillColor_1: string;
export const marginX: number;
export const marginY: number;
const fillColor_1: string;
export { fillColor_1 as fillColor };
let fontFamily_1: string;
const fontFamily_1: string;
export { fontFamily_1 as fontFamily };
let color_1: string;
const color_1: string;
export { color_1 as color };
let fontSize_1: number;
const fontSize_1: number;
export { fontSize_1 as fontSize };
let fontWeight_1: string;
const fontWeight_1: string;
export { fontWeight_1 as fontWeight };
let fontStyle_1: string;
const fontStyle_1: string;
export { fontStyle_1 as fontStyle };
let lineHeight_1: number;
const lineHeight_1: number;
export { lineHeight_1 as lineHeight };
let borderColor_1: string;
const borderColor_1: string;
export { borderColor_1 as borderColor };
let borderWidth_1: number;
const borderWidth_1: number;
export { borderWidth_1 as borderWidth };
let borderDasharray_1: string;
const borderDasharray_1: string;
export { borderDasharray_1 as borderDasharray };
let borderRadius_1: number;
const borderRadius_1: number;
export { borderRadius_1 as borderRadius };
let textDecoration_1: string;
const textDecoration_1: string;
export { textDecoration_1 as textDecoration };
}
namespace node {
let shape_2: string;
const shape_2: string;
export { shape_2 as shape };
let marginX_1: number;
const marginX_1: number;
export { marginX_1 as marginX };
let marginY_1: number;
const marginY_1: number;
export { marginY_1 as marginY };
let fillColor_2: string;
const fillColor_2: string;
export { fillColor_2 as fillColor };
let fontFamily_2: string;
const fontFamily_2: string;
export { fontFamily_2 as fontFamily };
let color_2: string;
const color_2: string;
export { color_2 as color };
let fontSize_2: number;
const fontSize_2: number;
export { fontSize_2 as fontSize };
let fontWeight_2: string;
const fontWeight_2: string;
export { fontWeight_2 as fontWeight };
let fontStyle_2: string;
const fontStyle_2: string;
export { fontStyle_2 as fontStyle };
let lineHeight_2: number;
const lineHeight_2: number;
export { lineHeight_2 as lineHeight };
let borderColor_2: string;
const borderColor_2: string;
export { borderColor_2 as borderColor };
let borderWidth_2: number;
const borderWidth_2: number;
export { borderWidth_2 as borderWidth };
let borderRadius_2: number;
const borderRadius_2: number;
export { borderRadius_2 as borderRadius };
let borderDasharray_2: string;
const borderDasharray_2: string;
export { borderDasharray_2 as borderDasharray };
let textDecoration_2: string;
const textDecoration_2: string;
export { textDecoration_2 as textDecoration };
}
namespace generalization {
let shape_3: string;
const shape_3: string;
export { shape_3 as shape };
let marginX_2: number;
const marginX_2: number;
export { marginX_2 as marginX };
let marginY_2: number;
const marginY_2: number;
export { marginY_2 as marginY };
let fillColor_3: string;
const fillColor_3: string;
export { fillColor_3 as fillColor };
let fontFamily_3: string;
const fontFamily_3: string;
export { fontFamily_3 as fontFamily };
let color_3: string;
const color_3: string;
export { color_3 as color };
let fontSize_3: number;
const fontSize_3: number;
export { fontSize_3 as fontSize };
let fontWeight_3: string;
const fontWeight_3: string;
export { fontWeight_3 as fontWeight };
let fontStyle_3: string;
const fontStyle_3: string;
export { fontStyle_3 as fontStyle };
let lineHeight_3: number;
const lineHeight_3: number;
export { lineHeight_3 as lineHeight };
let borderColor_3: string;
const borderColor_3: string;
export { borderColor_3 as borderColor };
let borderWidth_3: number;
const borderWidth_3: number;
export { borderWidth_3 as borderWidth };
let borderDasharray_3: string;
const borderDasharray_3: string;
export { borderDasharray_3 as borderDasharray };
let borderRadius_3: number;
const borderRadius_3: number;
export { borderRadius_3 as borderRadius };
let textDecoration_3: string;
const textDecoration_3: string;
export { textDecoration_3 as textDecoration };
}
}

View File

@@ -6,7 +6,7 @@ export function resizeImg(imgUrl: any, maxWidth: any, maxHeight: any): Promise<a
export function getStrWithBrFromHtml(str: any): any;
export function simpleDeepClone(data: any): any;
export function copyRenderTree(tree: any, root: any, removeActiveState?: boolean): any;
export function copyNodeTree(tree: any, root: any, removeActiveState?: boolean, keepId?: boolean): any;
export function copyNodeTree(tree: any, root: any, removeActiveState?: boolean, removeId?: boolean): any;
export function imgToDataUrl(src: any): Promise<any>;
export function parseDataUrl(data: any): any;
export function downloadFile(file: any, fileName: any): void;
@@ -62,8 +62,9 @@ export function checkTwoRectIsOverlap(minx1: any, maxx1: any, miny1: any, maxy1:
export function focusInput(el: any): void;
export function selectAllInput(el: any): void;
export function addDataToAppointNodes(appointNodes: any, data?: {}): any;
export function createUidForAppointNodes(appointNodes: any): any;
export function createUidForAppointNodes(appointNodes: any, createNewId?: boolean): any;
export function formatDataToArray(data: any): any[];
export function getNodeIndex(node: any): any;
export function generateColorByContent(str: any): string;
export function htmlEscape(str: any): any;
export function isSameObject(a: any, b: any): boolean;

View File

@@ -1,5 +1,19 @@
# Changelog
## 0.7.3-fix.1
Fix:
> 1.Fixed some issues where the box selection area did not disappear when multiple nodes were selected.
>
> 2.Fixed an issue where the box selection area does not disappear when releasing the mouse over multiple selected nodes.
>
> 3.Fixed rendering anomalies caused by duplicate node uids when pasting nodes multiple times.
Demo
> 1.Add protocol selection function to the hyperlink input box.
## 0.7.3
New: 1.Add a Cooperate editing plugin.

View File

@@ -1,6 +1,17 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.7.3-fix.1</h2>
<p>Fix:</p>
<blockquote>
<p>1.Fixed some issues where the box selection area did not disappear when multiple nodes were selected.</p>
<p>2.Fixed an issue where the box selection area does not disappear when releasing the mouse over multiple selected nodes.</p>
<p>3.Fixed rendering anomalies caused by duplicate node uids when pasting nodes multiple times.</p>
</blockquote>
<p>Demo</p>
<blockquote>
<p>1.Add protocol selection function to the hyperlink input box.</p>
</blockquote>
<h2>0.7.3</h2>
<p>New: 1.Add a Cooperate editing plugin.</p>
<p>Demo: 1.Fix the automatic closing of the sidebar caused by the formula sidebar component.</p>

View File

@@ -30,12 +30,22 @@ npm i
npm link simple-mind-map
```
2. Modify `web/src/pages/Edit/components/Edit.vue` file, To register Cooperate plugin, uncomment the line:
2. Modify `web/src/pages/Edit/components/Edit.vue` file
To register Cooperate plugin, uncomment the line:
```js
// .usePlugin(Cooperate)// Cooperate plugin
```
Change the signaling server address to your local IP:
```js
// cooperateTest function
signalingList: ['ws://【your ip】:4444']
```
3. To register a collaborative plugin, uncomment the line:
```bash

View File

@@ -25,10 +25,16 @@ npm i
npm link simple-mind-map
</code></pre>
<ol start="2">
<li>Modify <code>web/src/pages/Edit/components/Edit.vue</code> file, To register Cooperate plugin, uncomment the line:</li>
<li>Modify <code>web/src/pages/Edit/components/Edit.vue</code> file</li>
</ol>
<p>To register Cooperate plugin, uncomment the line:</p>
<pre class="hljs"><code><span class="hljs-comment">// .usePlugin(Cooperate)// Cooperate plugin</span>
</code></pre>
<p>Change the signaling server address to your local IP:</p>
<pre class="hljs"><code><span class="hljs-comment">// cooperateTest function</span>
<span class="hljs-attr">signalingList</span>: [<span class="hljs-string">&#x27;ws://【your ip】:4444&#x27;</span>]
</code></pre>
<ol start="3">
<li>To register a collaborative plugin, uncomment the line:</li>
</ol>

View File

@@ -18,6 +18,7 @@
- [x] Supoorts to export as `json``png``svg``pdf``markdown``xmind`, support import from `json``xmind``markdown`
- [x] Support shortcut keys, forward and backward, correlation lines, search and replacement, small maps, watermarks, and scrollbar
- [x] Provide rich configurations to meet various scenarios and usage habits
- [x] Support collaborative editing
## Repository Catalog Introduction
@@ -116,7 +117,7 @@ Unsupported: `IE` browser.
Open source is not easy. If this project is helpful to you, you can invite the author to have a cup of coffee~
> Please note the 【mind map】 for transfer. Your avatar and name will appear below.
> Please note the 【mind map】 for transfer.
<img src="../../../../assets/img/alipay.jpg" style="width: 300px" />

View File

@@ -8,16 +8,17 @@
</blockquote>
<h2>Features</h2>
<ul>
<li><input type="checkbox" id="checkbox15" checked="true" /><label for="checkbox15">Pluggable architecture, in addition to core functions, other functions are provided as plugins, which can be used as needed to reduce packaging volume</label></li>
<li><input type="checkbox" id="checkbox16" checked="true" /><label for="checkbox16">Support logical structure chart, mind map, Organizational chart, directory organization chart, timeline (horizontal and vertical), fishbone chart and other structures</label></li>
<li><input type="checkbox" id="checkbox17" checked="true" /><label for="checkbox17">Built-in multiple themes, allowing for highly customizable styles, and supporting registration of new themes</label></li>
<li><input type="checkbox" id="checkbox18" checked="true" /><label for="checkbox18">Node content supports text (regular text, rich text), images, icons, hyperlinks, notes, labels, summaries, and math formulas</label></li>
<li><input type="checkbox" id="checkbox19" checked="true" /><label for="checkbox19">Nodes support drag and drop (drag and move, freely adjust), multiple node shapes, and fully customize node content using DDM</label></li>
<li><input type="checkbox" id="checkbox20" checked="true" /><label for="checkbox20">Support canvas dragging and scaling</label></li>
<li><input type="checkbox" id="checkbox21" checked="true" /><label for="checkbox21">Supports two multi node selection methods: mouse button drag selection and Ctrl+left button selection</label></li>
<li><input type="checkbox" id="checkbox22" checked="true" /><label for="checkbox22">Supoorts to export as </label><code>json</code><code>png</code><code>svg</code><code>pdf</code><code>markdown</code><code>xmind</code>, support import from <code>json</code><code>xmind</code><code>markdown</code></li>
<li><input type="checkbox" id="checkbox23" checked="true" /><label for="checkbox23">Support shortcut keys, forward and backward, correlation lines, search and replacement, small maps, watermarks, and scrollbar</label></li>
<li><input type="checkbox" id="checkbox24" checked="true" /><label for="checkbox24">Provide rich configurations to meet various scenarios and usage habits</label></li>
<li><input type="checkbox" id="checkbox48" checked="true" /><label for="checkbox48">Pluggable architecture, in addition to core functions, other functions are provided as plugins, which can be used as needed to reduce packaging volume</label></li>
<li><input type="checkbox" id="checkbox49" checked="true" /><label for="checkbox49">Support logical structure chart, mind map, Organizational chart, directory organization chart, timeline (horizontal and vertical), fishbone chart and other structures</label></li>
<li><input type="checkbox" id="checkbox50" checked="true" /><label for="checkbox50">Built-in multiple themes, allowing for highly customizable styles, and supporting registration of new themes</label></li>
<li><input type="checkbox" id="checkbox51" checked="true" /><label for="checkbox51">Node content supports text (regular text, rich text), images, icons, hyperlinks, notes, labels, summaries, and math formulas</label></li>
<li><input type="checkbox" id="checkbox52" checked="true" /><label for="checkbox52">Nodes support drag and drop (drag and move, freely adjust), multiple node shapes, and fully customize node content using DDM</label></li>
<li><input type="checkbox" id="checkbox53" checked="true" /><label for="checkbox53">Support canvas dragging and scaling</label></li>
<li><input type="checkbox" id="checkbox54" checked="true" /><label for="checkbox54">Supports two multi node selection methods: mouse button drag selection and Ctrl+left button selection</label></li>
<li><input type="checkbox" id="checkbox55" checked="true" /><label for="checkbox55">Supoorts to export as </label><code>json</code><code>png</code><code>svg</code><code>pdf</code><code>markdown</code><code>xmind</code>, support import from <code>json</code><code>xmind</code><code>markdown</code></li>
<li><input type="checkbox" id="checkbox56" checked="true" /><label for="checkbox56">Support shortcut keys, forward and backward, correlation lines, search and replacement, small maps, watermarks, and scrollbar</label></li>
<li><input type="checkbox" id="checkbox57" checked="true" /><label for="checkbox57">Provide rich configurations to meet various scenarios and usage habits</label></li>
<li><input type="checkbox" id="checkbox58" checked="true" /><label for="checkbox58">Support collaborative editing</label></li>
</ul>
<h2>Repository Catalog Introduction</h2>
<p>1.<code>simple-mind-map</code></p>
@@ -27,16 +28,16 @@ frameworks such as Vue and React, or without a framework.</p>
<p>This is an online mind map built using the <code>simple-mind-map</code> library and based
on <code>Vue2.x</code> and <code>ElementUI</code>. Features include:</p>
<ul>
<li><input type="checkbox" id="checkbox25" checked="true" /><label for="checkbox25">Toolbar, which supports inserting and deleting nodes, and editing node</label>
<li><input type="checkbox" id="checkbox59" checked="true" /><label for="checkbox59">Toolbar, which supports inserting and deleting nodes, and editing node</label>
images, icons, hyperlinks, notes, tags, and summaries</li>
<li><input type="checkbox" id="checkbox26" checked="true" /><label for="checkbox26">Sidebar, with panels for basic style settings, node style settings,</label>
<li><input type="checkbox" id="checkbox60" checked="true" /><label for="checkbox60">Sidebar, with panels for basic style settings, node style settings,</label>
outline, theme selection, and structure selection</li>
<li><input type="checkbox" id="checkbox27" checked="true" /><label for="checkbox27">Import and export functionality; data is saved in the browser's local</label>
<li><input type="checkbox" id="checkbox61" checked="true" /><label for="checkbox61">Import and export functionality; data is saved in the browser's local</label>
storage by default, but it also supports creating, opening, and editing
local files on the computer directly</li>
<li><input type="checkbox" id="checkbox28" checked="true" /><label for="checkbox28">Right-click menu, which supports operations such as expanding, collapsing,</label>
<li><input type="checkbox" id="checkbox62" checked="true" /><label for="checkbox62">Right-click menu, which supports operations such as expanding, collapsing,</label>
and organizing layout</li>
<li><input type="checkbox" id="checkbox29" checked="true" /><label for="checkbox29">Bottom bar, which supports node and word count statistics, switching</label>
<li><input type="checkbox" id="checkbox63" checked="true" /><label for="checkbox63">Bottom bar, which supports node and word count statistics, switching</label>
between edit and read-only modes, zooming in and out, and switching to
full screen, support mini map</li>
</ul>
@@ -77,7 +78,7 @@ full screen, support mini map</li>
<h2>Invite the author to a cup of coffee</h2>
<p>Open source is not easy. If this project is helpful to you, you can invite the author to have a cup of coffee~</p>
<blockquote>
<p>Please note the mind map for transfer. Your avatar and name will appear below.</p>
<p>Please note the mind map for transfer.</p>
</blockquote>
<img src="../../../../assets/img/alipay.jpg" style="width: 300px" />
<img src="../../../../assets/img/wechat.jpg" style="width: 300px" />

View File

@@ -90,7 +90,9 @@ copyRenderTree({}, this.mindMap.renderer.renderTree);
- `removeActiveState`: `Boolean`, default is `false`, Whether to remove the active state of the node
- `keepId`: v0.4.6+, `Boolean`, default is `false`, Whether to retain the `id` of the replicated node will be deleted by default to prevent duplicate node `id`. However, for mobile node scenarios, the original `id` of the node needs to be retained
- `removeId`v0.7.3-fix.1+, Is remove the uid from the node data, default is `true`
> - `keepId`: (Original fourth parameter) v0.4.6+, `Boolean`, default is `false`, Whether to retain the `id` of the replicated node will be deleted by default to prevent duplicate node `id`. However, for mobile node scenarios, the original `id` of the node needs to be retained
Copy node tree data, mainly eliminating the reference `node` instance `_node`
and copying the `data` of the data object, example:
@@ -292,12 +294,14 @@ Focus and select all specified input boxes.
Adding additional data to the specified node list tree data will modify the original data.
#### createUidForAppointNodes(appointNodes)
#### createUidForAppointNodes(appointNodes, createNewId)
> v0.7.2+
- `appointNodes`Node instance list, array type.
- `createNewId`v0.7.3-fix.1+, `Boolean`, default is `false`, If the node does not have a 'uid', a new 'uid' will be created. If 'true' is passed, a new 'uid' will be created regardless of whether the node data originally exists or not`
Adding a uid to the specified node list tree data (if the uid does not exist) will modify the original data.
#### getNodeIndex(node)

View File

@@ -54,9 +54,14 @@ basic data, otherwise it will throw an error</p>
<p><code>removeActiveState</code>: <code>Boolean</code>, default is <code>false</code>, Whether to remove the active state of the node</p>
</li>
<li>
<p><code>keepId</code>: v0.4.6+, <code>Boolean</code>, default is <code>false</code>, Whether to retain the <code>id</code> of the replicated node will be deleted by default to prevent duplicate node <code>id</code>. However, for mobile node scenarios, the original <code>id</code> of the node needs to be retained</p>
<p><code>removeId</code>v0.7.3-fix.1+, Is remove the uid from the node data, default is <code>true</code></p>
</li>
</ul>
<blockquote>
<ul>
<li><code>keepId</code>: (Original fourth parameter) v0.4.6+, <code>Boolean</code>, default is <code>false</code>, Whether to retain the <code>id</code> of the replicated node will be deleted by default to prevent duplicate node <code>id</code>. However, for mobile node scenarios, the original <code>id</code> of the node needs to be retained</li>
</ul>
</blockquote>
<p>Copy node tree data, mainly eliminating the reference <code>node</code> instance <code>_node</code>
and copying the <code>data</code> of the data object, example:</p>
<pre class="hljs"><code>copyNodeTree({}, node);
@@ -222,12 +227,17 @@ and copying the <code>data</code> of the data object, example:</p>
</li>
</ul>
<p>Adding additional data to the specified node list tree data will modify the original data.</p>
<h4>createUidForAppointNodes(appointNodes)</h4>
<h4>createUidForAppointNodes(appointNodes, createNewId)</h4>
<blockquote>
<p>v0.7.2+</p>
</blockquote>
<ul>
<li><code>appointNodes</code>Node instance list, array type.</li>
<li>
<p><code>appointNodes</code>Node instance list, array type.</p>
</li>
<li>
<p><code>createNewId</code>v0.7.3-fix.1+, <code>Boolean</code>, default is <code>false</code>, If the node does not have a 'uid', a new 'uid' will be created. If 'true' is passed, a new 'uid' will be created regardless of whether the node data originally exists or not`</p>
</li>
</ul>
<p>Adding a uid to the specified node list tree data (if the uid does not exist) will modify the original data.</p>
<h4>getNodeIndex(node)</h4>

View File

@@ -1,5 +1,19 @@
# Changelog
## 0.7.3-fix.1
修复:
> 1.修复一些情况下多选节点时的框选区域没有消失的问题。
>
> 2.修复多选节点时在节点上松开鼠标时框选区域不会消失的问题。
>
> 3.修复多次粘贴节点时由于节点uid重复造成的渲染异常问题。
Demo
> 1.超链接输入框增加协议选择功能。
## 0.7.3
新增1.新增协同编辑插件。

View File

@@ -1,6 +1,17 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.7.3-fix.1</h2>
<p>修复</p>
<blockquote>
<p>1.修复一些情况下多选节点时的框选区域没有消失的问题</p>
<p>2.修复多选节点时在节点上松开鼠标时框选区域不会消失的问题</p>
<p>3.修复多次粘贴节点时由于节点uid重复造成的渲染异常问题</p>
</blockquote>
<p>Demo</p>
<blockquote>
<p>1.超链接输入框增加协议选择功能</p>
</blockquote>
<h2>0.7.3</h2>
<p>新增1.新增协同编辑插件</p>
<p>Demo1.修复公式侧边栏组件导致的侧边栏自动关闭问题</p>

View File

@@ -30,12 +30,22 @@ npm i
npm link simple-mind-map
```
2. 修改`web/src/pages/Edit/components/Edit.vue`文件,注册协同插件,即取消该行注释:
2. 修改`web/src/pages/Edit/components/Edit.vue`文件
注册协同插件,即取消该行注释:
```js
// .usePlugin(Cooperate)// 协同插件
```
将信令服务器地址改为你本机的ip
```js
// cooperateTest 函数
signalingList: ['ws://【你的ip】:4444']
```
3. 启动demo项目的本地服务
```bash

View File

@@ -25,10 +25,16 @@ npm i
npm link simple-mind-map
</code></pre>
<ol start="2">
<li>修改<code>web/src/pages/Edit/components/Edit.vue</code>文件注册协同插件即取消该行注释</li>
<li>修改<code>web/src/pages/Edit/components/Edit.vue</code>文件</li>
</ol>
<p>注册协同插件即取消该行注释</p>
<pre class="hljs"><code><span class="hljs-comment">// .usePlugin(Cooperate)// 协同插件</span>
</code></pre>
<p>将信令服务器地址改为你本机的ip</p>
<pre class="hljs"><code><span class="hljs-comment">// cooperateTest 函数</span>
<span class="hljs-attr">signalingList</span>: [<span class="hljs-string">&#x27;ws://【你的ip】:4444&#x27;</span>]
</code></pre>
<ol start="3">
<li>启动demo项目的本地服务</li>
</ol>

View File

@@ -4,7 +4,7 @@
## 插入子节点
插入子节点很节点,执行`INSERT_CHILD_NODE`命令即可:
插入子节点很简单,执行`INSERT_CHILD_NODE`命令即可:
```js
mindMap.execCommand('INSERT_CHILD_NODE')

View File

@@ -3,7 +3,7 @@
<h1>插入/删除节点前进回退</h1>
<p>首先和操作节点内容一样也需要监听节点的激活事件然后禁用相关按钮</p>
<h2>插入子节点</h2>
<p>插入子节点很节点执行<code>INSERT_CHILD_NODE</code>命令即可</p>
<p>插入子节点很简单执行<code>INSERT_CHILD_NODE</code>命令即可</p>
<pre class="hljs"><code>mindMap.execCommand(<span class="hljs-string">&#x27;INSERT_CHILD_NODE&#x27;</span>)
</code></pre>
<p>这样就会在当前激活节点如果存在多个激活节点默认会操作第一个激活节点下添加一个子节点</p>

View File

@@ -18,6 +18,7 @@
- [x] 支持导出为`json``png``svg``pdf``markdown``xmind`,支持从`json``xmind``markdown`导入
- [x] 支持快捷键、前进后退、关联线、搜索替换、小地图、水印、滚动条
- [x] 提供丰富的配置,满足各种场景各种使用习惯
- [x] 支持协同编辑
## 仓库目录介绍
@@ -105,11 +106,11 @@
## 请作者喝杯咖啡
开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡~
开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡~
> 厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds
> 推荐使用支付宝,微信获取不到头像。转账请备注【思维导图】。你的头像和名字将会出现在下面。
> 推荐使用支付宝,微信获取不到头像。转账请备注【思维导图】。
<img src="../../../../assets/img/alipay.jpg" style="width: 300px" />

View File

@@ -8,16 +8,17 @@
</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">节点支持拖拽拖拽移动自由调整多种节点形状支持使用 DDM 完全自定义节点内容</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">支持鼠标按键拖动选择和Ctrl+左键两种多选节点方式</label></li>
<li><input type="checkbox" id="checkbox7" checked="true" /><label for="checkbox7">支持导出为</label><code>json</code><code>png</code><code>svg</code><code>pdf</code><code>markdown</code><code>xmind</code>支持从<code>json</code><code>xmind</code><code>markdown</code>导入</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="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>
<li><input type="checkbox" id="checkbox36" checked="true" /><label for="checkbox36">节点支持拖拽拖拽移动自由调整多种节点形状支持使用 DDM 完全自定义节点内容</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">支持鼠标按键拖动选择和Ctrl+左键两种多选节点方式</label></li>
<li><input type="checkbox" id="checkbox39" checked="true" /><label for="checkbox39">支持导出为</label><code>json</code><code>png</code><code>svg</code><code>pdf</code><code>markdown</code><code>xmind</code>支持从<code>json</code><code>xmind</code><code>markdown</code>导入</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>
</ul>
<h2>仓库目录介绍</h2>
<p>1.<code>simple-mind-map</code></p>
@@ -25,11 +26,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="checkbox10" checked="true" /><label for="checkbox10">工具栏支持插入节点删除节点编辑节点图片图标超链接备注标签概要</label></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="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="checkbox43" checked="true" /><label for="checkbox43">工具栏支持插入节点删除节点编辑节点图片图标超链接备注标签概要</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></li>
<li><input type="checkbox" id="checkbox47" checked="true" /><label for="checkbox47">底部栏支持节点数量字数统计支持切换编辑和只读模式支持放大缩小支持全屏切换支持小地图</label></li>
</ul>
<p>提供文档页面服务</p>
<p>3.<code>dist</code></p>
@@ -66,12 +67,12 @@
<h2>License</h2>
<p><a href="https://opensource.org/licenses/MIT">MIT</a></p>
<h2>请作者喝杯咖啡</h2>
<p>开源不易如果本项目有帮助到你的话可以考虑请作者喝杯咖啡~</p>
<p>开源不易如果本项目有帮助到你的话可以考虑请作者喝杯咖啡~</p>
<blockquote>
<p>厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds</p>
</blockquote>
<blockquote>
<p>推荐使用支付宝微信获取不到头像转账请备注思维导图你的头像和名字将会出现在下面</p>
<p>推荐使用支付宝微信获取不到头像转账请备注思维导图</p>
</blockquote>
<img src="../../../../assets/img/alipay.jpg" style="width: 300px" />
<img src="../../../../assets/img/wechat.jpg" style="width: 300px" />

View File

@@ -82,11 +82,13 @@ walk(tree, null, () => {}, () => {}, false, 0, 0)
copyRenderTree({}, this.mindMap.renderer.renderTree)
```
#### copyNodeTree(tree, root, removeActiveState, keepId)
#### copyNodeTree(tree, root, removeActiveState, removeId)
- `removeActiveState``Boolean`,默认为`false`,是否移除节点的激活状态
- `keepId`v0.4.6+`Boolean`,默认为`false`,是否保留被复制节点的`id`,默认会删除`id`防止节点`id`重复,但是对于移动节点的场景,节点原`id`需要保留
- `removeId`v0.7.3-fix.1+是否移除节点数据中的uid默认为`true`
> - `keepId` (原第四个参数)`Boolean`,默认为`false`,是否保留被复制节点的`id`,默认会删除`id`防止节点`id`重复,但是对于移动节点的场景,节点原`id`需要保留。
复制节点树数据,主要是剔除其中的引用`node`实例的`_node`,然后复制`data`对象的数据,示例:
@@ -287,12 +289,14 @@ copyNodeTree({}, node)
给指定的节点列表树数据添加附加数据,会修改原数据。
#### createUidForAppointNodes(appointNodes)
#### createUidForAppointNodes(appointNodes, createNewId)
> v0.7.2+
- `appointNodes`:节点实例列表,数组类型。
- `createNewId`v0.7.3-fix.1+`Boolean`,默认为`false`,即如果节点不存在`uid`的话,会创建新的`uid`。如果传`true`,那么无论节点数据原来是否存在`uid`,都会创建新的`uid`
给指定的节点列表树数据添加uid如果uid不存在的话会修改原数据。
#### getNodeIndex(node)

View File

@@ -44,15 +44,20 @@
<p>复制渲染树数据示例</p>
<pre class="hljs"><code>copyRenderTree({}, <span class="hljs-built_in">this</span>.mindMap.renderer.renderTree)
</code></pre>
<h4>copyNodeTree(tree, root, removeActiveState, keepId)</h4>
<h4>copyNodeTree(tree, root, removeActiveState, removeId)</h4>
<ul>
<li>
<p><code>removeActiveState</code><code>Boolean</code>默认为<code>false</code>是否移除节点的激活状态</p>
</li>
<li>
<p><code>keepId</code>v0.4.6+<code>Boolean</code>默认为<code>false</code>是否保留被复制节点的<code>id</code>默认会删除<code>id</code>防止节点<code>id</code>重复但是对于移动节点的场景节点原<code>id</code>需要保留</p>
<p><code>removeId</code>v0.7.3-fix.1+是否移除节点数据中的uid默认为<code>true</code></p>
</li>
</ul>
<blockquote>
<ul>
<li><code>keepId</code> 原第四个参数<code>Boolean</code>默认为<code>false</code>是否保留被复制节点的<code>id</code>默认会删除<code>id</code>防止节点<code>id</code>重复但是对于移动节点的场景节点原<code>id</code>需要保留</li>
</ul>
</blockquote>
<p>复制节点树数据主要是剔除其中的引用<code>node</code>实例的<code>_node</code>然后复制<code>data</code>对象的数据示例</p>
<pre class="hljs"><code>copyNodeTree({}, node)
</code></pre>
@@ -217,12 +222,17 @@
</li>
</ul>
<p>给指定的节点列表树数据添加附加数据会修改原数据</p>
<h4>createUidForAppointNodes(appointNodes)</h4>
<h4>createUidForAppointNodes(appointNodes, createNewId)</h4>
<blockquote>
<p>v0.7.2+</p>
</blockquote>
<ul>
<li><code>appointNodes</code>节点实例列表数组类型</li>
<li>
<p><code>appointNodes</code>节点实例列表数组类型</p>
</li>
<li>
<p><code>createNewId</code>v0.7.3-fix.1+<code>Boolean</code>默认为<code>false</code>即如果节点不存在<code>uid</code>的话会创建新的<code>uid</code>如果传<code>true</code>那么无论节点数据原来是否存在<code>uid</code>都会创建新的<code>uid</code></p>
</li>
</ul>
<p>给指定的节点列表树数据添加uid如果uid不存在的话会修改原数据</p>
<h4>getNodeIndex(node)</h4>

View File

@@ -13,7 +13,14 @@
placeholder="http://xxxx.com/"
@keyup.native.stop
@keydown.native.stop
></el-input>
@blur="handleUrl()"
>
<el-select v-model="protocol" slot="prepend" style="width: 80px;">
<el-option label="https" value="https"></el-option>
<el-option label="http" value="http"></el-option>
<el-option label="无" value="none"></el-option>
</el-select>
</el-input>
</div>
<div class="item">
<span class="name">{{ $t('nodeHyperlink.name') }}</span>
@@ -46,7 +53,8 @@ export default {
dialogVisible: false,
link: '',
linkTitle: '',
activeNodes: []
activeNodes: [],
protocol: 'https'
}
},
created() {
@@ -63,6 +71,7 @@ export default {
if (this.activeNodes.length > 0) {
let firstNode = this.activeNodes[0]
this.link = firstNode.getData('hyperlink')
this.handleUrl(true)
this.linkTitle = firstNode.getData('hyperlinkTitle')
} else {
this.link = ''
@@ -70,6 +79,22 @@ export default {
}
},
removeProtocol(url) {
return url.replace(/^https?:\/\//, '')
},
handleUrl(setProtocolNoneIfNotExist) {
const res = this.link.match(/^(https?):\/\//)
if (res && res[1]) {
this.protocol = res[1]
} else if (!this.link) {
this.protocol = 'https'
} else if (setProtocolNoneIfNotExist) {
this.protocol = 'none'
}
this.link = this.removeProtocol(this.link)
},
handleShowNodeLink() {
this.activeNodes[0].mindMap.keyCommand.pause()
this.$bus.$emit('startTextEdit')
@@ -94,7 +119,10 @@ export default {
*/
confirm() {
this.activeNodes.forEach(node => {
node.setHyperlink(this.link, this.linkTitle)
node.setHyperlink(
(this.protocol === 'none' ? '' : this.protocol + '://') + this.link,
this.linkTitle
)
this.cancel()
})
}

View File

@@ -42,15 +42,15 @@ export default {
dataList: [
{
icon: 'iconstar',
value: 'Github star数量800+'
value: 'Github star数量1000+'
},
{
icon: 'iconfork',
value: 'Github fork数量150+'
value: 'Github fork数量200+'
},
{
icon: 'iconxiazai',
value: 'npm总下载次数15000+'
value: 'npm总下载次数20000+'
},
{
icon: 'iconteamwork',