Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/vue3-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"echarts": "^5.5.1",
"element-plus": "^2.0.4",
"postcss": "^8.4.41",
"tailwindcss": "latest",
"tailwindcss": "^3.4.7",
"vue": "^3.4.21",
"vue-router": "^4.3.0"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/vue3-app/src/components/chart/linkChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default class LinkChart {
this.flowId = graphModel.flowId!
})
g.init()
this.lf.extension.miniMap.show()
// this.lf.extension.miniMap.show()

// this.lf.render()
}
Expand Down
208 changes: 113 additions & 95 deletions examples/vue3-app/src/views/LFChartView.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<div class="w-full h-full">
<el-button @click="handelMiniMap">显示小地图</el-button>
<el-button @click="handelMiniMap()">{{ showMiniMap ? '隐藏' : '显示' }}小地图</el-button>
<el-button @click="addNode">增加自定义节点</el-button>
<el-button @click="clearFlow">卸载画布</el-button>
<div ref="container" class="flow w-full h-full overflow-hidden" />
<TeleportContainer :flow-id="flowId" />
Expand All @@ -22,6 +23,7 @@ const props = defineProps<IProps>()
const TeleportContainer = getTeleport()
const container = ref()
const graphData = ref<IGraphData>()
const showMiniMap = ref(false)

const flowId = ref('')

