How to define customer node by using gojs?

hi,
I want to create bpm project with gojs, but I don’t know how to define customer node looking like my own appearance .
and make it like the under image.
could you please give me some code to teach me, how to create my own node.
thanks

What have you created so far?

hi walter,
this picture just show you the goal which I want to get. so I need define customer node.but I don’t know the way that how to create it?

I suggest that you read the Introduction pages:
http://gojs.net/latest/intro/index.html
http://gojs.net/latest/intro/buildingObjects.html
http://gojs.net/latest/intro/textBlocks.html
http://gojs.net/latest/intro/shapes.html
http://gojs.net/latest/intro/panels.html
http://gojs.net/latest/intro/tablePanels.html
http://gojs.net/latest/intro/sizing.html
This will give you a basic understanding for how to put together almost anything.

Meanwhile I can work on implementing the basics of what you want, as I get spare time.

Take a look at: http://gojs.net/extras/hexagonalNode.html.
The complete implementation is on that page.

hi walter,
thanks very much, I just a freshman that I mean I learn about the gojs a few day ago. It‘s much terrible to me to verify whether the gojs can achieve my goal. so your example is very important to me.
thanks again !

hi walter,
I try the code which you post to me,
and I have some problem whit it.
first,the node can’t locate at the point which i have set as (loc:“10 10”),
second,the customer node (named : Hex) the color isn’t filled.
look at the image.

thanks very much !

there is my code (line 1 - line307):

