Compare commits

...

3 Commits

Author SHA1 Message Date
71acd3814b no message 2025-05-14 17:07:28 +08:00
70dbe5b72b no message 2025-05-14 16:46:13 +08:00
43ea54e0a3 no message 2025-05-14 16:39:15 +08:00
7 changed files with 597 additions and 561 deletions

0
.editorconfig Normal file
View File

0
.prettierrc Normal file
View File

24
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,24 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": null,
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.tabSize": 2,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.fixAll.eslint": true
}
}

View File

@ -1,325 +1,338 @@
export default MindMap;
import { MiniMap } from './src/plugins/MiniMap'
export default MindMap
declare class MindMap {
/**
*
* @param {defaultOpt} opt
*/
constructor(opt?:{
el?:any;
data?:any;
viewData?:any;
readonly?:boolean;
layout?:string;
fishboneDeg?:number;
theme?:string;
themeConfig?:{};
scaleRatio?:number;
translateRatio?:number;
minZoomRatio?:number;
maxZoomRatio?:number;
customCheckIsTouchPad?:any;
mouseScaleCenterUseMousePosition?:boolean;
maxTag?:number;
expandBtnSize?:number;
imgTextMargin?:number;
textContentMargin?:number;
customNoteContentShow?:any;
textAutoWrapWidth?:number;
customHandleMousewheel?:any;
mousewheelAction?:string;
mousewheelMoveStep?:number;
mousewheelZoomActionReverse?:boolean;
defaultInsertSecondLevelNodeText?:string;
defaultInsertBelowSecondLevelNodeText?:string;
expandBtnStyle?:{
color?:string;
fill?:string;
fontSize?:number;
strokeColor?:string;
};
expandBtnIcon?:{
open?:string;
close?:string;
};
expandBtnNumHandler?:any;
isShowExpandNum?:boolean;
enableShortcutOnlyWhenMouseInSvg?:boolean;
customCheckEnableShortcut?:any;
initRootNodePosition?:any;
nodeTextEditZIndex?:number;
nodeNoteTooltipZIndex?:number;
isEndNodeTextEditOnClickOuter?:boolean;
maxHistoryCount?:number;
alwaysShowExpandBtn?:boolean;
notShowExpandBtn?:boolean;
iconList?:any[];
maxNodeCacheCount?:number;
fitPadding?:number;
enableCtrlKeyNodeSelection?:boolean;
useLeftKeySelectionRightKeyDrag?:boolean;
beforeTextEdit?:any;
isUseCustomNodeContent?:boolean;
customCreateNodeContent?:any;
customInnerElsAppendTo?:any;
enableAutoEnterTextEditWhenKeydown?:boolean;
autoEmptyTextWhenKeydownEnterEdit?:boolean;
customHandleClipboardText?:any;
disableMouseWheelZoom?:boolean;
errorHandler?:(code?:any, error?:any) => void;
enableDblclickBackToRootNode?:boolean;
hoverRectColor?:string;
hoverRectPadding?:number;
selectTextOnEnterEditText?:boolean;
deleteNodeActive?:boolean;
fit?:boolean;
tagsColorMap?:{};
cooperateStyle?:{
avatarSize?:number;
fontSize?:number;
};
onlyOneEnableActiveNodeOnCooperate?:boolean;
defaultGeneralizationText?:string;
handleIsSplitByWrapOnPasteCreateNewNode?:any;
addHistoryTime?:number;
isDisableDrag?:boolean;
createNewNodeBehavior?:string;
defaultNodeImage?:string;
isLimitMindMapInCanvas?:boolean;
handleNodePasteImg?:any;
customCreateNodePath?:any;
customCreateNodePolygon?:any;
customTransformNodeLinePath?:any;
beforeShortcutRun?:any;
resetScaleOnMoveNodeToCenter?:boolean;
createNodePrefixContent?:any;
createNodePostfixContent?:any;
disabledClipboard?:boolean;
customHyperlinkJump?:any;
openPerformance?:boolean;
performanceConfig?:{
time?:number;
padding?:number;
removeNodeWhenOutCanvas?:boolean;
};
emptyTextMeasureHeightText?:string;
openRealtimeRenderOnNodeTextEdit?:boolean;
mousedownEventPreventDefault?:boolean;
onlyPasteTextWhenHasImgAndText?:boolean;
enableDragModifyNodeWidth?:boolean;
minNodeTextModifyWidth?:number;
maxNodeTextModifyWidth?:number;
customHandleLine?:any;
addHistoryOnInit?:boolean;
noteIcon?:{
icon?:string;
style?:{};
};
hyperlinkIcon?:{
icon?:string;
style?:{};
};
attachmentIcon?:{
icon?:string;
style?:{};
};
isShowCreateChildBtnIcon?:boolean;
quickCreateChildBtnIcon?:{
icon?:string;
style?:{};
};
customQuickCreateChildBtnClick?:any;
addCustomContentToNode?:any;
enableInheritAncestorLineStyle?:boolean;
selectTranslateStep?:number;
selectTranslateLimit?:number;
enableFreeDrag?:boolean;
autoMoveWhenMouseInEdgeOnDrag?:boolean;
dragMultiNodeRectConfig?:{
width?:number;
height?:number;
fill?:string;
};
dragPlaceholderRectFill?:string;
dragPlaceholderLineConfig?:{
color?:string;
width?:number;
};
dragOpacityConfig?:{
cloneNodeOpacity?:number;
beingDragNodeOpacity?:number;
};
handleDragCloneNode?:any;
beforeDragEnd?:any;
beforeDragStart?:any;
watermarkConfig?:{
onlyExport?:boolean;
text?:string;
lineSpacing?:number;
textSpacing?:number;
angle?:number;
textStyle?:{
color?:string;
opacity?:number;
fontSize?:number;
};
belowNode?:boolean;
};
exportPaddingX?:number;
exportPaddingY?:number;
resetCss?:string;
minExportImgCanvasScale?:number;
addContentToHeader?:any;
addContentToFooter?:any;
handleBeingExportSvg?:any;
maxCanvasSize?:number;
defaultAssociativeLineText?:string;
associativeLineIsAlwaysAboveNode?:boolean;
associativeLineInitPointsPosition?:{
from?:string;
to?:string;
};
enableAdjustAssociativeLinePoints?:boolean;
beforeAssociativeLineConnection?:any;
disableTouchZoom?:boolean;
minTouchZoomScale?:number;
maxTouchZoomScale?:number;
isLimitMindMapInCanvasWhenHasScrollbar?:boolean;
isOnlySearchCurrentRenderNodes?:boolean;
beforeCooperateUpdate?:any;
rainbowLinesConfig?:{
open?:boolean;
colorsList?:any[];
};
demonstrateConfig?:any;
enableEditFormulaInRichTextEdit?:boolean;
katexFontPath?:string;
getKatexOutputType?:any;
transformRichTextOnEnterEdit?:any;
beforeHideRichTextEdit?:any;
outerFramePaddingX?:number;
outerFramePaddingY?:number;
defaultOuterFrameText?:string;
onlyPainterNodeCustomStyles?:boolean;
beforeDeleteNodeImg?:any;
imgResizeBtnSize?:number;
minImgResizeWidth?:number;
minImgResizeHeight?:number;
maxImgResizeWidthInheritTheme?:boolean;
maxImgResizeWidth?:number;
maxImgResizeHeight?:number;
customDeleteBtnInnerHTML?:string;
customResizeBtnInnerHTML?:string;
});
opt?:any;
el?:any;
initWidth?:any;
initHeight?:any;
cssEl?:HTMLStyleElement;
cssTextMap?:{};
nodeInnerPrefixList?:any[];
nodeInnerPostfixList?:any[];
editNodeClassList?:any[];
extendShapeList?:any[];
event?:Event;
keyCommand?:KeyCommand;
command?:Command;
renderer?:Render;
view?:View;
batchExecution?:BatchExecution;
handleOpt(opt?:any):any;
handleData(data?:any):any;
initContainer():void;
associativeLineDraw?:any;
svg?:any;
draw?:any;
lineDraw?:any;
nodeDraw?:any;
otherDraw?:any;
clearDraw():void;
appendCss(key?:any, str?:any):void;
removeAppendCss(key?:any):void;
joinCss():string;
addCss():void;
removeCss():void;
checkEditNodeClassIndex(className?:any):number;
addEditNodeClass(className?:any):void;
deleteEditNodeClass(className?:any):void;
render(callback?:any, source?:string):void;
reRender(callback?:any, source?:string):void;
getElRectInfo():void;
elRect?:any;
width?:any;
height?:any;
resize():void;
on(event?:any, fn?:any):void;
emit(event?:any, ...args?:any[]):void;
off(event?:any, fn?:any):void;
initCache():void;
commonCaches?:{
measureCustomNodeContentSizeEl?:any;
measureRichtextNodeTextSizeEl?:any;
};
initTheme():void;
themeConfig?:any;
setTheme(theme?:any, notRender?:boolean):void;
getTheme():any;
setThemeConfig(config?:any, notRender?:boolean):void;
getCustomThemeConfig():any;
getThemeConfig(prop?:any):any;
getConfig(prop?:any):any;
updateConfig(opt?:{}):void;
getLayout():any;
setLayout(layout?:any, notRender?:boolean):void;
execCommand(...args?:any[]):void;
updateData(data?:any):void;
setData(data?:any):void;
setFullData(data?:any):void;
getData(withConfig?:any):any;
export(...args?:any[]):Promise<any>;
toPos(x?:any, y?:any):{
x?:number;
y?:number;
};
setMode(mode?:any):void;
getSvgData({ paddingX, paddingY, ignoreWatermark, addContentToHeader, addContentToFooter, node }?:{
paddingX?:number;
paddingY?:number;
ignoreWatermark?:boolean;
}):{
svg?:any;
svgHTML?:any;
clipData?:any;
rect?:any;
origWidth?:any;
origHeight?:any;
scaleX?:any;
scaleY?:any;
};
addShape(shape?:any):void;
removeShape(name?:any):void;
getSvgObjects():{
SVG?:any;
G?:any;
Rect?:any;
};
addPlugin(plugin?:any, opt?:any):void;
removePlugin(plugin?:any):void;
initPlugin(plugin?:any):void;
destroy():void;
constructor(opt?: {
el?: any
data?: any
viewData?: any
readonly?: boolean
layout?: string
fishboneDeg?: number
theme?: string
themeConfig?: {}
scaleRatio?: number
translateRatio?: number
minZoomRatio?: number
maxZoomRatio?: number
customCheckIsTouchPad?: any
mouseScaleCenterUseMousePosition?: boolean
maxTag?: number
expandBtnSize?: number
imgTextMargin?: number
textContentMargin?: number
customNoteContentShow?: any
textAutoWrapWidth?: number
customHandleMousewheel?: any
mousewheelAction?: string
mousewheelMoveStep?: number
mousewheelZoomActionReverse?: boolean
defaultInsertSecondLevelNodeText?: string
defaultInsertBelowSecondLevelNodeText?: string
expandBtnStyle?: {
color?: string
fill?: string
fontSize?: number
strokeColor?: string
}
expandBtnIcon?: {
open?: string
close?: string
}
expandBtnNumHandler?: any
isShowExpandNum?: boolean
enableShortcutOnlyWhenMouseInSvg?: boolean
customCheckEnableShortcut?: any
initRootNodePosition?: any
nodeTextEditZIndex?: number
nodeNoteTooltipZIndex?: number
isEndNodeTextEditOnClickOuter?: boolean
maxHistoryCount?: number
alwaysShowExpandBtn?: boolean
notShowExpandBtn?: boolean
iconList?: any[]
maxNodeCacheCount?: number
fitPadding?: number
enableCtrlKeyNodeSelection?: boolean
useLeftKeySelectionRightKeyDrag?: boolean
beforeTextEdit?: any
isUseCustomNodeContent?: boolean
customCreateNodeContent?: any
customInnerElsAppendTo?: any
enableAutoEnterTextEditWhenKeydown?: boolean
autoEmptyTextWhenKeydownEnterEdit?: boolean
customHandleClipboardText?: any
disableMouseWheelZoom?: boolean
errorHandler?: (code?: any, error?: any) => void
enableDblclickBackToRootNode?: boolean
hoverRectColor?: string
hoverRectPadding?: number
selectTextOnEnterEditText?: boolean
deleteNodeActive?: boolean
fit?: boolean
tagsColorMap?: {}
cooperateStyle?: {
avatarSize?: number
fontSize?: number
}
onlyOneEnableActiveNodeOnCooperate?: boolean
defaultGeneralizationText?: string
handleIsSplitByWrapOnPasteCreateNewNode?: any
addHistoryTime?: number
isDisableDrag?: boolean
createNewNodeBehavior?: string
defaultNodeImage?: string
isLimitMindMapInCanvas?: boolean
handleNodePasteImg?: any
customCreateNodePath?: any
customCreateNodePolygon?: any
customTransformNodeLinePath?: any
beforeShortcutRun?: any
resetScaleOnMoveNodeToCenter?: boolean
createNodePrefixContent?: any
createNodePostfixContent?: any
disabledClipboard?: boolean
customHyperlinkJump?: any
openPerformance?: boolean
performanceConfig?: {
time?: number
padding?: number
removeNodeWhenOutCanvas?: boolean
}
emptyTextMeasureHeightText?: string
openRealtimeRenderOnNodeTextEdit?: boolean
mousedownEventPreventDefault?: boolean
onlyPasteTextWhenHasImgAndText?: boolean
enableDragModifyNodeWidth?: boolean
minNodeTextModifyWidth?: number
maxNodeTextModifyWidth?: number
customHandleLine?: any
addHistoryOnInit?: boolean
noteIcon?: {
icon?: string
style?: {}
}
hyperlinkIcon?: {
icon?: string
style?: {}
}
attachmentIcon?: {
icon?: string
style?: {}
}
isShowCreateChildBtnIcon?: boolean
quickCreateChildBtnIcon?: {
icon?: string
style?: {}
}
customQuickCreateChildBtnClick?: any
addCustomContentToNode?: any
enableInheritAncestorLineStyle?: boolean
selectTranslateStep?: number
selectTranslateLimit?: number
enableFreeDrag?: boolean
autoMoveWhenMouseInEdgeOnDrag?: boolean
dragMultiNodeRectConfig?: {
width?: number
height?: number
fill?: string
}
dragPlaceholderRectFill?: string
dragPlaceholderLineConfig?: {
color?: string
width?: number
}
dragOpacityConfig?: {
cloneNodeOpacity?: number
beingDragNodeOpacity?: number
}
handleDragCloneNode?: any
beforeDragEnd?: any
beforeDragStart?: any
watermarkConfig?: {
onlyExport?: boolean
text?: string
lineSpacing?: number
textSpacing?: number
angle?: number
textStyle?: {
color?: string
opacity?: number
fontSize?: number
}
belowNode?: boolean
}
exportPaddingX?: number
exportPaddingY?: number
resetCss?: string
minExportImgCanvasScale?: number
addContentToHeader?: any
addContentToFooter?: any
handleBeingExportSvg?: any
maxCanvasSize?: number
defaultAssociativeLineText?: string
associativeLineIsAlwaysAboveNode?: boolean
associativeLineInitPointsPosition?: {
from?: string
to?: string
}
enableAdjustAssociativeLinePoints?: boolean
beforeAssociativeLineConnection?: any
disableTouchZoom?: boolean
minTouchZoomScale?: number
maxTouchZoomScale?: number
isLimitMindMapInCanvasWhenHasScrollbar?: boolean
isOnlySearchCurrentRenderNodes?: boolean
beforeCooperateUpdate?: any
rainbowLinesConfig?: {
open?: boolean
colorsList?: any[]
}
demonstrateConfig?: any
enableEditFormulaInRichTextEdit?: boolean
katexFontPath?: string
getKatexOutputType?: any
transformRichTextOnEnterEdit?: any
beforeHideRichTextEdit?: any
outerFramePaddingX?: number
outerFramePaddingY?: number
defaultOuterFrameText?: string
onlyPainterNodeCustomStyles?: boolean
beforeDeleteNodeImg?: any
imgResizeBtnSize?: number
minImgResizeWidth?: number
minImgResizeHeight?: number
maxImgResizeWidthInheritTheme?: boolean
maxImgResizeWidth?: number
maxImgResizeHeight?: number
customDeleteBtnInnerHTML?: string
customResizeBtnInnerHTML?: string
})
opt?: any
el?: any
initWidth?: any
initHeight?: any
cssEl?: HTMLStyleElement
cssTextMap?: {}
nodeInnerPrefixList?: any[]
nodeInnerPostfixList?: any[]
editNodeClassList?: any[]
extendShapeList?: any[]
event?: Event
keyCommand?: KeyCommand
command?: Command
renderer?: Render
view?: View
batchExecution?: BatchExecution
handleOpt(opt?: any): any
handleData(data?: any): any
initContainer(): void
associativeLineDraw?: any
svg?: any
draw?: any
lineDraw?: any
nodeDraw?: any
otherDraw?: any
clearDraw(): void
appendCss(key?: any, str?: any): void
removeAppendCss(key?: any): void
joinCss(): string
addCss(): void
removeCss(): void
checkEditNodeClassIndex(className?: any): number
addEditNodeClass(className?: any): void
deleteEditNodeClass(className?: any): void
render(callback?: any, source?: string): void
reRender(callback?: any, source?: string): void
getElRectInfo(): void
elRect?: any
width?: any
height?: any
resize(): void
on(event?: any, fn?: any): void
emit(event?: any, ...args: any[]): void
off(event?: any, fn?: any): void
initCache(): void
commonCaches?: {
measureCustomNodeContentSizeEl?: any
measureRichtextNodeTextSizeEl?: any
}
initTheme(): void
themeConfig?: any
setTheme(theme?: any, notRender?: boolean): void
getTheme(): any
setThemeConfig(config?: any, notRender?: boolean): void
getCustomThemeConfig(): any
getThemeConfig(prop?: any): any
getConfig(prop?: any): any
updateConfig(opt?: {}): void
getLayout(): any
setLayout(layout?: any, notRender?: boolean): void
execCommand(...args: any[]): void
updateData(data?: any): void
setData(data?: any): void
setFullData(data?: any): void
getData(withConfig?: any): any
export(...args: any[]): Promise<any>
toPos(
x?: any,
y?: any
): {
x?: number
y?: number
}
setMode(mode?: any): void
getSvgData({
paddingX,
paddingY,
ignoreWatermark,
addContentToHeader,
addContentToFooter,
node
}?: {
paddingX?: number
paddingY?: number
ignoreWatermark?: boolean
}): {
svg?: any
svgHTML?: any
clipData?: any
rect?: any
origWidth?: any
origHeight?: any
scaleX?: any
scaleY?: any
}
addShape(shape?: any): void
removeShape(name?: any): void
getSvgObjects(): {
SVG?: any
G?: any
Rect?: any
}
addPlugin(plugin?: any, opt?: any): void
removePlugin(plugin?: any): void
initPlugin(plugin?: any): void
destroy(): void
miniMap?: MiniMap
}
declare namespace MindMap {
function extendNodeDataNoStylePropList(list?:any[]):void;
function resetNodeDataNoStylePropList():void;
let pluginList:any[];
function usePlugin(plugin?:any, opt?:{}):typeof MindMap;
function hasPlugin(plugin?:any):number;
let instanceCount:number;
function defineTheme(name?:any, config?:{}):Error;
function removeTheme(name?:any):void;
function extendNodeDataNoStylePropList(list?: any[]): void
function resetNodeDataNoStylePropList(): void
let pluginList: any[]
function usePlugin(plugin?: any, opt?: {}): typeof MindMap
function hasPlugin(plugin?: any): number
let instanceCount: number
function defineTheme(name?: any, config?: {}): Error
function removeTheme(name?: any): void
}
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

