@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