<!DOCTYPE html>
<html>
<head>
<title>Swim Lanes (vertical)</title>
<meta name="description" content="Vertical swim lanes and pools with collapsible lanes and limited dragging." />
<!-- Copyright 1998-2016 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<style>
html, body {
    width:100%;
    height:100%;
    padding:0px;
    margin:0px;
}
</style>
<script src="Scripts/go.js"></script>
<!--<link href="Css/goSamples.css" rel="stylesheet" type="text/css" /> --> <!-- you don't need to use this -->
<!--<script src="Scripts/goSamples.js"></script> --> <!-- this is only for the GoJS Samples framework -->
<script id="code">
  // These parameters need to be set before defining the templates.
  var MINLENGTH = 200;  // this controls the minimum length of any swimlane
  var MINBREADTH = 20;  // this controls the minimum breadth of any non-collapsed swimlane
   
  // some shared functions
    
  // this may be called to force the lanes to be laid out again
  function relayoutLanes() {
    myDiagram.nodes.each(function(lane) {
      if (!(lane instanceof go.Group)) return;
      if (lane.category === "Pool") return;
      lane.layout.isValidLayout = false;  // force it to be invalid
    });
    myDiagram.layoutDiagram();
  }

  // this is called after nodes have been moved or lanes resized, to layout all of the Pool Groups again
  function relayoutDiagram() {
    myDiagram.layout.invalidateLayout();
    myDiagram.findTopLevelGroups().each(function(g) { if (g.category === "Pool") g.layout.invalidateLayout(); });
    myDiagram.layoutDiagram();
  }

  // compute the minimum size of a Pool Group needed to hold all of the Lane Groups
  function computeMinPoolSize(pool) {
    // assert(pool instanceof go.Group && pool.category === "Pool");
    var len = MINLENGTH;
    pool.memberParts.each(function(lane) {
      // pools ought to only contain lanes, not plain Nodes
      if (!(lane instanceof go.Group)) return;
      var holder = lane.placeholder;
      if (holder !== null) {
        var sz = holder.actualBounds;
        len = Math.max(len, sz.height);
      }
    });
    return new go.Size(NaN, len);
  }

  // compute the minimum size for a particular Lane Group
  function computeLaneSize(lane) {
    // assert(lane instanceof go.Group && lane.category !== "Pool");
    var sz = computeMinLaneSize(lane);
    if (lane.isSubGraphExpanded) {
      var holder = lane.placeholder;
      if (holder !== null) {
        var hsz = holder.actualBounds;
        sz.width = Math.max(sz.width, hsz.width);
      }
    }
    // minimum breadth needs to be big enough to hold the header
    var hdr = lane.findObject("HEADER");
    if (hdr !== null) sz.width = Math.max(sz.width, hdr.actualBounds.width);
    return sz;
  }

  // determine the minimum size of a Lane Group, even if collapsed
  function computeMinLaneSize(lane) {
    if (!lane.isSubGraphExpanded) return new go.Size(1, MINLENGTH);
    return new go.Size(MINBREADTH, MINLENGTH);
  }


  // define a custom ResizingTool to limit how far one can shrink a lane Group
  function LaneResizingTool() {
    go.ResizingTool.call(this);
  }
  go.Diagram.inherit(LaneResizingTool, go.ResizingTool);

  LaneResizingTool.prototype.isLengthening = function() {
    return (this.handle.alignment === go.Spot.Bottom);
  };

  /** @override */
  LaneResizingTool.prototype.computeMinPoolSize = function() {
    var lane = this.adornedObject.part;
    // assert(lane instanceof go.Group && lane.category !== "Pool");
    var msz = computeMinLaneSize(lane);  // get the absolute minimum size
    if (this.isLengthening()) {  // compute the minimum length of all lanes
      var sz = computeMinPoolSize(lane.containingGroup);
      msz.height = Math.max(msz.height, sz.height);
    } else {  // find the minimum size of this single lane
      var sz = computeLaneSize(lane);
      msz.width = Math.max(msz.width, sz.width);
      msz.height = Math.max(msz.height, sz.height);
    }
    return msz;
  };

  /** @override */
  LaneResizingTool.prototype.resize = function(newr) {
    var lane = this.adornedObject.part;
    if (this.isLengthening()) {  // changing the length of all of the lanes
      lane.containingGroup.memberParts.each(function(lane) {
        if (!(lane instanceof go.Group)) return;
        var shape = lane.resizeObject;
        if (shape !== null) {  // set its desiredSize length, but leave each breadth alone
          shape.height = newr.height;
        }
      });
        } else {  // changing the breadth of a single lane
      go.ResizingTool.prototype.resize.call(this, newr);
    }
    relayoutDiagram();  // now that the lane has changed size, layout the pool again
  };
  // end LaneResizingTool class


  // define a custom grid layout that makes sure the length of each lane is the same
  // and that each lane is broad enough to hold its subgraph
  function PoolLayout() {
    go.GridLayout.call(this);
    this.cellSize = new go.Size(1, 1);
    this.wrappingColumn = Infinity;
    this.wrappingWidth = Infinity;
    this.isRealtime = false;  // don't continuously layout while dragging
    this.alignment = go.GridLayout.Position;
    // This sorts based on the location of each Group.
    // This is useful when Groups can be moved up and down in order to change their order.
    this.comparer = function(a, b) {
      var ax = a.location.x;
      var bx = b.location.x;
      if (isNaN(ax) || isNaN(bx)) return 0;
      if (ax < bx) return -1;
      if (ax > bx) return 1;
      return 0;
    };
  }
  go.Diagram.inherit(PoolLayout, go.GridLayout);

  /** @override */
  PoolLayout.prototype.doLayout = function(coll) {
    var diagram = this.diagram;
    if (diagram === null) return;
    diagram.startTransaction("PoolLayout");
    var pool = this.group;
    if (pool !== null && pool.category === "Pool") {
      // make sure all of the Group Shapes are big enough
      var minsize = computeMinPoolSize(pool);
      pool.memberParts.each(function(lane) {
        if (!(lane instanceof go.Group)) return;
        if (lane.category !== "Pool") {
          var shape = lane.resizeObject;
          if (shape !== null) {  // change the desiredSize to be big enough in both directions
            var sz = computeLaneSize(lane);
            shape.width = (!isNaN(shape.width)) ? Math.max(shape.width, sz.width) : sz.width;
            shape.height = (isNaN(shape.height) ? minsize.height : Math.max(shape.height, minsize.height));
            var cell = lane.resizeCellSize;
            if (!isNaN(shape.width) && !isNaN(cell.width) && cell.width > 0) shape.width = Math.ceil(shape.width /     cell.width) * cell.width;
            if (!isNaN(shape.height) && !isNaN(cell.height) && cell.height > 0) shape.height = Math.ceil(shape.height / cell.height) * cell.height;
          }
        }
      });
    }
    // now do all of the usual stuff, according to whatever properties have been set on this GridLayout
    go.GridLayout.prototype.doLayout.call(this, coll);
    diagram.commitTransaction("PoolLayout");
  };
  // end PoolLayout class


  function init() {
    if (window.goSamples) goSamples();  // init for these samples -- you don't need to call this
var $ = go.GraphObject.make;

myDiagram =
  $(go.Diagram, "myDiagram",
    {
      // start everything in the middle of the viewport
      initialContentAlignment: go.Spot.Center,
      // use a custom ResizingTool (along with a custom ResizeAdornment on each Group)
      resizingTool: new LaneResizingTool(),
      // use a simple layout that ignores links to stack the top-level Pool Groups next to each other
      layout: $(PoolLayout),
      // don't allow dropping onto the diagram's background unless they are all Groups (lanes or pools)
      mouseDragOver: function(e) {
        if (!e.diagram.selection.all(function(n) { return n instanceof go.Group; })) {
          e.diagram.currentCursor = 'not-allowed';
        }
      },
      mouseDrop: function(e) {
        if (!e.diagram.selection.all(function(n) { return n instanceof go.Group; })) {
          e.diagram.currentTool.doCancel();
        }
      },
      // a clipboard copied node is pasted into the original node's group (i.e. lane).
      "commandHandler.copiesGroupKey": true,
      // automatically re-layout the swim lanes after dragging the selection
      "SelectionMoved": relayoutDiagram,  // this DiagramEvent listener is
      "SelectionCopied": relayoutDiagram, // defined above
      "animationManager.isEnabled": false,
      // enable undo & redo
      "undoManager.isEnabled": true
    });

// this is a Part.dragComputation function for limiting where a Node may be dragged
function stayInGroup(part, pt, gridpt) {
  // don't constrain top-level nodes
  var grp = part.containingGroup;
  if (grp === null) return pt;
  // try to stay within the background Shape of the Group
  var back = grp.resizeObject;
  if (back === null) return pt;
  // allow dragging a Node out of a Group if the Shift key is down
  if (part.diagram.lastInput.shift) return pt;
  var p1 = back.getDocumentPoint(go.Spot.TopLeft);
  var p2 = back.getDocumentPoint(go.Spot.BottomRight);
  var b = part.actualBounds;
  var loc = part.location;
  // find the padding inside the group's placeholder that is around the member parts
  var m = grp.placeholder.padding;
  // now limit the location appropriately
  var x = Math.max(p1.x + m.left, Math.min(pt.x, p2.x - m.right - b.width - 1)) + (loc.x-b.x);
  var y = Math.max(p1.y + m.top, Math.min(pt.y, p2.y - m.bottom - b.height - 1)) + (loc.y-b.y);
  return new go.Point(x, y);
}

//myDiagram.nodeTemplate =
//  $(go.Node, "Auto",
//    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
//    $(go.Shape, "Rectangle",
//      { fill: "white", portId: "", cursor: "pointer", fromLinkable: true, toLinkable: true }),
//    $(go.TextBlock, { margin: 5 },
//      new go.Binding("text", "key")),
//    { dragComputation: stayInGroup } // limit dragging of Nodes to stay within the containing Group, defined above
  //  );
myDiagram.nodeTemplate =
    $(go.Node, "Spot",
      $(go.Panel, "Auto",
      new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        $(go.Shape,  // the gray border around the whole node
          { fill: "transparent", stroke: "gray" },
          new go.Binding("figure")),
        $(go.Panel, "Table",
          $(go.RowColumnDefinition, { row: 0, background: "black", height: 3 }, new go.Binding("background", "color")),
          $(go.RowColumnDefinition, { column: 0, background: "black" }, new go.Binding("background", "color")),
          $(go.Shape,
            { // the main icon, in the left column
                column: 0, row: 1, fill: "white", strokeWidth: 0,
                width: 20, margin: 4, geometryStretch: go.GraphObject.Uniform,
                geometryString: "F1 M27.879 5.879l-3.757-3.757c-1.167-1.167-3.471-2.121-5.121-2.121h-14c-1.65 0-3 1.35-3 3v26c0 1.65 1.35 3 3 3h22c1.65 0 3-1.35 3-3v-18c0-1.65-0.955-3.955-2.121-5.121zM20 4.236c0.069 0.025 0.139 0.053 0.211 0.082 0.564 0.234 0.956 0.505 1.082 0.631l3.757 3.757c0.126 0.126 0.397 0.517 0.631 1.082 0.030 0.072 0.057 0.143 0.082 0.211h-5.764v-5.764zM26 28h-20v-24h12v8h8v16zM8 16h16v2h-16zM8 20h16v2h-16zM8 24h16v2h-16z"
            }),
          $(go.TextBlock,
            { column: 1, row: 1, width: 100, margin: 2, textAlign: "center" },
            new go.Binding("text"))
        )
      ),
      $(go.Shape,
        { // the normally not-visible icon at the top left
            alignment: new go.Spot(0, 0, -5, 0), alignmentFocus: go.Spot.TopRight,
            desiredSize: new go.Size(10, 10), visible: false
        },
        new go.Binding("visible", "showIcon"))
    );
go.Shape.defineFigureGenerator("Hex", function (shape, w, h) {
    var geo = new go.Geometry();
    geo.add(new go.PathFigure(10, 0)
             .add(new go.PathSegment(go.PathSegment.Line, w - 10, 0))
             .add(new go.PathSegment(go.PathSegment.Line, w, h / 2))
             .add(new go.PathSegment(go.PathSegment.Line, w - 10, h))
             .add(new go.PathSegment(go.PathSegment.Line, 10, h))
             .add(new go.PathSegment(go.PathSegment.Line, 0, h / 2).close()));
    // available space within this figure does not include the triangular portions on either side
    geo.spot1 = new go.Spot(0, 0, 10, 0);
    geo.spot2 = new go.Spot(1, 1, -10, 0);
    return geo;
});

myDiagram.nodeTemplateMap.add("Hex",
  $(go.Node, "Auto",
     new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
    $(go.Shape, "Hex",  // this figure is defined above
      { fill: "transparent", stroke: "gray" },
      new go.Binding("figure")),
    $(go.Panel, "Table",
      $(go.RowColumnDefinition, { row: 0, background: "black", height: 3 }, new go.Binding("background", "color")),
      $(go.RowColumnDefinition, { column: 0, background: "black" }, new go.Binding("background", "color")),
      $(go.Shape,
        { // the main icon, in the left column
            column: 0, row: 1, fill: "white", strokeWidth: 0,
            width: 20, margin: 4, geometryStretch: go.GraphObject.Uniform,
            geometryString: "F1 M11.366 22.564l1.291-1.807-1.414-1.414-1.807 1.291c-0.335-0.187-0.694-0.337-1.071-0.444l-0.365-2.19h-2l-0.365 2.19c-0.377 0.107-0.736 0.256-1.071 0.444l-1.807-1.291-1.414 1.414 1.291 1.807c-0.187 0.335-0.337 0.694-0.443 1.071l-2.19 0.365v2l2.19 0.365c0.107 0.377 0.256 0.736 0.444 1.071l-1.291 1.807 1.414 1.414 1.807-1.291c0.335 0.187 0.694 0.337 1.071 0.444l0.365 2.19h2l0.365-2.19c0.377-0.107 0.736-0.256 1.071-0.444l1.807 1.291 1.414-1.414-1.291-1.807c0.187-0.335 0.337-0.694 0.444-1.071l2.19-0.365v-2l-2.19-0.365c-0.107-0.377-0.256-0.736-0.444-1.071zM7 27c-1.105 0-2-0.895-2-2s0.895-2 2-2 2 0.895 2 2-0.895 2-2 2zM32 12v-2l-2.106-0.383c-0.039-0.251-0.088-0.499-0.148-0.743l1.799-1.159-0.765-1.848-2.092 0.452c-0.132-0.216-0.273-0.426-0.422-0.629l1.219-1.761-1.414-1.414-1.761 1.219c-0.203-0.149-0.413-0.29-0.629-0.422l0.452-2.092-1.848-0.765-1.159 1.799c-0.244-0.059-0.492-0.109-0.743-0.148l-0.383-2.106h-2l-0.383 2.106c-0.251 0.039-0.499 0.088-0.743 0.148l-1.159-1.799-1.848 0.765 0.452 2.092c-0.216 0.132-0.426 0.273-0.629 0.422l-1.761-1.219-1.414 1.414 1.219 1.761c-0.149 0.203-0.29 0.413-0.422 0.629l-2.092-0.452-0.765 1.848 1.799 1.159c-0.059 0.244-0.109 0.492-0.148 0.743l-2.106 0.383v2l2.106 0.383c0.039 0.251 0.088 0.499 0.148 0.743l-1.799 1.159 0.765 1.848 2.092-0.452c0.132 0.216 0.273 0.426 0.422 0.629l-1.219 1.761 1.414 1.414 1.761-1.219c0.203 0.149 0.413 0.29 0.629 0.422l-0.452 2.092 1.848 0.765 1.159-1.799c0.244 0.059 0.492 0.109 0.743 0.148l0.383 2.106h2l0.383-2.106c0.251-0.039 0.499-0.088 0.743-0.148l1.159 1.799 1.848-0.765-0.452-2.092c0.216-0.132 0.426-0.273 0.629-0.422l1.761 1.219 1.414-1.414-1.219-1.761c0.149-0.203 0.29-0.413 0.422-0.629l2.092 0.452 0.765-1.848-1.799-1.159c0.059-0.244 0.109-0.492 0.148-0.743l2.106-0.383zM21 15.35c-2.402 0-4.35-1.948-4.35-4.35s1.948-4.35 4.35-4.35 4.35 1.948 4.35 4.35c0 2.402-1.948 4.35-4.35 4.35z"
        }),
      $(go.TextBlock,
        { column: 1, row: 1, width: 100, textAlign: "center" },
        new go.Binding("text"))
    )
  ));

there is my code (line 308 - end):

function groupStyle() {  // common settings for both Lane and Pool Groups
  return [
    {
      layerName: "Background",  // all pools and lanes are always behind all nodes and links
      background: "transparent",  // can grab anywhere in bounds
      movable: true, // allows users to re-order by dragging
      copyable: false,  // can't copy lanes or pools
      avoidable: false,  // don't impede AvoidsNodes routed Links
      minLocation: new go.Point(-Infinity, NaN),  // only allow horizontal movement
      maxLocation: new go.Point(Infinity, NaN)
    },
    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify)
  ];
}

