Giter Club home page Giter Club logo

ggeditor's Introduction

English | 简体中文

GGEditor

基于 G6React 的可视化图编辑器

GitHub npm npm

安装

npm

npm install gg-editor --save

umd

<script src="https://unpkg.com/gg-editor@${version}/dist/index.js"></script>

使用

流程图

Edit GGEditor - Flow

import GGEditor, { Flow } from 'gg-editor';

const data = {
  nodes: [
    {
      id: '0',
      label: 'Node',
      x: 55,
      y: 55,
    },
    {
      id: '1',
      label: 'Node',
      x: 55,
      y: 255,
    },
  ],
  edges: [
    {
      label: 'Label',
      source: '0',
      target: '1',
    },
  ],
};

<GGEditor>
  <Flow style={{ width: 500, height: 500 }} data={data} />
</GGEditor>;

脑图

Edit GGEditor - Mind

import GGEditor, { Mind } from 'gg-editor';

const data = {
  label: 'Central Topic',
  children: [
    {
      label: 'Main Topic 1',
    },
    {
      label: 'Main Topic 2',
    },
    {
      label: 'Main Topic 3',
    },
  ],
};

<GGEditor>
  <Mind style={{ width: 500, height: 500 }} data={data} />
</GGEditor>;

示例

# 克隆仓库
$ git clone https://github.com/alibaba/GGEditor.git

# 切换目录
$ cd gg-editor

# 安装依赖
$ npm install

# 运行示例
$ npm start

ggeditor's People

Contributors

gaoli avatar lzcers avatar marckon avatar tennisonchan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ggeditor's Issues

请问Flowd实例方法在React中应该如何调用,如flow.save()

首先感谢作者提供这么棒的react解决方案,请问一下作者在框架中应该如何使用原生API中的实例方法呢?比如导出flow的data,在原生api中是flow.save(),但是在React版的Flow里面并没有见到实例方法,在此请教一下作者,多谢。

怎样调用save方法,保存数据?

因为save不是有效的Command命令,
所以我现在是使用react的ref获取到对应的graph实例做的.
请问是这样做吗?

renderMind() {
    return (
      <Mind
        data={data}
        ref={(ref) => { this.mindRef = ref; }}
        className={styles.mind}
      />
    );
  }

  componentDidMount() {
    // 能够打印出相关数据
    console.log(this.mindRef.graph.save());
  }

如何阻止添加node?

比如我要判断只能添加一次开始节点,添加第二次时就不让他添加成功怎么办?

新手快速入门

这个开源资源挺好的,按照我的理解这个应该就是我npm启动以后打开页面就可以直接操作。作为没有前端知识的小白来说,作者能否写简单且详细的快速入门使用手册,教如何一步步操作,可以进入到操作界面自由绘图

请问如何在群组上监听双击事件

  • 查看源码Page发现只支持node和edge
GRAPH_MOUSE_EVENTS.forEach((event) => {

      const eventName = GRAPH_MOUSE_REACT_EVENTS[event]

      addListener(this.graph, `node:${event}`, this.props[`onNode${eventName}`]);

      addListener(this.graph, `edge:${event}`, this.props[`onEdge${eventName}`]);

    });
  • 并且发现Flow,onClick事件都是无法使用的
import GGEditor, { Flow } from 'gg-editor';
<GGEditor><Flow
    onClick={(e) => {
      console.log(e);
    }}
  /></GGEditor>

Command有没有办法告诉它的父(祖先)组件当前命令不可用?

问题描述:

因为我的右键菜单会有二级菜单,故选用了antd.Menu来实现相关功能.
而目前Command作为Menu.Item的子组件,当Command为不可用状态时,Menu.Item不能知道Command当前的状态.
虽然Command组件上会添上disable类,可以通过css来修改样式,但是在这种情况下修改的样式过多,且很可能破坏Menu.Item的样式.

问题截图:

image

理想的状态是:

Menu.Item能够知道Command当前不可用,从而直接设置Menu.Item的disabled属性为true

次理想的状态:

当Command不能用的时候,能够在父(祖先)添加对应的类,从而更方便的书写css代码.

相关代码

ProcessEditorContextMenu.js

// 库引入
import React, { Component } from 'react';
import { inject, observer } from 'mobx-react';
import classNames from 'classnames';
import { ContextMenu, NodeMenu, CanvasMenu, EdgeMenu, Command } from 'gg-editor';
import { Menu, Icon } from 'antd';

//组件引入
import { IconFont } from '../../../../components/IconFont';

// 样式引入
import styles from './style.module.less';

