Echarts可编辑多边形

460 阅读1分钟

动画.gif

绘制多边形

只需要将折线图进行首尾相连即可实现多边形效果。

const seriesLine = {
    type: 'line',
    data: [[0,0],[1,2], [3,5],[0,0]],
    name: 'name',
    z: 1 // 这个层级设置很关键,后面会说明
}

编辑多编辑

捕获mousedown mousemove mouseup事件

通过echarts的内置事件,可以很轻易的捕获多边形端点的mousedown事件。 但是如何捕获mousemove事件呢?echarts的mousemove事件需要一个载体,否则无法获取鼠标在坐标系中的位置。可以在图表中添加graphic组件,覆盖整个图表,透明隐藏

graphic 是原生图形元素组件。可以支持的图形元素包括: imagetextcirclesectorringpolygonpolylinerectlinebezierCurvearcgroup,

在echarts的配置项中添加graphic, 初始需要将z=0,否则无法捕获到鼠标点击端点

const graphic = [
      {
        type: 'rect',
        left: 'center',
        top: 'center',
        z: 0,
        shape: {
          width: 4000,
          height: 4000,
        },
        style: {
          fill: 'rgba(0,0,0,0)',
        },
      },
    ]

然后在鼠标点击到多边形端点的时候,将graphic的层级提升,并且注册mouseup事件

chart.on('mousedown', (e) => {
    const { seriesName, event } = e
    if (event.which === 1) { // 点击左键
      
      // 判断点击的目标是否是多边形端点
      if (seriesName !== 'name') return
      dragging = true
      drag = e
      chart.setOption({ graphic: [{ type: 'rect', z: 100 }] })
      document.body.addEventListener(
        'mouseup',
        () => {
          dragging = false
          chart.setOption({ graphic: [{ type: 'rect', z: 0 }] })
          
        },
        { once: true }
      )
    }
})

然后监听mousemove事件, 在鼠标移动的时候同时更新serice.data,

  chart.on('mousemove', (e) => {
    if (!dragging || e.event.which !== 1) return
    const { event } = e
    const { offsetX, offsetY } = event || {}
    // 坐标系转换
    const [x1, y1] = chart.getModel?.().getSeriesByIndex(0).coordinateSystem.pointToData([offsetX, offsetY])
    // drag:当前拖拽的端点
    const index = drag.dataIndex === data.length ? 0 : drag.dataIndex
    seriesLine[index] = [x1, y1]
    // 重新绘制echats
    chart.setOption({ series: [seriesLine] }, { replaceMerge: ['series'] })
  })

官网示例

拖拽的实现