// hide links between lanes when either lane is collapsed
function updateCrossLaneLinks(group) {
  group.findExternalLinksConnected().each(function(l) {
    l.visible = (l.fromNode.isVisible() && l.toNode.isVisible());
  });
}

// each Group is a "swimlane" with a header on the left and a resizable lane on the right
myDiagram.groupTemplate =
  $(go.Group, "Vertical", groupStyle(),
    {
      selectionObjectName: "SHAPE",  // selecting a lane causes the body of the lane to be highlit, not the label
      resizable: true, resizeObjectName: "SHAPE",  // the custom resizeAdornmentTemplate only permits two kinds of resizing
      layout: $(go.LayeredDigraphLayout,  // automatically lay out the lane's subgraph
                {
                  isInitial: false,  // don't even do initial layout
                  isOngoing: false,  // don't invalidate layout when nodes or links are added or removed
                  direction: 90,
                  columnSpacing: 10,
                  layeringOption: go.LayeredDigraphLayout.LayerLongestPathSource
                }),
      computesBoundsAfterDrag: true,  // needed to prevent recomputing Group.placeholder bounds too soon
      computesBoundsIncludingLinks: false,  // to reduce occurrences of links going briefly outside the lane
      computesBoundsIncludingLocation: true,  // to support empty space at top-left corner of lane
      handlesDragDropForMembers: true,  // don't need to define handlers on member Nodes and Links
      mouseDrop: function(e, grp) {  // dropping a copy of some Nodes and Links onto this Group adds them to this Group
        if (!e.shift) return;  // cannot change groups with an unmodified drag-and-drop
        // don't allow drag-and-dropping a mix of regular Nodes and Groups
        if (!e.diagram.selection.any(function(n) { return n instanceof go.Group; })) {
          var ok = grp.addMembers(grp.diagram.selection, true);
          if (ok) {
            updateCrossLaneLinks(grp);
          } else {
            grp.diagram.currentTool.doCancel();
          }
        } else {
          e.diagram.currentTool.doCancel();
        }
      },
      subGraphExpandedChanged: function(grp) {
        var shp = grp.resizeObject;
        if (grp.diagram.undoManager.isUndoingRedoing) return;
        if (grp.isSubGraphExpanded) {
          shp.width = grp._savedBreadth;
        } else {
          grp._savedBreadth = shp.width;
          shp.width = NaN;
        }
        updateCrossLaneLinks(grp);
      }
    },
    new go.Binding("isSubGraphExpanded", "expanded").makeTwoWay(),
    // the lane header consisting of a Shape and a TextBlock
    $(go.Panel, "Horizontal",
      { name: "HEADER",
        angle: 0,  // maybe rotate the header to read sideways going up
        alignment: go.Spot.Center },
      $(go.Panel, "Horizontal",  // this is hidden when the swimlane is collapsed
        new go.Binding("visible", "isSubGraphExpanded").ofObject(),
        //$(go.Shape, "Diamond",
        //  { width: 8, height: 8, fill: "white" },
        //  new go.Binding("fill", "color")),
        $(go.TextBlock,  // the lane label
          { font: "bold 13pt sans-serif", editable: true, margin: new go.Margin(2, 0, 0, 0) },
          new go.Binding("text", "text").makeTwoWay())
      ),
      $("SubGraphExpanderButton", { margin: 5 })  // but this remains always visible!
    ),  // end Horizontal Panel
    $(go.Panel, "Auto",  // the lane consisting of a background Shape and a Placeholder representing the subgraph
      $(go.Shape, "Rectangle",  // this is the resized object
        { name: "SHAPE", fill: "white" },
        new go.Binding("fill", "color"),
        new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify)),
      $(go.Placeholder,
        { padding: 12, alignment: go.Spot.TopLeft }),
      $(go.TextBlock,  // this TextBlock is only seen when the swimlane is collapsed
        { name: "LABEL",
          font: "bold 13pt sans-serif", editable: true,
          angle: 90, alignment: go.Spot.TopLeft, margin: new go.Margin(4, 0, 0, 2) },
        new go.Binding("visible", "isSubGraphExpanded", function(e) { return !e; }).ofObject(),
        new go.Binding("text", "text").makeTwoWay())
    )  // end Auto Panel
  );  // end Group