// 一些值
const { Item: MenuItem } = Menu;

/**
 * Editor的右键菜单
 * 考虑到可能会有二级菜单,故使用antd.Menu
 */
@observer
class ProcessEditorContextMenu extends Component {
  render() {
    return (
      <ContextMenu className={ classNames(styles.processEditorContextMenu, this.props.className) } style={ this.props.style }>
        {/* 节点的右键菜单 */ }
        <NodeMenu>
          <Menu
            mode="vertical"
            selectable={ false }>
            <MenuItem><Command name="copy"><Icon type="copy" theme="outlined" /><span>复制</span></Command></MenuItem>
            <MenuItem><Command name="delete"><Icon type="delete" theme="outlined" /><span>删除</span></Command></MenuItem>
          </Menu>
        </NodeMenu>
        {/* 画布的右键菜单 */ }
        <CanvasMenu>
          <Menu
            mode="vertical"
            selectable={ false }>
            <MenuItem><Command name="undo"><Icon type="undo" theme="outlined" /><span>撤销</span></Command></MenuItem>
            <MenuItem><Command name="redo"><Icon type="redo" theme="outlined" /><span>重做</span></Command></MenuItem>
            <MenuItem><Command name="pasteHere"><IconFont type="icon-paste" /><span>粘贴</span></Command></MenuItem>
          </Menu>
        </CanvasMenu>
        {/* 连线的右键菜单 */ }
        <EdgeMenu>
          <Menu
            mode="vertical"
            selectable={ false }>
            <MenuItem><Command name="delete"><Icon type="delete" theme="outlined" /><span>删除</span></Command></MenuItem>
          </Menu>
        </EdgeMenu>
      </ContextMenu>
    );
  }
}

ProcessEditorContextMenu.defaultProps = {
};

const InjectProcessEditorContextMenu = inject(({ someStore = {} }) => ({ someProps: someStore.attribute }))(ProcessEditorContextMenu);

export {
  ProcessEditorContextMenu,
  InjectProcessEditorContextMenu
};

style.module.less

.processEditorContextMenu {
  // 默认是不可见的,除非右键点击
  display: none;
  :global {
    .ant-menu {
      border: none;
      border-radius: 4px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, .15);
    }
    // :has不管用现在
    .ant-menu-item:has(.disable) {
      color: red;
    }
  }
}

RegisterBehaviour组件报错:TypeError: page.behaviourOn is not a function

问题描述:
image

相关代码:

// 库引入
import React, {Component} from 'react';
import { RegisterBehaviour } from 'gg-editor';

class RegisterProcessMouseEnterFillRedBehaviour extends Component {
  mouseEnterFillRed = page =>{
    page.behaviourOn('node:mouseenter', ev=>{
      console.log('node:mouseenter');
      page.update(ev.item, {
        color: 'red'
      });
    });
  };
  render() {
    return (
      <RegisterBehaviour name="mouseEnterFillRed" behaviour={this.mouseEnterFillRed} />
    );
  }
}

RegisterProcessMouseEnterFillRedBehaviour.defaultProps = {
};

export {
  RegisterProcessMouseEnterFillRedBehaviour,
};

关于 onNodeDrop 和 onNodeDragEnd 触发的机制,是否是 BUG ?

问题描述:

我想实现的效果——不允许将某类型的节点拖动到另一特定类型的节点后面:通过拖动完成获取新的父节点类型来决定是否撤销此次拖动操作。
具体请看下面动图演示,拖动了三次,只有第二次光标在 placeholder 上释放时才能触发 onNodeDrop,并正确获取到新的父节点;
也尝试过使用 onNodeDragEnd,虽然此事件无论光标在哪儿释放都能触发,但只有在 placeholder 上释放才能正确获取到新的父节点(只要光标在 placeholder 附近释放都能拖动成功)

问题截图:

-2018-10-29-10 41 53

理想的状态是:

只要拖动成功,每次都触发 onNodeDrop (不论光标在哪儿释放)

次理想的状态:

光标只要不是在 placeholder 上释放,都拖动失败

相关代码

<Mind
    data={xmindData}
    className={styles.xmind}
    graph={{ fitView: 'cc' }}
    onNodeDrop={e => {
        const { propsAPI } = this.props;
        console.log('触发了 onNodeDrop: ', e);
        const parent = e && e.item && e.item.getParent();
        const parentModel = parent && parent.getModel();
        console.log('获取到的 parentModel: ', parentModel);
        if (parentModel && parentModel.type === 'jump') {
            propsAPI.executeCommand('undo');
            message.error('禁止该操作!');
        }
    }}
