This sample demonstrates a data flow or workflow graph with labeled ports on nodes. A real application would provide the ability to edit the details (properties) of each node so that the actual database operation could be executed.

The ports of each node are set up as panels, created within the makePort function. This function sets various properties of the Shape and TextBlock that make up the panel, and properties of the panel itself. Most notable are GraphObject.portId to declare the shape as a port, and GraphObject.fromLinkable and GraphObject.toLinkable to set the way the ports can be linked.

The diagram also uses the makeTemplate function to create the node templates with shared features. This function takes a type, an image, a background color, and arrays of ports to create the node to be added to the Diagram.nodeTemplateMap.

For the same data model rendered somewhat differently, see the Data Flow (vertical) sample.

Diagram Model saved in JSON format:
{ "class": "go.GraphLinksModel", "nodeCategoryProperty": "type", "linkFromPortIdProperty": "frompid", "linkToPortIdProperty": "topid", "nodeDataArray": [ {"key":1, "type":"Table", "name":"Product"}, {"key":2, "type":"Table", "name":"Sales"}, {"key":3, "type":"Table", "name":"Period"}, {"key":4, "type":"Table", "name":"Store"}, {"key":11, "type":"Join", "name":"Product, Class"}, {"key":12, "type":"Join", "name":"Period"}, {"key":13, "type":"Join", "name":"Store"}, {"key":21, "type":"Project", "name":"Product, Class"}, {"key":31, "type":"Filter", "name":"Boston, Jan2014"}, {"key":32, "type":"Filter", "name":"Boston, 2014"}, {"key":41, "type":"Group", "name":"Sales"}, {"key":42, "type":"Group", "name":"Total Sales"}, {"key":51, "type":"Join", "name":"Product Name"}, {"key":61, "type":"Sort", "name":"Product Name"}, {"key":71, "type":"Export", "name":"File"} ], "linkDataArray": [ {"from":1, "frompid":"OUT", "to":11, "topid":"L"}, {"from":2, "frompid":"OUT", "to":11, "topid":"R"}, {"from":3, "frompid":"OUT", "to":12, "topid":"R"}, {"from":4, "frompid":"OUT", "to":13, "topid":"R"}, {"from":11, "frompid":"M", "to":12, "topid":"L"}, {"from":12, "frompid":"M", "to":13, "topid":"L"}, {"from":13, "frompid":"M", "to":21}, {"from":21, "frompid":"OUT", "to":31}, {"from":21, "frompid":"OUT", "to":32}, {"from":31, "frompid":"OUT", "to":41}, {"from":32, "frompid":"OUT", "to":42}, {"from":41, "frompid":"OUT", "to":51, "topid":"L"}, {"from":42, "frompid":"OUT", "to":51, "topid":"R"}, {"from":51, "frompid":"OUT", "to":61}, {"from":61, "frompid":"OUT", "to":71} ]}

### GoJS Features in this sample

#### Table Panels

The "Table" Panel, Panel.Table, arranges objects in rows and columns. Each object in a Table Panel is put into the cell indexed by the value of GraphObject.row and GraphObject.column. The panel will look at the rows and columns for all of the objects in the panel to determine how many rows and columns the table should have. More information can be found in the GoJS Intro.

Related samples

#### Layered Digraph Layout

This predefined layout is used for placing Nodes of a general directed graph in layers (rows or columns). This is more general than TreeLayout, as it does not require that the graph be tree-structured. More information can be found in the GoJS Intro.

Related samples

#### Ports in Nodes

Specific elements of a Node at which links may connect are called ports. There may be any number of ports in a node. By default there is just one port, the whole node, which results in the effect of having the whole node act as the port. Port-like GraphObjects can only be in Nodes or Groups, not in Links or Adornments or simple Parts.

More information can be found in the GoJS Intro.

Related samples