// define a custom resize adornment that has two resize handles if the group is expanded
myDiagram.groupTemplate.resizeAdornmentTemplate =
  $(go.Adornment, "Spot",
    $(go.Placeholder),
    $(go.Shape,  // for changing the length of a lane
      {
        alignment: go.Spot.Bottom,
        desiredSize: new go.Size(50, 7),
        fill: "lightblue", stroke: "dodgerblue",
        cursor: "row-resize"
      },
      new go.Binding("visible", "", function(ad) { return ad.adornedPart.isSubGraphExpanded; }).ofObject()),
    $(go.Shape,  // for changing the breadth of a lane
      {
        alignment: go.Spot.Right,
        desiredSize: new go.Size(7, 50),
        fill: "lightblue", stroke: "dodgerblue",
        cursor: "col-resize"
      },
      new go.Binding("visible", "", function(ad) { return ad.adornedPart.isSubGraphExpanded; }).ofObject())
  );

myDiagram.groupTemplateMap.add("Pool",
  $(go.Group, "Auto", groupStyle(),
    { // use a simple layout that ignores links to stack the "lane" Groups next to each other
      layout: $(PoolLayout, { spacing: new go.Size(0, 0) })  // no space between lanes
    },
    $(go.Shape,
      { fill: "white" },
      new go.Binding("fill", "color")),
    $(go.Panel, "Table",
      { defaultRowSeparatorStroke: "black" },
      $(go.Panel, "Horizontal",
        { row: 0, angle: 0 },
        $(go.TextBlock,
          { font: "bold 16pt sans-serif", editable: true, margin: new go.Margin(2, 0, 0, 0) },
          new go.Binding("text").makeTwoWay())
      ),
      $(go.Placeholder,
        { row: 1 })
    )
  ));