/>

似乎不能正确撤销属性修改操作?

问题描述

我在自己的开发中遇到了这个问题,
查看gg-editor官方 demo,也有这个问题

操作步骤:

1.第一步:拖曳Item到画布上
2.第二步:重命名Item
3.第三步:点击撤销按钮

期望:

当点击撤销按钮的时候,应该撤销重命名操作

实际情况:

当点击撤销按钮的时候,撤销了第一步的操作

如图所示:

qq 20181015114825

其他

g6-editor的相关 demo 没有这个问题

执行build时报错

13 verbose stack Error: [email protected] build: NODE_ENV=production node --max_old_space_size=8192 ./node_modules/webpack/bin/webpack --config ./tools/webpack.config.prod.js --colors --profile --optimize-minimize
13 verbose stack Exit status 1
13 verbose stack at EventEmitter. (D:\Programs\nodejs\node_modules\npm\node_modules\npm-lifecycle\index.js:285:16)
13 verbose stack at emitTwo (events.js:126:13)
13 verbose stack at EventEmitter.emit (events.js:214:7)
13 verbose stack at ChildProcess. (D:\Programs\nodejs\node_modules\npm\node_modules\npm-lifecycle\lib\spawn.js:55:14)
13 verbose stack at emitTwo (events.js:126:13)
13 verbose stack at ChildProcess.emit (events.js:214:7)
13 verbose stack at maybeClose (internal/child_process.js:925:16)
13 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
14 verbose pkgid [email protected]
15 verbose cwd D:\Projects\react\gg-editor
16 verbose Windows_NT 10.0.17134
17 verbose argv "D:\Programs\nodejs\node.exe" "D:\Programs\nodejs\node_modules\npm\bin\npm-cli.js" "run" "build" "--scripts-prepend-node-path=auto"
18 verbose node v8.11.1
19 verbose npm v5.6.0
20 error code ELIFECYCLE
21 error errno 1
22 error [email protected] build: NODE_ENV=production node --max_old_space_size=8192 ./node_modules/webpack/bin/webpack --config ./tools/webpack.config.prod.js --colors --profile --optimize-minimize
22 error Exit status 1
23 error Failed at the [email protected] build script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

流程图报错

错误如下

bundle.js:7 Uncaught TypeError: Cannot read property 'getShape' of undefined
    at e.n.getShapeObj (bundle.js:7)
    at e.<anonymous> (bundle.js:13)
    at e.c.emitEvent (bundle.js:19)
    at e.c.emit (bundle.js:19)
    at bundle.js:13
    at Object.t.exports (bundle.js:1)
    at e.setSelected (bundle.js:13)
    at Object.n [as method] (bundle.js:13)
    at Object.a [as execute] (bundle.js:13)
    at Object.d.execute (bundle.js:13)
    at e.value (bundle.js:19)
    at e.<anonymous> (bundle.js:13)
    at e.c.emitEvent (bundle.js:13)
    at e.c.emit (bundle.js:13)
    at e.n.emitGraphEvent (bundle.js:7)
    at e.n._triggerEvent (bundle.js:7)
    at e.n._simulateEvents (bundle.js:7)
    at HTMLCanvasElement.<anonymous> (bundle.js:7)

代码如下:

        <RegisterNode name='model-card' config={modelCardConfig} />
        <RegisterNode name='k-means' config={keyMeandsConfig} extend='model-card' />
        <Flow 
        className={styles.flow} 
        data={data} 
        grid 
        item 
        />
        <FlowContextMenu />
      </Fragment>

优化事件名称

Many of the event names in the G6 editor are not in camelcase or snack case. That is really hard to work with and translate to react style events, like from afteritemunselected to onAfterItemUnselected.

如果要显示tooltip,最好的办法是什么呢?

需求描述

鼠标移入Item时,显示该Item的详细信息,移出则隐藏详细信息.

遇到的问题

1.没有内置Tooltip组件
2.想使用自定义交互进行处理,又遇到了 #78 的问题
所以就暂时卡住了

请问如何能够屏蔽掉 Mind 节点上的双击事件?

我在 Mind Demo 的基础上作了少量修改,以便我在 NodePanel 区域可以同时修改文本和文本颜色,这导致我双击 Mind 节点进入编辑状态时,节点读取到的是一个 [object Object],无法正常展示节点文本,部分代码如下:

// NodeDetail.js
// ...

let { label } = item.getModel();
if (typeof label === 'string') {
  label = {
    text: label,
    fill: '#333',
  };
}

