create-gojs-kit
Version:
A CLI for downloading GoJS samples, extensions, and docs
335 lines (300 loc) • 15 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
<meta name="description" content="Groups consisting of a RoundedTopRectangle and a RoundedBottomRectangle figure surrounding the Group's Placeholder." />
<meta itemprop="description" content="Groups consisting of a RoundedTopRectangle and a RoundedBottomRectangle figure surrounding the Group's Placeholder." />
<meta property="og:description" content="Groups consisting of a RoundedTopRectangle and a RoundedBottomRectangle figure surrounding the Group's Placeholder." />
<meta name="twitter:description" content="Groups consisting of a RoundedTopRectangle and a RoundedBottomRectangle figure surrounding the Group's Placeholder." />
<link rel="preconnect" href="https://rsms.me/">
<link rel="stylesheet" href="../assets/css/style.css">
<!-- Copyright 1998-2025 by Northwoods Software Corporation. -->
<meta itemprop="name" content="Groups with Rounded Headers and Footers" />
<meta property="og:title" content="Groups with Rounded Headers and Footers" />
<meta name="twitter:title" content="Groups with Rounded Headers and Footers" />
<meta property="og:image" content="https://gojs.net/latest/assets/images/screenshots/roundedgroups.png" />
<meta itemprop="image" content="https://gojs.net/latest/assets/images/screenshots/roundedgroups.png" />
<meta name="twitter:image" content="https://gojs.net/latest/assets/images/screenshots/roundedgroups.png" />
<meta property="og:url" content="https://gojs.net/latest/samples/roundedGroups.html" />
<meta property="twitter:url" content="https://gojs.net/latest/samples/roundedGroups.html" />
<meta name="twitter:card" content="summary_large_image" />
<meta property="og:type" content="website" />
<meta property="twitter:domain" content="gojs.net" />
<title>
Groups with Rounded Headers and Footers | GoJS Diagramming Library
</title>
</head>
<body>
<!-- This top nav is not part of the sample code -->
<nav id="navTop" class=" w-full h-[var(--topnav-h)] z-30 bg-white border-b border-b-gray-200">
<div class="max-w-screen-xl mx-auto flex flex-wrap items-start justify-between px-4">
<a class="text-white bg-nwoods-primary font-bold !leading-[calc(var(--topnav-h)_-_1px)] my-0 px-2 text-4xl lg:text-5xl logo"
href="../">
GoJS
</a>
<div class="relative">
<button id="topnavButton" class="h-[calc(var(--topnav-h)_-_1px)] px-2 m-0 text-gray-900 bg-inherit shadow-none md:hidden hover:!bg-inherit hover:!text-nwoods-accent hover:!shadow-none" aria-label="Navigation">
<svg class="h-7 w-7 block" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<div id="topnavList" class="hidden md:block">
<div class="absolute right-0 z-30 flex flex-col items-end rounded border border-gray-200 p-4 pl-12 shadow bg-white text-gray-900 font-semibold
md:flex-row md:space-x-4 md:items-start md:border-0 md:p-0 md:shadow-none md:bg-inherit">
<a href="../learn/">Learn</a>
<a href="../samples/">Samples</a>
<a href="../intro/">Intro</a>
<a href="../api/">API</a>
<a href="../download.html">Download</a>
<a href="https://forum.nwoods.com/c/gojs/11" target="_blank" rel="noopener">Forum</a>
<a id="tc" href="https://nwoods.com/contact.html"
target="_blank" rel="noopener" onclick="getOutboundLink('https://nwoods.com/contact.html', 'contact');">Contact</a>
<a id="tb" href="https://nwoods.com/sales/index.html"
target="_blank" rel="noopener" onclick="getOutboundLink('https://nwoods.com/sales/index.html', 'buy');">Buy</a>
</div>
</div>
</div>
</div>
</nav>
<script>
window.addEventListener("DOMContentLoaded", function () {
// topnav
var topButton = document.getElementById("topnavButton");
var topnavList = document.getElementById("topnavList");
if (topButton && topnavList) {
topButton.addEventListener("click", function (e) {
topnavList
.classList
.toggle("hidden");
e.stopPropagation();
});
document.addEventListener("click", function (e) {
// if the clicked element isn't the list, close the list
if (!topnavList.classList.contains("hidden") && !e.target.closest("#topnavList")) {
topButton.click();
}
});
// set active <a> element
var url = window
.location
.href
.toLowerCase();
var aTags = topnavList.getElementsByTagName('a');
for (var i = 0; i < aTags.length; i++) {
var lowerhref = aTags[i]
.href
.toLowerCase();
if (lowerhref.endsWith('.html'))
lowerhref = lowerhref.slice(0, -5);
if (url.startsWith(lowerhref)) {
aTags[i]
.classList
.add('active');
break;
}
}
}
});
</script>
<div class="flex flex-col prose">
<div class="w-full max-w-screen-xl mx-auto">
<!-- * * * * * * * * * * * * * -->
<!-- Start of GoJS sample code -->
<script src="https://cdn.jsdelivr.net/npm/gojs@3.1.0"></script>
<div id="allSampleContent" class="p-4 w-full">
<script src="../extensions/Figures.js"></script>
<script id="code">
function init() {
myDiagram = new go.Diagram('myDiagramDiv', {
layout: new go.TreeLayout({
setsPortSpot: false,
setsChildPortSpot: false,
isRealtime: false
})
});
myDiagram.nodeTemplate =
new go.Node('Vertical', {
defaultStretch: go.Stretch.Horizontal,
fromSpot: go.Spot.RightSide,
toSpot: go.Spot.LeftSide
})
.add(
new go.Panel('Auto')
.add(
new go.Shape('RoundedTopRectangle', { fill: 'white' })
.bind('fill', 'role', r => r[0] === 't' ? 'lightgray' : 'white'),
new go.TextBlock({
margin: new go.Margin(2, 2, 0, 2),
textAlign: 'center'
})
.bind('text', 'header')
),
new go.Panel('Auto', { minSize: new go.Size(NaN, 70) })
.add(
new go.Shape('Rectangle', { fill: 'white' }),
new go.TextBlock({
width: 120,
margin: new go.Margin(2, 2, 0, 2),
textAlign: 'center'
})
.bind('text'),
new go.Shape('BpmnActivityLoop', {
visible: false,
width: 10,
height: 10,
alignment: new go.Spot(0.5, 1, 0, -3),
alignmentFocus: go.Spot.Bottom
})
.bind('visible', 'loop')
),
new go.Panel('Auto')
.add(
new go.Shape('RoundedBottomRectangle', { fill: 'white' })
.bind('fill', 'role', r => r[0] === 'b' ? 'lightgray' : 'white'),
new go.TextBlock({
margin: new go.Margin(2, 2, 0, 2),
textAlign: 'center'
})
.bind('text', 'footer')
)
);
myDiagram.groupTemplate =
new go.Group('Vertical', {
layout: new go.TreeLayout({
setsPortSpot: false,
setsChildPortSpot: false
}),
defaultStretch: go.Stretch.Horizontal,
fromSpot: go.Spot.RightSide,
toSpot: go.Spot.LeftSide
})
.add(
new go.Panel('Auto')
.add(
new go.Shape('RoundedRectangle', { // Rounded top rectangle via parameter2
fill: 'white',
parameter2: 1 | 2
})
.bind('fill', 'role', r => r[0] === 't' ? 'lightgray' : 'white'),
new go.TextBlock({
margin: new go.Margin(2, 2, 0, 2),
textAlign: 'center'
})
.bind('text', 'header')
),
new go.Panel('Auto')
.add(
new go.Shape({ fill: 'white' }),
new go.Placeholder({ padding: 20 }),
new go.Shape('BpmnActivityLoop', {
visible: false,
width: 10,
height: 10,
alignment: new go.Spot(0.5, 1, 0, -3),
alignmentFocus: go.Spot.Bottom
})
.bind('visible', 'loop')
),
new go.Panel('Auto')
.add(
new go.Shape('RoundedRectangle', { // Rounded bottom rectangle via parameter2
fill: 'white',
parameter2: 4 | 8
})
.bind('fill', 'role', r => r[0] === 'b' ? 'lightgray' : 'white'),
new go.TextBlock({
margin: new go.Margin(2, 2, 0, 2),
textAlign: 'center'
})
.bind('text', 'footer')
)
);
myDiagram.linkTemplate =
new go.Link({ routing: go.Routing.Orthogonal, corner: 5 })
.add(
new go.Shape(),
new go.Shape({ toArrow: 'Triangle' })
);
myDiagram.model = new go.GraphLinksModel(
[
{ key: 1, header: 'Supplier', text: 'Planned Order Variations', footer: 'Retailer', role: 'b' },
{ key: 2, header: 'Supplier', text: 'Order & Delivery Variations', footer: 'Retailer', role: 't', loop: true },
{ key: 3, header: 'Supplier', isGroup: true, footer: 'Shipper', role: 'b' },
{ key: 4, header: 'Supplier', text: 'Planned Order Variations', footer: 'Retailer', role: 'b', group: 3 },
{ key: 5, header: 'Supplier', text: 'Order & Delivery Variations', footer: 'Retailer', role: 't', group: 3 },
{ key: 13, header: 'Supplier', isGroup: true, footer: 'Shipper', role: 'b', loop: true },
{ key: 14, header: 'Supplier', text: 'Planned Order Variations', footer: 'Retailer', role: 'b', group: 13 },
{ key: 15, header: 'Supplier', text: 'Order & Delivery Variations', footer: 'Retailer', role: 't', group: 13 }
],
[
{ from: 1, to: 2 },
{ from: 2, to: 3 },
{ from: 2, to: 13 },
{ from: 4, to: 5 },
{ from: 14, to: 15 }
]
);
}
window.addEventListener('DOMContentLoaded', init);
</script>
<div id="sample">
<div id="myDiagramDiv" style="border: solid 1px black; width: 100%; height: 600px"></div>
<p>
This Business Process Model and Notation (BPMN) Choreography diagram demonstrates how to define a group template to look like a node template, with a
rounded header and a rounded footer.
</p>
<p>We also have a <a href="../samples/bpmn/BPMN.html" target="_blank">BPMN Process Editor</a> sample.</p>
</div>
</div>
<!-- * * * * * * * * * * * * * -->
<!-- End of GoJS sample code -->
</div>
<div id="allTagDescriptions" class="p-4 w-full max-w-screen-xl mx-auto">
<hr/>
<h3 class="text-xl">GoJS Features in this sample</h3>
<!-- blacklist tags that do not correspond to a specific GoJS feature -->
<h4>Groups</h4>
<p>
The <a href="../api/symbols/Group.html" target="api">Group</a> class is used to treat a collection of <a href="../api/symbols/Node.html" target="api">Node</a>s and <a href="../api/symbols/Link.html" target="api">Link</a>s as if they were a single <a href="../api/symbols/Node.html" target="api">Node</a>.
Those nodes and links are members of the group; together they constitute a subgraph.
</p>
<p>
A subgraph is <em>not</em> another <a href="../api/symbols/Diagram.html" target="api">Diagram</a>, so there is no separate HTML Div element for the subgraph of a group.
All of the <a href="../api/symbols/Part.html" target="api">Part</a>s that are members of a <a href="../api/symbols/Group.html" target="api">Group</a> belong to the same Diagram as the Group.
There can be links between member nodes and nodes outside of the group as well as links between the group itself and other nodes.
There can even be links between member nodes and the containing group itself.
</p>
<p>
More information can be found in the <a href="../intro/groups.html">GoJS Intro</a>.
</p>
<p>
<a href="../samples/index.html#groups">Related samples</a>
</p>
<hr>
<!-- blacklist tags that do not correspond to a specific GoJS feature -->
<h4>Geometry Path Strings</h4>
<p>
The <b>GoJS</b> <a href="../api/symbols/Geometry.html" target="api">Geometry</a> class controls the "shape" of a <a href="../api/symbols/Shape.html" target="api">Shape</a>,
whereas the <a href="../api/symbols/Shape.html#fill" target="api">Shape.fill</a> and <a href="../api/symbols/Shape.html#stroke" target="api">Shape.stroke</a> and other shape properties control the colors and appearance of the shape.
For common shape figures, there are predefined geometries that can be used by setting <a href="../api/symbols/Shape.html#figure" target="api">Shape.figure</a>.
However one can also define custom geometries.
</p>
<p>
One can construct any Geometry by allocating and initializing a <a href="../api/symbols/Geometry.html" target="api">Geometry</a> of at least one <a href="../api/symbols/PathFigure.html" target="api">PathFigure</a> holding some <a href="../api/symbols/PathSegment.html" target="api">PathSegment</a>s.
But you may find that using the string representation of a Geometry is easier to write and save in a database.
Use the static method <a href="../api/symbols/Geometry.html#parse" target="api">Geometry.parse</a> or the <a href="../api/symbols/Shape.html#geometryString" target="api">Shape.geometryString</a> property to transform a geometry path string into a <a href="../api/symbols/Geometry.html" target="api">Geometry</a> object.
</p>
<p>
More information can be found in the <a href="../intro/geometry.html">GoJS Intro</a>.
</p>
<p>
<a href="../samples/index.html#geometries">Related samples</a>
</p>
<hr>
</div>
</div>
</body>
<!-- This script is part of the gojs.net website, and is not needed to run the sample -->
<script src="../assets/js/goSamples.js"></script>
</html>