react + gojs

1,825 阅读4分钟

官方 GoJS with Reactgojs-react

通过 gojs-react 简化,gojs在react项目中的使用,gojs-react 提供了 ReactDiagramReactPaletteReactOverview 以供使用, gojs-react-basic 提供了示例用法。
  1. 安装 npm install gojs gojs-react
  2. 设置画布样式,需要指定宽度/高度。
    /* App.css */
    .diagram-component {
      width: 400px;
      height: 400px;
      border: solid 1px black;
      background-color: white;
    }
    
  3. 基础应用
    // App.js
    import React from 'react';
    import * as go from 'gojs';
    import { ReactDiagram } from 'gojs-react';
    import './App.css';  // 引入对应样式/**
     * 初始化图表方法,该方法用于制作图表初始化模型模版;模型的数据不由此设置,ReactDiagram组件通过其他props处理
     */
    function initDiagram() {
      const $ = go.GraphObject.make;
      const diagram =
        $(go.Diagram,
          {
            'undoManager.isEnabled': true,  // 撤销管理器,应始终启用 UndoManager 以允许发生事务,但可以将 UndoManager.maxHistoryLength 设置为 0 以防止撤消和重做
            // 'undoManager.maxHistoryLength': 0,  // 取消注释禁用撤消/重做功能
            'clickCreatingTool.archetypeNodeData': { text: 'new node', color: 'lightblue' },
            model: $(go.GraphLinksModel,
              {
                linkKeyProperty: 'key'  // 使用 GraphLinksModel 时应始终设置此项
              })
          });
    ​
      diagram.nodeTemplate =
        $(go.Node, 'Auto',
          new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
          $(go.Shape, 'RoundedRectangle',
            { name: 'SHAPE', fill: 'white', strokeWidth: 0 },
            // 图形填充颜色和数据对象的color绑定
            new go.Binding('fill', 'color')),
          $(go.TextBlock,
            { margin: 8, editable: true }, 
            new go.Binding('text').makeTwoWay()
          )
        );
    ​
      return diagram;
    }
    ​
    function handleModelChange(changes) {
      alert('GoJS model changed!');
    }
    ​
    // linkDataArray 链接关系数组,只有在使用 GraphLinksModel 时才需要,而Models或 TreeModels 则不需要
    function App() {
      return (
        <div>
          ...
          <ReactDiagram
            initDiagram={initDiagram}
            divClassName='diagram-component'
            nodeDataArray={[
              { key: 0, text: 'Alpha', color: 'lightblue', loc: '0 0' },
              { key: 1, text: 'Beta', color: 'orange', loc: '150 0' },
              { key: 2, text: 'Gamma', color: 'lightgreen', loc: '0 150' },
              { key: 3, text: 'Delta', color: 'pink', loc: '150 150' }
            ]}
            linkDataArray={[
              { key: -1, from: 0, to: 1 },
              { key: -2, from: 0, to: 2 },
              { key: -3, from: 1, to: 1 },
              { key: -4, from: 2, to: 3 },
              { key: -5, from: 3, to: 0 }
            ]}
            onModelChange={handleModelChange}
          />
          ...
        </div>
      );
    }
    

    画鱼骨图参考 vue+gojs 绘制鱼骨图 实现,需要引入对应FishboneLayout.js

  4. 获取图片
    • makeImage 返回<img src='...base64...' >
    • makeImageData 返回 base64 字符串(如果显示为黑色,不显示线条,尝试将 background: 'white'

      此方法使用 HTMLCanvasElement 的 toDataURL 方法创建数据 URL,或 Canvas Context 的 getImageData 方法。 与 toDataURL 不同的是,如果在画布上绘制了跨域图像,此方法不会抛出错误,而是会返回忽略这些图像的位图的数据 URL

    按照如上官方提供的基础案例和获取图片方法,会下意识的认为要写在 initDiagram 对应的方法里,但实际上写在这获取数据为null,应该是因为在这一步并没有生成Dom元素。
    useRef 设置变量,在 initDiagram 对应的方法里将 diagram 赋值 给对应变量,然后在 onModelChange 对应方法中用获取图片的方法获取到对应值。
    //如上个案例的重复部分就不赘述,用省略替代,结合前面理解
    import React, { useRef } from 'react';
    // ...省略其他import引入...
    const Diagram = ({}) => {
        const diagramRef = useRef(null);
        const initDiagram = () => {
            const $ = go.GraphObject.make;
            const diagram = $(go.Diagram, {
                isReadOnly: true
            });
            ...
        diagramRef.current = diagram;
        return diagram;
      };
      const handleModelChange = (changes) => {
          diagramRef.current.makeImageData({ 
              background: 'white', 
              type:'image/jpeg' 
          });
      };
        // ...省略其他设置方法...
        return (
            <ReactDiagram
              initDiagram={initDiagram}
              onModelChange={handleModelChange}
              // ...省略其他设置...
            />
      );
    }
    export default Diagram;
    ```react + gojs
    

官方 GoJS with Reactgojs-react

通过 gojs-react 简化,gojs在react项目中的使用,gojs-react 提供了 ReactDiagramReactPaletteReactOverview 以供使用, gojs-react-basic 提供了示例用法。
  1. 安装 npm install gojs gojs-react
  2. 设置画布样式,需要指定宽度/高度。
    /* App.css */
    .diagram-component {
      width: 400px;
      height: 400px;
      border: solid 1px black;
      background-color: white;
    }
    
  3. 基础应用
    // App.js
    import React from 'react';
    import * as go from 'gojs';
    import { ReactDiagram } from 'gojs-react';
    import './App.css';  // 引入对应样式/**
     * 初始化图表方法,该方法用于制作图表初始化模型模版;模型的数据不由此设置,ReactDiagram组件通过其他props处理
     */
    function initDiagram() {
      const $ = go.GraphObject.make;
      const diagram =
        $(go.Diagram,
          {
            'undoManager.isEnabled': true,  // 撤销管理器,应始终启用 UndoManager 以允许发生事务,但可以将 UndoManager.maxHistoryLength 设置为 0 以防止撤消和重做
            // 'undoManager.maxHistoryLength': 0,  // 取消注释禁用撤消/重做功能
            'clickCreatingTool.archetypeNodeData': { text: 'new node', color: 'lightblue' },
            model: $(go.GraphLinksModel,
              {
                linkKeyProperty: 'key'  // 使用 GraphLinksModel 时应始终设置此项
              })
          });
    ​
      diagram.nodeTemplate =
        $(go.Node, 'Auto',
          new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
          $(go.Shape, 'RoundedRectangle',
            { name: 'SHAPE', fill: 'white', strokeWidth: 0 },
            // 图形填充颜色和数据对象的color绑定
            new go.Binding('fill', 'color')),
          $(go.TextBlock,
            { margin: 8, editable: true }, 
            new go.Binding('text').makeTwoWay()
          )
        );
    ​
      return diagram;
    }
    ​
    function handleModelChange(changes) {
      alert('GoJS model changed!');
    }
    ​
    // linkDataArray 链接关系数组,只有在使用 GraphLinksModel 时才需要,而Models或 TreeModels 则不需要
    function App() {
      return (
        <div>
          ...
          <ReactDiagram
            initDiagram={initDiagram}
            divClassName='diagram-component'
            nodeDataArray={[
              { key: 0, text: 'Alpha', color: 'lightblue', loc: '0 0' },
              { key: 1, text: 'Beta', color: 'orange', loc: '150 0' },
              { key: 2, text: 'Gamma', color: 'lightgreen', loc: '0 150' },
              { key: 3, text: 'Delta', color: 'pink', loc: '150 150' }
            ]}
            linkDataArray={[
              { key: -1, from: 0, to: 1 },
              { key: -2, from: 0, to: 2 },
              { key: -3, from: 1, to: 1 },
              { key: -4, from: 2, to: 3 },
              { key: -5, from: 3, to: 0 }
            ]}
            onModelChange={handleModelChange}
          />
          ...
        </div>
      );
    }
    

    画鱼骨图参考 vue+gojs 绘制鱼骨图 实现,需要引入对应FishboneLayout.js

  4. 获取图片
    • makeImage 返回<img src='...base64...' >
    • makeImageData 返回 base64 字符串(如果显示为黑色,不显示线条,尝试将 background: 'white'

      此方法使用 HTMLCanvasElement 的 toDataURL 方法创建数据 URL,或 Canvas Context 的 getImageData 方法。 与 toDataURL 不同的是,如果在画布上绘制了跨域图像,此方法不会抛出错误,而是会返回忽略这些图像的位图的数据 URL

    按照如上官方提供的基础案例和获取图片方法,会下意识的认为要写在 initDiagram 对应的方法里,但实际上写在这获取数据为null,应该是因为在这一步并没有生成Dom元素。
    useRef 设置变量,在 initDiagram 对应的方法里将 diagram 赋值 给对应变量,然后在 onModelChange 对应方法中用获取图片的方法获取到对应值。
    //如上个案例的重复部分就不赘述,用省略替代,结合前面理解
    import React, { useRef } from 'react';
    // ...省略其他import引入...
    const Diagram = ({}) => {
        const diagramRef = useRef(null);
        const initDiagram = () => {
            const $ = go.GraphObject.make;
            const diagram = $(go.Diagram, {
                isReadOnly: true
            });
            ...
        diagramRef.current = diagram;
        return diagram;
      };
      const handleModelChange = (changes) => {
          diagramRef.current.makeImageData({ 
              background: 'white', 
              type:'image/jpeg' 
          });
      };
        // ...省略其他设置方法...
        return (
            <ReactDiagram
              initDiagram={initDiagram}
              onModelChange={handleModelChange}
              // ...省略其他设置...
            />
      );
    }
    export default Diagram;