myDiagram.linkTemplate =
  $(go.Link,
    { routing: go.Link.AvoidsNodes, corner: 5 },
    { relinkableFrom: true, relinkableTo: true },
     $(go.Shape,
   new go.Binding("stroke", "color"),
   new go.Binding("strokeWidth", "width"),
   new go.Binding("strokeDashArray", "dash")),
   new go.Binding("toArrow", "toArrow")
  );


// define some sample graphs in some of the lanes
myDiagram.model = new go.GraphLinksModel(
[ // node data
  { key: "Pool1", isGroup: true, category: "Pool"},
  //{ key: "Pool2", text: "Pool2", isGroup: true, category: "Pool" },
  { key: "Lane1", text: "组织", isGroup: true, group: "Pool1", color: "white", loc: "0 0" },
  { key: "Lane2", text: "流程", isGroup: true, group: "Pool1", color: "white",loc:"1 0" },
  { key: "Lane3", text: "业务信息数据", isGroup: true, group: "Pool1", color: "white", loc: "2 0" },
  { key: "Lane4", text: "输入", isGroup: true, group: "Pool1", color: "white", loc: "3 0" },
  { key: "Lane5", text: "屏幕", isGroup: true, group: "Pool1", color: "white", loc: "4 0" },
  { key: "oneA", group: "Lane1", text: "职位", color: "#CC9900", loc: "100,40" },
  { key: "oneB", group: "Lane1", text: "角色", color: "#CC9900" },
  { key: "oneC", group: "Lane1", text: "组织单元", color: "#FF9900" },
  { key: "twoA", group: "Lane2", text: "用户 选购商品", color: "#990066", category: "Hex" },
  { key: "twoB", group: "Lane2", text: "拍下商品", color: "#006600" },
  { key: "twoC", group: "Lane2", text: "订单已确认", color: "#990066", category: "Hex" },
  { key: "twoD", group: "Lane2", text: "付款", color: "#006600" },
  { key: "twoE", group: "Lane2", text: "客户已付款", color: "#990066", category: "Hex" },
  { key: "twoF", group: "Lane2", text: "发货", color: "#006600" },
  { key: "twoG", group: "Lane2", text: "已发货", color: "#990066", category: "Hex" },
  { key: "twoH", group: "Lane2", text: "收货", color: "#006600" },
  { key: "threeA", group: "Lane3", text: "客户订单", color: "#660099" },
  { key: "threeB", group: "Lane3", text: "付款单", color: "#660099" },
  { key: "threeC", group: "Lane3", text: "发货单", color: "#660099" },
  { key: "threeD", group: "Lane3", text: "收货时间", color: "#0099CC" },
  { key: "threeE", group: "Lane3", text: "收货签名", color: "#0099CC" },
  { key: "fourA", group: "Lane4", text: "功能", color: "#006600" },
  { key: "fourB", group: "Lane4", text: "收货地址", color: "#0099CC" },
  { key: "fiveA", group: "Lane5", text: "拍下商品", color: "#669933" },
  { key: "fiveB", group: "Lane5", text: "付款", color: "#669933" },
  { key: "fiveC", group: "Lane5", text: "发货", color: "#669933" },
],
[ // link data
  { from: "oneB", to: "twoB" },
  { from: "twoA", to: "twoB", color: "black", toArrow: "Standard" },
  { from: "twoB", to: "twoC" },
  { from: "twoC", to: "twoD" },
  { from: "twoD", to: "twoE" },
  { from: "twoE", to: "twoF" },
  { from: "twoF", to: "twoG" },
  { from: "twoG", to: "twoH" },
  { from: "threeA", to: "twoB" },
  { from: "fiveA", to: "twoB" },
  { from: "fiveB", to: "twoD" },
  { from: "threeB", to: "twoD" },
  { from: "threeC", to: "twoF" },
  { from: "fiveC", to: "twoF" },
  { from: "fourB", to: "twoH",  color: "orange", dash: [3, 2] },
  { from: "twoH", to: "threeD", color: "orange", dash: [3, 2] },
  { from: "twoH", to: "threeE", color: "orange", dash: [3, 2] }

]);
// force all lanes' layouts to be performed
relayoutLanes();
  }  // end init

  // Show the diagram's model in JSON format
  function save() {
    document.getElementById("mySavedModel").value = myDiagram.model.toJson();
    myDiagram.isModified = false;
  }
  function load() {
    myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value);
    myDiagram.delayInitialization(relayoutDiagram);
      }
