antvis / X6

🚀 JavaScript diagramming library that uses SVG and HTML for rendering.
https://x6.antv.antgroup.com
MIT License
5.76k stars 1.71k forks source link

edge-editor 双击编辑完后,点击画布空白处则内容丢失创建失败; 点击别的地方才成功。创建时如何初始化一段文字? #3797

Open hylerrix opened 1 year ago

hylerrix commented 1 year ago

问题描述

在使用官方示例 https://x6.antv.vision/en/examples/node/tool#editable 的时候没什么问题。这里求指点一下思路。

但我在业务中深度使用后出现了如下 gif 图的问题——“edge-tool 双击编辑完后,点击画布空白处则内容丢失创建失败; 点击别的地方才成功”。

同时在如下两个地方加入了点击事件的 console.log。

this.canvas.graph.on('blank:click', (e) => {
  console.log('!!!blank:click click event success')
})
window.canvas = canvas.current = new Canvas({
  container: x6Container.current,
})

<div ref={x6Container} onClick={() => { console.log('!!!x6 ref container click event success') }}/>

CleanShot 2023-07-21 at 22 43 18

如 gif 图所示:失败时 (点击画布空白区) 两个 console 先出现 !!!blank 再出现 !!!x6。成功时 (点击非画布空白区) 反而只出现了 !!!x6

所以有什么思路来让点击画布即 graph.on('blank:click', ) 时也能创建成功?我在 blank:click 里也没写 e.stopPropagation()e.preventDefault() 呀。

重现链接

暂无

重现步骤

和业务深度绑定,仅作探讨。

预期行为

希望如 gif 图所示点击非画布空白处时一样的,创建成功。

平台

屏幕截图或视频(可选)

No response

补充说明(可选)

No response

x6-bot[bot] commented 1 year ago

👋 @hylerrix

Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. To help make it easier for us to investigate your issue, please follow the contributing guidelines. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.

hylerrix commented 1 year ago

还有一个另一个问题是,双击创建时如何初始化一段默认值并全选并聚焦?

image

我试了一个 text: "initial...", 并不行...? 目前我还没进行自定义 tools (https://github.com/antvis/X6/pull/3577#issuecomment-1632561247),还是想把 edge-editor 直接用好。

this.graph.on('edge:dblclick', ({ cell, e }) => {
  const name = 'edge-editor'
  cell.addTools({
    name,
    args: {
      event: e,
      markup: [
        ...
      ],
      attrs: {
        backgroundColor: channel?.protocol.color,
        text: "initial...",
      },
    },
  })
hylerrix commented 1 year ago

✅ 初始化一段文字

我用的是 hack 技术:

const cellEditor = Array.from(document.querySelectorAll('[contenteditable]'))
  .find(dom => dom.className.indexOf('x6-cell-tool-editor') > -1)
if (!cellEditor) { return  }
const preContent = cellEditor.innerHTML
cellEditor.innerHTML = preContent.length
  ? preContent
  : (channel?.name || '')

❌ 点击空白画布创建和更新失败

我尝试了如下方案,只成功了一半,太多需要魔改的地方,暂时放弃。

this.graph.on('edge:dblclick', ({ cell, e, view }) => {
  // ...localStorage.setItem('cellEditorDistance', '100')
  localStorage.setItem('cellEditorId', cell.id)
  localStorage.setItem('cellEditorLabelIndex', e?.toElement?.parentElement?.dataset?.index)
  localStorage.setItem('cellEditorContent', cellEditor.innerHTML)
  localStorage.setItem('cellEditorEnabled', 'true')
  cellEditor.addEventListener('input', function(event){
    localStorage.setItem('cellEditorContent', cellEditor.innerHTML)
  })
this.canvas.graph.on('blank:click', (e) => {
  if (localStorage.getItem('cellEditorEnabled') === 'false') {
    return
  }

  const cellEditorId = localStorage.getItem('cellEditorId') || ''
  const cellEditorLabelIndex = localStorage.getItem('cellEditorLabelIndex')
  const cellEditorContent = localStorage.getItem('cellEditorContent') || ''
  const cellEditorDistance = localStorage.getItem('cellEditorDistance') || ''
  // cell prototype -> cls -> Edge -> Cell 中 Cell 是有 getLabelAt 等方法的
  const cell: any = this.canvas.graph.getCellById(cellEditorId)

  if (parseInt(cellEditorLabelIndex || '') >= 0) {
    // 修改之前已经有的标签,找到之前的标签并重新赋值debugger
    const label = cell?.getLabelAt(parseInt(cellEditorLabelIndex || ''))
    cell?.setLabelAt(parseInt(cellEditorLabelIndex || ''), {
      ...label,
      attrs: {
        ...label?.attrs,
        label: {
          ...label?.attrs?.label,
          text: cellEditorContent,
        }
      }
    })
  } else {
    // 新创建的标签,点击画布外丢失了,这里手动创建
    const label = {
      position: {
        distance: parseFloat(cellEditorDistance),
      },
      attrs: {
        label: {
          text: cellEditorContent,
        },
      },
    }
    cell?.appendLabel(label)
    return
  }
})
NewByVector commented 1 year ago

第一个问题我尝试复现,但是没法复现,可能和你的业务代码相关。第二个问题可以新增一个配置,也就是默认文本。欢迎提 PR。