// ...
// mind.js
export default {
  roots: [
    {
      label: {
        text: '根节点',
        fill: 'red',
      },
      children: [
        // ...
      ],
    },
  ],
};

我有尝试重写 graph 上监听的双击事件,但并不能覆盖默认的编辑事件
那么,我想请教有没有办法简单粗暴的屏蔽掉 Mind 节点上的双击编辑事件,保留单击选中,只让在右侧 NodePanel 区域编辑呢?
或者另一种方案:是否可以考虑让节点能够解析部分 html 标签以及样式呢?类似 Flow 的自定义图项?
以上,谢谢!

在结合vue开发时报错

[HMR] Waiting for update signal from WDS...
vue.runtime.esm.js?2b0e:587 [Vue warn]: Error in render: "TypeError: Cannot call a class as a function"

found in

---> at src/components/HelloWorld.vue
at src/App.vue

warn @ vue.runtime.esm.js?2b0e:587
logError @ vue.runtime.esm.js?2b0e:1733
globalHandleError @ vue.runtime.esm.js?2b0e:1728
handleError @ vue.runtime.esm.js?2b0e:1717
Vue._render @ vue.runtime.esm.js?2b0e:4542
updateComponent @ vue.runtime.esm.js?2b0e:2784
get @ vue.runtime.esm.js?2b0e:3138
Watcher @ vue.runtime.esm.js?2b0e:3127
mountComponent @ vue.runtime.esm.js?2b0e:2791
Vue.$mount @ vue.runtime.esm.js?2b0e:7995
init @ vue.runtime.esm.js?2b0e:4133
createComponent @ vue.runtime.esm.js?2b0e:5604
createElm @ vue.runtime.esm.js?2b0e:5551
createChildren @ vue.runtime.esm.js?2b0e:5678
createElm @ vue.runtime.esm.js?2b0e:5580
patch @ vue.runtime.esm.js?2b0e:6087
Vue._update @ vue.runtime.esm.js?2b0e:2656
updateComponent @ vue.runtime.esm.js?2b0e:2784
get @ vue.runtime.esm.js?2b0e:3138
Watcher @ vue.runtime.esm.js?2b0e:3127
mountComponent @ vue.runtime.esm.js?2b0e:2791
Vue.$mount @ vue.runtime.esm.js?2b0e:7995
init @ vue.runtime.esm.js?2b0e:4133
createComponent @ vue.runtime.esm.js?2b0e:5604
createElm @ vue.runtime.esm.js?2b0e:5551
patch @ vue.runtime.esm.js?2b0e:6126
Vue._update @ vue.runtime.esm.js?2b0e:2656
updateComponent @ vue.runtime.esm.js?2b0e:2784
get @ vue.runtime.esm.js?2b0e:3138
Watcher @ vue.runtime.esm.js?2b0e:3127
mountComponent @ vue.runtime.esm.js?2b0e:2791
Vue.$mount @ vue.runtime.esm.js?2b0e:7995
(anonymous) @ main.js?56d7:6
./src/main.js @ app.js:2142
webpack_require @ app.js:725
fn @ app.js:102
0 @ app.js:2155
webpack_require @ app.js:725
(anonymous) @ app.js:792
(anonymous) @ app.js:795
vue.runtime.esm.js?2b0e:1737 TypeError: Cannot call a class as a function
at i (bundle.js?af06:19)
at e (bundle.js?af06:19)
at resolveAsyncComponent (vue.runtime.esm.js?2b0e:2334)
at createComponent (vue.runtime.esm.js?2b0e:4215)
at _createElement (vue.runtime.esm.js?2b0e:4416)
at createElement (vue.runtime.esm.js?2b0e:4353)
at vm._c (vue.runtime.esm.js?2b0e:4485)
at Proxy.render (eval at ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules\.cache\vue-loader","cacheIdentifier":"25898f58-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/components/HelloWorld.vue?vue&type=template&id=469af010&scoped=true& (app.js:924), :11:6)
at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:4540)
at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:2784)

propsAPI为undefined的问题

如下代码可以重现

import React from 'react';
import { withPropsAPI } from 'gg-editor';

class Component extends React.Component {
  componentDidMount() {
    const { propsAPI } = this.props;

    console.log(propsAPI);
  }
  render(){
    return <div>222</div>
  }
}

export default withPropsAPI(Component);

afterAddPage 事件阅读来源

像编辑器上的afterAddPage时间,在g6-editor的官方文档也没有说明,请问你们是阅读源代码找到的吗?是怎么找到的啊?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.