Expand All @@ -41,16 +43,16 @@ onMounted(() => {
category: '分类123' + props.activeKey
}
},
{
id: 'node_id_2',
type: 'defaultNode',
x: 0,
y: 0,
properties: {
type: 'first',
url: 'http://www.test.com'
}
},
// {
// id: 'node_id_2',
// type: 'defaultNode',
// x: 0,
// y: 0,
// properties: {
// type: 'first',
// url: 'http://www.test.com'
// }
// },
{
id: 'node_id_3',
type: 'analysisNode',
Expand All @@ -61,90 +63,90 @@ onMounted(() => {
url: 'http://www.emei.vip/aaa.html',
category: '分类123'
}
},
{
id: 'node_id_4',
type: 'analysisNode',
x: 0,
y: 0,
properties: {
type: 'first',
url: 'http://365897.com/aaa.html',
category: '分类123'
}
},
{
id: 'node_id_5',
type: 'defaultNode',
x: 0,
y: 0,
properties: {
type: 'middle',
url: 'https://118037.com/1.html'
}
},
{
id: 'node_id_6',
type: 'defaultNode',
x: 0,
y: 0,
properties: {
type: 'middle',
url: 'https://www.emei.vip'
}
},
{
id: 'node_id_7',
type: 'defaultNode',
x: 0,
y: 0,
properties: {
type: 'middle',
url: 'https://bbbb.com'
}
},
{
id: 'node_id_8',
type: 'analysisNode',
x: 0,
y: 0,
properties: {
type: 'middle',
url: 'http://www.emei.vip/a.html',
category: '分类123'
}
},
{
id: 'node_id_9',
type: 'defaultNode',
x: 0,
y: 0,
properties: {
type: 'middle',
url: 'https://aaaa.com',
seq: 1
}
},
{
id: 'node_id_10',
type: 'defaultNode',
x: 0,
y: 0,
properties: {
type: 'landing',
url: 'https://bbbb.com'
}
},
{
id: 'node_id_11',
type: 'defaultNode',
x: 0,
y: 0,
properties: {
type: 'landing',
url: 'https://cccc.com'
}
}
// {
// id: 'node_id_4',
// type: 'analysisNode',
// x: 0,
// y: 0,
// properties: {
// type: 'first',
// url: 'http://365897.com/aaa.html',
// category: '分类123'
// }
// },
// {
// id: 'node_id_5',
// type: 'defaultNode',
// x: 0,
// y: 0,
// properties: {
// type: 'middle',
// url: 'https://118037.com/1.html'
// }
// },
// {
// id: 'node_id_6',
// type: 'defaultNode',
// x: 0,
// y: 0,
// properties: {
// type: 'middle',
// url: 'https://www.emei.vip'
// }
// },
// {
// id: 'node_id_7',
// type: 'defaultNode',
// x: 0,
// y: 0,
// properties: {
// type: 'middle',
// url: 'https://bbbb.com'
// }
// },
// {
// id: 'node_id_8',
// type: 'analysisNode',
// x: 0,
// y: 0,
// properties: {
// type: 'middle',
// url: 'http://www.emei.vip/a.html',
// category: '分类123'
// }
// },
// {
// id: 'node_id_9',
// type: 'defaultNode',
// x: 0,
// y: 0,
// properties: {
// type: 'middle',
// url: 'https://aaaa.com',
// seq: 1
// }
// },
// {
// id: 'node_id_10',
// type: 'defaultNode',
// x: 0,
// y: 0,
// properties: {
// type: 'landing',
// url: 'https://bbbb.com'
// }
// },
// {
// id: 'node_id_11',
// type: 'defaultNode',
// x: 0,
// y: 0,
// properties: {
// type: 'landing',
// url: 'https://cccc.com'
// }
// }
],
edges: [
{
Expand Down Expand Up @@ -215,8 +217,24 @@ onMounted(() => {
})
flowId.value = linkChart.flowId!
})
const addNode = () => {
linkChart.lf.addNode({
type: 'analysisNode',
x: 110,
y: 110,
properties: {
type: 'middle',
url: 'https://bbbb.com'
}
})
}
const handelMiniMap = () => {
linkChart.lf.extension.miniMap.show()
if (showMiniMap.value) {
linkChart.lf.extension.miniMap.hide()
} else {
linkChart.lf.extension.miniMap.show()
}
showMiniMap.value = !showMiniMap.value
}
const clearFlow = () => {
linkChart.destroy()
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/model/GraphModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ export class GraphModel {
this.animation = setupAnimation(animation)
this.overlapMode = options.overlapMode || OverlapMode.DEFAULT

this.isMiniMap = options.isMiniMap || false
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The isMiniMap property is not declared in the class definition before being used in the constructor. It should be declared as a class property with appropriate documentation explaining its purpose (e.g., "Indicates whether this graph instance is used in a MiniMap component").

Copilot uses AI. Check for mistakes.
this.width = options.width ?? this.rootEl.getBoundingClientRect().width
this.isContainerWidth = isNil(options.width)
this.height = options.height ?? this.rootEl.getBoundingClientRect().height
Expand Down
11 changes: 1 addition & 10 deletions packages/extension/src/components/mini-map/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import LogicFlow from '@logicflow/core'
import {
createTeleportContainer,
destroyTeleportContainer,
} from '@logicflow/vue-node-registry'

import Position = LogicFlow.Position
import MiniMapOption = MiniMap.MiniMapOption
Expand Down Expand Up @@ -240,8 +236,6 @@ export class MiniMap {
*/
public hide = () => {
if (this.isShow) {
// 隐藏小地图时摧毁实例
destroyTeleportContainer(this.lfMap.graphModel.flowId)
this.lf.off('graph:resize', this.onGraphResize)
this.lfMap.destroy()
// 保证重新创建实例时,小地图中内容偏移正确
Expand Down Expand Up @@ -363,14 +357,12 @@ export class MiniMap {
history: false,
snapline: false,
disabledPlugins: this.disabledPlugins,
isMiniMap: true,
})
// minimap中禁用adapter。
// this.lfMap.adapterIn = (a) => a
// this.lfMap.adapterOut = (a) => a

// 创建teleport容器(vue3中生效)
createTeleportContainer(miniMapWrap, this.lfMap.graphModel.flowId)

this.miniMapWrap = miniMapWrap
this.createViewPort()
miniMapWrap.addEventListener('click', this.mapClick)
Expand Down Expand Up @@ -687,7 +679,6 @@ export class MiniMap {
}

destroy() {
destroyTeleportContainer(this.lfMap.graphModel.flowId)
this.lf.off('graph:resize', this.onGraphResize)
}
}
Expand Down
27 changes: 26 additions & 1 deletion packages/vue-node-registry/src/teleport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {

let active = false
const appInstances = new Map<string, InstanceType<any>>()
const appNodesMap = new Map<string, any>() // 用于储存当前流程图节点id当节点都销毁时同时卸载vueApp实例
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing punctuation and spacing in Chinese comment. Should be "用于储存当前流程图节点id,当节点都销毁时同时卸载vueApp实例" (add comma after 'id').

Suggested change
const appNodesMap = new Map<string, any>() // 用于储存当前流程图节点id当节点都销毁时同时卸载vueApp实例
const appNodesMap = new Map<string, any>() // 用于储存当前流程图节点id,当节点都销毁时同时卸载vueApp实例

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Map is typed as Map<string, any> but based on usage it should be Map<string, string[]> since it stores arrays of node IDs. This makes the code more maintainable and provides better type safety.

Suggested change
const appNodesMap = new Map<string, any>() // 用于储存当前流程图节点id当节点都销毁时同时卸载vueApp实例
const appNodesMap = new Map<string, string[]>() // 用于储存当前流程图节点id当节点都销毁时同时卸载vueApp实例

Copilot uses AI. Check for mistakes.
const items = reactive<{ [key: string]: any }>({})

export function connect(
Expand All @@ -22,6 +23,9 @@ export function connect(
graph: GraphModel,
) {
if (active) {
if (graph.isMiniMap) {
createTeleportContainer(container, graph.flowId)
}
items[id] = markRaw(
defineComponent({
render: () =>
Expand All @@ -37,9 +41,21 @@ export function connect(
}
}

export function disconnect(id: string) {
export function disconnect(id: string, flowId: string) {
if (active) {
delete items[id]
if (appInstances.has(flowId)) {
const appNodeList = appNodesMap.get(flowId) || []
const index = appNodeList.indexOf(id)
if (index > -1) {
appNodeList.splice(index, 1)
if (appNodeList.length === 0) {
destroyTeleportContainer(flowId)
} else {
appNodesMap.set(flowId, appNodeList)
}
}
}
}
}

Expand Down Expand Up @@ -74,6 +90,13 @@ export function getTeleport(): any {
// 比如items[0]属于Page1的数据,那么Page2无论active=true/false,都无法执行items[0]

if (id.startsWith(props.flowId)) {
if (appInstances.has(props.flowId)) {
const appNodeList = appNodesMap.get(props.flowId) || []
if (!appNodeList.includes(id)) {
appNodeList.push(id)
appNodesMap.set(props.flowId, appNodeList)
}
}
children.push(items[id])
}
})
Expand Down Expand Up @@ -115,6 +138,7 @@ export function createTeleportContainer(
app.mount(mountPoint)

appInstances.set(flowId, app)
appNodesMap.set(flowId, [])
}
/**
* 卸载 Teleport 容器组件
Expand All @@ -126,5 +150,6 @@ export function destroyTeleportContainer(flowId: string | undefined): void {
if (app) {
app.unmount()
appInstances.delete(flowId)
appNodesMap.delete(flowId)
}
}
2 changes: 1 addition & 1 deletion packages/vue-node-registry/src/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export class VueNodeView extends HtmlNode {

unmount() {
if (isActive()) {
disconnect(this.targetId())
disconnect(this.targetId(), this.props.graphModel.flowId as string)
}
this.unmountVueComponent()
}
Expand Down
Loading