Highcharts Legend 拖拽插件

/**
 * Highcharts Draggable Legend Plugin
 * legend对象需添加 {floating: true, draggable:true}属性
 * @param HC Highcharts 对象
 * @author CG
 * @date 2024-09-05 14:35:21
 * @remark 使用方法 DraggableLegend(Highcharts)
 */
const DraggableLegend = (HC) => {
  /*一切的一切需在Highcharts实例存在的前提下执行*/
  if (!HC || !HC instanceof Object) {
    return
  }
  //事件枚举
  const MouseEvent = Object.freeze({
    MOUSE_DOWN: 'mousedown',
    MOUSE_MOVE: 'mousemove',
    MOUSE_UP: 'mouseup'
    //...其他事件没用到定义了也是浪费内存
  })
  /*通过wrap扩展Chart类的init方法并保留原来的init功能完整*/
  HC.wrap(HC.Chart.prototype, 'init', function (proceed) {
    /*包装器回调函数*/
    proceed.apply(this, Array.prototype.slice.call(arguments, 1));
    /*获取到Chart this指向HC.Chart.prototype*/
    const chart = this
    //如果legend的draggable为true
    if (chart.legend.options.draggable) {
      const {legend: {box}} = chart//获取到legend.box对象
      //添加鼠标样式为move标志
      box.css({cursor: 'move'});
      //定义鼠标按下时的Function对象
      const handleMousedown = (event) => {
        /*获取到Chart this指向HC.Chart.prototype ⚠在此处取值可以防止全屏模式无法拖动问题*/
        const {chartWidth, chartHeight, legend, legend: {options, legendWidth, legendHeight}} = chart//获取到chart及legend的相关对象
        event = chart.pointer.normalize(event);
        const {chartX, chartY} = event;//获取到鼠标按下时的x,y坐标
        const {x, y} = options;//获取到legend的x,y坐标
        const currentX = legend.group.attr('translateX');//记录鼠标按下时x的位置
        const currentY = legend.group.attr('translateY');//记录鼠标按下时y的位置
        let dragging = true;//标记鼠标是否正在拖动状态
        //使用闭包模式定义鼠标移动时的Function对象(一切起源于你在legend上按下了鼠标)
        const handleMousemove = (event) => {
          if (dragging) {
            event = chart.pointer.normalize(event);
            const draggedX = event.chartX - chartX;//获取到鼠标移动时的x坐标
            const draggedY = event.chartY - chartY;//获取到鼠标移动时的y坐标
            options.x = x + draggedX;//获取到legend的x坐标
            options.y = y + draggedY;//获取到legend的y坐标
            //拖动过程中判断是否出轨
            const isInsideBox = (currentX + draggedX > 0 && currentX + draggedX + legendWidth < chartWidth && currentY + draggedY > 0 && currentY + draggedY + legendHeight < chartHeight);
            //没出轨则更新位置
            if (isInsideBox) {
              legend.group.placed = false;//防止触发动画
              legend.group.align(HC.extend({width: legendWidth, height: legendHeight}, options), true, 'spacingBox');//定位
            }
            //如果有被选择的标记点
            if (chart.pointer.selectionMarker) {
              chart.pointer.selectionMarker = chart.pointer.selectionMarker.destroy();//销毁标记点dom元素
            }
          }
        };
        //使用闭包模式定义鼠标抬起时的Function对象(一切起源于你在legend上按下了鼠标)
        const handleMouseup = () => {
          dragging = false;//改变拖拽状态为false
          //本次拖动结束及时扫地释放内存
          HC.removeEvent(chart.container, MouseEvent.MOUSE_MOVE, handleMousemove);
          HC.removeEvent(document, MouseEvent.MOUSE_UP, handleMouseup);
        };
        //事件注册
        HC.addEvent(chart.container, MouseEvent.MOUSE_MOVE, handleMousemove);
        HC.addEvent(document, MouseEvent.MOUSE_UP, handleMouseup);
      };
      //在legend挂载鼠标按下事件
      HC.addEvent(box.element, MouseEvent.MOUSE_DOWN, handleMousedown);
    }
  });
}
export default DraggableLegend;//导出

使用方法:

import Highcharts from "highcharts";
import DraggableLegend from  "@/{your path}/draggable-legend"
DraggableLegend(Highcharts)


//Highcharts legend 配置
 legend: {
          enabled: true,
          floating: true,
          draggable:true,
          //others legend options.....
         }

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值