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

Broken port behavior

$
0
0

@SimonBrodtmann wrote:

I used the flow chart example to first create a simple chart output without editing possibilities. The JSON is generated by the server and everything works fine.
After that, I tried to add some editing possibilities again, but failed at the ports so far. New links start with a wrong direction and go through the rectangle. Relinking existing links from the JSON source is not possible at all.
I checked the code a few times but cannot find the problem.

I use GoJS 1.6.7, Firefox 44 on Windows 10.

The first screenshot shows the generated graph. It looks exactly like I want it to:

In the second screenshot, I tried to add two links (top and bottom). The routing is just broken:

The third screenshot shows me trying to relink. I don't get any other proposals than the whole rectangle. The ports are in the middle of all four sides:

The Code (I make some use of jQuery):
var make = go.GraphObject.make;

// 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 make(go.Shape, "Circle",
        {
            fill: "transparent",
            stroke: null,
            strokeWidth: 1,
            desiredSize: new go.Size(8, 8),
            alignment: spot, alignmentFocus: spot,
            portId: name,
            fromSpot: spot, toSpot: spot,
            fromLinkable: output, toLinkable: input,
            cursor: "pointer"
        }
    );
}

// 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", "position", 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); }
            }
    ];
}

// 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) {
        if (show) {
            port.stroke = "#333333";
            port.fill = "#0078d0";
            port.mouseEnter = function (e, obj) {
                obj.fill = "#e00034";
            };
            port.mouseLeave = function (e, obj) {
                obj.fill = "#0078d0";
            };
        } else {
            port.stroke = null;
            port.fill = null;
            port.mouseEnter = null;
            port.mouseLeave = null;
        }
    });
}

