美文网首页
GGEditor使用说明

GGEditor使用说明

作者: Lethe35 | 来源:发表于2020-07-24 17:46 被阅读0次

    一、3.1.3版本

    1. 自定义节点RegisterNode

    <RegisterNode
      name="customStartNode"
      config={{
        getCustomConfig(model) {
          return {
            size: [80, 40],
            wrapperStyle: {
              fill: '#5E6A7D', // 节点最外层边框填充的颜色
            },
            contentStyle: {
              fill: '#5E6A7D',  // 节点内容区域填充的颜色
            },
            labelStyle: {
              fill: '#FFFFFF', // 节点内部文案的颜色
            },
          };
        },
        getAnchorPoints() {  // 节点可选的连接点集合,该点有4个可选的连接点
          return [
            [0.5, 0], // 上边中点
            [0.5, 1], // 下边中点
            [0, 0.5], // 左边中点
            [1, 0.5], // 右边中点
          ];
        },
      }}
      extend="bizFlowNode" // 要继承的节点类型
    />
    

    2. 自定义边RegisterEdge

    用法和RegisterNode类似,初始节点渲染到画布上可以显示自定义的边,但是从节点上新拉出的线死活都是默认的。文档没有提到,Issue也没相关的,尝试了n久,差点自闭。最后在放弃的边缘挣扎了下,看源码注意到个shape,灵感来了

    image.png

    重点来了:在FlowgraphConfig属性的defaultEdge中加上shape为自定义边的name就成了,成了成了成了……

    // 1. 自定义边
    <RegisterEdge
      name="testEdge"
      config={CustomFlowEdge}
      extend="polyline"
    />
    // 2. 把自定义边组件加到<GGEditor />标签内
    <GGEditor style={{ height: '100%' }}>
      <div className={styles.content}>
        {/* 2. 中间部分 */}
        <div className={styles.middle}>
          {/* 中间上部分 - 工具栏 */}
          <div className={styles['editor-toolbar']}>
            <FlowToolbar />
          </div>
          {/* 中间下部分 - 绘制面板 */}
          <div className={styles['editor-panel']}>
            <Flow
              className={styles.graph}
              data={data}
              style={{ backgroundColor: '#F8F8F8' }}
              graphConfig={{
                defaultNode: {
                  type: 'startNode',
                },
                defaultEdge: {
                  type: 'testEdge',
                  shape: 'testEdge',
                },
              }}
            />
            <StartNode />
            {/* <EditableLabel /> 节点标签编辑,好像只能编辑节点的,线的不行,位置有点问题 */}
            <FlowContextMenu />
          </div>
        </div>
        {/* 1. 左边部分 - 元素面板 */}
        <div className={styles['editor-item']}>
          <FlowItemPanel {...props} />
        </div>
        {/* 3. 右边部分 - 属性面板 */}
        <div className={styles[`detail-panel`]}>
          <FlowDetailPanel />
        </div>
      </div>
      <TestEdge />
    </GGEditor>
    

    3. 自定义命令RegisterCommand

    <RegisterCommand
      name="saveFlow"
      config={{
        canExecute() {
          return true;
        },
        shouldExecute() {
          return true;
        },
        canUndo() {
          return false;
        },
        init() { },
    
        execute: () => {
          const { onSave, graph } = this.props;
          const data = graph.save();
          onSave(data);
        },
        undo() { },
    
        shortcuts: [],
      }}
    />
    

    4. Item自定义节点元素

    它有4个属性,1个必须的属性model;5种状态

    // Item的4个属性
    style?: React.CSSProperties;
    className?: string;
    type?: ItemType;  // 可选node和edge
    model: Partial<NodeModel>;
    
    // Item的5种状态
    Active = 'active',
    ActiveAnchorPoints = 'activeAnchorPoints',
    Selected = 'selected',
    HighLight = 'highLight',
    Error = 'error',
    
    <Item
      className={styles.item}
      model={{
        type: 'circle',
        size: 50,
        label: 'circle',
      }}
    >
      <img
        src="https://gw.alicdn.com/tfs/TB1IRuSnRr0gK0jSZFnXXbRRXXa-110-112.png"
        width="55"
        height="56"
        draggable={false}
      />
    </Item>
    

    5. ContextMenu右键菜单

    好像有个bug:鼠标右键连续调出不同类型的菜单会多个同时显示

       // 菜单类型,可取值 canvas,node,edge;默认取canvas
      type?: ContextMenuType;
      // 菜单内容
      renderContent: (item: Item, position: { x: number; y: number }, hide: () => void) => React.ReactNode;
    
    <ContextMenu
      type='node'
      renderContent={(item, position, hide) => {
        const { x: left, y: top } = position;
        return (
          <div
            className={styles[`flow-context-menu`]}
            style={{ position: 'absolute', top: top + 80, left: left + 200 }}
          >
            {NODE_COMMAND_LIST.map((commandItem) => {
              const { _key, _name, _description, _icon } = commandItem;
              return (
                <Command
                  key={_key}
                  name={_name}
                  className={styles.command}
                  disabledClassName={styles.commandDisabled}
                >
                  <div onClick={hide}>
                    <Icon type={_icon} />
                    <span>{_description}</span>
                  </div>
                </Command>
              );
            })}
          </div>
        );
      }}
    />
    

    6. setAnchorPointsState设置连接点(锚点)的状态样式

    // 自定义节点时
    setState(name, value, item) {
      const group = item.getContainer();
      const shape = group.get('children')[0]; // 顺序根据 draw 时确定
      // 选中节点时的状态
      if (name === 'selected') {
        if (value) {
          shape.attr({
            fill: 'white',
            stroke: '#29BECE',
            opacity: 1,
          });
        } else {
          shape.attr({
            fill: 'white',
            stroke: 'rgba(41,190,206,0.50)',
          });
        }
      }
      setAnchorPointsState.call(
        this,
        name,
        value,
        item,
        (point, anchorPoint) => {
          const { width, height } = point.getKeyShape().getBBox();
    
          const [x, y] = anchorPoint;
          // 覆盖默认锚点的样式
          return {
            x: width * x - width / 2,
            y: height * y - height / 2,
            lineWidth: 1,
            fill: '#FFFFFF',
            stroke: '#29BECE',
          };
        },
        (point, anchorPoint) => {
          const { width, height } = point.getKeyShape().getBBox();
    
          const [x, y] = anchorPoint;
    
          return {
            x: width * x - width / 2,
            y: height * y - height / 2,
            lineWidth: 1,
            fill: '#FFFFFF',
            stroke: '#29BECE',
          };
        }
      );
    },
    

    二、2.0.4版本

    1. 复制、粘贴快捷键无效问题

    RegisterCommand自定义新命令继承原有复制、粘贴命令,设置快捷键

    import { RegisterCommand, withPropsAPI } from 'gg-editor';
    
    class PasteItemCommand extends React.Component {
      render() {
        const config = {
          // 快捷按键配置
          shortcutCodes: [["metaKey", "v"], ["ctrlKey", "v"]],
        };
    
        return <RegisterCommand name="pasteItem" config={config} extend="paste" />;
      }
    }
    
    export default withPropsAPI(PasteItemCommand);
    

    2. 自定义保存命令,执行后,命令行的撤销、重做命令错乱并且执行撤销或者重做后控制台报错如下

    image.png

    解决方法:定义命令时,queue属性设置为false(queue 表示 是否进入命令队列,进入命令队列则可以执行撤销、重做)

    3. 流程图保存(异步操作之后),原先选中的元素失去焦点问题

    解决方法:保存之前把选中的元素保存下来,执行保存方法之后手动把之前选中的元素设置成选中状态

    // 1.保存前把选中的元素存下来
    const { page } = flowRef.current; // flowRef为Flow的实例
    const selectedItems = page.getSelected().map(i => i.id); // 获取保存之前选中的元素
    
    // 2. 保存完(我这是再调获取流程图数据后)把之前存下来的选中的元素设置成选中状态
    page.setSelected(selectedItems, true);
    page.focusGraphWrapper();
    

    4. 自定义命令

    import React from "react";
    import { RegisterCommand } from "gg-editor";
    
    class CustomCommand extends React.Component {
      render() {
        const config = {
          // 是否进入列队,默认为 true
          queue: true,
    
          // 命令是否可用
          enable(/* editor */) {
            return true;
          },
    
          // 正向命令逻辑
          execute(/* editor */) {
            console.log("执行正向命令");
          },
    
          // 反向命令逻辑
          back(/* editor */) {
            console.log("执行反向命令");
          },
    
          // 快捷按键配置
          shortcutCodes: [["metaKey", "s"], ["ctrlKey", "s"]]
        };
    
        return <RegisterCommand name="customCommand" config={config} />;
      }
    }
    
    export default CustomCommand;
    

    相关文章

      网友评论

          本文标题:GGEditor使用说明

          本文链接:https://www.haomeiwen.com/subject/udszkktx.html