1、首先下载GOJS

npm install gojs --save


2、Vue中使用

import gojs from "gojs";
var go = gojs;
var $ = go.GraphObject.make;
//代码所需要的JSON格式
import json from "./json";
//项目中应用到的图片
import zhong from "@/assets/basic/zhong.png";
import da from "@/assets/basic/da.png";
import xiao from "@/assets/basic/xiao.png";

3、将注册实例以及业务代码编写再init函数中在mounted挂载中调用

  init() {
      // 结合后端数据进行 赋值各项不同节点的与图片文字
      json["nodeDataArray"].forEach((item) => {
        switch (+item.size) {
          case 100:
            item.source = xiao;
            item.stroke = item.type === "0" ? "red" : "#56b1ff";
            break;
          case 150:
            item.source = zhong;
            item.stroke = "#fff";
            break;
          case 200:
            item.source = da;
            item.stroke = "#fff";
            break;
          default:
            item.source = xiao;
            break;
        }
        if (item.type === "0") {
          item.stroke = "red";
        }
      });
      // 判断实例是否存在进行数据变更
      if (this.myDiagram) {
        this.myDiagram.model = go.Model.fromJson(json);

        return;
      }

      this.myDiagram = $(
        go.Diagram,
        this.$refs.myDiagram, //获取原生dom进行gojs的注入
        {
          "undoManager.isEnabled": true, //是否可以进行撤销等操作
          // "undoManager.isEnabled": false,
          initialContentAlignment: go.Spot.Center, //启动视口中间的所有内容
          // "toolManager.mouseWheelBehavior": go.ToolManager.WheelNone, //鼠标滚轮事件禁止
          "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, //开启滚轮事件
          // allowHorizontalScroll: false, //禁止水平拖动
          // allowVerticalScroll: false, // 禁止垂直拖动
          // isReadOnly: true, //是否为只读状态
          minScale: 0.2, //  缩小临界值
          maxScale: 1.5, //放大临街值
          scale: 0.38, //初始视图大小比例
          LinkDrawn: this.maybeChangeLinkCategory, // 连线判断
          LinkRelinked: this.maybeChangeLinkCategory, // 连线判断
        }
      );

      const portSize = new go.Size(6, 6); //小节点大小
      var _that = this;
      // 给节点的设置右键按钮  //  nodeMenu上下文菜单
      const nodeMenu = $(
        "ContextMenu",
        this.makeButton("复制", (e, obj) =>
          e.diagram.commandHandler.copySelection()
        ),
        this.makeButton("粘贴", (e, obj) =>
          e.diagram.commandHandler.pasteSelection()
        ),
        this.makeButton("删除", (e, obj) =>
          e.diagram.commandHandler.deleteSelection()
        ),
        this.makeButton("更改背景", (e, obj) =>
          this.changeBackground(obj.part.adornedObject)
        ),
        this.makeButton("添加头部小节点", (e, obj) => this.addPort("top")),
        this.makeButton("添加左侧小节点", (e, obj) => this.addPort("left")),
        this.makeButton("添加右侧小节点", (e, obj) => this.addPort("right")),
        this.makeButton("添加底部小节点", (e, obj) => this.addPort("bottom"))
      );

      // 给小节点(端口)设置删除
      const portMenu = $(
        "ContextMenu",
        this.makeButton("更改小节点颜色", (e, obj) =>
          this.changeColor(obj.part.adornedObject)
        ),
        this.makeButton(
          "删除小节点",
          // 在click事件处理程序中,obj。一部分是装饰;
          // 它的父对象是端口
          (e, obj) => this.removePort(obj.part.adornedObject)
        ),
        this.makeButton("删除全部小节点", (e, obj) =>
          this.removeAll(obj.part.adornedObject)
        )
      );

      //   节点模板
      this.myDiagram.nodeTemplate = $(
        go.Node,
        "Table",
        {
          locationObjectName: "BODY",
          locationSpot: go.Spot.Center, //将节点放置中间
          selectionObjectName: "BODY",
          contextMenu: nodeMenu, // 去除右键
        },
        // 动态绑定位置信息
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(
          go.Point.stringify
        ),
        // 声明面板 the body
        $(
          go.Panel,
          "Auto",
          //   面板默认设置
          {
            row: 1,
            column: 1,
            name: "BODY",
            stretch: go.GraphObject.Fill,
          },
          $(
            go.Picture,
            {
              name: "Picture",
              source: zhong,
              width: 100,
              height: 100,
              cursor: "pointer",
            },
            //根据JSON格式动态绑定,第三个参数接受一个函数用户业务逻辑的判断
            new go.Binding("source", "source").makeTwoWay(),
            new go.Binding("width", "size", (size) => {
              return +size;
            }),
            new go.Binding("height", "size", (size) => {
              return +size;
            }).makeTwoWay(),
            new go.Binding("name", "type").makeTwoWay()
          ),
            // 这次我使用用的是图片代替节点样式 下面内容是设置节点样式部分
          // $(
          //   go.Shape,
          //   "Circle" , //圆形
          //   // fn( new go.Binding('backgroud').makeTwoWay()),

          //   {
          //     name: "SHAPE",
          //     //   背景色和填充
          //     background: null,

          //     // 内容颜色
          //     fill: "#59b2fb",
          //     //边框色
          //     stroke: '#fcfafa',
          //     strokeWidth: 5,
          //     cursor: "pointer",

          //     // figure: "Circle",
          //     // Ellipse椭圆
          //     // 最小值
          //     minSize: new go.Size(42, 42),
          //   },
          //   //   动态设置
          //   new go.Binding("background", "backgroud").makeTwoWay(),
          //   // new go.Binding("geometryString", "geometryString").makeTwoWay(),
          // ),
            
          $(
            go.TextBlock,
            {
              font: "11pt Helvetica, Arial, sans-serif",
              stroke: "#fff",
              cursor: "pointer",
              editable: false,
            },
            new go.Binding("text", "name").makeTwoWay(),
            new go.Binding("stroke", "stroke").makeTwoWay(),
            new go.Binding("font", "size", (k) => {
              switch (+k) {
                case 100:
                  return "10pt Helvetica, Arial, sans-serif";
                case 150:
                  return "21px Segoe UI,sans-serif";
                case 200:
                  return "24px Segoe UI,sans-serif";
                default:
                  return "11pt Helvetica, Arial, sans-serif";
              }
            })
          )
        ),
        // 设置小节点
        // 绑定 itemArray leftArray
        // 为itemArray中的每个项创建,并绑定到数据。左数组
        $(go.Panel, "Vertical", new go.Binding("itemArray", "leftArray"), {
          row: 1,
          column: 0,
          itemTemplate: $(
            go.Panel,
            {
              _side: "left", //内部属性,以便更容易地判断它位于哪一侧
              fromSpot: go.Spot.Left, //从左
              toSpot: go.Spot.Left, //到左
              fromLinkable: true,
              toLinkable: true,
              cursor: "pointer",
              contextMenu: portMenu,
            },
            new go.Binding("portId", "portId"),
            $(
              go.Shape,
              "Rectangle",
              {
                fill: "#2e68cc",
                stroke: null,
                strokeWidth: 5,
                desiredSize: portSize,
                margin: new go.Margin(10, -3),
              },
              new go.Binding("fill", "portColor")
            )
          ),
        }),
        $(go.Panel, "Horizontal", new go.Binding("itemArray", "topArray"), {
          row: 0,
          column: 1,
          itemTemplate: $(
            go.Panel,
            {
              _side: "top",
              fromSpot: go.Spot.Top,
              toSpot: go.Spot.Top,
              fromLinkable: true,
              toLinkable: true,
              cursor: "pointer",
              contextMenu: portMenu,
            },
            new go.Binding("portId", "portId"),
            $(
              go.Shape,
              "Rectangle",
              {
                stroke: null,
                strokeWidth: 0,
                desiredSize: portSize, //小节点大小
                margin: new go.Margin(0, 10),
              },
              new go.Binding("fill", "portColor")
            )
          ), // end itemTemplate
        }),
        $(go.Panel, "Vertical", new go.Binding("itemArray", "rightArray"), {
          row: 1,
          column: 2,
          itemTemplate: $(
            go.Panel,
            {
              _side: "right",
              fromSpot: go.Spot.Right,
              toSpot: go.Spot.Right,
              fromLinkable: true,
              toLinkable: true,
              cursor: "pointer",
              contextMenu: portMenu,
            },
            new go.Binding("portId", "portId"),
            $(
              go.Shape,
              "Rectangle",
              {
                stroke: null,
                strokeWidth: 0,
                desiredSize: portSize,
                margin: new go.Margin(6, 0),
              },
              new go.Binding("fill", "portColor")
            )
          ), // end itemTemplate
        }),
        $(go.Panel, "Horizontal", new go.Binding("itemArray", "bottomArray"), {
          row: 2,
          column: 1,
          itemTemplate: $(
            go.Panel,
            {
              _side: "bottom",
              fromSpot: go.Spot.Bottom,
              toSpot: go.Spot.Bottom,
              fromLinkable: true,
              toLinkable: true,
              cursor: "pointer",
              contextMenu: portMenu,
            },
            new go.Binding("portId", "portId"),
            $(
              go.Shape,
              "Rectangle",
              {
                stroke: null,
                strokeWidth: 0,
                fill: "#2e68cc",
                desiredSize: portSize,
                margin: new go.Margin(0, 10),
              },
              new go.Binding("fill", "portColor")
            )
          ), // end itemTemplate
        })
      );

      // 实线
      this.myDiagram.linkTemplate = $(
        "Link",
        {
          routing: go.Link.AvoidsNodes,
          adjusting: go.Link.FROM,
          curve: go.Link.JumpGap,
          reshapable: true,
          resegmentable: true,
          relinkableFrom: true,
          relinkableTo: true,
          corner: 4,
          toShortLength: 1,
          cursor: "pointer",
        },
        new go.Binding("points").makeTwoWay(),
        // 线条颜色
        $(
          "Shape",
          {
            name: "LINE",
            isPanelMain: true,
            stroke: "#5aaefd",
            // stroke: "#01C0CA",

            strokeWidth: 4,
          },
          new go.Binding("stroke", "color").makeTwoWay(),
          new go.Binding("strokeWidth", "voltage", (item) => {
            switch (item) {
              case "500kV":
                return 10;
              case "220kV":
                return 10;
              case "110kV":
                return 7;
              default:
                return 7;
            }
          })
        ),
    // 用于动画效果
        // $(
        //   "Shape",
        //   {
        //     isPanelMain: true,
        //     // stroke: "lightblue",
        //     stroke: "#01C0CA",
        //     // stroke: "",
        //     strokeWidth: 8,
        //     name: "DongHua",
        //     // 10 35
        //     strokeDashArray: [10, 35],
        //   },
        //   new go.Binding("stroke", "ShapeColor").makeTwoWay()
        // ),
        // 线路背景设置
        // $(go.Shape, "RoundedRectangle", {
        //   name: "SHAPE",
        //   fill: "rgba(255,255,255,0.4)",
        //   height: 24,
        //   strokeWidth: 1,
        //   // stroke: "rgba(255,255,255,0.8)",
        //   stroke: "rgba(255,255,255,0.8)",
        // }),
        $(
          go.TextBlock,
          "",
          {
            textAlign: "center",
            font: "12pt helvetica, arial, sans-serif",
            stroke: "#A1F9FA",
            editable: true,
          },
          new go.Binding("text", "port1").makeTwoWay()
        )
      );
    //在每条线中心添加小节点以便实现T接线方式
      this.myDiagram.nodeTemplateMap.add(
        "LinkLabel",
        $(
          "Node",
          {
            selectable: false,
            avoidable: false,
            layerName: "Foreground",
          },
          $("Shape", "Ellipse", {
            width: 10,
            height: 10,
            stroke: null,
            fill: null, //去掉小圆点
            portId: "",
            fromLinkable: true,
            toLinkable: true,
            cursor: "pointer",
          })
        )
      );

      // GraphLinkModel对链接标签节点的支持需要指定两个属性
      // 优化连线

      this.myDiagram.model = $(go.GraphLinksModel, {
        linkLabelKeysProperty: "labelKeys",
      });
      // 每当通过链接工具绘制新链接时,它还添加节点数据对象。
      // 用作链接的标签节点的,以允许向链接绘制链接或从链接绘制链接。
      this.myDiagram.toolManager.linkingTool.archetypeLabelNodeData = {
        category: "LinkLabel",
      };

      this.myDiagram.model = go.Model.fromJson(json);

        //动画效果
      // this.changeImg();
    },