</script>
</head>
<body onload="init()">
<div id="sample" style="height:100%">
  <div id="myDiagram" style="width:100%; height:100%;margin:0 auto"></div>
</div>
</body>
</html>

I have updated http://gojs.net/extras/hexagonalNode.html.

hi walter,

thanks for your help, but I find that your updated code has not solved my problem.
my problems is here:
first,the node can’t locate at the point wheni have set it point as (loc:“10 10”),
second,the customer node (named : Hex) the blackcolor isn’t filled.

and you can see my current appearance which code and image i have uploaded yesterday.
thanks very much.

I thought you wanted the left triangular area to be filled, so I extended the “Hex” figure to fill that area.

Maybe you didn’t load the latest version of the page?

hi walter,

thanks very much.
I have saw the page you update,but there is some different from the picture which I post,
look at the picture:

anthor problem:

how to set the node’s location like this code :“loc:0,0”; and how to define links make that the diagram can contain some different links that some has arrow some not

I’m sorry, but I really cannot debug your code. Have you paid for a support contract?

I don’t see what’s different between what I created for you and what you show in the screenshot. I assume you know enough GoJS to be able to increase the margins on the TextBlock and change the Shape that is shown on the left side and to modify the colors appropriately and to change the width of the node, as desired.

hi walter,
I’m sorry, it’s my mistake,so I post my project on GitHub.please Check it.This is my project
and there is three problem with me, could you please help me solve it ?

  1. the “Hex” Node’s backcolor don‘t looks like which I want to get.

  2. how to set the node’s location like this code :“loc:0,0”

  3. how to define links make that the diagram can contain some different links that some has arrow some not.

you can check “Test002.html” page and that page it my current code . this my goal that I want to get

thanks again.

Those are all simple parameterizations that you implement using data binding. Please read http://gojs.net/latest/intro/usingModels.html and http://gojs.net/latest/intro/dataBinding.html.

hi walter,
I have already read those page. the simple in this page is to easy and I can’t find the way to solve my problem. so I ask you for help.
and my project has already use nodeTemplate,linkTemplate,DataBinding. and the "loc"binding doesn’t effect; “toArrow” binding also fails.