ctx.createDiagram = function(el, graph) {
    var diagram = make(go.Diagram, el, {
        initialContentAlignment: go.Spot.Center,
        allowDrop: true,
        mouseWheelBehavior: go.ToolManager.WheelZoom,
        layout: new go.TreeLayout(),
        "undoManager.isEnabled": true
    });

    diagram.nodeTemplateMap.add("diamond",
        make(go.Node, "Spot", nodeStyle(),
            make(go.Panel, "Auto",
                make(go.Shape, "Diamond", {fill: "transparent", stroke: "black", strokeWidth: 2, desiredSize:  new go.Size(60, 60)})
            ),
            makePort("T", go.Spot.Top, true, true),
            makePort("L", go.Spot.Left, true, false),
            makePort("R", go.Spot.Right, false, true),
            makePort("B", go.Spot.Bottom, true, true)
        )
    );

    diagram.nodeTemplateMap.add("bar",
        make(go.Node, "Spot", nodeStyle(),
            make(go.Panel, "Auto",
                make(go.Shape, "Rectangle", {fill: "black", stroke: null, desiredSize:  new go.Size(15, 80)})
            ),
            makePort("L", go.Spot.Left, true, false),
            makePort("R", go.Spot.Right, false, true)
        )
    );

    diagram.nodeTemplateMap.add("activity",
        make(go.Node, "Spot", nodeStyle(),
            make(go.Panel, "Auto",
                make(go.Shape, "RoundedRectangle", {fill: "transparent", stroke: "black", strokeWidth: 2 }),
                make(go.Panel, "Vertical",
                    make(go.TextBlock,
                        {
                            font: "8pt Lato, sans-serif",
                            stroke: "black",
                            margin: 4,
                            maxSize: new go.Size(160, NaN),
                            wrap: go.TextBlock.WrapFit,
                            editable: false,
                            alignment: go.Spot.Left
                        }, new go.Binding("text", "role")
                    ),
                    make(go.TextBlock,
                        {
                            font: "12pt Lato, sans-serif",
                            stroke: "#0078d0",
                            margin: 4,
                            maxSize: new go.Size(160, NaN),
                            wrap: go.TextBlock.WrapFit,
                            editable: false,
                            alignment: go.Spot.Left,
                            click: function(e, target) {
                                var win = window.open("/testcases.html?activity=" + target.part.data.key, '_blank');
                                win.focus();
                            },
                            cursor: "pointer",
                                mouseEnter: function(e, target) {
                            target.stroke = "#e00034";
                            },
                            mouseLeave: function(e, target) {
                                target.stroke = "#0078d0";
                            }
                        }, new go.Binding("text", "name")
                    ), make(go.TextBlock,
                        {
                            font: "10pt Lato, sans-serif",
                            stroke: "black",
                            margin: 4,
                            maxSize: new go.Size(160, NaN),
                            wrap: go.TextBlock.WrapFit,
                            editable: false,
                            visible: false,
                            name: "description",
                        }, new go.Binding("text", "description", function(text) {
                            return $("<div>").html(text).text();
                        })
                    )
                )
            ),
            makePort("T", go.Spot.Top, true, true),
            makePort("L", go.Spot.Left, true, false),
            makePort("R", go.Spot.Right, false, true),
            makePort("B", go.Spot.Bottom, true, true)
        )
    );

    diagram.nodeTemplateMap.add("start",
        make(go.Node, "Spot", nodeStyle(),
            make(go.Shape, "Circle", {desiredSize: new go.Size(40, 40), fill: "black", stroke: null }),
            makePort("R", go.Spot.Right, true, false)
        )
    );

    diagram.nodeTemplateMap.add("end",
        make(go.Node, "Spot", nodeStyle(),
            make(go.Shape, "Circle", {desiredSize: new go.Size(40, 40), fill: "transparent", stroke: "black", strokeWidth: 2 }),
            make(go.Shape, "Circle", {desiredSize: new go.Size(32, 32), fill: "black", stroke: null }),
            makePort("L", go.Spot.Left, false, true)
        )
    );

    diagram.linkTemplate = make(go.Link, {
            routing: go.Link.AvoidsNodes,
            curve: go.Link.JumpOver,
            corner: 5,
            toShortLength: 4,
            relinkableFrom: true,
            relinkableTo: true,
            reshapable: true,
            resegmentable: 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(),
        make(go.Shape, {isPanelMain: true, strokeWidth: 8, stroke: "transparent", name: "HIGHLIGHT"}),
        make(go.Shape, {isPanelMain: true, stroke: "black", strokeWidth: 2}),
        make(go.Shape, {toArrow: "standard", stroke: null, fill: "black"}),
        make(go.Panel, "Auto", {visible: false, name: "label", segmentIndex: 2, segmentFraction: 0.5},
            make(go.Shape, "RoundedRectangle", {fill: "#F8F8F8", stroke: null}),
            make(go.TextBlock,
                {
                    textAlign: "center",
                    font: "10pt Lato, sans-serif",
                    stroke: "black",
                    editable: false
                },
                new go.Binding("text", "text")
            )
        )
    );

    // temporary links used by LinkingTool and RelinkingTool are also orthogonal:
    diagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;
    diagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal;

    // Nur die Anfangsanimation soll aus
    diagram.animationManager.isEnabled = false;
    diagram.model = go.Model.fromJson(graph);
    diagram.animationManager.isEnabled = true;

    // Show non-empty labels
    var i = diagram.findLinksByExample({text: function(text) {
        return typeof text !== "undefined";
    }});
    while (i.next()) {
        var label = i.value.findObject("label");
        label.visible = true;
    }

    // Show non-empty descriptions
    var i = diagram.findNodesByExample({description: function(description) {
        return typeof description !== "undefined";
    }});
    while (i.next()) {
        var label = i.value.findObject("description");
        label.visible = true;
    }
};

The example graph:
{"nodeDataArray":[{"role":"Controller","name":"Report ETA","description":"<p>The controller reports the ETAs to every involved customers of the tour.</p>","category":"activity","key":257628},{"role":"Controller","name":"Plan route","description":"<p>The controller plans the route considering additional orders that can be combined with this one.</p>","category":"activity","key":257626},{"role":"Controller","name":"Replan open tour parts","category":"activity","key":257657},{"role":"Controller","name":"Receive order","category":"activity","key":257616},{"role":"Controller","name":"Check tour / stall fee","category":"activity","key":257664},{"role":"Controller","name":"Send tour","description":"<p>The controller sends the tour to the vehicle.</p>","category":"activity","key":257630},{"role":"Controller","name":"Approve tour for invoice processing","category":"activity","key":257668},{"role":"Driver","name":"Receive tour","category":"activity","key":257652},{"role":"Driver","name":"Drive tour","category":"activity","key":257654},{"role":"Controller","name":"Plan tour","description":"<p>The controller creates a tour containing the order and assigns it to a vehicle/driver.</p>","category":"activity","key":257621},{"category":"diamond","key":257660},{"category":"bar","key":258057},{"category":"bar","key":258061},{"category":"diamond","key":257624},{"category":"start","key":-1},{"category":"end","key":-2}],"linkDataArray":[{"from":257660,"to":257657,"text":"Disturbances occur"},{"from":257657,"to":257624},{"from":257654,"to":257660},{"from":257660,"to":257664,"text":"No disturbances occur"},{"from":257621,"to":258057},{"from":257664,"to":257668},{"from":257628,"to":258061},{"from":257626,"to":257621},{"from":258057,"to":257630},{"from":258057,"to":257628},{"from":257624,"to":257626},{"from":258061,"to":257654},{"from":257630,"to":257652},{"from":257616,"to":257624},{"from":257652,"to":258061},{"from":-1,"to":257616},{"from":257668,"to":-2}],"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort"}

Can you please help me fix those two problems?

Thanks.

Posts: 2

Participants: 2

Read full topic


Viewing all articles
Browse latest Browse all 7069

Trending Articles