Skip to content
Open
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
23 changes: 11 additions & 12 deletions src/plugin/minimap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,23 +315,22 @@ export class MiniMap extends View implements GraphPlugin {
protected scrollTo(evt: Dom.MouseDownEvent) {
const e = this.normalizeEvent(evt)

let x: number
let y: number
// 使用 pageX/pageY 相对于 targetGraph.container 的偏移,避免 offsetX/offsetY
// 相对于内部子元素导致坐标基准不一致的问题
const containerOffset = Dom.offset(this.targetGraph.container)
const x = e.pageX - containerOffset.left
const y = e.pageY - containerOffset.top
Comment on lines +320 to +322

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

改进建议
Dom.offset 在某些极端情况下(例如元素未挂载、处于测试环境或 DOM 结构异常时)可能会返回 nullundefined。如果直接访问其属性可能会导致运行时报错 TypeError: Cannot read properties of null

建议进行防御性处理,为 containerOffset 提供一个默认值,例如 || { left: 0, top: 0 },以增强代码的健壮性。

Suggested change
const containerOffset = Dom.offset(this.targetGraph.container)
const x = e.pageX - containerOffset.left
const y = e.pageY - containerOffset.top
const containerOffset = Dom.offset(this.targetGraph.container) || { left: 0, top: 0 }
const x = e.pageX - containerOffset.left
const y = e.pageY - containerOffset.top


const ts = this.targetGraph.translate()
ts.ty = ts.ty || 0

if (e.offsetX == null) {
const offset = Dom.offset(this.targetGraph.container)
x = e.pageX - offset.left
y = e.pageY - offset.top
} else {
x = e.offsetX
y = e.offsetY
}
// 使用 targetGraph 的实际缩放比替代 this.ratio
// 原版用 this.ratio,但非 scroller 模式下 zoomToFit() 会重新计算缩放比,
// 导致 this.ratio 与 targetGraph 实际缩放比不一致,坐标转换产生偏差
const targetScale = this.targetGraph.transform.getScale()

const cx = (x - ts.tx) / this.ratio
const cy = (y - ts.ty) / this.ratio
const cx = (x - ts.tx) / targetScale.sx
const cy = (y - ts.ty) / targetScale.sy
Comment on lines +330 to +333

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

改进建议

  1. 除零/NaN 防御:在极端情况下(例如容器尺寸为 0、缩放比例异常或处于某些过渡动画中),targetScale.sxtargetScale.sy 可能会为 0NaN。直接作为除数会导致计算结果为 InfinityNaN,从而使 centerPoint 计算失效。建议对它们进行防御性处理,若为 0 或无效值,则回退到 this.ratio1
  2. doAction 中的一致性问题:虽然本次修改解决了 scrollTo(点击跳转)中的缩放比不一致问题,但在 doAction 方法(处理拖拽平移,约第 274-280 行)中,依然在使用 this.ratio 进行坐标转换。在非 scroller 模式下,这同样会导致拖拽视口时出现偏差(拖拽速度与鼠标不贴合)。建议在后续重构或同一 PR 中,将 doAction 中的 this.ratio 也替换为 targetScale.sxtargetScale.sy,以保持逻辑的一致性。
const targetScale = this.targetGraph.transform.getScale()
const sx = targetScale.sx || this.ratio || 1
const sy = targetScale.sy || this.ratio || 1

const cx = (x - ts.tx) / sx
const cy = (y - ts.ty) / sy

this.sourceGraph.centerPoint(cx, cy)
}

Expand Down