Quantcast
Channel: GoJS - Northwoods Software
Viewing all articles
Browse latest Browse all 6968

Link re-routing and port location

$
0
0

@bkowalchuk wrote:

We have created a design based very closely on your flowchart sample.The flowchart sample DOES have the behavior that I want.

I am having a couple small problems that I can't seem to resolve.

Problem 1: When link is added, the link is redrawn with different ports. Very annoying.
Problem 2: The ports on the Condition node (Diamond shape) appear inside the shape, not on the edges.

Below is the JS code from my page:

        function init() {  // init for these samples -- you don't need to call this
            var $ = go.GraphObject.make;  // for conciseness in defining templates
            //IsReadOnly = parentWindow.IsReadOnly;

            switch (qsMode){
                case 0:
                    IsReadOnly = true;
                    IsDisabled = true;
                    break;
                case 1:
                    IsReadOnly = true;
                    IsDisabled = false;
                    break;
                case 2:
                    IsReadOnly = false;
                    IsDisabled = false;
                    break;
                default:
                    break;
            }

            if ((hdnGoJSData.value != "")) {
                (jQuery)("#mySavedModel").val(hdnGoJSData.value);
            }

            goDiagram =
                $(go.Diagram, "myDiagram",  // must name or refer to the DIV HTML element
                    {
                        initialContentAlignment : go.Spot.TopCenter,
                        allowDrop: true,  // must be true to accept drops from the Palette
                        //    isReadOnly: IsReadOnly,
                        "LinkDrawn": showLinkLabel,  // this DiagramEvent listener is defined below
                        "LinkRelinked": showLinkLabel,
                        "undoManager.isEnabled": true  // enable undo & redo
                    });


            //Call the ajax to redraw the runtime diagram from the server values on initial load
            goDiagram.addDiagramListener("InitialLayoutCompleted", function (ev){
                var itmestatusjson = document.getElementById("<%= WorkflowItemStatus.ClientID %>");
                SetWorkflowItemState(itmestatusjson.value);
            });

            goDiagram.addDiagramListener("ObjectContextClicked", function (ev) {

                if (qsMode != 1) {

                    //set popup title, ev.subject.le is inner text
                    var selectedNode = goDiagram.selection.iterator.first();
                    var selectedNodeText = selectedNode.Qe.text;
                    if (selectedNodeText === 'undefined') {
                        return false;
                    }

                    // Only allow action items and decision items to show a popup in design mode
                    var selectedNodeCategory = selectedNode.Qe.category;
                    if (selectedNodeCategory === 'Start' || selectedNodeCategory === 'End' || selectedNodeCategory === 'Link' || selectedNodeCategory === 'Comment') {
                        return false;
                    }

                    // Set the title text (for both design and runtime popups)
                    (jQuery)("#lblNodeText").text(selectedNodeText);
                    (jQuery)("#lblNodeText2").text(selectedNodeText);
                    (jQuery)("#lblConditionNodeText").text(selectedNodeText);
                    (jQuery)("#lblComplianceNodeText").text(selectedNodeText);

                    if (selectedNodeCategory) {
                        OnSingleClick(selectedNodeCategory);
                    }
                }
                return false;
            });

            goDiagram.addDiagramListener("ObjectSingleClicked", function (ev) {
                if (qsMode == 1) {

                    //set popup title, ev.subject.le is inner text
                    var selectedNode = goDiagram.selection.iterator.first();
                    var selectedNodeText = selectedNode.Qe.text;
                    if (selectedNodeText === 'undefined') {
                        return false;
                    }

                    // Only allow action items and decision items to show a popup in design mode
                    var selectedNodeCategory = selectedNode.Qe.category;
                    if (selectedNodeCategory === 'Start' || selectedNodeCategory === 'End' || selectedNodeCategory === 'Link' || selectedNodeCategory === 'Comment') {
                        return false;
                    }

                    // Set the title text (for both design and runtime popups)
                    (jQuery)("#lblNodeText").text(selectedNodeText);
                    (jQuery)("#lblNodeText2").text(selectedNodeText);
                    (jQuery)("#lblConditionNodeText").text(selectedNodeText);
                    (jQuery)("#lblComplianceNodeText").text(selectedNodeText);

                    var selectedNodeKey = selectedNode.Qe.key;

                    if (selectedNodeCategory) {

                        var statusItem = null;
                        for (var k = 0; k < itemsarray.Items.Item.length; k++) {
                            if (itemsarray.Items.Item[k].Key == selectedNodeKey) {
                                statusItem = itemsarray.Items.Item[k];
                                break;
                            }
                        }

                        if (statusItem.IsDisabled != "1") {
                            OnSingleClick(selectedNodeCategory);
                        }
                    }
                }
                return false;
            });

            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,
                        //isShadowed: true,
                        //shadowColor: "#888",
                        // handle mouse enter/leave events to show/hide the ports
                        mouseEnter: function (e, obj) { showPorts(obj.part, true); },
                        mouseLeave: function (e, obj) { showPorts(obj.part, false); },
                    }
                ];
            }

            // 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 circle that has a white stroke when it is made visible
                return $(go.Shape, "Circle",
                    {
                        fill: "transparent",
                        stroke: null,  // this is changed to "white" in the showPorts function
                        desiredSize: new go.Size(8, 8),
                        alignment: spot, alignmentFocus: spot,  // align the port on the main 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
                    });
            }

            // define the Node templates for regular nodes

            var lightText = 'whitesmoke';

            goDiagram.nodeTemplateMap.add("",  // the default category
                $(go.Node, "Spot", nodeStyle(),
                    // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
                    $(go.Panel, "Auto",
                        $(go.Shape, "Rectangle",
                        { fill: "#00A9C9", stroke: null},
                        new go.Binding("figure", "figure"),
                        new go.Binding("fill","fill").makeTwoWay()),
                        $(go.TextBlock,
                            {   name: "TEXTBLOCK",
                                font: "bold 11pt Helvetica, Arial, sans-serif",
                                stroke: lightText,
                                margin: 8,
                                maxSize: new go.Size(160, NaN),
                                wrap: go.TextBlock.WrapFit,
                                editable: true
                            },
                            new go.Binding("text", "text").makeTwoWay())
                ),
                // four 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)
            ));

            goDiagram.nodeTemplateMap.add("Start",
                $(go.Node, "Spot", nodeStyle(),
                    $(go.Panel, "Auto",
                        $(go.Shape, "Circle",
                            { minSize: new go.Size(40, 60), fill: "#79C900", stroke: null}),
                        $(go.TextBlock, "Start",
                            { margin: 5, font: "bold 11pt Helvetica, Arial, sans-serif", stroke: lightText },
                            new go.Binding("text", "text").makeTwoWay())
                    ),
                    // three named ports, one on each side except the top, all output only:
                    makePort("L", go.Spot.Left, true, false),
                    makePort("R", go.Spot.Right, true, false),
                    makePort("B", go.Spot.Bottom, true, false)
                ));

            goDiagram.nodeTemplateMap.add("End",
                $(go.Node, "Spot", nodeStyle(),
                    $(go.Panel, "Auto",
                        $(go.Shape, "Circle",
                            { minSize: new go.Size(40, 60), fill: "#DC3C00", stroke: null} ),
                        $(go.TextBlock, "End",
                            { margin: 5, font: "bold 11pt Helvetica, Arial, sans-serif", stroke: lightText }, new go.Binding("text", "text").makeTwoWay())
                    ),

                    // three named ports, one on each side except the bottom, all input only:
                    makePort("T", go.Spot.Top, false, true),
                    makePort("L", go.Spot.Left, false, true),
                    makePort("R", go.Spot.Right, false, true)
                ));

            goDiagram.nodeTemplateMap.add("Action",
                $(go.Node, "Auto", nodeStyle(),
                    $(go.Shape, "File",
                        { fill: "#EFFAB4", stroke: null},
                        new go.Binding("fill","fill").makeTwoWay()),
                    $(go.TextBlock,
                        {   name: "TEXTBLOCK",
                            margin: 5,
                            maxSize: new go.Size(200, NaN),
                            wrap: go.TextBlock.WrapFit,
                            textAlign: "center",
                            editable: true,
                            font: "bold 11pt Helvetica, Arial, sans-serif",
                            stroke: '#454545'
                        },
                        new go.Binding("text", "text").makeTwoWay()),
                    makePort("T", go.Spot.Top, false, true),
                    makePort("L", go.Spot.Left, true, false),
                    makePort("R", go.Spot.Right, true, false),
                    makePort("B", go.Spot.Bottom, true, false)
                ));


            goDiagram.nodeTemplateMap.add("Condition",
                $(go.Node, "Auto", nodeStyle(),
                    $(go.Shape, "Diamond",
                        { fill: "#70706F", stroke: null},
                        new go.Binding("fill","fill").makeTwoWay()),
                    $(go.TextBlock,
                        {   name: "TEXTBLOCK",
                            margin: 5,
                            maxSize: new go.Size(200, NaN),
                            wrap: go.TextBlock.WrapFit,
                            textAlign: "center",
                            editable: true,
                            font: "bold 11pt Helvetica, Arial, sans-serif",
                            stroke: 'whitesmoke'
                        },
                        new go.Binding("text", "text").makeTwoWay()),
                    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)
                ));

            goDiagram.nodeTemplateMap.add("Compliance",
                $(go.Node, "Auto", nodeStyle(),
                    $(go.Shape, "ManualOperation",
                        { fill: "#009900", stroke: null},
                        new go.Binding("fill","fill").makeTwoWay()),
                    $(go.TextBlock,
                        {   name: "TEXTBLOCK",
                            margin: 5,
                            maxSize: new go.Size(200, NaN),
                            wrap: go.TextBlock.WrapFit,
                            textAlign: "center",
                            editable: true,
                            font: "bold 11pt Helvetica, Arial, sans-serif",
                            stroke: 'whitesmoke'
                        },
                        new go.Binding("text", "text").makeTwoWay()),
                    makePort("T", go.Spot.Top, true, true),
                    makePort("B", go.Spot.Bottom, true, true) //Two ports, only required
                ));

            goDiagram.nodeTemplateMap.add("Comment",
                $(go.Node, "Auto", nodeStyle(),
                    $(go.Shape, "File",
                        { fill: "#EFF28E", stroke: null }),
                    $(go.TextBlock,
                        {   name: "TEXTBLOCK",
                            margin: 5,
                            maxSize: new go.Size(200, NaN),
                            wrap: go.TextBlock.WrapFit,
                            textAlign: "center",
                            editable: true,
                            font: "bold 11pt Helvetica, Arial, sans-serif",
                            stroke: '#454545'
                        },
                        new go.Binding("text", "text").makeTwoWay())
                    // no ports, because no links are allowed to connect with a comment
                ));

            // replace the default Link template in the linkTemplateMap
            goDiagram.linkTemplate =
                $(go.Link,  // the whole link panel
                    {
                        routing: go.Link.Orthogonal,
                        curve: go.Link.JumpOver,
                        corner: 5,
                        toShortLength: 4,
                        relinkableFrom: true,
                        relinkableTo: true,
                        //reshapable: true,
                        mouseEnter: function(e, link) { link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.2)"; },
                        mouseLeave: function(e, link) { link.findObject("HIGHLIGHT").stroke = "transparent"; }
                    },
                    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, name: "LINK" },
                         new go.Binding("stroke", "stroke").makeTwoWay()),
                    $(go.Shape,  // the arrowhead
                        { toArrow: "standard", stroke: null, 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", stroke: null }),
                        $(go.TextBlock, "Enter Choice",  // the label
                            {
                                name: "TEXTBLOCK",
                                textAlign: "center",
                                font: "10pt helvetica, arial, sans-serif",
                                stroke: "#333333",
                                editable: true,
                            },
                            new go.Binding("text", "text").makeTwoWay(),
                            new go.Binding("stroke", "stroke").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 === "Condition");
                }
            }

            // temporary links used by LinkingTool and RelinkingTool are also orthogonal:
            goDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;
            goDiagram.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, "myPalette",  // must name or refer to the DIV HTML element
                    {
                        nodeTemplateMap: goDiagram.nodeTemplateMap,  // share the templates used by goDiagram
                        model: new go.GraphLinksModel([  // specify the contents of the Palette
                            { category: "Start", text: "<%= GetLocalResourceObject("gojsStartTagResource1")%>" },
                            { category: "ActionNode", text: "<%=GetLocalResourceObject("gojsActionTagResource1")%>", color: "#1E90FF" },
                            { category: "Condition", text: "<%=GetLocalResourceObject("gojsConditionTagResource1")%>", figure: "Diamond" },
                            { category: "Comment", text: "<%= GetLocalResourceObject("gojsCommentTagResource1")%>", figure: "RoundedRectangle" },
                            { category: "Compliance", text: "<%= GetLocalResourceObject("gojsComplianceResource1")%>", figure: "ManualEntry" },
                            { category: "End", text: "<%= GetLocalResourceObject("gojsEndTagResource1")%>" }
                        ])
                    });
                } // init END


                // Make all ports on a node visible when the mouse is over the node
                function showPorts(node, show) {
                    var diagram = node.diagram;
                    if (!diagram || diagram.isReadOnly || !diagram.allowLink) return;
                    node.ports.each(function (port) {
                        port.stroke = (show ? "white" : null);
                    });
                }


                // Show the diagram's model in JSON format that the user may edit
                function load() {
                    goDiagram.model = go.Model.fromJson((jQuery)("#mySavedModel").val());
                    if (IsDisabled) // thsi doesn't appear to be working with goJS
                    {
                        goDiagram.isDisabled = true;
                    }

                    goDiagram.isReadOnly =  IsReadOnly;

                }

Posts: 4

Participants: 2

Read full topic


Viewing all articles
Browse latest Browse all 6968

Trending Articles