4、判断连线是否为小黑点(并不是节点,而是用于T接线的黑点)

maybeChangeLinkCategory(e) {
      var link = e.subject;
      var linktolink = link.fromNode.isLinkLabel || link.toNode.isLinkLabel;
        //在线中判断是否连接小黑点用于个人业务逻辑
      e.diagram.model.setCategoryForLinkData(
        link.data,
        linktolink ? "linkToLink" : ""
      );
    },

5、右键按钮事件封装成公共方法

  //上下文button
    makeButton(text, action, visiblePredicate) {
      return $(
        "ContextMenuButton",
        $(go.TextBlock, text, {
          alignment: go.Spot.Left,
          margin: 5,
          textAlign: "center",
          font: "14px sans-serif",
          opacity: 0.85,
          stroke: "#404040",
          width: 100,
        }),
        { click: action },
        // don't bother with binding GraphObject.visible if there's no predicate
        visiblePredicate
          ? new go.Binding("visible", "", (o, e) =>
              o.diagram ? visiblePredicate(o, e) : false
            ).ofObject()
          : {}
      );
    },

6.对应的右键事件处理函数封装

  // 添加头部小节点
    addPort(side) {
      this.myDiagram.startTransaction("addPort");
      this.myDiagram.selection.each((node) => {
        // skip any selected Links
        if (!(node instanceof go.Node)) return;
        // compute the next available index number for the side
        let i = 0;
        while (node.findPort(side + i.toString()) !== node) i++;
        // now this new port name is unique within the whole Node because of the side prefix
        const name = side + i.toString();
        // get the Array of port data to be modified
        const arr = node.data[side + "Array"];
        if (arr) {
          // create a new port data object
          const newportdata = {
            portId: name,
            portColor: "#2e68cc",
          };
          // and add it to the Array of port data
          this.myDiagram.model.insertArrayItem(arr, -1, newportdata);
        }
      });
      this.myDiagram.commitTransaction("addPort");
    },
    // 删除小节点
    removePort(port) {
      this.myDiagram.startTransaction("removePort");
      const pid = port.portId;
      const arr = port.panel.itemArray;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].portId === pid) {
          this.myDiagram.model.removeArrayItem(arr, i);
          break;
        }
      }
      this.myDiagram.commitTransaction("removePort");
    },
    // 删除全部小节点
    removeAll(port) {
      this.myDiagram.startTransaction("removePorts");
      const nodedata = port.part.data;
      const side = port._side; // there are four property names, all ending in "Array"
      this.myDiagram.model.setDataProperty(nodedata, side + "Array", []); // an empty Array
      this.myDiagram.commitTransaction("removePorts");
    },
    // 更改小节点颜色
    changeColor(port) {
      this.myDiagram.startTransaction("colorPort");
      const data = port.data;
      this.myDiagram.model.setDataProperty(data, "portColor", "#ddd");
      this.myDiagram.commitTransaction("colorPort");
    },
    // 更改背景色
    changeBackground(port) {
      // this.myDiagram.startTransaction("colorPort");
      const data = port.data;
      this.myDiagram.model.setDataProperty(data, "source", error2);
      // this.myDiagram.commitTransaction("colorPort");
    },

7.动画效果的实现

AnimationYes() {
      var animation = new go.Animation();
      animation.easing = go.Animation.EaseLinear;
      this.myDiagram.links.each(function (link) {
        // 60 20
        animation.add(link.findObject("DongHua"), "strokeDashOffset", 60, 20);
      });
      animation.runCount = Infinity;
      animation.start();
    },

模拟电流

Logo

前往低代码交流专区

更多推荐