美文网首页
gojs实现自定义图表

gojs实现自定义图表

作者: wsj_2012 | 来源:发表于2020-10-20 15:45 被阅读0次

效果图:


截屏2020-10-20 下午3.36.51.png

1、vuecli创建gojs-demo脚手架工程。

package.json文件中引入gojs组件,vscode打开工程执行yarn命令

{
  "name": "gojs-demo",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "element-ui": "^2.13.0",
    "gojs": "^2.1.4",
    "svg-sprite-loader": "^4.1.6",
    "vue": "^2.6.11"
  },
  "devDependencies": {
    "@types/svgo": "^1.3.0",
    "@vue/cli-plugin-babel": "^4.5.0",
    "@vue/cli-plugin-eslint": "^4.5.0",
    "@vue/cli-service": "^4.5.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "less": "^3.10.3",
    "less-loader": "^5.0.0",
    "node-sass": "^4.14.1",
    "sass": "^1.26.10",
    "sass-loader": "^8.0.0",
    "svgo": "^1.1.0",
    "svgo-loader": "^2.1.0",
    "vue-cli-plugin-svg-sprite": "^1.0.0",
    "vue-template-compiler": "^2.6.11"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

2、在pages中添加类

  • 图表需要的数据data.vue
<script>
export default {
  data() {
    return {
      myjson: {
        class: "GraphLinksModel",
        linkFromPortIdProperty: "fromPort",
        linkToPortIdProperty: "toPort",
        nodeDataArray: [
          {
            category: "RoundedRectangle",
            text: "文件读取模块",
            name: "M_READER",
            func: "",
            params: "",
            floatText: "b",
            key: -1,
            loc: "-1106.2159292834895 -4446.625"
          },
          {
            category: "RoundedRectangle",
            text: "算法模块",
            name: "M_EXTRACTOR",
            func: "",
            params: "",
            floatText: "b",
            key: -2,
            loc: "-953.1523437500002 -4536.800781250001"
          },
          {
            category: "RoundedRectangle",
            text: "算法模块",
            name: "M_EXTRACTOR",
            func: "",
            params: "",
            floatText: "b",
            key: -7,
            loc: "-955.5390625000002 -4447.234375000001"
          },
          {
            category: "RoundedRectangle",
            text: "算法模块",
            name: "M_EXTRACTOR",
            func: "",
            params: "",
            floatText: "使用算法:逆向正则算法\n字段名称:超声所见\n参数:超声所见某某声提示",
            key: -8,
            loc: "-956.5078125000002 -4364.792968750001"
          },
          {
            category: "RoundedRectangle",
            text: "算法模块",
            name: "M_EXTRACTOR",
            func: "",
            params: "",
            floatText: "b",
            key: -11,
            loc: "-802.5546875000002 -4447.464843750001"
          },
          {
            category: "RoundedRectangle",
            text: "算法模块",
            name: "M_EXTRACTOR",
            func: "",
            params: "",
            floatText: "b",
            key: -9,
            loc: "-803.2812500000002 -4365.003906250001"
          },
          {
            category: "End",
            text: "OR",
            name: "M_OR",
            key: -10,
            loc: "-672.9257812500001 -4466.085937500001"
          }
        ],
        linkDataArray: [
          {
            from: -1,
            to: -2,
            fromPort: "R",
            toPort: "L",
            points: [
              -1065.7159292834895,
              -4458.875,
              -1055.7159292834895,
              -4458.875,
              -1003.6523437500002,
              -4536.800781250001,
              -993.6523437500002,
              -4536.800781250001
            ]
          },
          {
            from: -1,
            to: -7,
            fromPort: "R",
            toPort: "L",
            points: [
              -1065.7159292834895,
              -4446.625,
              -1055.7159292834895,
              -4446.625,
              -1006.0390625000002,
              -4447.234375000001,
              -996.0390625000002,
              -4447.234375000001
            ]
          },
          {
            from: -1,
            to: -8,
            fromPort: "R",
            toPort: "L",
            points: [
              -1065.7159292834895,
              -4434.375,
              -1055.7159292834895,
              -4434.375,
              -1007.0078125000002,
              -4364.792968750001,
              -997.0078125000002,
              -4364.792968750001
            ]
          },
          {
            from: -2,
            to: -10,
            fromPort: "R",
            toPort: "L",
            points: [
              -912.6523437500002,
              -4536.800781250001,
              -902.6523437500002,
              -4536.800781250001,
              -713.4257812500001,
              -4466.085937500001,
              -703.4257812500001,
              -4466.085937500001
            ]
          },
          {
            from: -7,
            to: -11,
            fromPort: "R",
            toPort: "L",
            points: [
              -915.0390625000002,
              -4447.234375000001,
              -905.0390625000002,
              -4447.234375000001,
              -853.0546875000002,
              -4447.464843750001,
              -843.0546875000002,
              -4447.464843750001
            ]
          },
          {
            from: -8,
            to: -9,
            fromPort: "R",
            toPort: "L",
            points: [
              -916.0078125000002,
              -4364.792968750001,
              -906.0078125000002,
              -4364.792968750001,
              -853.7812500000002,
              -4365.003906250001,
              -843.7812500000002,
              -4365.003906250001
            ]
          },
          {
            from: -9,
            to: -10,
            fromPort: "R",
            toPort: "L",
            points: [
              -762.7812500000002,
              -4365.003906250001,
              -752.7812500000002,
              -4365.003906250001,
              -713.4257812500001,
              -4466.085937500001,
              -703.4257812500001,
              -4466.085937500001
            ]
          },
          {
            from: -11,
            to: -10,
            fromPort: "R",
            toPort: "L",
            points: [
              -762.0546875000002,
              -4447.464843750001,
              -752.0546875000002,
              -4447.464843750001,
              -713.4257812500001,
              -4466.085937500001,
              -703.4257812500001,
              -4466.085937500001
            ]
          }
        ]
      }
    };
  }
};
</script>
  • 图表实现类FlowCharts.vue
<template>
  <div style="padding: 20 5; background: #EEEEEE">
    <div class="flow-btn">
      <el-button class="btn" type="primary" round plain @click="resetAction">重置</el-button>
      <el-button class="btn" type="primary" round plain>另存为</el-button>
      <el-button id="SaveButton" class="btn" type="primary" round plain @click="save">保存</el-button>
      <el-button class="btn" type="primary" round @click="runAction">运行</el-button>
    </div>

    <div class="canvas-head">
      <i class="el-icon-right" style="margin-right: 15px" @click="redo"></i>
      <i class="el-icon-back" style="margin-right: 15px" @click="undo"></i>
      <i class="el-icon-remove-outline" style="margin-right: 15px" @click="reduceCanvas"></i>
      <i class="el-icon-circle-plus-outline" style="margin-right: 15px" @click="enlargeCanvas"></i>
      <i class="el-icon-delete" @click="deleteNode"></i>

      <div class="flow-introduce">
        <svg-icon class="svg" name="introduce"></svg-icon>
        <!-- <i class="el-icon-edit"></i> -->
        <span>使用说明</span>
      </div>
    </div>
    <div class="canvas-container">
      <div class="content-left">
        <div class="custom-text" style="border-top-width: 0;">
          <span>自定义模型单元</span>
        </div>
        <div id="myPaletteTopDiv" style="width: 100%; height: 180px;"></div>
        <div class="custom-text">
          <span>关系操作符</span>
        </div>
        <div id="myPaletteBtDiv" style="width: 100%; height: 180px;"></div>
      </div>
      <div
        id="myDiagramDiv"
        v-show="show"
        :style="{flexGrow: 1, height: contentHeight, background: '#EEEEEE16'}"
      ></div>
      <div class="content-right">
        <div class="custom-text" style="border-top-width: 0;">
          <span>参数设置</span>
        </div>
        <div class="custom-text">
          <span>缩略图导航</span>
        </div>
        <div id="myOverviewDiv" style="width: 100%; height: 100px;"></div>
      </div>
    </div>
  </div>
</template>

<script>
import go from "gojs";
window.go = go;
var $ = go.GraphObject.make;
import datam from "./data";

export default {
  mixins: [datam],

  data() {
    return {
      myDiagram: null,
      myPalette: null,
      show: true
    };
  },

  computed: {
    contentHeight() {
      var h =
        document.documentElement.clientHeight || document.body.clientHeight;
      return h - 100 + "px";
    }
  },

  mounted() {
    this.load();
  },

  methods: {
    load() {
      this.init();
      // this.addNodeTemplate(this.User);
      // this.addNodeTemplate(this.Supplier);
      this.layout();
    },
    layout() {
      console.log(
        this.myjson.nodeDataArray.length +
          "  " +
          this.myjson.linkDataArray.length
      );
      this.myDiagram.model = go.Model.fromJson(this.myjson);
      //   this.myDiagram.layoutDiagram(true);
    },

    init() {
      this.myDiagram = $(
        go.Diagram,
        "myDiagramDiv", // must name or refer to the DIV HTML element
        {
          LinkDrawn: this.showLinkLabel, // this DiagramEvent listener is defined below
          LinkRelinked: this.showLinkLabel,
          "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,
          "undoManager.isEnabled": true, // enable undo & redo
          "animationManager.isEnabled": false, //禁止画布初始化动画
          "grid.visible": true, //显示网格
          "toolManager.hoverDelay": 0,
          ModelChanged: e => {
            if (e.isTransactionFinished) {
              console.log("ModelChanged");
            }
          },

          nodeSelectionAdornmentTemplate: $(
            go.Adornment,
            "Auto",
            $(go.Shape, {
              fill: null,
              stroke: "#1890FF",
              strokeWidth: 4
            }),
            $(go.Placeholder)
          )
        }
      );

      this.myOverview = $(go.Overview, "myOverviewDiv", {
        observed: this.myDiagram,
        contentAlignment: go.Spot.Center
      });

      // 背景网格线
      this.myDiagram.grid = $(
        go.Panel,
        go.Panel.Grid,
        { gridCellSize: new go.Size(25, 25) },
        $(go.Shape, "LineH", {
          stroke: "#A5B1BE",
          strokeWidth: 0.5,
          strokeDashArray: [2, 2, 2, 2]
        }),
        $(go.Shape, "LineV", {
          stroke: "#A5B1BE",
          strokeWidth: 0.5,
          strokeDashArray: [2, 2, 2, 2]
        })
      );

      this.myDiagram.addDiagramListener("externalobjectsdropped", e => {
        e.subject.each(n => {
          //得到从Palette拖过来的节点
          console.log(n.data.key);
          if (this.myjson && n.data.text === "文件读取模块") {
            let fileReaders = this.myjson.nodeDataArray.filter(v => {
              return v.text === "文件读取模块";
            });
            if (fileReaders.length > 1) {
              this.$message.error("添加失败, 文件读取模块只能有一个");
              this.myjson.nodeDataArray.pop();
              this.$nextTick(() => {
                this.myDiagram.model = go.Model.fromJson(this.myjson);
                this.myDiagram.layoutDiagram(true);
              });
            }
          }
        });
      });

      // when the document is modified, add a "*" to the title and enable the "Save" button
      this.myDiagram.addDiagramListener("Modified", () => {
        var button = document.getElementById("SaveButton");
        if (button) button.disabled = !this.myDiagram.isModified;
        var idx = document.title.indexOf("*");
        if (this.myDiagram.isModified) {
          if (idx < 0) document.title += "*";
        } else {
          if (idx >= 0) document.title = document.title.substr(0, idx);
        }
      });

      //添加监听线生成事件
      this.myDiagram.addDiagramListener("LinkDrawn", e => {
        console.log(e.subject.data);
        var fromNode = this.myDiagram.model.findNodeDataForKey(
          e.subject.data.from
        );
        var toNode = this.myDiagram.model.findNodeDataForKey(e.subject.data.to);
        console.log("from:" + fromNode);
        console.log("to:" + toNode);
        if (fromNode.text === "算法模块" && toNode.text === "文件读取模块") {
          this.$message.error("操作非法");
          this.myjson.linkDataArray.pop();
          this.$nextTick(() => {
            this.myDiagram.model = go.Model.fromJson(this.myjson);
            this.myDiagram.layoutDiagram(true);
          });
        }
      });
      this.myDiagram.addDiagramListener("ObjectSingleClicked", function(e) {
        console.log(e.subject.part.data);
      });
      this.myDiagram.addDiagramListener("ObjectContextClicked", function(e) {
        console.log(e.subject.part.data);
      });

      this.myDiagram.nodeTemplateMap.add(
        "", // the default category
        $(
          go.Node,
          "Table",
          this.nodeStyle(),
          $(
            go.Panel,
            "Auto",
            $(
              go.Shape,
              "RoundedRectangle",
              {
                desiredSize: new go.Size(80, 48),
                fill: "#E6F7FF",
                stroke: "#1890FF",
                strokeWidth: 1,
                minSize: new go.Size(80, 48),
                maxSize: new go.Size(80, 48)
              },
              //   new go.Binding("figure", "figure"),
              {
                // define a tooltip for each node that displays the color as text
                toolTip: $(
                  "ToolTip",
                  { background: "transparent" },
                  $(
                    go.TextBlock,
                    this.textStyle(),
                    { margin: 4 },
                    new go.Binding("text", "floatText")
                  )
                ) // end of Adornment
              }
            ),
            $(
              go.TextBlock,
              this.textStyle(),
              {
                maxSize: new go.Size(160, NaN),
                wrap: go.TextBlock.WrapFit,
                editable: false,
                textAlign: "center"
              },
              new go.Binding("text").makeTwoWay()
            )
          ),
          // four named ports, one on each side:
          this.makePort("T", go.Spot.Top, go.Spot.TopSide, true, true),
          this.makePort("L", go.Spot.Left, go.Spot.LeftSide, true, true),
          this.makePort("R", go.Spot.Right, go.Spot.RightSide, true, true),
          this.makePort("B", go.Spot.Bottom, go.Spot.BottomSide, true, true)
        )
      );

      this.myDiagram.nodeTemplateMap.add(
        "Conditional",
        $(
          go.Node,
          "Table",
          this.nodeStyle(),
          // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
          $(
            go.Panel,
            "Auto",
            $(
              go.Shape,
              "Diamond",
              {
                desiredSize: new go.Size(80, 72),
                fill: "#5CDBD333",
                stroke: "#5CDBD3",
                strokeWidth: 1
              },
              new go.Binding("figure", "figure")
            ),
            $(
              go.TextBlock,
              this.textStyle(),
              {
                // margin: 8,
                maxSize: new go.Size(160, NaN),
                wrap: go.TextBlock.WrapFit,
                textAlign: "center",
                editable: true
              },
              new go.Binding("text").makeTwoWay()
            )
          ),
          // four named ports, one on each side:
          this.makePort("T", go.Spot.Top, go.Spot.Top, false, true),
          this.makePort("L", go.Spot.Left, go.Spot.Left, true, true),
          this.makePort("R", go.Spot.Right, go.Spot.Right, true, true),
          this.makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
        )
      );

      this.myDiagram.nodeTemplateMap.add(
        "End",
        $(
          go.Node,
          "Table",
          this.nodeStyle(),
          $(
            go.Panel,
            "Spot",
            $(go.Shape, "Circle", {
              desiredSize: new go.Size(60, 60),
              fill: "#FFF2E8",
              stroke: "#FFC069",
              strokeWidth: 1
            }),
            $(go.TextBlock, "End", this.textStyle(), new go.Binding("text"))
          ),
          // three named ports, one on each side except the bottom, all input only:
          this.makePort("T", go.Spot.Top, go.Spot.Top, false, true),
          this.makePort("L", go.Spot.Left, go.Spot.Left, false, true),
          this.makePort("R", go.Spot.Right, go.Spot.Right, true, true)
        )
      );

      // taken from ../extensions/Figures.js:
      go.Shape.defineFigureGenerator("File", function(shape, w, h) {
        var geo = new go.Geometry();
        var fig = new go.PathFigure(0, 0, true); // starting point
        geo.add(fig);
        fig.add(new go.PathSegment(go.PathSegment.Line, 0.75 * w, 0));
        fig.add(new go.PathSegment(go.PathSegment.Line, w, 0.25 * h));
        fig.add(new go.PathSegment(go.PathSegment.Line, w, h));
        fig.add(new go.PathSegment(go.PathSegment.Line, 0, h).close());
        var fig2 = new go.PathFigure(0.75 * w, 0, false);
        geo.add(fig2);
        // The Fold
        fig2.add(new go.PathSegment(go.PathSegment.Line, 0.75 * w, 0.25 * h));
        fig2.add(new go.PathSegment(go.PathSegment.Line, w, 0.25 * h));
        geo.spot1 = new go.Spot(0, 0.25);
        geo.spot2 = go.Spot.BottomRight;
        return geo;
      });

      // replace the default Link template in the linkTemplateMap
      this.myDiagram.linkTemplate = $(
        go.Link, // the whole link panel
        {
          routing: go.Link.Normal,
          curve: go.Link.Bezier,
          corner: 5,
          toShortLength: 4,
          relinkableFrom: true,
          relinkableTo: true,
          reshapable: true,
          resegmentable: true,
          curviness: 100,
          // mouse-overs subtly highlight links:
          mouseEnter: function(e, link) {
            link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.2)";
          },
          mouseLeave: function(e, link) {
            link.findObject("HIGHLIGHT").stroke = "transparent";
          },
          selectionAdorned: true
        },
        new go.Binding("points").makeTwoWay(),
        $(
          go.Shape, // the highlight shape, normally transparent
          {
            isPanelMain: true,
            strokeWidth: 1,
            stroke: "transparent",
            name: "HIGHLIGHT"
          }
        ),
        $(
          go.Shape, // the link path shape
          { isPanelMain: true, stroke: "#ACB7C3", strokeWidth: 1.5 },
          new go.Binding("stroke", "isSelected", function(sel) {
            return sel ? "dodgerblue" : "#ACB7C3";
          }).ofObject()
        ),
        $(
          go.Shape, // the arrowhead
          { toArrow: "standard", strokeWidth: 0, fill: "#ACB7C3" }
        ),
        $(
          go.Panel,
          "Auto", // the link label, normally not visible
          {
            visible: false,
            name: "LABEL",
            segmentIndex: 2,
            segmentFraction: 0.5
          },
          new go.Binding("visible", "visible").makeTwoWay(),
          $(
            go.Shape,
            "Rectangle", // the label shape
            { fill: "#F8F8F8", strokeWidth: 0 }
          ),
          $(
            go.TextBlock,
            "Yes", // the label
            {
              textAlign: "center",
              font: "10pt helvetica, arial, sans-serif",
              stroke: "#333333",
              editable: true
            },
            new go.Binding("text").makeTwoWay()
          )
        )
      );

      //   this.myDiagram.nodeTemplate = $(
      //     go.Node,
      //     "Auto",
      //     // $(
      //     //   go.Shape,
      //     //   "Rectangle",
      //     // //   { fill: "red" },
      //     // //   new go.Binding("fill", "color")
      //     // ),
      //     // $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")),
      //     {
      //       // define a tooltip for each node that displays the color as text
      //       toolTip: $(
      //         "ToolTip",
      //         $(go.TextBlock, { margin: 4 }, new go.Binding("text", "text"))
      //       ) // end of Adornment
      //     }
      //   );

      this.myPaletteTop = $(
        go.Palette,
        "myPaletteTopDiv", // must name or refer to the DIV HTML element
        {
          // Instead of the default animation, use a custom fade-down
          "animationManager.initialAnimationStyle": go.AnimationManager.None,
          //   InitialAnimationStarting: this.animateFadeDown, // Instead, animate with this function
          nodeSelectionAdornmentTemplate: $(
            go.Adornment,
            "Auto",
            $(go.Shape, {
              fill: null,
              stroke: "#1890FF",
              strokeWidth: 4
            }),
            $(go.Placeholder)
          ),
          nodeTemplateMap: this.myDiagram.nodeTemplateMap, // share the templates used by myDiagram
          model: new go.GraphLinksModel([
            {
              category: "RoundedRectangle",
              text: "文件读取模块",
              name: "M_READER",
              func: "",
              params: "",
              floatText: "b"
            },
            {
              category: "RoundedRectangle",
              text: "算法模块",
              name: "M_EXTRACTOR",
              func: "",
              params: "",
              floatText: "b"
            }
          ])
        }
      );

      this.myPaletteBt = $(
        go.Palette,
        "myPaletteBtDiv", // must name or refer to the DIV HTML element
        {
          // Instead of the default animation, use a custom fade-down
          "animationManager.initialAnimationStyle": go.AnimationManager.None,
          //   InitialAnimationStarting: this.animateFadeDown, // Instead, animate with this function
          nodeSelectionAdornmentTemplate: $(
            go.Adornment,
            "Auto",
            $(go.Shape, {
              fill: null,
              stroke: "#1890FF",
              strokeWidth: 4
            }),
            $(go.Placeholder)
          ),
          nodeTemplateMap: this.myDiagram.nodeTemplateMap,
          model: new go.GraphLinksModel([
            { category: "Conditional", text: "AND", name: "M_AND" },
            { category: "End", text: "OR", name: "M_OR" }
          ])
        }
      );

      this.myDiagram.toolManager.linkingTool.temporaryLink.routing =
        go.Link.Orthogonal;
      this.myDiagram.toolManager.relinkingTool.temporaryLink.routing =
        go.Link.Orthogonal;
    },

    nodeStyle() {
      return [
        // The Node.location comes from the "loc" property of the node data,
        // converted by the Point.parse static method.
        // If the Node.location is changed, it updates the "loc" property of the node data,
        // converting back using the Point.stringify static method.
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(
          go.Point.stringify
        ),
        {
          // the Node.location is at the center of each node
          locationSpot: go.Spot.Center
        }
      ];
    },

    // Define a function for creating a "port" that is normally transparent.
    // The "name" is used as the GraphObject.portId,
    // the "align" is used to determine where to position the port relative to the body of the node,
    // the "spot" is used to control how links connect with the port and whether the port
    // stretches along the side of the node,
    // and the boolean "output" and "input" arguments control whether the user can draw links from or to the port.
    makePort(name, align, spot, output, input) {
      var horizontal =
        align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);
      // the port is basically just a transparent rectangle that stretches along the side of the node,
      // and becomes colored when the mouse passes over it
      return $(go.Shape, {
        fill: "transparent", // changed to a color in the mouseEnter event handler
        strokeWidth: 0, // no stroke
        width: horizontal ? NaN : 8, // if not stretching horizontally, just 8 wide
        height: !horizontal ? NaN : 8, // if not stretching vertically, just 8 tall
        alignment: align, // align the port on the main Shape
        stretch: horizontal
          ? go.GraphObject.Horizontal
          : go.GraphObject.Vertical,
        portId: name, // declare this object to be a "port"
        fromSpot: spot, // declare where links may connect at this port
        fromLinkable: output, // declare whether the user may draw links from here
        toSpot: spot, // declare where links may connect at this port
        toLinkable: input, // declare whether the user may draw links to here
        cursor: "pointer", // show a different cursor to indicate potential link point
        mouseEnter: function(e, port) {
          // the PORT argument will be this Shape
          if (!e.diagram.isReadOnly) port.fill = "rgba(255,0,255,0.5)";
        },
        mouseLeave: function(e, port) {
          port.fill = "transparent";
        }
      });
    },

    textStyle() {
      return {
        font: "solid 12pt PingFangSC-Regular, PingFang SC",
        stroke: "black",
        opacity: 0.65
      };
    },

    showLinkLabel(e) {
      var label = e.subject.findObject("LABEL");
      if (label !== null)
        label.visible = e.subject.fromNode.data.category === "Conditional";
    },

    save() {
      this.myDiagram.isModified = false;
      console.log(this.myDiagram.model.toJson());
    },

    resetAction() {
      this.myjson.nodeDataArray = [];
      this.myjson.linkDataArray = [];
      this.$nextTick(() => {
        this.myDiagram.model = go.Model.fromJson(this.myjson);
        this.myDiagram.layoutDiagram(true);
      });
    },

    runAction() {
      this.layout();
    },

    deleteNode() {
      if (this.myDiagram.commandHandler.canDeleteSelection()) {
        this.myDiagram.commandHandler.deleteSelection();
      } else {
        this.$message.error("未选中要删除的节点或连线");
      }
    },

    enlargeCanvas() {
      if (this.myDiagram.scale >= 1.4) {
        this.myDiagram.scale = 1.4;
      } else {
        this.myDiagram.scale += 0.1;
      }
    },

    reduceCanvas() {
      if (this.myDiagram.scale <= 0.4) {
        this.myDiagram.scale = 0.4;
      } else {
        this.myDiagram.scale -= 0.1;
      }
    },

    // 重做
    redo() {
      this.myDiagram.undoManager.redo();
    },

    undo() {
      this.myDiagram.undoManager.undo();
    }
  }
};
</script>

