From f52d2e475a5e3ef6dc9512f971c626852e536589 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Mon, 19 Aug 2024 10:55:38 +0800
Subject: [PATCH 01/23] =?UTF-8?q?feat:windows=E4=B8=8B=E7=BC=96=E8=AF=91?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
examples/x6-example-features/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/x6-example-features/package.json b/examples/x6-example-features/package.json
index da862fa857..2bdac9c80b 100644
--- a/examples/x6-example-features/package.json
+++ b/examples/x6-example-features/package.json
@@ -3,7 +3,7 @@
"name": "@antv/x6-example-features",
"version": "2.1.1",
"scripts": {
- "start": "export NODE_OPTIONS=--openssl-legacy-provider && umi dev",
+ "start": "set NODE_OPTIONS=--openssl-legacy-provider && umi dev",
"build": "umi build",
"lint": "eslint 'src/**/*.{js,ts}?(x)' --fix"
},
From e4ed2d48f84520f06102cdc383e444f2e7259e9b Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Mon, 19 Aug 2024 10:57:15 +0800
Subject: [PATCH 02/23] =?UTF-8?q?bug:x6=E5=B0=8F=E5=9C=B0=E5=9B=BE?=
=?UTF-8?q?=E5=AE=9A=E4=BD=8D=E4=B8=8D=E5=87=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6-plugin-minimap/src/index.ts | 97 ++++++++++++++++++++++---
1 file changed, 86 insertions(+), 11 deletions(-)
diff --git a/packages/x6-plugin-minimap/src/index.ts b/packages/x6-plugin-minimap/src/index.ts
index 42a4167a80..e7cb12c79f 100644
--- a/packages/x6-plugin-minimap/src/index.ts
+++ b/packages/x6-plugin-minimap/src/index.ts
@@ -1,4 +1,4 @@
-import { FunctionExt, CssLoader, Dom, View, Graph, EventArgs } from '@antv/x6'
+import { FunctionExt, CssLoader, Dom, View, Graph, EventArgs } from '../../x6/src/index'
import { content } from './style/raw'
export class MiniMap extends View implements Graph.Plugin {
@@ -108,6 +108,7 @@ export class MiniMap extends View implements Graph.Plugin {
this.sourceGraph.on('model:updated', this.onModelUpdated, this)
}
this.sourceGraph.on('resize', this.updatePaper, this)
+ // 当前container委托mousedown、touchstart事件到startAction事件;只有小地图容器被点击,才开始在startAction中监听mousemove等拖拽事件
this.delegateEvents({
mousedown: 'startAction',
touchstart: 'startAction',
@@ -140,12 +141,17 @@ export class MiniMap extends View implements Graph.Plugin {
}
protected onModelUpdated() {
+ // 模型每次更新,都调用小地图的targetGraph 缩放到合适位置
this.targetGraph.zoomToFit()
}
protected updatePaper(width: number, height: number): this
protected updatePaper({ width, height }: EventArgs['resize']): this
protected updatePaper(w: number | EventArgs['resize'], h?: number) {
+ // Graph 中指定的是viewPort 视口宽高,contentArea会根据内容撑开
+ // MiniMap option中的宽高也是指定的 viewPort 视口宽高
+ // 置于为什么contentArea 比viewPortArea小,并且全部显示了;还能拖拽移动,是svg的transform: matrix的作用
+
let width: number
let height: number
if (typeof w === 'object') {
@@ -156,14 +162,18 @@ export class MiniMap extends View implements Graph.Plugin {
height = h as number
}
+ // ratio:宽高比、scale:缩放比
+
const origin = this.sourceGraph.options
const scale = this.sourceGraph.transform.getScale()
+ // 小地图的最大宽高 = 宽高 - 2 * padding
const maxWidth = this.options.width - 2 * this.options.padding
const maxHeight = this.options.height - 2 * this.options.padding
-
+ // 主视图的实际宽高 = 宽高 / 缩放比
width /= scale.sx // eslint-disable-line
height /= scale.sy // eslint-disable-line
+ // 小地图宽|高比 = min(小地图viewArea宽/主视图viewArea宽, 小地图viewArea高/主地图viewArea高)
this.ratio = Math.min(maxWidth / width, maxHeight / height)
const ratio = this.ratio
@@ -172,20 +182,26 @@ export class MiniMap extends View implements Graph.Plugin {
width *= ratio // eslint-disable-line
height *= ratio // eslint-disable-line
+ // 小地图图形实际宽高 = 主视图宽高 * 小地图宽|高比
this.targetGraph.resize(width, height)
this.targetGraph.translate(x, y)
if (this.scroller) {
+ // 有Scroller插件,直接使用宽高比作为缩放比
this.targetGraph.scale(ratio, ratio)
} else {
+ // 没有使用Scroller插件,自适应缩放;并且计算小地图的缩放比
this.targetGraph.zoomToFit()
}
this.updateViewport()
return this
}
-
+ // 更新小地图视口的框选区域
protected updateViewport() {
+
+
+ // 缩放比例
const sourceGraphScale = this.sourceGraph.transform.getScale()
const targetGraphScale = this.targetGraph.transform.getScale()
@@ -197,12 +213,21 @@ export class MiniMap extends View implements Graph.Plugin {
}
const position = Dom.position(this.targetGraph.container)
+
const translation = this.targetGraph.translate()
translation.ty = translation.ty || 0
+
+ // 小地图框选div(整体区域)位置
this.geometry = {
+ // viewPort元素本身的top/left(不变) + 大窗口x.y位置 * 小地图缩放比例 + 小地图matrix矩阵偏移 x.y(不变)
top: position.top + origin.y * targetGraphScale.sy + translation.ty,
left: position.left + origin.x * targetGraphScale.sx + translation.tx,
+ // 小地图区域宽度 = 大窗口宽度 * 小地图缩放比例 / 大窗口缩放比例
+ // 依据公式:小地图区域宽度 / 小地图缩放比例 = 大窗口宽度 / 大窗口缩放比例
+ // 小地图缩放比例越小,小地图区域宽度也就越小
+
+ // 缩放比 = 视口宽高 / 画布内容区域宽高
width:
(this.graphContainer.clientWidth! * targetGraphScale.sx) /
sourceGraphScale.sx,
@@ -215,8 +240,10 @@ export class MiniMap extends View implements Graph.Plugin {
protected startAction(evt: Dom.MouseDownEvent) {
const e = this.normalizeEvent(evt)
+ // 缩放还是平移
const action = e.target === this.zoomHandle ? 'zooming' : 'panning'
const { tx, ty } = this.sourceGraph.translate()
+
const eventData: Util.EventData = {
action,
clientX: e.clientX,
@@ -232,29 +259,44 @@ export class MiniMap extends View implements Graph.Plugin {
this.targetGraphTransforming = true
this.delegateDocumentEvents(Util.documentEvents, eventData)
}
-
+ // 拖动
protected doAction(evt: Dom.MouseMoveEvent) {
const e = this.normalizeEvent(evt)
const clientX = e.clientX
const clientY = e.clientY
const data = e.data as Util.EventData
switch (data.action) {
+ // 平移
case 'panning': {
const scale = this.sourceGraph.transform.getScale()
+ const targetScale = this.targetGraph.transform.getScale()
+
+ // 相对于起始位置偏移了多少px
const rx = (clientX - data.clientX) * scale.sx
const ry = (clientY - data.clientY) * scale.sy
+
if (this.scroller) {
this.graphContainer.scrollLeft = data.scrollLeft + rx / this.ratio
this.graphContainer.scrollTop = data.scrollTop + ry / this.ratio
} else {
+ // this.sourceGraph.translate(
+ // data.translateX - rx / this.ratio,
+ // data.translateY - ry / this.ratio,
+ // )
+
+ // 计算每次的偏移距离
+ const x = (rx ) / targetScale.sx
+ const y = (ry ) / targetScale.sy
+
+ // 现有偏移位置 - 每次偏移距离
this.sourceGraph.translate(
- data.translateX - rx / this.ratio,
- data.translateY - ry / this.ratio,
+ data.translateX - x,
+ data.translateY - y,
)
}
break
}
-
+ // 缩放
case 'zooming': {
const startScale = data.scale
const startGeometry = data.geometry
@@ -284,7 +326,7 @@ export class MiniMap extends View implements Graph.Plugin {
this.undelegateDocumentEvents()
this.targetGraphTransforming = false
}
-
+ // 点击滚动
protected scrollTo(evt: Dom.MouseDownEvent) {
const e = this.normalizeEvent(evt)
@@ -294,6 +336,8 @@ export class MiniMap extends View implements Graph.Plugin {
const ts = this.targetGraph.translate()
ts.ty = ts.ty || 0
+ console.log('scrollTo ts', ts)
+
if (e.offsetX == null) {
const offset = Dom.offset(this.targetGraph.container)
x = e.pageX - offset.left
@@ -303,9 +347,40 @@ export class MiniMap extends View implements Graph.Plugin {
y = e.offsetY
}
- const cx = (x - ts.tx) / this.ratio
- const cy = (y - ts.ty) / this.ratio
- this.sourceGraph.centerPoint(cx, cy)
+ const sourceScale = this.sourceGraph.transform.getScale()
+ const targetScale = this.targetGraph.transform.getScale()
+
+ // // const cx = (x - ts.tx) / this.ratio
+ // // const cy = (y - ts.ty) / this.ratio
+
+ // const originX = (x - ts.tx)
+ // const originY = (y - ts.ty)
+ // console.log('scrollTo', this.ratio, originX, originY)
+ // // 小地图scale缩小,大地图scale被放大, cx就越大;偏移差距也就越大
+ // // 小地图scale放大,大地图scale被缩小, cx就越小;偏移差距也就越小
+ // const cx = (originX * sourceScale.sx)/ targetScale.sx
+ // const cy = (originY * sourceScale.sy)/ targetScale.sy
+
+ // console.log('big position', cx, cy)
+
+ const position = Dom.position(this.viewport)
+ const containerPosition = Dom.position(this.targetGraph.container)
+ const {width, height} = this.viewport.getBoundingClientRect()
+ const start = {
+ x: position.left + width/2,
+ y: position.top - containerPosition.top + height/2,
+ }
+ const cx = (x - start.x) * sourceScale.sx / targetScale.sx
+ const cy = (y - start.y) * sourceScale.sy / targetScale.sy
+
+ const { tx, ty } = this.sourceGraph.translate()
+
+ this.sourceGraph.translate(tx - cx, ty - cy)
+
+
+
+
+ // this.sourceGraph.centerPoint(cx, cy)
}
@View.dispose()
From df812a72527645cddab6ef4b26c2d13e9766d453 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Mon, 19 Aug 2024 11:02:41 +0800
Subject: [PATCH 03/23] =?UTF-8?q?feat:=E9=83=A8=E5=88=86=E6=BA=90=E7=A0=81?=
=?UTF-8?q?=E5=A4=87=E6=B3=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../x6-example-features/src/pages/index.tsx | 4 ++
.../src/pages/minimap/index.less | 8 +--
.../src/pages/minimap/index.tsx | 59 ++++++++++++-------
packages/x6-common/src/dom/event/core.ts | 1 +
packages/x6-geometry/src/rectangle.ts | 1 +
packages/x6/src/graph/graph.ts | 2 +-
packages/x6/src/graph/transform.ts | 12 +++-
packages/x6/src/index.ts | 2 +-
packages/x6/src/model/cell.ts | 4 +-
9 files changed, 62 insertions(+), 31 deletions(-)
diff --git a/examples/x6-example-features/src/pages/index.tsx b/examples/x6-example-features/src/pages/index.tsx
index d218d81ced..c676fb0d2a 100755
--- a/examples/x6-example-features/src/pages/index.tsx
+++ b/examples/x6-example-features/src/pages/index.tsx
@@ -183,6 +183,10 @@ const dataSource = [
example: 'history',
description: '时光回溯',
},
+ {
+ example: 'minimap',
+ description: '小地图',
+ },
].map((item, index) => ({ key: index, ...item }))
const columns = [
diff --git a/examples/x6-example-features/src/pages/minimap/index.less b/examples/x6-example-features/src/pages/minimap/index.less
index d79bb95346..166801ed6e 100644
--- a/examples/x6-example-features/src/pages/minimap/index.less
+++ b/examples/x6-example-features/src/pages/minimap/index.less
@@ -9,10 +9,10 @@
.app-minimap {
position: absolute;
- bottom: 0;
- left: 620px;
- width: 200px;
- height: 150px;
+ bottom: 16px;
+ right: 167px;
+ width: 400px;
+ height: 400px;
}
.x6-widget-minimap-viewport {
diff --git a/examples/x6-example-features/src/pages/minimap/index.tsx b/examples/x6-example-features/src/pages/minimap/index.tsx
index 4b6add5436..cb141f820e 100644
--- a/examples/x6-example-features/src/pages/minimap/index.tsx
+++ b/examples/x6-example-features/src/pages/minimap/index.tsx
@@ -1,6 +1,6 @@
import * as React from 'react'
import { Graph } from '@antv/x6'
-import { MiniMap } from '@antv/x6-plugin-minimap'
+import { MiniMap } from '../../../../../packages/x6-plugin-minimap/src/index'
import { Scroller } from '@antv/x6-plugin-scroller'
import { Radio } from 'antd'
import { SimpleNodeView } from './simple-view'
@@ -18,29 +18,28 @@ export default class Example extends React.Component {
componentDidMount() {
this.graph = new Graph({
+ panning: {
+ enabled: true,
+ modifiers: [],
+ eventTypes: ['leftMouseDown'],
+ },
+ mousewheel: {
+ enabled: true,
+ },
container: this.container,
- width: 600,
- height: 320,
+ width: 1600,
+ height: 800,
background: {
color: '#F2F7FA',
},
})
- this.graph.use(
- new Scroller({
- pageVisible: true,
- pageBreak: false,
- pannable: true,
- }),
- )
- this.graph.use(
- new MiniMap({
- container: this.minimapContainer,
- width: 200,
- height: 160,
- padding: 10,
- }),
- )
+ // this.graph.use(
+ // new Scroller({
+ // pannable: false,
+ // }),
+ // )
+
this.graph.addNode({
x: 200,
@@ -78,8 +77,8 @@ export default class Example extends React.Component {
const target = this.graph.addNode({
shape: 'circle',
- x: 160,
- y: 180,
+ x: 1160,
+ y: 2180,
width: 60,
height: 60,
label: 'World',
@@ -102,6 +101,22 @@ export default class Example extends React.Component {
},
},
})
+
+
+ this.graph.use(
+ new MiniMap({
+ container: this.minimapContainer,
+ width: 400,
+ height: 400,
+ padding: 1,
+ preserveAspectRatio:false,
+ graphOptions:{
+ width:400,
+ height:400
+ }
+ }),
+ )
+
}
onMinimapViewChange = (val: string) => {
@@ -148,6 +163,9 @@ export default class Example extends React.Component {
refMiniMapContainer = (container: HTMLDivElement) => {
this.minimapContainer = container
}
+ changeSize = () => {
+ this.graph.resize(1800, 800)
+ }
render() {
return (
@@ -159,6 +177,7 @@ export default class Example extends React.Component {
defaultValue={'detailed'}
optionType="button"
/>
+
diff --git a/packages/x6-common/src/dom/event/core.ts b/packages/x6-common/src/dom/event/core.ts
index e37a917195..ee076737e3 100644
--- a/packages/x6-common/src/dom/event/core.ts
+++ b/packages/x6-common/src/dom/event/core.ts
@@ -244,6 +244,7 @@ export namespace Core {
event.data = handleObj.data
const hookHandle = EventHook.get(handleObj.originType).handle
+ console.log('dispatch 事件触发', handleObj.originType, hookHandle, handleObj.handler)
const result = hookHandle
? hookHandle(matched.elem as Store.EventTarget, event, ...args)
diff --git a/packages/x6-geometry/src/rectangle.ts b/packages/x6-geometry/src/rectangle.ts
index f728e2dbba..7d1d785f06 100644
--- a/packages/x6-geometry/src/rectangle.ts
+++ b/packages/x6-geometry/src/rectangle.ts
@@ -624,6 +624,7 @@ export class Rectangle extends Geometry implements Rectangle.RectangleLike {
/**
* Returns a rectangle that is a union of this rectangle and rectangle `rect`.
+ * 返回一个矩形区域,该矩形是两个矩形区域的并集(最大区域)。
*/
union(rect: Rectangle.RectangleLike | Rectangle.RectangleData) {
const ref = Rectangle.clone(rect)
diff --git a/packages/x6/src/graph/graph.ts b/packages/x6/src/graph/graph.ts
index ea57fdf198..ed192acafc 100644
--- a/packages/x6/src/graph/graph.ts
+++ b/packages/x6/src/graph/graph.ts
@@ -1,5 +1,5 @@
import { Basecoat, NumberExt, Dom, KeyValue } from '@antv/x6-common'
-import { Point, Rectangle } from '@antv/x6-geometry'
+import { Point, Rectangle } from '../../../x6-geometry/src/index'
import { Model, Collection, Cell, Node, Edge } from '../model'
import { CellView } from '../view'
import * as Registry from '../registry'
diff --git a/packages/x6/src/graph/transform.ts b/packages/x6/src/graph/transform.ts
index b4178d2c47..1e6d4bc5ff 100644
--- a/packages/x6/src/graph/transform.ts
+++ b/packages/x6/src/graph/transform.ts
@@ -1,5 +1,5 @@
-import { Dom, NumberExt } from '@antv/x6-common'
-import { Point, Rectangle } from '@antv/x6-geometry'
+import { Dom, NumberExt } from '../../../x6-common/src/index'
+import { Point, Rectangle } from '../../../x6-geometry/src/index'
import { Base } from './base'
import { Util } from '../util'
import { Cell } from '../model'
@@ -322,6 +322,7 @@ export class TransformManager extends Base {
options: TransformManager.ScaleContentToFitOptions = {},
translate = true,
) {
+ console.log('scaleContentToFitImpl', options)
let contentBBox
let contentLocalOrigin
if (options.contentArea) {
@@ -367,8 +368,10 @@ export class TransformManager extends Base {
})
const currentScale = this.getScale()
-
+ // 新的X轴缩放比(scaleX) = (视口宽 / 内容区域宽) * 当前X轴缩放比
+ // 保证区域内容都在视口中展示
let newSX = (fittingBox.width / contentBBox.width) * currentScale.sx
+ // 新的y轴缩放比(scaleY) = (视口高 / 内容区域高) * 当前Y轴缩放比
let newSY = (fittingBox.height / contentBBox.height) * currentScale.sy
if (options.preserveAspectRatio !== false) {
@@ -421,8 +424,10 @@ export class TransformManager extends Base {
const area = Rectangle.create(rect)
const graph = this.graph
+ // 内容区域位置信息
options.contentArea = area
if (options.viewportArea == null) {
+ // 视口位置信息(视口一般会小于内容区域位置,移动视口可以看内容区域不同位置)
options.viewportArea = {
x: graph.options.x,
y: graph.options.y,
@@ -459,6 +464,7 @@ export class TransformManager extends Base {
y = cy - y * scale.sy // eslint-disable-line
if (ts.tx !== x || ts.ty !== y) {
+ console.log('centerPoint', x, y)
this.translate(x, y)
}
}
diff --git a/packages/x6/src/index.ts b/packages/x6/src/index.ts
index 7b9f015750..51f31725ac 100644
--- a/packages/x6/src/index.ts
+++ b/packages/x6/src/index.ts
@@ -7,7 +7,7 @@ export * from './graph'
export * from './config'
export * from './util'
-export * from '@antv/x6-common'
+export * from '../../x6-common/src/index'
export * from '@antv/x6-geometry'
export { Shape, Registry }
diff --git a/packages/x6/src/model/cell.ts b/packages/x6/src/model/cell.ts
index 87e94587a7..a0b66c2cd5 100644
--- a/packages/x6/src/model/cell.ts
+++ b/packages/x6/src/model/cell.ts
@@ -8,8 +8,8 @@ import {
KeyValue,
Size,
Basecoat,
-} from '@antv/x6-common'
-import { Rectangle, Point } from '@antv/x6-geometry'
+} from '../../../x6-common/src/index'
+import { Rectangle, Point } from '../../../x6-geometry/src/index'
import { NonUndefined } from 'utility-types'
import { Attr } from '../registry'
import { Model } from './model'
From 494716f431d141618f1ea0f191b26f8680f18178 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Mon, 19 Aug 2024 13:11:11 +0800
Subject: [PATCH 04/23] =?UTF-8?q?feat:x6-plugin-history=EF=BC=8C=E6=92=A4?=
=?UTF-8?q?=E9=94=80=E5=9B=9E=E9=80=80=E6=8F=92=E4=BB=B6=E5=8E=9F=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6-plugin-history/src/index.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/packages/x6-plugin-history/src/index.ts b/packages/x6-plugin-history/src/index.ts
index dd685eb411..004c17cb4d 100644
--- a/packages/x6-plugin-history/src/index.ts
+++ b/packages/x6-plugin-history/src/index.ts
@@ -176,6 +176,7 @@ export class History
this.model.on('batch:start', this.initBatchCommand, this)
this.model.on('batch:stop', this.storeBatchCommand, this)
if (this.options.eventNames) {
+ // 监听哪些事件操作需要进入撤销回退队列,统一进入addCommand中处理
this.options.eventNames.forEach((name, index) => {
this.handlers[index] = this.addCommand.bind(this, name)
this.model.on(name, this.handlers[index])
@@ -525,11 +526,13 @@ export class History
}
protected push(cmd: History.Command, options: KeyValue) {
+ // 有新的操作进入撤销队列undoStack时,重做队列redoStack清空
this.redoStack = []
if (cmd.batch) {
this.lastBatchIndex = Math.max(this.lastBatchIndex, 0)
this.emit('batch', { cmd, options })
} else {
+ // 操作进入撤销队列
this.undoStackPush(cmd)
this.consolidateCommands()
this.notify('add', cmd, options)
From ff4bf7121b51f8f6220897442bc9a77ccace8839 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Mon, 19 Aug 2024 13:38:39 +0800
Subject: [PATCH 05/23] =?UTF-8?q?feat:=20Dom=E5=85=AC=E5=85=B1=E6=96=B9?=
=?UTF-8?q?=E6=B3=95=E5=B0=81=E8=A3=85=EF=BC=88=E5=8F=AF=E5=80=9F=E9=89=B4?=
=?UTF-8?q?=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6-common/src/dom/index.ts | 2 +-
packages/x6-common/src/dom/position.ts | 7 ++++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/packages/x6-common/src/dom/index.ts b/packages/x6-common/src/dom/index.ts
index 0a5c952325..4432a36d39 100644
--- a/packages/x6-common/src/dom/index.ts
+++ b/packages/x6-common/src/dom/index.ts
@@ -1,3 +1,3 @@
import * as Dom from './main'
-
+// 封装Dom相关的操作方法,可以借鉴
export { Dom }
diff --git a/packages/x6-common/src/dom/position.ts b/packages/x6-common/src/dom/position.ts
index 0bd5804306..10dfebe11c 100644
--- a/packages/x6-common/src/dom/position.ts
+++ b/packages/x6-common/src/dom/position.ts
@@ -20,7 +20,11 @@ export function height(elem: Element) {
const rect = elem.getBoundingClientRect()
return rect.height
}
-
+/**
+ * 计算元素相对于父元素的绝对定位
+ * @param elem
+ * @returns
+ */
export function position(elem: Element) {
const isFixed = computeStyle(elem, 'position') === 'fixed'
let offsetValue: ReturnType
@@ -38,6 +42,7 @@ export function position(elem: Element) {
(offsetParent === doc.body || offsetParent === doc.documentElement) &&
computeStyle(offsetParent, 'position') === 'static'
) {
+ // 如果 offsetParent 是 body 或 html 并且其定位属性为 static,则继续寻找更高层的定位父元素
offsetParent = offsetParent.parentNode
}
if (offsetParent !== elem && isElement(offsetParent)) {
From db423672c99dad94e3a665470c3255f7fb2ef78f Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Mon, 19 Aug 2024 14:59:53 +0800
Subject: [PATCH 06/23] =?UTF-8?q?feat:=E5=AF=B9=E8=B1=A1=E5=B1=9E=E6=80=A7?=
=?UTF-8?q?mixins?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6-common/src/object/mixins.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/x6-common/src/object/mixins.ts b/packages/x6-common/src/object/mixins.ts
index ff848ad125..661493fe54 100644
--- a/packages/x6-common/src/object/mixins.ts
+++ b/packages/x6-common/src/object/mixins.ts
@@ -1,4 +1,5 @@
/**
+ * 对象属性混入mixins
* @see https://www.typescriptlang.org/docs/handbook/mixins.html
*/
export function applyMixins(derivedCtor: any, ...baseCtors: any[]) {
From 70702af01b1ef84c69fb33ee6800455a246fd1fb Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Mon, 19 Aug 2024 15:23:32 +0800
Subject: [PATCH 07/23] =?UTF-8?q?feat:Dom=E4=BA=8B=E4=BB=B6=E6=B3=A8?=
=?UTF-8?q?=E5=86=8C=E4=B8=8EGraph=E6=9C=AC=E8=BA=AB=E7=9A=84=E4=BA=8B?=
=?UTF-8?q?=E4=BB=B6=E6=B3=A8=E5=86=8C=E5=8C=BA=E5=88=86=E5=BC=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6-common/src/dom/event/core.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/packages/x6-common/src/dom/event/core.ts b/packages/x6-common/src/dom/event/core.ts
index ee076737e3..66296c198c 100644
--- a/packages/x6-common/src/dom/event/core.ts
+++ b/packages/x6-common/src/dom/event/core.ts
@@ -8,6 +8,8 @@ import './special'
export namespace Core {
let triggered: string | undefined
+
+ // Dom的事件注册,与Graph本身的事件注册机制区分开;使用Dom.Event.on进行Dom事件注册
export function on(
elem: Store.EventTarget,
types: string,
@@ -44,6 +46,7 @@ export namespace Core {
let mainHandler = store.handler
if (mainHandler == null) {
mainHandler = store.handler = function (e, ...args: any[]) {
+ // 事件处理器
return triggered !== e.type ? dispatch(elem, e, ...args) : undefined
}
}
From 65ddd454203601fa793b012c8dee67dd2657d74d Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Mon, 19 Aug 2024 15:46:09 +0800
Subject: [PATCH 08/23] =?UTF-8?q?feat:=20Renderer=E6=B8=B2=E6=9F=93?=
=?UTF-8?q?=E5=99=A8=E6=B8=B2=E6=9F=93=E5=8E=9F=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/renderer/renderer.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/x6/src/renderer/renderer.ts b/packages/x6/src/renderer/renderer.ts
index 72225ccd22..6f023df7c3 100644
--- a/packages/x6/src/renderer/renderer.ts
+++ b/packages/x6/src/renderer/renderer.ts
@@ -7,6 +7,7 @@ import { CellView, EdgeView } from '../view'
import { Util } from '../util'
export class Renderer extends Base {
+ // 初始化Renderer时,传入graph;再Renderer中的Scheduler调度器中,监听graph的相关事件(例如添加节点cell:added),然后进行渲染更新
private readonly schedule: Scheduler = new Scheduler(this.graph)
requestViewUpdate(view: CellView, flag: number, options: any = {}) {
From 5ebb94a420509824458f947ff7bef250e9589c58 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Mon, 19 Aug 2024 16:45:33 +0800
Subject: [PATCH 09/23] =?UTF-8?q?feat:=E8=B0=83=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
examples/x6-example-features/src/pages/minimap/index.tsx | 2 +-
packages/x6/src/graph/graph.ts | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/examples/x6-example-features/src/pages/minimap/index.tsx b/examples/x6-example-features/src/pages/minimap/index.tsx
index cb141f820e..f423fc471e 100644
--- a/examples/x6-example-features/src/pages/minimap/index.tsx
+++ b/examples/x6-example-features/src/pages/minimap/index.tsx
@@ -1,5 +1,5 @@
import * as React from 'react'
-import { Graph } from '@antv/x6'
+import { Graph } from '../../../../../packages/x6'
import { MiniMap } from '../../../../../packages/x6-plugin-minimap/src/index'
import { Scroller } from '@antv/x6-plugin-scroller'
import { Radio } from 'antd'
diff --git a/packages/x6/src/graph/graph.ts b/packages/x6/src/graph/graph.ts
index ed192acafc..6df21af833 100644
--- a/packages/x6/src/graph/graph.ts
+++ b/packages/x6/src/graph/graph.ts
@@ -1,4 +1,4 @@
-import { Basecoat, NumberExt, Dom, KeyValue } from '@antv/x6-common'
+import { Basecoat, NumberExt, Dom, KeyValue } from '../../../x6-common'
import { Point, Rectangle } from '../../../x6-geometry/src/index'
import { Model, Collection, Cell, Node, Edge } from '../model'
import { CellView } from '../view'
@@ -52,6 +52,7 @@ export class Graph extends Basecoat {
this.css = new Css(this)
this.view = new GraphView(this)
this.defs = new Defs(this)
+ // 坐标
this.coord = new Coord(this)
this.transform = new Transform(this)
this.highlight = new Highlight(this)
@@ -68,6 +69,7 @@ export class Graph extends Basecoat {
this.renderer = new ViewRenderer(this)
this.panning = new Panning(this)
this.mousewheel = new Wheel(this)
+ // 虚拟渲染
this.virtualRender = new VirtualRender(this)
this.size = new Size(this)
}
From 1f88d3da6ae640b7ea8a2408c44e57eec1eddd68 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Mon, 19 Aug 2024 18:11:52 +0800
Subject: [PATCH 10/23] =?UTF-8?q?feat:=E9=BC=A0=E6=A0=87=E4=BA=A4=E4=BA=92?=
=?UTF-8?q?=EF=BC=8C=E5=8F=8A=E5=85=83=E7=B4=A0=E6=8D=95=E6=8D=89+?=
=?UTF-8?q?=E4=BA=8B=E4=BB=B6=E8=A7=A6=E5=8F=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/graph/graph.ts | 8 +++++++-
packages/x6/src/graph/view.ts | 3 +++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/packages/x6/src/graph/graph.ts b/packages/x6/src/graph/graph.ts
index 6df21af833..ec9a0ab305 100644
--- a/packages/x6/src/graph/graph.ts
+++ b/packages/x6/src/graph/graph.ts
@@ -52,7 +52,7 @@ export class Graph extends Basecoat {
this.css = new Css(this)
this.view = new GraphView(this)
this.defs = new Defs(this)
- // 坐标
+ // 坐标?(用于捕捉交互的元素?)
this.coord = new Coord(this)
this.transform = new Transform(this)
this.highlight = new Highlight(this)
@@ -826,6 +826,12 @@ export class Graph extends Basecoat {
// #region coord
+ /**
+ * 捕捉到栅格?(是否捕捉到栅格上的元素)
+ * @param x
+ * @param y
+ * @returns
+ */
snapToGrid(p: Point.PointLike): Point
snapToGrid(x: number, y: number): Point
snapToGrid(x: number | Point.PointLike, y?: number) {
diff --git a/packages/x6/src/graph/view.ts b/packages/x6/src/graph/view.ts
index 1923f1942a..83d5b2ae8b 100644
--- a/packages/x6/src/graph/view.ts
+++ b/packages/x6/src/graph/view.ts
@@ -50,6 +50,7 @@ export class GraphView extends View {
}
delegateEvents() {
+ // 委托监听this.container dom事件上的交互事件;在对应的handler上再去触发graph上的事件
const ctor = this.constructor as typeof GraphView
super.delegateEvents(ctor.events)
return this
@@ -126,9 +127,11 @@ export class GraphView extends View {
}
const localPoint = this.graph.snapToGrid(e.clientX, e.clientY)
+ // 捕捉到元素,触发事件
if (view) {
view.onClick(e, localPoint.x, localPoint.y)
} else {
+ // 没有找到,触发空白点击事件
this.graph.trigger('blank:click', {
e,
x: localPoint.x,
From c3b844e421a705977f206d807771835356eb0a40 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 09:02:48 +0800
Subject: [PATCH 11/23] =?UTF-8?q?feat:=E8=B0=83=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../x6-example-features/src/pages/minimap/index.tsx | 2 +-
packages/x6/src/graph/graph.ts | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/examples/x6-example-features/src/pages/minimap/index.tsx b/examples/x6-example-features/src/pages/minimap/index.tsx
index f423fc471e..8d65106023 100644
--- a/examples/x6-example-features/src/pages/minimap/index.tsx
+++ b/examples/x6-example-features/src/pages/minimap/index.tsx
@@ -1,5 +1,5 @@
import * as React from 'react'
-import { Graph } from '../../../../../packages/x6'
+import { Graph } from '../../../../../packages/x6/src/index'
import { MiniMap } from '../../../../../packages/x6-plugin-minimap/src/index'
import { Scroller } from '@antv/x6-plugin-scroller'
import { Radio } from 'antd'
diff --git a/packages/x6/src/graph/graph.ts b/packages/x6/src/graph/graph.ts
index ec9a0ab305..e170d43c04 100644
--- a/packages/x6/src/graph/graph.ts
+++ b/packages/x6/src/graph/graph.ts
@@ -1,4 +1,4 @@
-import { Basecoat, NumberExt, Dom, KeyValue } from '../../../x6-common'
+import { Basecoat, NumberExt, Dom, KeyValue } from '@antv/x6-common/es'
import { Point, Rectangle } from '../../../x6-geometry/src/index'
import { Model, Collection, Cell, Node, Edge } from '../model'
import { CellView } from '../view'
@@ -826,11 +826,11 @@ export class Graph extends Basecoat {
// #region coord
- /**
+ /**
* 捕捉到栅格?(是否捕捉到栅格上的元素)
- * @param x
- * @param y
- * @returns
+ * @param x
+ * @param y
+ * @returns
*/
snapToGrid(p: Point.PointLike): Point
snapToGrid(x: number, y: number): Point
From 624da976b917b55dd1f19e49c3cd097a8fc01bf9 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 14:36:30 +0800
Subject: [PATCH 12/23] =?UTF-8?q?feat:=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86?=
=?UTF-8?q?=EF=BC=8C=E6=9E=84=E5=BB=BA=E8=87=AA=E5=AE=9A=E4=B9=89event?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6-common/src/dom/event/core.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/packages/x6-common/src/dom/event/core.ts b/packages/x6-common/src/dom/event/core.ts
index 66296c198c..d36adf52d0 100644
--- a/packages/x6-common/src/dom/event/core.ts
+++ b/packages/x6-common/src/dom/event/core.ts
@@ -212,6 +212,7 @@ export namespace Core {
evt: Event | EventObject | string,
...args: any[]
) {
+ // 构建自定义的event数据
const event = EventObject.create(evt)
event.delegateTarget = elem as Element
@@ -243,11 +244,14 @@ export namespace Core {
event.rnamespace == null ||
(handleObj.namespace && event.rnamespace.test(handleObj.namespace))
) {
+ if(handleObj.originType === 'mousedown'){
+ console.log('handleObj', handleObj.originType, handleObj)
+ }
event.handleObj = handleObj
event.data = handleObj.data
const hookHandle = EventHook.get(handleObj.originType).handle
- console.log('dispatch 事件触发', handleObj.originType, hookHandle, handleObj.handler)
+ // console.log('dispatch 事件触发', handleObj.originType)
const result = hookHandle
? hookHandle(matched.elem as Store.EventTarget, event, ...args)
From 48f6c0d08fc874f640c65aa30f34a30e3d5437b7 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 14:37:42 +0800
Subject: [PATCH 13/23] =?UTF-8?q?feat:=20render=E5=8F=8AqueueJob=20?=
=?UTF-8?q?=E4=BB=BB=E5=8A=A1=E9=98=9F=E5=88=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/renderer/queueJob.ts | 13 +++++++++++--
packages/x6/src/renderer/renderer.ts | 2 +-
packages/x6/src/renderer/scheduler.ts | 1 +
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/packages/x6/src/renderer/queueJob.ts b/packages/x6/src/renderer/queueJob.ts
index 0a6690f00a..1a9128fcdc 100644
--- a/packages/x6/src/renderer/queueJob.ts
+++ b/packages/x6/src/renderer/queueJob.ts
@@ -58,7 +58,9 @@ export class JobQueue {
this.queueFlush()
}
}
-
+ /**
+ * 同步刷新执行任务队列
+ */
flushJobsSync() {
this.isFlushPending = false
this.isFlushing = true
@@ -76,6 +78,11 @@ export class JobQueue {
this.isFlushing = false
}
+ /**
+ * 二分法查找任务插入的位置,优先级高的排列在前
+ * @param job
+ * @returns
+ */
private findInsertionIndex(job: Job) {
let left = 0
let ins = this.queue.length
@@ -92,7 +99,9 @@ export class JobQueue {
}
return ins
}
-
+ /**
+ * 异步任务调度,使用requestIdleCallback/setTimeout实现
+ */
private scheduleJob() {
if ('requestIdleCallback' in window) {
if (this.scheduleId) {
diff --git a/packages/x6/src/renderer/renderer.ts b/packages/x6/src/renderer/renderer.ts
index 6f023df7c3..67c3a990ef 100644
--- a/packages/x6/src/renderer/renderer.ts
+++ b/packages/x6/src/renderer/renderer.ts
@@ -7,7 +7,7 @@ import { CellView, EdgeView } from '../view'
import { Util } from '../util'
export class Renderer extends Base {
- // 初始化Renderer时,传入graph;再Renderer中的Scheduler调度器中,监听graph的相关事件(例如添加节点cell:added),然后进行渲染更新
+ // 初始化Renderer时,传入graph;再Renderer中的Scheduler调度器中,监听graph的相关事件,注意这里监听的是model的事件(例如添加节点cell:added),然后进行渲染更新
private readonly schedule: Scheduler = new Scheduler(this.graph)
requestViewUpdate(view: CellView, flag: number, options: any = {}) {
diff --git a/packages/x6/src/renderer/scheduler.ts b/packages/x6/src/renderer/scheduler.ts
index 7abddb9269..e2f8dd714c 100644
--- a/packages/x6/src/renderer/scheduler.ts
+++ b/packages/x6/src/renderer/scheduler.ts
@@ -316,6 +316,7 @@ export class Scheduler extends Disposable {
if (viewItem) {
const zIndex = view.cell.getZIndex()
const pivot = this.addZPivot(zIndex)
+ // 先将view(NodeView/EdgeView)的Dom框架内容插入到container
this.container.insertBefore(view.container, pivot)
if (!view.cell.isVisible()) {
From 17bef501c6b573c1830fd8dbc5eab56f203c99fb Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 14:44:28 +0800
Subject: [PATCH 14/23] =?UTF-8?q?feat:model=E4=B8=AD=E5=88=9B=E5=BB=BANode?=
=?UTF-8?q?=E3=80=81Edge=E6=A8=A1=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/model/edge.ts | 1 +
packages/x6/src/model/model.ts | 2 ++
packages/x6/src/model/node.ts | 1 +
3 files changed, 4 insertions(+)
diff --git a/packages/x6/src/model/edge.ts b/packages/x6/src/model/edge.ts
index 1f7ce8b856..c8427b943c 100644
--- a/packages/x6/src/model/edge.ts
+++ b/packages/x6/src/model/edge.ts
@@ -1183,6 +1183,7 @@ export namespace Edge {
export function create(options: Metadata) {
const shape = options.shape || 'edge'
+ // 从registry 注册中心获取对应边的构造函数
const Ctor = registry.get(shape)
if (Ctor) {
return new Ctor(options)
diff --git a/packages/x6/src/model/model.ts b/packages/x6/src/model/model.ts
index a40912ccd5..92d2474ccb 100644
--- a/packages/x6/src/model/model.ts
+++ b/packages/x6/src/model/model.ts
@@ -252,6 +252,7 @@ export class Model extends Basecoat {
}
createNode(metadata: Node.Metadata) {
+ // 构建Node模型
return Node.create(metadata)
}
@@ -262,6 +263,7 @@ export class Model extends Basecoat {
}
createEdge(metadata: Edge.Metadata) {
+ // 构建Edge模型
return Edge.create(metadata)
}
diff --git a/packages/x6/src/model/node.ts b/packages/x6/src/model/node.ts
index 0241e93093..a42e216c4b 100644
--- a/packages/x6/src/model/node.ts
+++ b/packages/x6/src/model/node.ts
@@ -1188,6 +1188,7 @@ export namespace Node {
export function create(options: Metadata) {
const shape = options.shape || 'rect'
+ // 从registry 注册中心获取对应图形的构造函数(自定义的图形也会在registry中注册)
const Ctor = registry.get(shape)
if (Ctor) {
return new Ctor(options)
From 86376baf426718f9014f2ad751e07433f71d9690 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 15:06:09 +0800
Subject: [PATCH 15/23] =?UTF-8?q?feat:=E5=85=83=E7=B4=A0=E6=8D=95=E6=8D=89?=
=?UTF-8?q?=E9=80=BB=E8=BE=91(=E5=BD=93=E5=89=8D=E5=85=83=E7=B4=A0?=
=?UTF-8?q?=E5=90=91=E4=B8=8A=E9=80=92=E5=BD=92=E6=8B=A5=E6=9C=89data-cell?=
=?UTF-8?q?-id=E7=9A=84=E7=88=B6=E5=85=83=E7=B4=A0=E7=9A=84id=E5=80=BC)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/graph/view.ts | 8 ++++++--
packages/x6/src/renderer/renderer.ts | 2 ++
packages/x6/src/renderer/scheduler.ts | 2 ++
packages/x6/src/view/view.ts | 4 ++--
4 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/packages/x6/src/graph/view.ts b/packages/x6/src/graph/view.ts
index 83d5b2ae8b..423b6b18ef 100644
--- a/packages/x6/src/graph/view.ts
+++ b/packages/x6/src/graph/view.ts
@@ -88,7 +88,11 @@ export class GraphView extends View {
return true
}
-
+ /**
+ * 根据element查找对应的view (NodeView/EdgeView)
+ * @param elem
+ * @returns
+ */
protected findView(elem: Element) {
return this.graph.findViewByElem(elem)
}
@@ -127,7 +131,7 @@ export class GraphView extends View {
}
const localPoint = this.graph.snapToGrid(e.clientX, e.clientY)
- // 捕捉到元素,触发事件
+ // 捕捉到元素(NodeView、EdgeView),触发对应view中的onclick事件
if (view) {
view.onClick(e, localPoint.x, localPoint.y)
} else {
diff --git a/packages/x6/src/renderer/renderer.ts b/packages/x6/src/renderer/renderer.ts
index 67c3a990ef..e733563d15 100644
--- a/packages/x6/src/renderer/renderer.ts
+++ b/packages/x6/src/renderer/renderer.ts
@@ -35,10 +35,12 @@ export class Renderer extends Base {
: elem[0]
if (target) {
+ // 通过当前target元素,一直向上查找元素,直到找到拥有data-cell-id属性的元素,获取id值,在schedule中的views中,通过id找到对应的view
const id = this.graph.view.findAttr('data-cell-id', target)
if (id) {
const views = this.schedule.views
if (views[id]) {
+ // 返回view
return views[id].view
}
}
diff --git a/packages/x6/src/renderer/scheduler.ts b/packages/x6/src/renderer/scheduler.ts
index e2f8dd714c..d5f1fc0d71 100644
--- a/packages/x6/src/renderer/scheduler.ts
+++ b/packages/x6/src/renderer/scheduler.ts
@@ -7,6 +7,7 @@ import { FlagManager } from '../view/flag'
import { Graph } from '../graph'
export class Scheduler extends Disposable {
+ // 存储所有的NodeView、EdgeView
public views: KeyValue = {}
public willRemoveViews: KeyValue = {}
protected zPivots: KeyValue
@@ -186,6 +187,7 @@ export class Scheduler extends Disposable {
options,
state: Scheduler.ViewState.CREATED,
}
+ // scheduler中的views,存储所有的CellView(NodeView、EdgeView)
this.views[id] = viewItem
}
}
diff --git a/packages/x6/src/view/view.ts b/packages/x6/src/view/view.ts
index d6d255884d..307526da96 100644
--- a/packages/x6/src/view/view.ts
+++ b/packages/x6/src/view/view.ts
@@ -1,4 +1,4 @@
-import { Dom, KeyValue, Basecoat } from '@antv/x6-common'
+import { Dom, KeyValue, Basecoat } from '../../../x6-common/src/index.ts'
import { EventArgs } from '@antv/x6-common/lib/event/types'
import { Config } from '../config'
import { Markup } from './markup'
@@ -111,7 +111,7 @@ export abstract class View extends Basecoat {
if (current === this.container) {
return null
}
-
+ // 向上递归寻找拥有指定属性attrName的元素
current = current.parentNode as Element
}
From ea2b31bd6e5715518071712480b09e5d85c625c5 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 15:23:17 +0800
Subject: [PATCH 16/23] =?UTF-8?q?feat:=20view=E5=B1=82=EF=BC=8C=E4=BA=8B?=
=?UTF-8?q?=E4=BB=B6handler=EF=BC=8C=E8=A7=A6=E5=8F=91=E5=AF=B9=E5=BA=94?=
=?UTF-8?q?=E7=9A=84CellView(NodeView/EdgeView)=E7=9A=84=E4=BA=8B=E4=BB=B6?=
=?UTF-8?q?=E7=9B=91=E5=90=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/graph/view.ts | 1 +
packages/x6/src/view/edge.ts | 2 ++
packages/x6/src/view/node.ts | 3 +++
3 files changed, 6 insertions(+)
diff --git a/packages/x6/src/graph/view.ts b/packages/x6/src/graph/view.ts
index 423b6b18ef..60ab72c4d0 100644
--- a/packages/x6/src/graph/view.ts
+++ b/packages/x6/src/graph/view.ts
@@ -133,6 +133,7 @@ export class GraphView extends View {
const localPoint = this.graph.snapToGrid(e.clientX, e.clientY)
// 捕捉到元素(NodeView、EdgeView),触发对应view中的onclick事件
if (view) {
+ // view事件触发
view.onClick(e, localPoint.x, localPoint.y)
} else {
// 没有找到,触发空白点击事件
diff --git a/packages/x6/src/view/edge.ts b/packages/x6/src/view/edge.ts
index 98502e2f17..864ac81e44 100644
--- a/packages/x6/src/view/edge.ts
+++ b/packages/x6/src/view/edge.ts
@@ -1403,7 +1403,9 @@ export class EdgeView<
}
onClick(e: Dom.ClickEvent, x: number, y: number) {
+ // 触发CellView的click事件 graph.on('cell:click')
super.onClick(e, x, y)
+ // 触发EdgeView的click事件 graph.on('edge:click')
this.notify('edge:click', this.getEventArgs(e, x, y))
}
diff --git a/packages/x6/src/view/node.ts b/packages/x6/src/view/node.ts
index 07ddcc5760..3d9fb80b86 100644
--- a/packages/x6/src/view/node.ts
+++ b/packages/x6/src/view/node.ts
@@ -518,8 +518,11 @@ export class NodeView<
}
onClick(e: Dom.ClickEvent, x: number, y: number) {
+ // 触发CellView的click事件 graph.on('cell:click')
super.onClick(e, x, y)
+ // 触发NodeView的click事件 graph.on('node:click'),这个监听会更具体
this.notify('node:click', this.getEventArgs(e, x, y))
+ // 触发连接桩点击事件
this.notifyPortEvent('node:port:click', e, { x, y })
}
From 8b9675efd6386e448b2eb51eeba902502a4a6c38 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 17:38:54 +0800
Subject: [PATCH 17/23] =?UTF-8?q?feat:=E4=BA=8B=E4=BB=B6=E8=A7=A6=E5=8F=91?=
=?UTF-8?q?=EF=BC=8C=E9=80=9A=E8=BF=87store=E5=AD=98=E5=82=A8=E4=B9=8B?=
=?UTF-8?q?=E5=89=8Devent=E4=B8=AD=E7=9A=84data=E6=95=B0=E6=8D=AE=EF=BC=8C?=
=?UTF-8?q?=E4=B8=8B=E6=AC=A1=E6=93=8D=E4=BD=9C=E5=90=8C=E7=B1=BB=E5=9E=8B?=
=?UTF-8?q?=E4=BA=8B=E4=BB=B6=E8=83=BD=E5=8F=96=E5=88=B0=E7=9B=B8=E5=BA=94?=
=?UTF-8?q?=E6=95=B0=E6=8D=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6-common/src/dom/event/core.ts | 10 ++++++----
packages/x6-common/src/dom/event/store.ts | 1 +
packages/x6-common/src/dom/event/util.ts | 2 ++
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/packages/x6-common/src/dom/event/core.ts b/packages/x6-common/src/dom/event/core.ts
index d36adf52d0..41bb2ceda8 100644
--- a/packages/x6-common/src/dom/event/core.ts
+++ b/packages/x6-common/src/dom/event/core.ts
@@ -39,7 +39,7 @@ export namespace Core {
// if (!Util.isValidSelector(elem, selector)) {
// throw new Error('Delegate event with invalid selector.')
// }
-
+ // 确保elem进入store,后续dispatch 中Util.getHandlerQueue(elem, event)会用到
const store = Store.ensure(elem)
// Ensure the main handle
@@ -64,6 +64,8 @@ export namespace Core {
}
let type = originType
+ // 事件名称hook,通过事件名转换成其它事件名称;EventHook.register方法注册转换逻辑
+ // 例如mouseenter 会被转换为mouseover 事件
let hook = EventHook.get(type)
// If selector defined, determine special event type, otherwise given type
@@ -109,8 +111,10 @@ export namespace Core {
Util.setHandlerId(handleObj.handler, guid)
}
+
// Add to the element's handler list, delegates in front
if (selector) {
+ // 有选择器的情况下(理解为具体的cell选择器),将delegateCount+1,代表有多少个具体cell选择器
bag.handlers.splice(bag.delegateCount, 0, handleObj)
bag.delegateCount += 1
} else {
@@ -244,9 +248,7 @@ export namespace Core {
event.rnamespace == null ||
(handleObj.namespace && event.rnamespace.test(handleObj.namespace))
) {
- if(handleObj.originType === 'mousedown'){
- console.log('handleObj', handleObj.originType, handleObj)
- }
+ // 恢复之前的操作数据
event.handleObj = handleObj
event.data = handleObj.data
diff --git a/packages/x6-common/src/dom/event/store.ts b/packages/x6-common/src/dom/event/store.ts
index 515ead168a..202f075937 100644
--- a/packages/x6-common/src/dom/event/store.ts
+++ b/packages/x6-common/src/dom/event/store.ts
@@ -27,6 +27,7 @@ export namespace Store {
export function ensure(target: EventTarget) {
if (!cache.has(target)) {
+ // 构建以element为key 的events对象
cache.set(target, { events: Object.create(null) })
}
return cache.get(target)!
diff --git a/packages/x6-common/src/dom/event/util.ts b/packages/x6-common/src/dom/event/util.ts
index 9f1e788fc4..3ef3eb513e 100644
--- a/packages/x6-common/src/dom/event/util.ts
+++ b/packages/x6-common/src/dom/event/util.ts
@@ -100,6 +100,7 @@ export namespace Util {
export namespace Util {
export function getHandlerQueue(elem: Store.EventTarget, event: EventObject) {
const queue = []
+ // Store中使用WeakMap进行cache缓存,缓存相关数据
const store = Store.get(elem)
const bag = store && store.events && store.events[event.type]
const handlers = (bag && bag.handlers) || []
@@ -161,6 +162,7 @@ export namespace Util {
// Add the remaining (directly-bound) handlers
if (delegateCount < handlers.length) {
+ // 截取delegateCount之后的handler,也就是用于具体cell选择器的handler
queue.push({ elem, handlers: handlers.slice(delegateCount) })
}
From 630895074e575459620adbc9d65db6f6ca56218e Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 17:40:07 +0800
Subject: [PATCH 18/23] =?UTF-8?q?feat:=E5=85=B3=E4=BA=8E=E8=87=AA=E5=AE=9A?=
=?UTF-8?q?=E4=B9=89=E4=BA=8B=E4=BB=B6event=EF=BC=8C=E5=AD=98=E5=82=A8?=
=?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89data=E7=9A=84=E9=83=A8=E5=88=86?=
=?UTF-8?q?=E5=9C=BA=E6=99=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/view/node.ts | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/packages/x6/src/view/node.ts b/packages/x6/src/view/node.ts
index 3d9fb80b86..17b8621a66 100644
--- a/packages/x6/src/view/node.ts
+++ b/packages/x6/src/view/node.ts
@@ -1055,21 +1055,28 @@ export class NodeView<
return area || null
}
-
+ /**
+ * 开始节点拖拽
+ * @param e
+ * @param x
+ * @param y
+ * @returns
+ */
protected startNodeDragging(e: Dom.MouseDownEvent, x: number, y: number) {
const targetView = this.getDelegatedView()
if (targetView == null || !targetView.can('nodeMovable')) {
return this.notifyUnhandledMouseDown(e, x, y)
}
-
+ // 往自定义event中传数据
this.setEventData(e, {
targetView,
action: 'move',
})
-
+ // 当前cell的位置
const position = Point.create(targetView.cell.getPosition())
targetView.setEventData(e, {
moving: false,
+ // 当前点击位置相对于cell的位置的偏移量
offset: position.diff(x, y),
restrict: this.getRestrictArea(targetView),
})
@@ -1107,7 +1114,12 @@ export class NodeView<
this.processEmbedding(e, data)
}
}
-
+ /**
+ * 结束时间拖拽
+ * @param e
+ * @param x
+ * @param y
+ */
protected stopNodeDragging(e: Dom.MouseUpEvent, x: number, y: number) {
const data = this.getEventData(e)
if (data.embedding) {
From 0e97ca47b76cf49f4db03dd9b208c05a570a92e5 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 17:41:39 +0800
Subject: [PATCH 19/23] =?UTF-8?q?feat:=20CellView=EF=BC=88NodeView/EdgeVie?=
=?UTF-8?q?w=EF=BC=89=E4=B8=AD=E5=8C=85=E5=90=ABCell=EF=BC=88Node/Edge?=
=?UTF-8?q?=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/view/cell.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/x6/src/view/cell.ts b/packages/x6/src/view/cell.ts
index 970c1135f7..9101389b84 100644
--- a/packages/x6/src/view/cell.ts
+++ b/packages/x6/src/view/cell.ts
@@ -102,7 +102,7 @@ export class CellView<
constructor(cell: Entity, options: Partial = {}) {
super()
-
+ // CellView中包含 Model中的Node、Edge
this.cell = cell
this.options = this.ensureOptions(options)
this.graph = this.options.graph
From 7478b0b660bca873f109754588e982ed3598c55c Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 17:46:08 +0800
Subject: [PATCH 20/23] =?UTF-8?q?feat:=20Model=E4=B8=AD=E7=9A=84Collection?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0Cell=EF=BC=8C=E9=80=9A=E8=BF=87=E4=BA=8B?=
=?UTF-8?q?=E4=BB=B6=E5=91=8A=E7=9F=A5Scheduler=E8=B0=83=E5=BA=A6=E5=99=A8?=
=?UTF-8?q?=EF=BC=8C=E8=BF=9B=E8=A1=8C=E7=9B=B8=E5=BA=94=E7=9A=84CellView?=
=?UTF-8?q?=E7=9A=84=E5=88=9B=E5=BB=BA=EF=BC=8C=E5=B9=B6=E9=80=9A=E8=BF=87?=
=?UTF-8?q?queueJob=E4=BB=BB=E5=8A=A1=E9=98=9F=E5=88=97=E8=BF=9B=E8=A1=8C?=
=?UTF-8?q?=E8=A7=86=E5=9B=BE=E6=B8=B2=E6=9F=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/model/collection.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/packages/x6/src/model/collection.ts b/packages/x6/src/model/collection.ts
index 38c38918cd..e612b0b041 100644
--- a/packages/x6/src/model/collection.ts
+++ b/packages/x6/src/model/collection.ts
@@ -105,6 +105,8 @@ export class Collection extends Basecoat {
}
this.trigger('added', args)
if (!localOptions.dryrun) {
+ // 元素添加后触发added事件,从而创建对应的CellView对象(NodeView、EdgeView )
+ // 会触发model.notify('cell:added')事件,Scheduler 监听了model.on('cell:added')事件,从而在Scheduler中创建对应的CellView对象(NodeView、EdgeView )
cell.notify('added', { ...args })
}
})
From b85ca7fb2848bbb7fbca58e57b5862724d6de797 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 17:46:22 +0800
Subject: [PATCH 21/23] =?UTF-8?q?feat:=E8=B0=83=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/pages/minimap/index.tsx | 35 +++++++++++--------
packages/x6/src/graph/graph.ts | 2 +-
2 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/examples/x6-example-features/src/pages/minimap/index.tsx b/examples/x6-example-features/src/pages/minimap/index.tsx
index 8d65106023..c3f528141e 100644
--- a/examples/x6-example-features/src/pages/minimap/index.tsx
+++ b/examples/x6-example-features/src/pages/minimap/index.tsx
@@ -39,7 +39,6 @@ export default class Example extends React.Component {
// pannable: false,
// }),
// )
-
this.graph.addNode({
x: 200,
@@ -102,20 +101,28 @@ export default class Example extends React.Component {
},
})
+ // this.graph.use(
+ // new MiniMap({
+ // container: this.minimapContainer,
+ // width: 400,
+ // height: 400,
+ // padding: 1,
+ // preserveAspectRatio: false,
+ // graphOptions: {
+ // width: 400,
+ // height: 400,
+ // },
+ // }),
+ // )
- this.graph.use(
- new MiniMap({
- container: this.minimapContainer,
- width: 400,
- height: 400,
- padding: 1,
- preserveAspectRatio:false,
- graphOptions:{
- width:400,
- height:400
- }
- }),
- )
+
+ this.graph.on('cell:click', ({ e, x, y, cell, view }) => {
+ console.log('graph cell:click')
+ })
+
+ this.graph.on('node:click',()=>{
+ console.log('graph node:click')
+ })
}
diff --git a/packages/x6/src/graph/graph.ts b/packages/x6/src/graph/graph.ts
index e170d43c04..1f2b45161b 100644
--- a/packages/x6/src/graph/graph.ts
+++ b/packages/x6/src/graph/graph.ts
@@ -827,7 +827,7 @@ export class Graph extends Basecoat {
// #region coord
/**
- * 捕捉到栅格?(是否捕捉到栅格上的元素)
+ * 当前事件在栅格中的坐标
* @param x
* @param y
* @returns
From dc6ca1a089f16f3ba347dccc05e60cbfeb988c8f Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Tue, 20 Aug 2024 18:31:17 +0800
Subject: [PATCH 22/23] =?UTF-8?q?feat=EF=BC=9A=E4=BA=8B=E4=BB=B6=E5=A7=94?=
=?UTF-8?q?=E6=89=98=EF=BC=8C=E8=A7=A6=E5=8F=91=E6=B5=81=E7=A8=8B=E5=A4=87?=
=?UTF-8?q?=E6=B3=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/graph/view.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/packages/x6/src/graph/view.ts b/packages/x6/src/graph/view.ts
index 60ab72c4d0..a59fcaa261 100644
--- a/packages/x6/src/graph/view.ts
+++ b/packages/x6/src/graph/view.ts
@@ -51,6 +51,9 @@ export class GraphView extends View {
delegateEvents() {
// 委托监听this.container dom事件上的交互事件;在对应的handler上再去触发graph上的事件
+ // 1. GraphView中将ctor.events事件都绑定在this.container上,回调事件根据配置,指向GraphView上具体的函数
+ // 2.this.container中的DOM事件触发之后,根据事件信息,找到对应的CellView子类,然后触发CellView上的事件
+ // 3.CellView中的notify,会触发this.graph.trigger事件,从而将事件传递给graph;业务层如果监听了graph上的事件(例如 this.graph.on('cell:added'))),也会收到事件
const ctor = this.constructor as typeof GraphView
super.delegateEvents(ctor.events)
return this
From a14c3c58ac8968596fe4ddeed5e863aba9d905f9 Mon Sep 17 00:00:00 2001
From: yelikang <530331059@qq.com>
Date: Wed, 21 Aug 2024 16:43:49 +0800
Subject: [PATCH 23/23] =?UTF-8?q?feat:=20coord=20=E5=9D=90=E6=A0=87?=
=?UTF-8?q?=E8=BD=AC=E6=8D=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/x6/src/graph/graph.ts | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/packages/x6/src/graph/graph.ts b/packages/x6/src/graph/graph.ts
index 1f2b45161b..fe558303e4 100644
--- a/packages/x6/src/graph/graph.ts
+++ b/packages/x6/src/graph/graph.ts
@@ -52,7 +52,7 @@ export class Graph extends Basecoat {
this.css = new Css(this)
this.view = new GraphView(this)
this.defs = new Defs(this)
- // 坐标?(用于捕捉交互的元素?)
+ // 坐标(用于画布与客户端/浏览器的坐标转换)
this.coord = new Coord(this)
this.transform = new Transform(this)
this.highlight = new Highlight(this)
@@ -889,7 +889,10 @@ export class Graph extends Basecoat {
return this.coord.localToPagePoint(x, y)
}
-
+ /**
+ * 画布坐标转换为客户端坐标(浏览器坐标)
+ * @param rect
+ */
clientToLocal(rect: Rectangle.RectangleLike): Rectangle
clientToLocal(x: number, y: number, width: number, height: number): Rectangle
clientToLocal(p: Point.PointLike): Point
@@ -915,7 +918,10 @@ export class Graph extends Basecoat {
return this.coord.clientToLocalPoint(x, y)
}
-
+ /**
+ * 浏览器坐标转换为画布端坐标
+ * @param rect
+ */
localToClient(rect: Rectangle.RectangleLike): Rectangle
localToClient(x: number, y: number, width: number, height: number): Rectangle
localToClient(p: Point.PointLike): Point