GGEditor使用说明

一、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;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335