@ -148,6 +148,15 @@ export default {
getImgUrl(img => {
this.mindMapImg = img
})
console.log('viewBoxStyle', {
getImgUrl,
viewBoxStyle,
miniMapBoxScale,
miniMapBoxLeft,
miniMapBoxTop
})
this.viewBoxStyle = viewBoxStyle
this.svgBoxScale = miniMapBoxScale
this.svgBoxLeft = miniMapBoxLeft

View File

@ -1,3 +1,225 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick, Ref } from "vue";
import { useMindMapStore } from "../index";
import { storeToRefs } from "pinia";
import { debounce } from "simple-mind-map/src/utils";
const mindMapStore = useMindMapStore();
const { getMindMapInstance } = mindMapStore;
const { isDark, showMiniMap } = storeToRefs(mindMapStore);
const debouncedDrawMiniMap = debounce(
() => {
drawMiniMap();
},
500,
null
);
// 使
const debouncedSetSize = debounce(
() => {
width.value = Math.min(window.innerWidth - 80, 370);
nextTick(() => {
if (showMiniMap.value && navigatorBoxRef.value) {
drawMiniMap();
}
});
},
300,
null
);
const svgBoxScale = ref(1);
const svgBoxLeft = ref(0);
const svgBoxTop = ref(0);
const viewBoxStyle = ref({
left: "0px",
top: "0px",
bottom: "0px",
right: "0px",
});
const mindMapImg = ref("");
const width = ref(0);
const withTransition = ref(true);
const navigatorBoxRef: Ref<HTMLElement | null> = ref(null);
const svgBoxRef = ref(null);
async function init() {
await nextTick();
const mindMapInstance = getMindMapInstance();
// mini_map_view_box_position_change
mindMapInstance?.on(
"mini_map_view_box_position_change",
(e: { left: string; right: string; top: string; bottom: string }) => {
onViewBoxPositionChange(e);
}
);
// view_data_change
mindMapInstance?.on("view_data_change", dataChange);
//node_tree_render_end
mindMapInstance?.on("node_tree_render_end", dataChange);
// toggle_mini_map
mindMapInstance?.on("toggle_mini_map", (show: boolean) => {
showMiniMap.value = show;
});
// data_change
mindMapInstance?.on("data_change", dataChange);
}
function drawMiniMap() {
const mindMapInstance = getMindMapInstance();
if (!mindMapInstance || !mindMapInstance?.miniMap) return;
if (!navigatorBoxRef.value) return;
const rect = navigatorBoxRef.value.getBoundingClientRect();
const calculationResult = mindMapInstance?.miniMap?.calculationMiniMap(
rect.width,
rect.height
);
if (!calculationResult) return;
const {
getImgUrl,
viewBoxStyle: __viewBoxStyle,
miniMapBoxScale,
miniMapBoxLeft,
miniMapBoxTop,
} = calculationResult;
getImgUrl &&
getImgUrl((img: string) => {
mindMapImg.value = img;
});
viewBoxStyle.value = __viewBoxStyle;
svgBoxScale.value = miniMapBoxScale;
svgBoxLeft.value = miniMapBoxLeft;
svgBoxTop.value = miniMapBoxTop;
}
function dataChange() {
if (!showMiniMap.value) return;
debouncedDrawMiniMap();
}
function setSize() {
debouncedSetSize();
}
function onMousedown(e: MouseEvent) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance?.miniMap &&
typeof mindMapInstance?.miniMap?.onMousedown === "function"
) {
mindMapInstance?.miniMap?.onMousedown(e);
}
}
function onMousemove(e: MouseEvent) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance?.miniMap &&
typeof mindMapInstance?.miniMap?.onMousemove === "function"
) {
mindMapInstance?.miniMap?.onMousemove(e);
}
}
function onMouseup(e: MouseEvent) {
if (!withTransition.value) withTransition.value = true;
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance?.miniMap &&
typeof mindMapInstance?.miniMap?.onMouseup === "function"
) {
mindMapInstance?.miniMap?.onMouseup(e);
}
}
function onViewBoxMousedown(e: MouseEvent) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance?.miniMap &&
typeof mindMapInstance?.miniMap?.onViewBoxMousedown === "function"
) {
mindMapInstance?.miniMap?.onViewBoxMousedown(e);
}
}
function onViewBoxMousemove(e: MouseEvent) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance?.miniMap &&
typeof mindMapInstance?.miniMap?.onViewBoxMousemove === "function"
) {
mindMapInstance?.miniMap?.onViewBoxMousemove(e);
}
}
function onViewBoxPositionChange({
left,
right,
top,
bottom,
}: {
left: string;
right: string;
top: string;
bottom: string;
}) {
withTransition.value = false;
viewBoxStyle.value.left = left;
viewBoxStyle.value.right = right;
viewBoxStyle.value.top = top;
viewBoxStyle.value.bottom = bottom;
}
onMounted(async () => {
await init();
setSize();
window.addEventListener("resize", setSize);
window.addEventListener("mouseup", onMouseup);
});
onUnmounted(() => {
window.removeEventListener("resize", setSize);
window.removeEventListener("mouseup", onMouseup);
const mindMapInstance = getMindMapInstance();
if (mindMapInstance && typeof mindMapInstance?.off === "function") {
mindMapInstance?.off("data_change", dataChange);
mindMapInstance?.off(
"mini_map_view_box_position_change",
onViewBoxPositionChange
);
}
});
</script>
<template>
<div
v-if="showMiniMap"
@ -8,9 +230,9 @@
@mousedown="onMousedown"
@mousemove="onMousemove"
>
<span>svgBoxScale:{{ svgBoxScale }}</span>
<!-- <span>svgBoxScale:{{ svgBoxScale }}</span>
<span>svgBoxLeft:{{ svgBoxLeft }}</span>
<span>svgBoxTop:{{ svgBoxTop }}</span>
<span>svgBoxTop:{{ svgBoxTop }}</span> -->
<div
class="svgBox"
ref="svgBoxRef"
@ -32,239 +254,11 @@
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, computed, nextTick, watch } from "vue";
import { useMindMapStore } from "../index";
import { storeToRefs } from "pinia";
import { throttle, debounce } from 'simple-mind-map/src/utils';
const mindMapStore = useMindMapStore();
const { getMindMapInstance } = mindMapStore;
const { isDark, showMiniMap } = storeToRefs(mindMapStore);
// 使
const debouncedDrawMiniMap = debounce(() => {
drawMiniMap();
}, 500);
// 使
const debouncedSetSize = debounce(() => {
width.value = Math.min(window.innerWidth - 80, 370);
nextTick(() => {
if (showMiniMap.value && navigatorBoxRef.value) {
init();
drawMiniMap();
}
});
}, 300);
const boxWidth = ref(0);
const boxHeight = ref(0);
const svgBoxScale = ref(1);
const svgBoxLeft = ref(0);
const svgBoxTop = ref(0);
const viewBoxStyle = ref({
left: "0px", //
top: "0px",
bottom: "0px",
right: "0px",
});
const mindMapImg = ref("");
const width = ref(0);
const withTransition = ref(true);
const navigatorBoxRef = ref(null);
const svgBoxRef = ref(null);
async function init() {
if (!navigatorBoxRef.value) return;
const rect = navigatorBoxRef.value.getBoundingClientRect();
// console.log("rect", rect);
boxWidth.value = rect.width;
boxHeight.value = rect.height;
await nextTick();
const mindMapInstance = getMindMapInstance();
// data_change
mindMapInstance.on("data_change", data_change);
// mini_map_view_box_position_change
mindMapInstance.on("mini_map_view_box_position_change", (e) => {
onViewBoxPositionChange(e);
});
// view_data_change
mindMapInstance.on("view_data_change", data_change);
//node_tree_render_end
mindMapInstance.on("node_tree_render_end", data_change);
// data_change
mindMapInstance.on("data_change", data_change);
// toggle_mini_map
mindMapInstance.on("toggle_mini_map", (show) => {
showMiniMap.value = show;
});
}
function drawMiniMap() {
const mindMapInstance = getMindMapInstance();
if (
!mindMapInstance ||
!mindMapInstance.miniMap ||
!boxWidth.value ||
!boxHeight.value
)
return;
const calculationResult = mindMapInstance.miniMap.calculationMiniMap(
boxWidth.value,
boxHeight.value
);
if (!calculationResult) return;
const {
getImgUrl,
viewBoxStyle: newViewBoxStyle,
miniMapBoxScale,
miniMapBoxLeft,
miniMapBoxTop,
} = calculationResult;
getImgUrl &&
getImgUrl((img) => {
mindMapImg.value = img;
});
viewBoxStyle.value = newViewBoxStyle;
svgBoxScale.value = miniMapBoxScale;
svgBoxLeft.value = miniMapBoxLeft;
svgBoxTop.value = miniMapBoxTop;
}
watch(
() => showMiniMap.value,
(isShown) => {
if (!isShown) return;
nextTick(() => {
navigatorBoxRef.value && init();
svgBoxRef.value && drawMiniMap();
});
},
{ immediate: true }
);
function data_change() {
if (!showMiniMap.value) return;
debouncedDrawMiniMap();
}
function setSize() {
debouncedSetSize();
}
function onMousedown(e) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance.miniMap &&
typeof mindMapInstance.miniMap.onMousedown === "function"
) {
mindMapInstance.miniMap.onMousedown(e);
}
}
function onMousemove(e) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance.miniMap &&
typeof mindMapInstance.miniMap.onMousemove === "function"
) {
mindMapInstance.miniMap.onMousemove(e);
}
}
function onMouseup(e) {
if (!withTransition.value) withTransition.value = true;
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance.miniMap &&
typeof mindMapInstance.miniMap.onMouseup === "function"
) {
mindMapInstance.miniMap.onMouseup(e);
}
}
function onViewBoxMousedown(e) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance.miniMap &&
typeof mindMapInstance.miniMap.onViewBoxMousedown === "function"
) {
mindMapInstance.miniMap.onViewBoxMousedown(e);
}
}
function onViewBoxMousemove(e) {
const mindMapInstance = getMindMapInstance();
if (
mindMapInstance &&
mindMapInstance.miniMap &&
typeof mindMapInstance.miniMap.onViewBoxMousemove === "function"
) {
mindMapInstance.miniMap.onViewBoxMousemove(e);
}
}
function onViewBoxPositionChange({ left, right, top, bottom }) {
withTransition.value = false;
viewBoxStyle.value.left = left;
viewBoxStyle.value.right = right;
viewBoxStyle.value.top = top;
viewBoxStyle.value.bottom = bottom;
}
onMounted(() => {
setSize();
window.addEventListener("resize", setSize);
window.addEventListener("mouseup", onMouseup);
});
onUnmounted(() => {
window.removeEventListener("resize", setSize);
window.removeEventListener("mouseup", onMouseup);
const mindMapInstance = getMindMapInstance();
if (mindMapInstance && typeof mindMapInstance.off === "function") {
mindMapInstance.off("data_change", data_change);
mindMapInstance.off(
"mini_map_view_box_position_change",
onViewBoxPositionChange
);
}
debouncedDrawMiniMap.cancel && debouncedDrawMiniMap.cancel();
debouncedSetSize.cancel && debouncedSetSize.cancel();
});
</script>
<style lang="scss" scoped>
.navigatorBox * {
margin: 0;
padding: 0;
}
.navigatorBox {
position: absolute;
height: 220px;
@ -284,13 +278,12 @@ onUnmounted(() => {
.svgBox {
position: absolute;
left: 0;
top: 0;
transform-origin: left top;
}
.windowBox {
position: absolute;
border: 2px solid #ee4545;
border: 2px solid rgb(238, 69, 69);
background-color: rgba(238, 69, 69, 0.2);
&.withTransition {

View File

@ -31,14 +31,11 @@ import { layoutGroupList } from "../../store/helpers/layoutGroupList";
import { useMindMapStore } from "../../index";
import { storeToRefs } from "pinia";
// 使store
const store = useMindMapStore();
const { useLayout } = store;
const { currentLayout } = storeToRefs(store);
onMounted(() => {
});
onMounted(() => {});
</script>
<style scoped></style>