react使用gg-editor编写拓扑编辑器

标题需求开发过程中使用文档地址

  • Ant Design Pro -demo地址
  • 语雀Graph文档
  • ant pro 使用指南

准备工作

  • 运行ant pro查看代码

地址引导
因为需要查看完整功能,因此选择完整版代码
react使用gg-editor编写拓扑编辑器_第1张图片

  • 查看代码:核心实现是gg-editor,版本号是2.0.2
    react使用gg-editor编写拓扑编辑器_第2张图片
    react使用gg-editor编写拓扑编辑器_第3张图片
  • 准备数据结构
    捕获数据结构react使用gg-editor编写拓扑编辑器_第4张图片
    回显数据结构:
    react使用gg-editor编写拓扑编辑器_第5张图片

项目中加载跟ant pro同版本的项目,因此代码可以参考ant pro

在开发过程中需额外增加的功能

  • 保存图谱
  • 下载图谱缩略图,png jpg 透明以及白底
  • 鼠标移入时,显示对应节点详情
  • 显示列表图谱小图翻阅,具体效果如下
    react使用gg-editor编写拓扑编辑器_第6张图片
    具体功能实现:
    1.保存图谱+redux
import React from 'react';
import { withPropsAPI } from 'gg-editor';
import { Button } from 'antd';
import { connect } from 'react-redux'; 
import { RootState } from '../../../redux/rootReducer'; 
import { asyncActionsCreator } from '../../../pages/relationship_graph/action';

export interface EditorCommand {
  relationResourceDatas: any;
  relataBtn: any;
  addGraphData: any;
  editGraphData: any;
  [key: string]: any;
  editorTag: any;
}
class Save extends React.Component {
  constructor(EditorCommand) {
    super(EditorCommand);
  }

  handleClick = () => {
    const { propsAPI } = this.props as any;
    const { relationResourceDatas, editGraphData, inputval, editorTag, isFisrt } = this.props;
    propsAPI.save();
    const graphData = JSON.parse(JSON.stringify(propsAPI.save())); //保存下来的数据
  };

  render() {
    return (
      
    );
  }
}

const mapStateToProps = (state: RootState) => {
  const {redux方法 } = state.ReliationShipGraph;


  return {
  redux方法 
  };
};

const mapDispatchToProps = (dispatch: any) => {
  return {
   redux值: (val) => dispatch(asyncActionsCreator.addGraphRelation(val)),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(withPropsAPI(Save as any)); 

方法来源:
react使用gg-editor编写拓扑编辑器_第7张图片react使用gg-editor编写拓扑编辑器_第8张图片

2.下载图谱缩略图,png jpg 透明以及白底

function downloadImg(type: string, state?: boolean) {
    //绘制画布
    const divCanvas: Element | any = document.getElementsByClassName('graph-container')[0];
    //缩略画布
    const minicanvas = divCanvas.getElementsByTagName('canvas')[0];
    if (minicanvas) {
      let src = '';
      const ctx = minicanvas.getContext('2d');
      const imgW = minicanvas.width;
      const imgH = minicanvas.height;
      const imageData = ctx.getImageData(0, 0, imgW, imgH);
      //jpg白色透明背景  png白色
      if (type == 'jpg') {
        for (let i = 0; i < imageData.data.length; i += 4) {
          if (imageData.data[i + 3] < 128) {
            imageData.data[i] = 255;
            imageData.data[i + 1] = 255;
            imageData.data[i + 2] = 255;
            imageData.data[i + 3] = 255;
          }
        }
        ctx.putImageData(imageData, 0, 0);
        src = minicanvas.toDataURL('image/jpeg');
        const file = dataURLtoBlob(src, '关系图谱图片', type);
        if (!state) {
          return file;
        } else {
          downloadCanvasIamge(src, '关系图谱', type);
        }
      } else {
        for (let i = 0; i < imageData.data.length; i += 4) {
          // 当该像素是透明的,则设置成白色
          //改变rgb
          if (imageData.data[i + 3] < 128) {
            imageData.data[i] = 255;
            imageData.data[i + 1] = 255;
            imageData.data[i + 2] = 255;
            imageData.data[i + 3] = 0;
          }
        }
        ctx.putImageData(imageData, 0, 0);
        src = minicanvas.toDataURL('image/png');
      }
      if (!state) {
        downloadCanvasIamge(src, '关系图谱', type);
      }
    }
  }

  function downloadCanvasIamge(src, name, type) {
    // 通过选择器获取canvas元素
    // 使用toDataURL方法将图像转换被base64编码的URL字符串
    // let url = canvas.toDataURL('image/png');
    // const url = canvas.toDataURL('image/png');
    // 生成一个a元素
    const a = document.createElement('a');
    // 创建一个单击事件
    const event = new MouseEvent('click');
    // 将a的download属性设置为我们想要下载的图片名称,若name不存在则使用‘下载图片名称’作为默认名称
    a.download = name || '下载图片名称';
    // 将生成的URL设置为a.href属性
    a.href = src;

    // 触发a的单击事件
    a.dispatchEvent(event);
  }

  • 鼠标移入移出问题
function onMouseEnter(params: any) {
    if (
      params._type === 'mouseenter' &&
      // params._isItemChange &&
      params.shape?.eventPreFix == 'node'
    ) {
     //移入
    }
  }
  • 图谱列表,采用组件react-slick
import React, { useState, useEffect, useMemo, FC } from 'react';
import Slider from 'react-slick';
// import './styles.css';
import CanEditInput from '../../../components/canEditInput';
import styles from './index.module.scss';
import { Image, Tag, Row, Col, Empty } from 'antd';
import tagColors from '../../../style/tag-colors';
import SeeTuoPuEditoer from '../../../components/relationship_graph/seeGraph/index';
import { useDispatch } from 'react-redux';
import { actionType } from '../../../pages/relationship_graph/action';

type IProps = {
  datas: any; // 图谱数据+ img轮播图数据 + 其他数据
};

const GraphImgLIst: FC<IProps> = (props: IProps) => {
  const dispatch = useDispatch();
  const { datas } = props;
  const [itemData, setitemData] = useState<any>({}); //slider settings

  const settings = {
    dots: false,
    infinite: false,
    speed: 500,
    slidesToShow: 5,
    slidesToScroll: 2,
    initialSlide: 0,
    className: 'centerBox',
  };
  useEffect(() => {
    if (datas && datas.length) {
      setitemData(datas[0]);
      dispatch({ type: actionType.GET_GRAPH_EDITDATA, payload: datas[0] });
    }
  }, [datas]);

  const imgListDom = useMemo(() => {
    return datas?.map((item) => {
      return (
        <div key={item.id}>
          <Image
            className={itemData?.id === item.id ? styles.img : undefined}
            width="100%"
            key={item.id}
            src={`/index/RelationGraph/getImage?image_path=` + item.icon}
            preview={false}
            onClick={() => imgClick(item)}
          ></Image>
          <div style={{ paddingLeft: 8, fontWeight: 500 }}>{item.name}</div>
        </div>
      );
    });
  }, [datas, itemData]);
  function imgClick(data: any): void {
    setitemData(data);
    dispatch({ type: actionType.GET_GRAPH_EDITDATA, payload: data });
  }
  return (
    <div className={styles.normal}>
      {datas && datas.length ? (
          <Slider {...settings}>{imgListDom}</Slider>
      ) : (
        <Empty style={{ margin: '20px 0px' }} />
      )}
    </div>
  );
};
export default GraphImgLIst;

你可能感兴趣的:(React,react.js,编辑器,javascript)