gojs实现流程图(含绑定某数据)

首先引用go-debug.js  https://download.csdn.net/download/qq_37528703/12038175

html示例1:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Draggable Link</title>
    <meta name="description" content="Drag a link to reconnect it. Nodes have custom Adornments for selection, resizing, and reshaping." />
    <!-- Copyright 1998-2017 by Northwoods Software Corporation. -->
    <meta charset="UTF-8">
    <link type="text/css" rel="stylesheet" href="/syyj/jslib/miniui/themes/default/miniui.css" />
    <script type="text/javascript" src="../js/go-debug.js"></script>
    <script type="text/javascript" src="/syyj/jslib/jquery/jquery-1.8.3-min.js"></script>
    <script type="text/javascript" src="/syyj/jslib/miniui/miniui.js"></script>
    <script id="code">
        var yaid;
        function init() {
            if (window.goSamples) goSamples();  // init for these samples -- you don't need to call this
            var objGo = go.GraphObject.make;  // for conciseness in defining templates

            myDiagram =
                objGo(go.Diagram, "myDiagramDiv",  // must name or refer to the DIV HTML element
                    {
                        grid: objGo(go.Panel, "Grid",
                            objGo(go.Shape, "LineH", { stroke: "lightgray", strokeWidth: 0.5 }),
                            objGo(go.Shape, "LineH", { stroke: "gray", strokeWidth: 0.5, interval: 10 }),
                            objGo(go.Shape, "LineV", { stroke: "lightgray", strokeWidth: 0.5 }),
                            objGo(go.Shape, "LineV", { stroke: "gray", strokeWidth: 0.5, interval: 10 })
                        ),
                        allowDrop: true,  // must be true to accept drops from the Palette
                        "draggingTool.dragsLink": true,
                        "draggingTool.isGridSnapEnabled": true,
                        "linkingTool.isUnconnectedLinkValid": true,
                        "linkingTool.portGravity": 20,
                        "relinkingTool.isUnconnectedLinkValid": true,
                        "relinkingTool.portGravity": 20,
                        "relinkingTool.fromHandleArchetype":
                            objGo(go.Shape, "Diamond", { segmentIndex: 0, cursor: "pointer", desiredSize: new go.Size(8, 8), fill: "tomato", stroke: "darkred" }),
                        "relinkingTool.toHandleArchetype":
                            objGo(go.Shape, "Diamond", { segmentIndex: -1, cursor: "pointer", desiredSize: new go.Size(8, 8), fill: "darkred", stroke: "tomato" }),
                        "linkReshapingTool.handleArchetype":
                            objGo(go.Shape, "Diamond", { desiredSize: new go.Size(7, 7), fill: "lightblue", stroke: "deepskyblue" }),
                        rotatingTool: objGo(TopRotatingTool),  // defined below
                        "rotatingTool.snapAngleMultiple": 15,
                        "rotatingTool.snapAngleEpsilon": 15,
                        "undoManager.isEnabled": true,
                        "LinkDrawn": showLinkLabel,  // this DiagramEvent listener is defined below
                        "LinkRelinked": showLinkLabel,
                    });

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

            // Define a function for creating a "port" that is normally transparent.
            // The "name" is used as the GraphObject.portId, the "spot" is used to control how links connect
            // and where the port is positioned on the node, and the boolean "output" and "input" arguments
            // control whether the user can draw links from or to the port.
            function makePort(name, spot, output, input) {
                // the port is basically just a small transparent square
                return objGo(go.Shape, "Circle",
                    {
                        fill: null,  // not seen, by default; set to a translucent gray by showSmallPorts, defined below
                        stroke: null,
                        desiredSize: new go.Size(7, 7),
                        alignment: spot,  // align the port on the main Shape
                        alignmentFocus: spot,  // just inside the Shape
                        portId: name,  // declare this object to be a "port"
                        fromSpot: spot, toSpot: spot,  // declare where links may connect at this port
                        fromLinkable: output, toLinkable: input,  // declare whether the user may draw links to/from here
                        cursor: "pointer"  // show a different cursor to indicate potential link point
                    });
            }

            var nodeSelectionAdornmentTemplate =
                objGo(go.Adornment, "Auto",
                    objGo(go.Shape, { fill: null, stroke: "deepskyblue", strokeWidth: 1.5, strokeDashArray: [4, 2] }),
                    objGo(go.Placeholder)
                );

            var nodeResizeAdornmentTemplate =
                objGo(go.Adornment, "Spot",
                    { locationSpot: go.Spot.Right },
                    objGo(go.Placeholder),
                    objGo(go.Shape, { alignment: go.Spot.TopLeft, cursor: "nw-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
                    objGo(go.Shape, { alignment: go.Spot.Top, cursor: "n-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
                    objGo(go.Shape, { alignment: go.Spot.TopRight, cursor: "ne-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),

                    objGo(go.Shape, { alignment: go.Spot.Left, cursor: "w-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
                    objGo(go.Shape, { alignment: go.Spot.Right, cursor: "e-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),

                    objGo(go.Shape, { alignment: go.Spot.BottomLeft, cursor: "se-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
                    objGo(go.Shape, { alignment: go.Spot.Bottom, cursor: "s-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
                    objGo(go.Shape, { alignment: go.Spot.BottomRight, cursor: "sw-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" })
                );

            var nodeRotateAdornmentTemplate =
                objGo(go.Adornment,
                    { locationSpot: go.Spot.Center, locationObjectName: "CIRCLE" },
                    objGo(go.Shape, "Circle", { name: "CIRCLE", cursor: "pointer", desiredSize: new go.Size(7, 7), fill: "lightblue", stroke: "deepskyblue" }),
                    objGo(go.Shape, { geometryString: "M3.5 7 L3.5 30", isGeometryPositioned: true, stroke: "deepskyblue", strokeWidth: 1.5, strokeDashArray: [4, 2] })
                );

            myDiagram.nodeTemplate =
                objGo(go.Node, "Spot",
                    { locationSpot: go.Spot.Center },
                    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
                    { selectable: true, selectionAdornmentTemplate: nodeSelectionAdornmentTemplate },
                    { resizable: true, resizeObjectName: "PANEL", resizeAdornmentTemplate: nodeResizeAdornmentTemplate },
                    { rotatable: true, rotateAdornmentTemplate: nodeRotateAdornmentTemplate },
                    new go.Binding("angle").makeTwoWay(),
                    // the main object is a Panel that surrounds a TextBlock with a Shape
                    objGo(go.Panel, "Auto",
                        { name: "PANEL" },
                        new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
                        objGo(go.Shape, "Rectangle",  // default figure
                            {
                                portId: "", // the default port: if no spot on link data, use closest side
                                fromLinkable: true, toLinkable: true, cursor: "pointer",
                                fill: "white",  // default color
                                strokeWidth: 2
                            },
                            new go.Binding("figure"),
                            new go.Binding("fill")),
                        objGo(go.TextBlock,
                            {
                                font: "bold 11pt Helvetica, Arial, sans-serif",
                                margin: 8,
                                maxSize: new go.Size(160, NaN),
                                wrap: go.TextBlock.WrapFit,
                                editable: true
                            },
                            new go.Binding("text").makeTwoWay())
                    ),
                    // four small named ports, one on each side:
                    makePort("T", go.Spot.Top, false, true),
                    makePort("L", go.Spot.Left, true, true),
                    makePort("R", go.Spot.Right, true, true),
                    makePort("B", go.Spot.Bottom, true, false),
                    { // handle mouse enter/leave events to show/hide the ports
                        mouseEnter: function(e, node) { showSmallPorts(node, true); },
                        mouseLeave: function(e, node) { showSmallPorts(node, false); }
                    }
                );

            function showSmallPorts(node, show) {
                node.ports.each(function(port) {
                    if (port.portId !== "") {  // don't change the default port, which is the big shape
                        port.fill = show ? "rgba(0,0,0,.3)" : null;
                    }
                });
            }

            var linkSelectionAdornmentTemplate =
                objGo(go.Adornment, "Link",
                    objGo(go.Shape,
                        // isPanelMain declares that this Shape shares the Link.geometry
                        { isPanelMain: true, fill: null, stroke: "deepskyblue", strokeWidth: 0 })  // use selection object's strokeWidth
                );

            myDiagram.linkTemplate =
                objGo(go.Link,  // the whole link panel
                    { selectable: true, selectionAdornmentTemplate: linkSelectionAdornmentTemplate },
                    { relinkableFrom: true, relinkableTo: true, reshapable: true },
                    {
                        routing: go.Link.AvoidsNodes,
                        curve: go.Link.JumpOver,
                        corner: 5,
                        toShortLength: 4
                    },
                    new go.Binding("points").makeTwoWay(),
                    objGo(go.Shape,  // the link path shape
                        { isPanelMain: true, strokeWidth: 2 }),
                    objGo(go.Shape,  // the arrowhead
                        { toArrow: "Standard", stroke: null }),
                    objGo(go.Panel, "Auto",  // the link label, normally not visible
                        { visible: false, name: "LABEL", segmentIndex: 2, segmentFraction: 0.5 },
                        new go.Binding("visible", "visible").makeTwoWay(),
                        objGo(go.Shape, "RoundedRectangle",  // the label shape
                            { fill: "#F8F8F8", strokeWidth: 0 }),
                        objGo(go.TextBlock,"???" , // the label
                            {
                                textAlign: "center",
                                font: "10pt helvetica, arial, sans-serif",
                                stroke: "#333333",
                                editable: true
                            },
                            new go.Binding("text").makeTwoWay())
                    )
                );

            function showLinkLabel(e) {
                var label = e.subject.findObject("LABEL");
                if (label !== null) label.visible = (e.subject.fromNode.data.figure === "Diamond");
            }

            // initialize the Palette that is on the left side of the page
            myPalette =
                objGo(go.Palette, "myPaletteDiv",  // must name or refer to the DIV HTML element
                    {
                        maxSelectionCount: 1,
                        nodeTemplateMap: myDiagram.nodeTemplateMap,  // share the templates used by myDiagram
                        linkTemplate: // simplify the link template, just in this Palette
                            objGo(go.Link,
                                { // because the GridLayout.alignment is Location and the nodes have locationSpot == Spot.Center,
                                    // to line up the Link in the same manner we have to pretend the Link has the same location spot
                                    locationSpot: go.Spot.Center,
                                    selectionAdornmentTemplate:
                                        objGo(go.Adornment, "Link",
                                            { locationSpot: go.Spot.Center },
                                            objGo(go.Shape,
                                                { isPanelMain: true, fill: null, stroke: "deepskyblue", strokeWidth: 0 }),
                                            objGo(go.Shape,  // the arrowhead
                                                { toArrow: "Standard", stroke: null })
                                        )
                                },
                                {
                                    routing: go.Link.AvoidsNodes,
                                    curve: go.Link.JumpOver,
                                    corner: 5,
                                    toShortLength: 4
                                },
                                new go.Binding("points"),
                                objGo(go.Shape,  // the link path shape
                                    { isPanelMain: true, strokeWidth: 2 }),
                                objGo(go.Shape,  // the arrowhead
                                    { toArrow: "Standard", stroke: null })
                            ),
                        model: new go.GraphLinksModel([  // specify the contents of the Palette
                            { text: "Start", figure: "RoundedRectangle", fill: "#00AD5F" },
                            { text: "Step", figure:"Rectangle",fill: "lightyellow" },
                            { text: "Sel", figure: "Diamond", fill: "lightskyblue" },
                            { text: "End", figure: "RoundedRectangle", fill: "#CE0620" },
                        ], [
                            // the Palette also has a disconnected Link, which the user can drag-and-drop
                            { points: new go.List(go.Point).addAll([new go.Point(0, 0), new go.Point(30, 0), new go.Point(30, 40), new go.Point(60, 40)]) }
                        ])
                    });
        }


        function TopRotatingTool() {
            go.RotatingTool.call(this);
        }
        go.Diagram.inherit(TopRotatingTool, go.RotatingTool);


        //获取url路径前缀
        function getAddress() {
            var curWWWPath = window.document.location.href;
            var pathname = window.document.location.pathname;
            var pos = curWWWPath.indexOf(pathname);
            var localhostPath = curWWWPath.substring(0, pos);
            return localhostPath+"/syyj";
        }

        /** @override */
        TopRotatingTool.prototype.updateAdornments = function(part) {
            go.RotatingTool.prototype.updateAdornments.call(this, part);
            var adornment = part.findAdornment("Rotating");
            if (adornment !== null) {
                adornment.location = part.rotateObject.getDocumentPoint(new go.Spot(0.5, 0, 0, -30));  // above middle top
            }
        };

        /** @override */
        TopRotatingTool.prototype.rotate = function(newangle) {
            go.RotatingTool.prototype.rotate.call(this, newangle + 90);
        };
        // end of TopRotatingTool class
        //初始化流程图
        function SetData(data){
            yaid = data.yaid;
            $.ajax({
                url: getAddress()+"/sjzx/szya/queryLct?yaid="+data.yaid,
                dataType: "json",
                async: false,
                success: function (data) {
                    load(data);
                },
                error: function (e) {
                }
            })
            if(data.state=='0'){
                $("#saveBut").show();
            }
        }

        // Show the diagram's model in JSON format that the user may edit
        function save() {
            saveDiagramProperties();  // do this first, before writing to JSON
            var model =  myDiagram.model.toJson();
            model=JSON.parse(model);
            for(var i=0;i<model.linkDataArray.length;i++){
                if((!model.linkDataArray[i].hasOwnProperty("from"))||(!model.linkDataArray[i].hasOwnProperty("to"))){
                    mini.alert("所有线段必须全部连接!");
                    return
                }
            }
            var linkString = JSON.stringify(model.linkDataArray);
            var nodeString = JSON.stringify(model.nodeDataArray);
            var position = model.modelData.position;
            myDiagram.isModified = false;
            $.ajax({
                url: getAddress()+"/sjzx/szya/saveLct",
                dataType: "json",
                data:{"linkString":linkString,"nodeString":nodeString,"position":position,"yaid":yaid},
                async: false,
                success: function (data) {
                    mini.alert(data.msg);
                },
                error: function (e) {
                    mini.alert("保存失败!");
                }
            })

        }

        function load(data) {
            myDiagram.model = go.Model.fromJson(data);
            loadDiagramProperties();  // do this after the Model.modelData has been brought into memory
        }

        function saveDiagramProperties() {
            myDiagram.model.modelData.position = go.Point.stringify(myDiagram.position);
        }
        function loadDiagramProperties(e) {
            // set Diagram.initialPosition, not Diagram.position, to handle initialization side-effects
            var pos = myDiagram.model.modelData.position;
            if (pos) myDiagram.initialPosition = go.Point.parse(pos);
        }
    </script>
</head>
<body οnlοad="init()">
<div id="sample">
    <div style="width:100%; white-space:nowrap;">
    <span style="display: inline-block; vertical-align: top; width:105px">
      <div id="myPaletteDiv" style="border: solid 1px black; height: 650px"></div>
    </span>

        <span style="display: inline-block; vertical-align: top; width:90%">
      <div id="myDiagramDiv" style="border: solid 1px black; height: 650px"></div>
    </span>
    </div>
    <div id="saveBut" style="display: none;">
            <button id="SaveButton" style="width:100px;height:30px;float: right;margin-right: 45%;margin-top: 10px;" οnclick="save()">保存</button>
    </div>
</div>
</body>
</html>

java部分

controller

@RequestMapping("/saveLct")
@ResponseBody
public Map<String,Object> saveLct(@RequestParam Map<String,Object> map){ return szyaService.saveLct(map); }

service

//查询流程图
Map<String, Object> queryLct(Map<String, Object> map);
//保存流程图
Map<String, Object> saveLct(Map<String, Object> map);

serviceimpl

@Override
    public Map<String,Object> queryLct(Map<String,Object> map){
        Map<String,Object> resMap = new HashMap<String, Object>();
        Map<String,Object> posMap = new HashMap<String, Object>();

        List<Map<String,Object>> nodeList = szyaDao.queryNodeList(map);
        List<Map<String,Object>> linkList = szyaDao.queryLinkList(map);
        if(nodeList.size()!=0) {
            for (int i = 0; i < nodeList.size(); i++) {
                if (nodeList.get(i).get("size") == null) {
                    nodeList.get(i).remove("size");
                }
                nodeList.get(i).put("key", nodeList.get(i).get("key1"));
            }
            posMap.put("position", nodeList.get(0).get("position"));
            resMap.put("modelData",posMap);
        }
        if(linkList.size()!=0) {
            for (int i = 0; i < linkList.size(); i++) {
                String[] pointsArry = null;
                String pointsString = (String) linkList.get(i).get("points");
                pointsArry = pointsString.split(",");
                Double[] pointsDArray = new Double[pointsArry.length];
                for (int j = 0; j < pointsArry.length; j++) {
                    pointsDArray[j] = Double.parseDouble(pointsArry[j]);
                }
                linkList.get(i).put("points", pointsDArray);
                linkList.get(i).put("from", linkList.get(i).get("from1"));
                linkList.get(i).put("to", linkList.get(i).get("to1"));
                if (linkList.get(i).get("text") == null) {
                    linkList.get(i).remove("text");
                }
                linkList.get(i).put("visible",linkList.get(i).get("visible").equals("true")?true:false);
            }
        }
        resMap.put("class","GraphLinksModel");
        resMap.put("linkFromPortIdProperty","fromPort");
        resMap.put("linkToPortIdProperty","toPort");
        resMap.put("nodeDataArray",nodeList);
        resMap.put("linkDataArray",linkList);

        return resMap;
    }

    @Override
    public Map<String,Object> saveLct(Map<String,Object> map){
        Map<String,Object> resMap = new HashMap<String, Object>();
        resMap.put("msg","保存成功!");

        JSONArray jsonArray = JSONArray.fromObject(map.get("linkString"));
        List<Map<String,Object>> linkList=(List<Map<String,Object>>)JSONArray.toCollection(jsonArray, Map.class);
        JSONArray jsonArray2 = JSONArray.fromObject(map.get("nodeString"));
        List<Map<String,Object>> nodeList=(List<Map<String,Object>>)JSONArray.toCollection(jsonArray2, Map.class);
        try {
            szyaDao.removeNodeList(map);
            for (Map<String, Object> m : nodeList) {
                m.put("position",(String)map.get("position"));
                m.put("yaid", map.get("yaid"));
                szyaDao.saveNodeList(m);
            }
            szyaDao.removeLinkList(map);
            for (Map<String, Object> m : linkList) {
                m.put("yaid", map.get("yaid"));
                String str="";
                List<Double> dlist = (List<Double>)m.get("points");
                for(int i=0;i<dlist.size();i++){
                    if(i==dlist.size()-1) {
                        str += dlist.get(i);
                    }else{
                        str += dlist.get(i) + ",";
                    }
                }
                m.put("points",str);
                szyaDao.saveLinkList(m);
            }
        }catch (Exception e){
            e.printStackTrace();
            resMap.put("msg","保存失败!");
            return resMap;
        }
        return resMap;

    }

dao

List<Map<String,Object>> queryNodeList(Map<String,Object> map);

List<Map<String,Object>> queryLinkList(Map<String,Object> map);

void saveLinkList(Map<String,Object> map);

void saveNodeList(Map<String,Object> map);

void removeLinkList(Map<String,Object> map);

void removeNodeList(Map<String,Object> map);

daoimpl

@Override
public List<Map<String, Object>> queryNodeList(Map<String, Object> map){
    StringBuffer sql = new StringBuffer();
    sql.append("select * from szya_lct_node where yaid = #{yaid}");
    return this.queryForList(sql.toString(),map);
}

@Override
public List<Map<String, Object>> queryLinkList(Map<String, Object> map){
    StringBuffer sql = new StringBuffer();
    sql.append("select * from szya_lct_link where yaid = #{yaid}");
    return this.queryForList(sql.toString(),map);
}

@Override
public void saveNodeList(Map<String,Object> map){
    StringBuffer sql = new StringBuffer();
    map.put("id",Md5Util.UUID());
    if (ObjectUtils.isEmpty(map.get("size"))) {
        map.put("size1",null);
    }
    map.put("size1",map.get("size"));
    sql.append("insert into szya_lct_node (id,text,figure,fill,key1,size,loc,position,yaid) ");
    sql.append("values(#{id},#{text},#{figure},#{fill},#{key},#{size1},#{loc},#{position},#{yaid})");
    this.update(sql.toString(),map);
}

@Override
    public void saveLinkList(Map<String,Object> map){
        StringBuffer sql = new StringBuffer();
        map.put("id",Md5Util.UUID());
        if (ObjectUtils.isEmpty(map.get("text"))) {
            map.put("text",null);
        }
        if (ObjectUtils.isEmpty(map.get("fromPort"))) {
            map.put("fromPort",null);
        }
        if (ObjectUtils.isEmpty(map.get("toPort"))) {
            map.put("toPort",null);
        }
        if (ObjectUtils.isEmpty(map.get("visible"))) {
            map.put("visible","false");
        }else{
            map.put("visible","true");
        }
        sql.append("insert into szya_lct_link (id,text,visible,points,from1,to1,fromPort,toPort,yaid) ");
        sql.append("values(#{id},#{text},#{visible},#{points},#{from},#{to},#{fromPort},#{toPort},#{yaid})");
        this.update(sql.toString(),map);
    }

@Override
public void removeNodeList(Map<String,Object> map){
    StringBuffer sql = new StringBuffer();
    sql.append("delete from szya_lct_node where yaid=#{yaid}");
    this.update(sql.toString(),map);
}

@Override
public void removeLinkList(Map<String,Object> map){
    StringBuffer sql = new StringBuffer();
    sql.append("delete from szya_lct_link where yaid=#{yaid}");
    this.update(sql.toString(),map);
}

示例1效果图

扫描二维码关注公众号,回复: 9816907 查看本文章

html示例2

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Flowchart</title>
    <meta name="description" content="Interactive flowchart diagram implemented by GoJS in JavaScript for HTML." />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Copyright 1998-2019 by Northwoods Software Corporation. -->

    <script src="../js/go-debug.js"></script>
    <link href='https://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
     <!-- this is only for the GoJS Samples framework -->
    <script id="code">
        function init() {
            if (window.goSamples) goSamples();  // init for these samples -- you don't need to call this
            var $ = go.GraphObject.make;  // for conciseness in defining templates
            myDiagram =
                $(go.Diagram, "myDiagramDiv",  // must name or refer to the DIV HTML element
                    {
                        "LinkDrawn": showLinkLabel,  // this DiagramEvent listener is defined below
                        "LinkRelinked": showLinkLabel,
                        "undoManager.isEnabled": true  // enable undo & redo
                    });
            // when the document is modified, add a "*" to the title and enable the "Save" button
            myDiagram.addDiagramListener("Modified", function(e) {
                var button = document.getElementById("SaveButton");
                if (button) button.disabled = !myDiagram.isModified;
                var idx = document.title.indexOf("*");
                if (myDiagram.isModified) {
                    if (idx < 0) document.title += "*";
                } else {
                    if (idx >= 0) document.title = document.title.substr(0, idx);
                }
            });
            // helper definitions for node templates
            function 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.
            function 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";
                        }
                    });
            }
            function textStyle() {
                return {
                    font: "bold 11pt Lato, Helvetica, Arial, sans-serif",
                    stroke: "#282c34"
                }
            }
            // define the Node templates for regular nodes
            myDiagram.nodeTemplateMap.add("",  // the default category
                $(go.Node, "Table", nodeStyle(),
                    // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
                    $(go.Panel, "Auto",
                        $(go.Shape, "Rectangle",
                            { fill: "#00AD5F", stroke: "#282c34", strokeWidth: 3.5 },
                            new go.Binding("figure", "figure")),
                        $(go.TextBlock, textStyle(),
                            {
                                margin: 8,
                                maxSize: new go.Size(160, NaN),
                                wrap: go.TextBlock.WrapFit,
                                editable: true
                            },
                            new go.Binding("text").makeTwoWay())
                    ),
                    // four named ports, one on each side:
                    makePort("T", go.Spot.Top, go.Spot.TopSide, false, true),
                    makePort("L", go.Spot.Left, go.Spot.LeftSide, true, true),
                    makePort("R", go.Spot.Right, go.Spot.RightSide, true, true),
                    makePort("B", go.Spot.Bottom, go.Spot.BottomSide, true, false)
                ));
            myDiagram.nodeTemplateMap.add("Conditional",
                $(go.Node, "Table", nodeStyle(),
                    // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
                    $(go.Panel, "Auto",
                        $(go.Shape, "Diamond",
                            { fill: "#00B2BF", stroke: "#282c34", strokeWidth: 3.5 },
                            new go.Binding("figure", "figure")),
                        $(go.TextBlock, textStyle(),
                            {
                                margin: 8,
                                maxSize: new go.Size(160, NaN),
                                wrap: go.TextBlock.WrapFit,
                                editable: true
                            },
                            new go.Binding("text").makeTwoWay())
                    ),
                    // four named ports, one on each side:
                    makePort("T", go.Spot.Top, go.Spot.Top, false, true),
                    makePort("L", go.Spot.Left, go.Spot.Left, true, true),
                    makePort("R", go.Spot.Right, go.Spot.Right, true, true),
                    makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
                ));
            myDiagram.nodeTemplateMap.add("Start",
                $(go.Node, "Table", nodeStyle(),
                    $(go.Panel, "Spot",
                        $(go.Shape, "Circle",
                            { desiredSize: new go.Size(70, 70), fill: "#00AD5F", stroke: "#282c34", strokeWidth: 3.5 }),
                        $(go.TextBlock, "Start", textStyle(),
                            new go.Binding("text"))
                    ),
                    // three named ports, one on each side except the top, all output only:
                    makePort("T", go.Spot.Top, go.Spot.Top, false, true),
                    makePort("L", go.Spot.Left, go.Spot.Left, true, true),
                    makePort("R", go.Spot.Right, go.Spot.Right, true, true),
                    makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
                ));
            myDiagram.nodeTemplateMap.add("Step",
                $(go.Node, "Table", nodeStyle(),
                    // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
                    $(go.Panel, "Auto",
                        $(go.Shape, "Rectangle",
                            { fill: "#FCE0A6", stroke: "#282c34", strokeWidth: 3.5 },
                            new go.Binding("figure", "figure")),
                        $(go.TextBlock, textStyle(),
                            {
                                margin: 8,
                                maxSize: new go.Size(160, NaN),
                                wrap: go.TextBlock.WrapFit,
                                editable: true
                            },
                            new go.Binding("text").makeTwoWay())
                    ),
                    // four named ports, one on each side:
                    makePort("T", go.Spot.Top, go.Spot.Top, false, true),
                    makePort("L", go.Spot.Left, go.Spot.Left, true, true),
                    makePort("R", go.Spot.Right, go.Spot.Right, true, true),
                    makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
                ));
            myDiagram.nodeTemplateMap.add("End",
                $(go.Node, "Table", nodeStyle(),
                    // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
                    $(go.Panel, "Auto",
                        $(go.Shape, "RoundedRectangle",
                            { fill: "#CE0620", stroke: "#282c34", strokeWidth: 3.5 },
                            new go.Binding("figure", "figure")),
                        $(go.TextBlock, textStyle(),
                            {
                                margin: 8,
                                maxSize: new go.Size(160, NaN),
                                wrap: go.TextBlock.WrapFit,
                                editable: true
                            },
                            new go.Binding("text").makeTwoWay())
                    ),
                    // four named ports, one on each side:
                    makePort("T", go.Spot.Top, go.Spot.Top, false, true),
                    makePort("L", go.Spot.Left, go.Spot.Left, true, true),
                    makePort("R", go.Spot.Right, go.Spot.Right, true, true),
                    makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
                ));
            // 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, .75 * w, 0));
                fig.add(new go.PathSegment(go.PathSegment.Line, w, .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(.75 * w, 0, false);
                geo.add(fig2);
                // The Fold
                fig2.add(new go.PathSegment(go.PathSegment.Line, .75 * w, .25 * h));
                fig2.add(new go.PathSegment(go.PathSegment.Line, w, .25 * h));
                geo.spot1 = new go.Spot(0, .25);
                geo.spot2 = go.Spot.BottomRight;
                return geo;
            });
            myDiagram.nodeTemplateMap.add("Comment",
                $(go.Node, "Auto", nodeStyle(),
                    $(go.Shape, "File",
                        { fill: "#282c34", stroke: "#DEE0A3", strokeWidth: 3 }),
                    $(go.TextBlock, textStyle(),
                        {
                            margin: 8,
                            maxSize: new go.Size(200, NaN),
                            wrap: go.TextBlock.WrapFit,
                            textAlign: "center",
                            editable: true
                        },
                        new go.Binding("text").makeTwoWay())
                    // no ports, because no links are allowed to connect with a comment
                ));
            // replace the default Link template in the linkTemplateMap
            myDiagram.linkTemplate =
                $(go.Link,  // the whole link panel
                    {
                        routing: go.Link.AvoidsNodes,
                        curve: go.Link.JumpOver,
                        corner: 5, toShortLength: 4,
                        relinkableFrom: true,
                        relinkableTo: true,
                        reshapable: true,
                        resegmentable: true,
                        // 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: false
                    },
                    new go.Binding("points").makeTwoWay(),
                    $(go.Shape,  // the highlight shape, normally transparent
                        { isPanelMain: true, strokeWidth: 8, stroke: "transparent", name: "HIGHLIGHT" }),
                    $(go.Shape,  // the link path shape
                        { isPanelMain: true, stroke: "gray", strokeWidth: 2 },
                        new go.Binding("stroke", "isSelected", function(sel) { return sel ? "dodgerblue" : "gray"; }).ofObject()),
                    $(go.Shape,  // the arrowhead
                        { toArrow: "standard", strokeWidth: 0, fill: "gray" }),
                    $(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, "RoundedRectangle",  // 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())
                    )
                );
            // Make link labels visible if coming out of a "conditional" node.
            // This listener is called by the "LinkDrawn" and "LinkRelinked" DiagramEvents.
            function showLinkLabel(e) {
                var label = e.subject.findObject("LABEL");
                if (label !== null) label.visible = (e.subject.fromNode.data.category === "Conditional");
            }

            // temporary links used by LinkingTool and RelinkingTool are also orthogonal:
            myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;
            myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal;
            //load();  // load an initial diagram from some JSON text
            // initialize the Palette that is on the left side of the page
            myPalette =
                $(go.Palette, "myPaletteDiv",  // 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": animateFadeDown, // Instead, animate with this function
                        nodeTemplateMap: myDiagram.nodeTemplateMap,  // share the templates used by myDiagram
                        model: new go.GraphLinksModel([  // specify the contents of the Palette
                            { text: "Start", figure: "RoundedRectangle", fill: "#00AD5F" },
                            { category: "Step",figure: "Rectangle",text: "Step",fill: "lightyellow" },
                            { category: "Conditional", text: "sel", figure: "Diamond",fill: "lightskyblue" },
                            { category: "End", text: "End",figEndure: "RoundedRectangle", fill: "#CE0620" },
                        ], [
                            // the Palette also has a disconnected Link, which the user can drag-and-drop
                            { points: new go.List(go.Point).addAll([new go.Point(0, 0), new go.Point(30, 0), new go.Point(30, 40), new go.Point(60, 40)]) }
                        ])
                    });
            // This is a re-implementation of the default animation, except it fades in from downwards, instead of upwards.
            function animateFadeDown(e) {
                var diagram = e.diagram;
                var animation = new go.Animation();
                animation.isViewportUnconstrained = true; // So Diagram positioning rules let the animation start off-screen
                animation.easing = go.Animation.EaseOutExpo;
                animation.duration = 900;
                // Fade "down", in other words, fade in from above
                animation.add(diagram, 'position', diagram.position.copy().offset(0, 200), diagram.position);
                animation.add(diagram, 'opacity', 0, 1);
                animation.start();
            }
        } // end init
        // Show the diagram's model in JSON format that the user may edit
        function save() {
            document.getElementById("mySavedModel").value = myDiagram.model.toJson();
            myDiagram.isModified = false;
        }
        function load() {
            myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value);
        }
        // print the diagram by opening a new window holding SVG images of the diagram contents for each page
        function printDiagram() {
            var svgWindow = window.open();
            if (!svgWindow) return;  // failure to open a new Window
            var printSize = new go.Size(700, 960);
            var bnds = myDiagram.documentBounds;
            var x = bnds.x;
            var y = bnds.y;
            while (y < bnds.bottom) {
                while (x < bnds.right) {
                    var svg = myDiagram.makeSVG({ scale: 1.0, position: new go.Point(x, y), size: printSize });
                    svgWindow.document.body.appendChild(svg);
                    x += printSize.width;
                }
                x = bnds.x;
                y += printSize.height;
            }
            setTimeout(function() { svgWindow.print(); }, 1);
        }
    </script>
</head>
<body οnlοad="init()">
<div id="sample">
    <div style="width:100%; white-space:nowrap;">
    <span style="display: inline-block; vertical-align: top; width:105px">
      <div id="myPaletteDiv" style="border: solid 1px black; height: 620px"></div>
    </span>

        <span style="display: inline-block; vertical-align: top; width:90%">
      <div id="myDiagramDiv" style="border: solid 1px black; height: 620px"></div>
    </span>
    </div>
    <p>
        The FlowChart sample demonstrates several key features of GoJS,
        namely <a href="../intro/palette.html">Palette</a>s,
        <a href="../intro/links.html">Linkable nodes</a>, Drag/Drop behavior,
        <a href="../intro/textBlocks.html">Text Editing</a>, and the use of
        <a href="../intro/templateMaps.html">Node Template Maps</a> in Diagrams.
    </p>
    <p>
        Mouse-over a Node to view its ports.
        Drag from these ports to create new Links.
        Selecting Links allows you to re-shape and re-link them.
        Selecting a Node and then clicking its TextBlock will allow
        you to edit text (except on the Start and End Nodes).
    </p>
    <button id="SaveButton" οnclick="save()">Save</button>
    <button οnclick="load()">Load</button>
    Diagram Model saved in JSON format:
    <textarea id="mySavedModel" style="width:100%;height:300px">
{ "class": "go.GraphLinksModel",
  "linkFromPortIdProperty": "fromPort",
  "linkToPortIdProperty": "toPort",
  "nodeDataArray": [
{"category":"Comment", "loc":"360 -10", "text":"Kookie Brittle", "key":-13},
{"key":-1, "category":"Start", "loc":"175 0", "text":"Start"},
{"key":0, "loc":"-5 75", "text":"Preheat oven to 375 F"},
{"key":1, "loc":"175 100", "text":"In a bowl, blend: 1 cup margarine, 1.5 teaspoon vanilla, 1 teaspoon salt"},
{"key":2, "loc":"175 200", "text":"Gradually beat in 1 cup sugar and 2 cups sifted flour"},
{"key":3, "loc":"175 290", "text":"Mix in 6 oz (1 cup) Nestle's Semi-Sweet Chocolate Morsels"},
{"key":4, "loc":"175 380", "text":"Press evenly into ungreased 15x10x1 pan"},
{"key":5, "loc":"355 85", "text":"Finely chop 1/2 cup of your choice of nuts"},
{"key":6, "loc":"175 450", "text":"Sprinkle nuts on top"},
{"key":7, "loc":"175 515", "text":"Bake for 25 minutes and let cool"},
{"key":8, "loc":"175 585", "text":"Cut into rectangular grid"},
{"key":-2, "category":"End", "loc":"175 660", "text":"Enjoy!"}
 ],
  "linkDataArray": [
{"from":1, "to":2, "fromPort":"B", "toPort":"T"},
{"from":2, "to":3, "fromPort":"B", "toPort":"T"},
{"from":3, "to":4, "fromPort":"B", "toPort":"T"},
{"from":4, "to":6, "fromPort":"B", "toPort":"T"},
{"from":6, "to":7, "fromPort":"B", "toPort":"T"},
{"from":7, "to":8, "fromPort":"B", "toPort":"T"},
{"from":8, "to":-2, "fromPort":"B", "toPort":"T"},
{"from":-1, "to":0, "fromPort":"B", "toPort":"T"},
{"from":-1, "to":1, "fromPort":"B", "toPort":"T"},
{"from":-1, "to":5, "fromPort":"B", "toPort":"T"},
{"from":5, "to":4, "fromPort":"B", "toPort":"T"},
{"from":0, "to":4, "fromPort":"B", "toPort":"T"}
 ]}
  </textarea>
    <button οnclick="printDiagram()">Print Diagram Using SVG</button>
</div>
</body>
</html>

示例2代码根据1代码适当修改

示例2效果图

相关表设计

 

发布了5 篇原创文章 · 获赞 1 · 访问量 1791

猜你喜欢

转载自blog.csdn.net/qq_37528703/article/details/103597982