<style lang="scss">
* {
  outline: none;
}

div {
  border: none;
}

canvas {
  border: 0px;
  outline: none;
}

:focus {
  outline: 0;
}

.canvas-container {
  display: flex;
  justify-content: space-between;
  width: 100%;
  background: white;
  margin-top: 1px;
}

.content-left {
  width: 180px;
  margin-right: 2px;
  background-color: #f7f9fb;
  border-right: 1px solid #dce3e8;
}

.content-right {
  width: 200px;
  margin-left: 2px;
  border-left: 1px solid #dce3e8;
  background-color: #f7f9fb;
}

.custom-text {
  text-align: left;
  font-size: 14px;
  padding-left: 10px;
  height: 32px;
  margin-bottom: 10px;
  border-top: 1px solid #dce3e8;
  border-bottom: 1px solid #dce3e8;
  background: #fff;
  color: #000;
  line-height: 32px;
}

.flow-btn {
  position: absolute;
  bottom: 60px;
  right: 220px;
  z-index: 9999;
}

.canvas-head {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 44px;
  background: white;
  box-shadow: 0 8px 12px 0 rgba(0, 52, 107, 0.04);
}

.flow-introduce {
  position: absolute;
  top: 15px;
  right: 20px;
  z-index: 100;
  vertical-align: middle;

  span {
    font-family: PingFangSC-Regular;
    font-size: 16px;
    color: #666666;
    letter-spacing: 0;
    text-align: right;
    margin-left: 10px;
    vertical-align: text-bottom;
  }

  .svg {
    font-size: 20px;
    color: #666666;
    // vertical-align: middle;
    height: 20px;
    width: 20px;
  }
}

