PointsBuild前端点位辅助创建工具--帮你快速创建echart链路图,不用再一个个点位修改了

本文介绍了作者开发的前端辅助工具PointsBuild,用于简化链路图中点位的创建过程。通过提供React代码示例,展示了如何使用该工具进行DOM定位和坐标系定位,减少了手动调整坐标的时间。文章还提供了配置说明和安装方式,鼓励读者根据需求进行扩展,如适配地图点位。
摘要由CSDN通过智能技术生成

这几天写链路图,边写边想写这东西这么消耗体力,就想写个小工具出来能加快效率,但奈何比较懒,想着链路图应该很快能调好,可发现调了一个多小时,线还没开始,麻了!
链路图效果
思考了下,工具写起来应该比较简单,然后花了点时间写了这个PointsBuild,废话不多说,上代码::

import React, { useState, useRef } from 'react';
import Clipboard from 'clipboard';

/**
 * 链路图点位工具
 * @param {number} cartesianMaxY y轴最大值,默认为0,表示DOM定位方式
 * @param {number} width 占位宽度
 * @param {number} height 占位高度
 * @param {url} background 占位背景
 * @param {json} style 占位style
 * @param {bool} notice 是否提示复制信息
 * @param {string} formatter 数据输出格式,使用${x}${y}占位
 * @param {bool} multi 多点连续输出,默认单点输出
 */

const listenerCatch = (obj, e, hander) => {
  if (obj.addEventListener) {
    obj.addEventListener(e, hander, false);
  } else if (obj.attachEvent) {
    e = 'on' + e;
    obj.attachEvent(e, hander);
  }
};
const cancelEvent = (e) => {
  if (e.preventDefault) {
    e.preventDefault();
    e.stopPropagation();
  } else {
    e.returnValue = false;
    e.cancelBubble = true;
  }
};

const PointsBuild = ({
  cartesianMaxY = 0,
  width = 100,
  height = 100,
  background = null,
  style = {},
  notice = true,
  formatter = '',
  multi = false,
}) => {
  const [top, setTop] = useState(0);
  const [left, setLeft] = useState(0);
  const [mesWidth, setWidth] = useState(0);
  const [pointer, points, ref] = [useRef({ x: 0, y: 0 }), useRef(''), useRef(null)];

  const drag = (e) => {
    !pointer.current.x && !pointer.current.y && listenerCatch(document, 'mousemove', mousemove);
    pointer.current = { x: e.pageX, y: e.pageY };
  };

  const mousemove = (e) => {
    cancelEvent(e);
    let [x, y] = [e.pageX, e.pageY];
    if (ref.current.offsetLeft <= 5 && ref.current.offsetTop <= 5) points.current = '';
    setLeft((l) => l + x - pointer.current.x);
    setTop((t) => t + y - pointer.current.y);
    pointer.current = { x: x, y: y };
  };

  const copy = (e) => {
    let text;
    if (formatter) {
      let [x, y] = cartesianMaxY ? [left + width / 2, cartesianMaxY - top - height / 2] : [left, top];
      if (points.current.indexOf('${x}') == -1) multi ? (points.current += formatter) : (points.current = formatter);
      points.current = points.current.replace('${x}', x).replace('${y}', y);
      text = points.current;
    } else {
      cartesianMaxY && (points.current += `[${left + width / 2}, ${cartesianMaxY - top - height / 2}],`);
      text = cartesianMaxY ? points.current : `left: '${left}px', top: '${top}px',`;
    }
    const clipboard = new Clipboard('.btn', {
      text: function () {
        return text;
      },
    });
    clipboard.on('success', () => {
      clipboard.destroy();
    });
    clipboard.on('error', function () {
      clipboard.destroy();
    });
    clipboard.onClick(e);
    if (notice) {
      const mes = document.createElement('div');
      mes.className = `mes-mark`;
      document.body.appendChild(mes);
      mes.textContent = `复制坐标${text}成功`;
      setWidth(mes.clientWidth);
      setTimeout(() => {
        mes.remove();
      }, 1500);
    }
  };

  return (
    <div onMouseDown={(e) => drag(e)} onClick={(e) => copy(e)} ref={ref} style={style} className="pointsbuild-mark">
      <style jsx="true">
        {`
          .pointsbuild-mark {
            width: ${width}px;
            height: ${height}px;
            background: url(${background}) center no-repeat;
            position: absolute;
            top: ${top}px;
            left: ${left}px;
            border: 1px solid red;
            z-index: 100000;
          }
          .mes-mark {
            position: fixed;
            top: 50px;
            font-size: 18px;
            padding: 0 20px;
            border-radius: 8px;
            line-height: 30px;
            height: 30px;
            background: rgba(255, 255, 255, 1);
            left: calc(50% - ${mesWidth / 2}px);
          }
        `}
      </style>
    </div>
  );
};

export default PointsBuild;

代码是react的,vue就不写了,其实一样的,先来看看这东西怎么用的:
请添加图片描述
请添加图片描述
替代了原先在代码上一个个写定位然后在浏览器上面调坐标的方式,直接写好格式化输出语句,直接在浏览器上取点直接复制到代码上即可。现在来说说怎么使用:

/**
 * 链路图点位工具
 * @param {number} cartesianMaxY y轴最大值,默认为0,表示DOM定位方式
 * @param {number} width 占位宽度
 * @param {number} height 占位高度
 * @param {url} background 占位背景
 * @param {json} style 占位style
 * @param {bool} notice 是否提示复制信息
 * @param {string} formatter 数据输出格式,使用${x}${y}占位
 * @param {bool} multi 多点连续输出,默认单点输出
 */

cartesianMaxY区分是DOM定位还是坐标系定位,为0是dom定位,坐标系定位时,这里要填入最大纵坐标值,width、height、background、style是定位框的大小样式,可以直接用需要定位的元素替代。notice是否弹出提示框,formatter是输出格式, x {x} x{y}是占位符,输出时会替换为对应坐标值。multi设置多点输出还是单点输出,没有设置formatter在坐标系模式下默认多点输出。示例如下:

<PointsBuild
  cartesianMaxY={1445}
  width={25}
  height={17}
  multi={true}
  //formatter是string格式,这里为了方便展示,用了``格式
  formatter={`{
    lineStyle: {
      color: '#fff',
      type: 'solid',
      opacity: 1,
    },
    coords: [
      [${'${x}'}, ${'${y}'}],
      [${'${x}'}, ${'${y}'}],
      [${'${x}'}, ${'${y}'}],
    ],
  },`}
/>

DOM定位配置比较简单,把这个组件扔到需要定位的元素同一父节点(为了定位一致)下就行,坐标系定位的话需要另外将坐标系展示范围设置和父节点一致,cartesianMaxY设为y轴最大值,具体配置如下:

<ReactEcharts
  // 父节点大小
  style={{ width: 3500, height: 1445 }}
  option={options}
/>
// 设置展示区域为100%以及x、y轴的最大值与父节点分辨率一致
const options = {
  grid: {
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
  },
  xAxis: {
    min: 0,
    max: 3500,
  },
  yAxis: {
    min: 0,
    max: 1445,
  }
 }

以上配置都是为了获取范围的坐标系与应用的坐标系保持一致,好了设置好这些就能食用了。
安装方式

npm install pointsbuild -D

有兴趣的同学可以改成读取地图点位的,需要考虑比例尺以及原点位置。

本文原创,未经授权,谢绝转载!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值