</style>

3、将FlowCharts.vue加载在主页中

App.vue中:

<template>
  <div id="app">
    <Charts />
  </div>
</template>

<script>
import Charts from './pages/FlowCharts.vue'
export default {
  name: "App",
  components: {
    Charts,
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

相关文章

  • gojs实现自定义图表

    效果图: 1、vuecli创建gojs-demo脚手架工程。 package.json文件中引入gojs组件,vs...

  • Gojs 快速入门

    一、前言Gojs提供了很多API给我们使用,下面只是提供完成关系图表(如下图)的某种方法,用其他方法也可以实现同样...

  • 使用Gojs实现族谱

    效果图 介绍 支持点击任何族人时,高亮显示该族人同一支的信息 通过颜色区分族人属性, 属性包括: 男、女、死亡、在...

  • IOS支持滑动的自定义柱形图

    实现效果 实现步骤: 1.自定义一个UIView,用来呈现整个图表。 2.UIView上绘制Y轴,Y轴显示标签。 ...

  • Android自定义View,画一个好看带延长线的饼状图

    前言 在Android中,图表的实现是比较麻烦的,基本只能通过自定义View来实现。目前Github上有一些集成度...

  • gojs库学习记录(一)

    gojs[https://gojs.net/latest/index.html] 图形库功能非常强大,大家先看它的...

  • 使用MPAndroid打造自定义Chart

    记一次工作内容_打造自定义Chart 工作需求需要实现一个自定义操作方式的图表,感觉还行,效果如下: 需求如下:1...

  • gojs

    Gojs项目文档 简介: Gojs 用canvas 作图,一般用来绘制流程图,关系图,表示节点与节点之间的关系,节...

  • Android自定义柱状图表

    本文通过示例代码介绍如何自定义简单的直方图表,此图表并非常见的直方图表,而是可以分组的。此文不会过多涉及原理,比较...

  • Android实现自定义view实现图表功能

    简单实现了一个自定义view,仅供学习用效果图:

网友评论

      本文标题:gojs实现自定义图表

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