create-gojs-kit
Version:
A CLI for downloading GoJS samples, extensions, and docs
735 lines (699 loc) • 31.2 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"/>
<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="Shapes" />
<meta property="og:title" content="Shapes" />
<meta name="twitter:title" content="Shapes" />
<meta property="og:image" content="https://gojs.net/latest/assets/images/fp/defaultCard.png" />
<meta itemprop="image" content="https://gojs.net/latest/assets/images/fp/defaultCard.png" />
<meta name="twitter:image" content="https://gojs.net/latest/assets/images/fp/defaultCard.png" />
<meta property="og:url" content="https://gojs.net/latest/intro/shapes.html" />
<meta property="twitter:url" content="https://gojs.net/latest/intro/shapes.html" />
<meta name="twitter:card" content="summary_large_image" />
<meta property="og:type" content="website" />
<meta property="twitter:domain" content="gojs.net" />
<title>
Shapes | GoJS
</title>
<link rel="stylesheet" href="../assets/css/prism.css"/>
</head>
<script>
window.diagrams = [];
window.goCode = function (pre, w, h, parentid, animation) {
window
.diagrams
.push([pre, w, h, parentid, animation]);
}
</script>
<body>
<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="sticky top-0 left-0 z-10 px-2 w-full bg-white border-b border-b-gray-200 md:hidden">
<button id="sidenavButton" class="flex p-2 text-gray-900 bg-inherit shadow-none items-center text-sm font-semibold hover:!bg-inherit hover:!text-nwoods-accent hover:!shadow-none" aria-label="Navigation">
<svg class="h-7 w-7 block mr-2" 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>
<span>Menu</span>
</button>
</div>
<script>
window.addEventListener("DOMContentLoaded", function () {
// sidenav
var sideButton = document.getElementById("sidenavButton");
var sidenav = document.getElementById("sidenav");
if (sideButton && sidenav) {
sideButton.addEventListener("click", function (e) {
sidenav
.classList
.toggle("hidden");
e.stopPropagation();
});
document.addEventListener("click", function (e) {
// if the clicked element isn't the list, close the list
if (!sidenav.classList.contains("hidden") && !e.target.closest("#sidenavList")) {
sideButton.click();
}
});
}
});
</script>
<div class="flex flex-row md:min-h-screen w-full max-w-screen-xl mx-auto">
<aside id="sidenav"
class="hidden fixed top-0 left-0 z-10 w-full bg-black/10 min-h-screen max-h-screen overflow-x-hidden overflow-y-auto shrink-0
md:block md:sticky md:w-52 md:min-h-0 md:bg-inherit md:border-r md:border-r-gray-200 md:overscroll-auto">
<nav id="sidenavList" class="flex flex-col bg-white w-52 min-h-screen pl-2 pt-4 pb-24 md:w-full md:min-h-0">
<a href="index.html">Basics</a>
<a href="buildingObjects.html">Building Parts</a>
<a href="usingModels.html">Using Models</a>
<a href="dataBinding.html">Data Binding</a>
<a href="react.html">GoJS with React</a>
<a href="svelte.html">GoJS with Svelte</a>
<a href="angular.html">GoJS with Angular</a>
<a href="textBlocks.html">TextBlocks</a>
<a href="shapes.html">Shapes</a>
<a href="pictures.html">Pictures</a>
<a href="panels.html">Panels</a>
<a href="tablePanels.html">Table Panels</a>
<a href="brush.html">Brushes</a>
<a href="sizing.html">Sizing Objects</a>
<a href="itemArrays.html">Item Arrays</a>
<a href="changedEvents.html">Changed Events</a>
<a href="transactions.html">Transactions</a>
<a href="viewport.html">Coordinates</a>
<a href="initialView.html">Initial View</a>
<a href="collections.html">Collections</a>
<a href="links.html">Links</a>
<a href="linkLabels.html">Link Labels</a>
<a href="connectionPoints.html">Link Points</a>
<a href="ports.html">Ports</a>
<a href="nodes.html">Nodes</a>
<a href="typings.html">Typings</a>
<a href="debugging.html">Debugging</a>
<a href="layouts.html">Layouts</a>
<a href="routers.html">Routers</a>
<a href="trees.html">Trees</a>
<a href="subtrees.html">SubTrees</a>
<a href="groups.html">Groups</a>
<a href="subgraphs.html">SubGraphs</a>
<a href="sizedGroups.html">Sized Groups</a>
<a href="selection.html">Selection</a>
<a href="highlighting.html">Highlighting</a>
<a href="theming.html">Theming</a>
<a href="tooltips.html">ToolTips</a>
<a href="contextMenus.html">Context Menus</a>
<a href="events.html">Diagram Events</a>
<a href="tools.html">Tools</a>
<a href="commands.html">Commands</a>
<a href="accessibility.html">Accessibility</a>
<a href="buttons.html">Buttons</a>
<a href="permissions.html">Permissions</a>
<a href="validation.html">Validation</a>
<a href="animation.html">Animation</a>
<a href="HTMLInteraction.html">HTML Interaction</a>
<a href="layers.html">Layers & Z-ordering</a>
<a href="palette.html">Palette</a>
<a href="overview.html">Overview</a>
<a href="replacingDeleting.html">Replacing and Deleting</a>
<a href="templateMaps.html">Template Maps</a>
<a href="legends.html">Legends and Titles</a>
<a href="extensions.html">Extensions</a>
<a href="geometry.html">Geometry Strings</a>
<a href="grids.html">Grid Patterns</a>
<a href="graduatedPanels.html">Graduated Panels</a>
<a href="SVGContext.html">Rendering to SVG</a>
<a href="makingSVG.html">Snapshot to SVG</a>
<a href="makingImages.html">Diagram Images</a>
<a href="printing.html">Printing</a>
<a href="serverSideImages.html">Server-side Images</a>
<a href="nodeScript.html">GoJS in Node.js</a>
<a href="testing.html">Testing</a>
<a href="performance.html">Performance</a>
<a href="platforms.html">Platforms</a>
<a href="deployment.html">Deployment</a>
</nav>
</aside>
<script>
var navList = document.getElementById('sidenavList');
if (navList !== null) {
var url = window.location.href;
var lindex = url.lastIndexOf('/');
url = url
.slice(lindex + 1)
.toLowerCase();
var aTags = navList.getElementsByTagName('a');
var currentindex = -1;
for (var i = 0; i < aTags.length; i++) {
var lowerhref = aTags[i]
.href
.toLowerCase();
if (lowerhref.indexOf('/' + url) !== -1) {
currentindex = i;
aTags[i]
.classList
.add('active');
break;
}
}
}
</script>
<div class="px-4 pb-16 w-full overflow-hidden prose">
<h1>Shapes</h1>
<p>
Use the <a>Shape</a> class to paint a geometrical figure.
You can control what kind of shape is drawn and how its outline is stroked and how its interior is filled.
</p>
<p>
Shapes, like <a>TextBlock</a>s and <a>Picture</a>s, are "atomic" objects -- they cannot contain any other objects.
So a Shape will never draw some text or an image.
</p>
<p>
In these simplistic demonstrations, the code programmatically creates a Part and adds it to the Diagram.
Once you learn about models and data binding you will generally not create parts (nodes or links) programmatically.
</p>
<h2 id="Figures">Figures</h2>
<p>
You can set the <a>Shape.figure</a> property to commonly named kinds of shapes.
When using the constructor, you can pass the figure name as a string argument.
You may also need to set the <a>GraphObject.desiredSize</a> or <a>GraphObject.width</a> and <a>GraphObject.height</a> properties,
although it is also common to have the size determined by the Panel that the shape is in.
</p>
<p>Here are several of the most often used Shape figures:</p>
<pre class="lang-js" id="figureShapes"><code>
const settings = { width: 40, height: 60, margin: 4, fill: null };
diagram.add(
new go.Part("Horizontal")
.add(
new go.Shape("Rectangle", settings),
new go.Shape("RoundedRectangle", settings),
new go.Shape("Capsule", settings),
new go.Shape("Ellipse", settings),
new go.Shape("Diamond", settings),
new go.Shape("TriangleRight", settings),
new go.Shape("TriangleDown", settings),
new go.Shape("TriangleLeft", settings),
new go.Shape("TriangleUp", settings),
new go.Shape("MinusLine", settings),
new go.Shape("PlusLine", settings),
new go.Shape("XLine", settings)
));
</code></pre>
<script>
goCode('figureShapes', 600, 100);
</script>
<p>
You can see all of the named geometrical figures in the <a href="../samples/shapes.html" target="samples">shapes</a> sample.
Some of the most commonly used figures are predefined in the <b>GoJS</b> library.
But most figures are defined in the <a href="../extensions/Figures.js" target="_blank">Figures.js</a> file in the extensions directory.
</p>
<h2 id="FillAndStrokes">Fill and Strokes</h2>
<p>
The <a>Shape.stroke</a> property specifies the brush used to draw the shape's outline.
The <a>Shape.fill</a> property specifies the brush used to fill the shape's outline.
Additional "stroke..." properties also control how the shape's outline is drawn.
The most common such property is <a>Shape.strokeWidth</a>.
It is often set to zero so that no stroke is drawn at all -- only the fill occupying the geometry of the shape.
</p>
<pre class="lang-js" id="strokedShapes"><code>
const settings = { figure: "Club", width: 40, height: 40, margin: 4 };
diagram.add(
new go.Part("Horizontal")
.add(
new go.Shape(settings)
.set({ /* default fill and stroke are "black" */ }),
new go.Shape(settings)
.set({ fill: "green" }),
new go.Shape(settings)
.set({ fill: "green", stroke: null }),
new go.Shape(settings)
.set({ fill: null, stroke: "green" }),
new go.Shape(settings)
.set({ fill: null, stroke: "green", strokeWidth: 3 }),
new go.Shape(settings)
.set({ fill: null, stroke: "green", strokeWidth: 6 }),
new go.Shape(settings)
.set({ fill: "green", background: "orange" })
));
</code></pre>
<script>
goCode('strokedShapes', 600, 100);
</script>
<p>
The <a>Shape.stroke</a> and <a>Shape.fill</a> properties take <a>Brush</a>es but most often are given a CSS color string
to specify a solid color brush.
These two properties default to a solid black brush.
However it is common to assign one of them to be either null or "transparent".
A null brush means that nothing is drawn for that stroke or fill.
A transparent brush produces the same appearance but different hit-testing behavior.
A shape with a null <a>Shape.fill</a> produces a hollow shape -- clicking inside the shape will not hit that shape and
thus not select the <a>Node</a> that that shape is in.
But a shape with a "transparent" fill produces a filled shape -- a mouse event inside the shape will hit that shape.
</p>
<p>
Note that specifying a null or transparent <a>Shape.stroke</a> still means that the size of the shape includes the width of the stroke,
even though nothing is drawn there.
If you don't want any stroke at all, it is usually best to set <a>Shape.strokeWidth</a> to zero.
</p>
<pre class="lang-js" class="lang-js" id="fill"><code>
diagram.div.style.background = "lightgray";
const settings = { row: 0, figure: "Club", width: 60, height: 60, margin: 4 };
diagram.add(
new go.Part("Table")
.add(
new go.Shape(settings)
.set({ column: 0, fill: "green" }),
new go.TextBlock("green", { row: 1, column: 0 }),
new go.Shape(settings)
.set({ column: 1, fill: "white" }),
new go.TextBlock("white", { row: 1, column: 1 }),
new go.Shape(settings)
.set({ column: 2, fill: "transparent" }),
new go.TextBlock("transparent", { row: 1, column: 2 }),
new go.Shape(settings)
.set({ column: 3, fill: null }),
new go.TextBlock("null", { row: 1, column: 3 })
));
</code></pre>
<script>
goCode('fill', 600, 100);
</script>
<p>
Try clicking inside each of the shapes to see which ones will respond to the click and cause the whole panel to be selected.
Note that with the "transparent" fill you can see the diagram background, yet when you click in it you hit the Shape.
Only the last one, with a null fill, is truly hollow.
Clicking in the last shape will only result in a click on the diagram background, unless you click on the stroke outline.
</p>
<h2 id="Geometry">Geometry</h2>
<p>
Every <a>Shape</a> gets its "shape" from the <a>Geometry</a> that it uses.
A Geometry is just a saved description of how to draw some lines given a set of points.
Setting <a>Shape.figure</a> uses a named predefined geometry that can be parameterized.
In general it is most efficient to give a Shape a Geometry rather than giving it a figure.
</p>
<p>
If you want something different from all of the predefined figures in <b>GoJS</b>,
you can construct your own Geometry and set <a>Shape.geometry</a>.
One way of building your own <a>Geometry</a> is by building <a>PathFigure</a>s consisting of <a>PathSegment</a>s.
This is often necessary when building a geometry whose points are computed based on some data.
</p>
<p>
But an easier way to create constant geometries is by calling <a>Geometry.parse</a> to read a string that has a geometry-defining path expression,
or to set <a>Shape.geometryString</a> to such a string.
These expressions have commands for moving an imaginary "pen".
The syntax for geometry paths is documented in the <a href="geometry.html">Geometry Path Strings</a> page.
</p>
<p>
This example creates a Geometry that looks like the letter "W" and uses it in several Shape objects with different stroke characteristics.
Geometry objects may be shared by multiple Shapes.
Note that there may be no need to specify the <a>GraphObject.desiredSize</a> or <a>GraphObject.width</a> and <a>GraphObject.height</a>,
because the Geometry defines its own size.
If the size is set or if it is imposed by the containing Panel, the effective geometry is determined by the <a>Shape.geometryStretch</a> property.
Depending on the value of the geometryStretch property, this may result in extra empty space or the clipping of the shape.
</p>
<pre class="lang-js" id="geometries"><code>
const W_geometry = go.Geometry.parse("M 0,0 L 10,50 20,10 30,50 40,0", false);
diagram.add(
new go.Part("Horizontal")
.add(
new go.Shape({ geometry: W_geometry,
/* default stroke */ strokeWidth: 2, /* default strokeJoin and strokeCap */
}),
new go.Shape({ geometry: W_geometry,
stroke: "blue", strokeWidth: 10, strokeJoin: "miter", strokeCap: "butt"
}),
new go.Shape({ geometry: W_geometry,
stroke: "blue", strokeWidth: 10, strokeJoin: "miter", strokeCap: "round"
}),
new go.Shape({ geometry: W_geometry,
stroke: "blue", strokeWidth: 10, strokeJoin: "miter", strokeCap: "square"
}),
new go.Shape({ geometry: W_geometry,
stroke: "green", strokeWidth: 10, strokeJoin: "bevel", strokeCap: "butt"
}),
new go.Shape({ geometry: W_geometry,
stroke: "green", strokeWidth: 10, strokeJoin: "bevel", strokeCap: "round"
}),
new go.Shape({ geometry: W_geometry,
stroke: "green", strokeWidth: 10, strokeJoin: "bevel", strokeCap: "square"
}),
new go.Shape({ geometry: W_geometry,
stroke: "red", strokeWidth: 10, strokeJoin: "round", strokeCap: "butt"
}),
new go.Shape({ geometry: W_geometry,
stroke: "red", strokeWidth: 10, strokeJoin: "round", strokeCap: "round"
}),
new go.Shape({ geometry: W_geometry,
stroke: "red", strokeWidth: 10, strokeJoin: "round", strokeCap: "square"
}),
new go.Shape({ geometry: W_geometry,
stroke: "purple", strokeWidth: 2, strokeDashArray: [4, 2]
}),
new go.Shape({ geometry: W_geometry,
stroke: "purple", strokeWidth: 2, strokeDashArray: [6, 6, 2, 2]
})
));
</code></pre>
<script>
goCode('geometries', 600, 100);
</script>
<h2 id="AngleAndScale">Angle and Scale</h2>
<p>
Besides setting the <a>GraphObject.desiredSize</a> or <a>GraphObject.width</a> and <a>GraphObject.height</a> to declare the size of a <a>Shape</a>, you can
also set other properties to affect the appearance. For example, you can set the <a>GraphObject.angle</a> and <a>GraphObject.scale</a> properties.
</p>
<pre class="lang-js" id="transformedShapes"><code>
const settings = { figure: "Club", fill: "green", width: 40, height: 40 };
diagram.add(
new go.Part("Table")
.add(
new go.Shape(settings)
.set({
column: 1, /* default angle is zero; default scale is one */
}),
new go.Shape(settings)
.set({
column: 2, angle: 30
}),
new go.Shape(settings)
.set({
column: 3, scale: 1.5
}),
new go.Shape(settings)
.set({
column: 4, angle: 30, scale: 1.5
})
));
</code></pre>
<script>
goCode('transformedShapes', 600, 100);
</script>
<p>The <a>Shape.fill</a> and <a>GraphObject.background</a> brushes scale and rotate along with the shape.</p>
<p>
The following shapes show how three separate linear gradient brushes are drawn for the
<a>Shape.fill</a>, <a>Shape.stroke</a>, and <a>GraphObject.background</a> of a Shape whose angle isn't zero.
</p>
<pre class="lang-js" id="backgrounds"><code>
const bluered = new go.Brush("Linear", { 0.0: "blue", 1.0: "red" });
const yellowgreen = new go.Brush("Linear", { 0.0: "yellow", 1.0: "green" });
const grays = new go.Brush("Linear", { 1.0: "black", 0.0: "lightgray" });
const settings = {
figure: "Club", width: 40, height: 40,
fill: bluered,
stroke: grays, strokeWidth: 2,
background: yellowgreen
};
diagram.add(
new go.Part("Table")
.add(
new go.Shape({ column: 0, angle: 0, scale: 2 })
.set(settings),
new go.Shape({ column: 1, angle: 45, scale: 2 })
.set(settings)
));
</code></pre>
<script>
goCode('backgrounds', 600, 150);
</script>
<h2 id="SimpleIconsUsingFonts">Simple Icons Using Fonts</h2>
<p>
Note: for showing simple icons you may want to use an icon font.
See the example using a <a>TextBlock</a> rather than a <a>Shape</a> at:
<a href="textBlocks.html#IconFonts">Icon Fonts</a>
</p>
<h2 id="CustomFigures">Custom Figures</h2>
<p>
As shown above, one can easily create custom shapes just by setting <a>Shape.geometry</a> or <a>Shape.geometryString</a>. This is particularly convenient when
importing SVG. However it is also possible to define additional named figures, which is convenient when you want to be able to easily specify or change the
geometry of an existing Shape by setting or data binding the <a>Shape.figure</a> property.
</p>
<p>
The static function <a>Shape.defineFigureGenerator</a> can be used to define new figure names. The second argument is a function that is called with the
<a>Shape</a> and the expected width and height in order to generate and return a <a>Geometry</a>. This permits parameterization of the geometry based on
properties of the Shape and the expected size. In particular, the <a>Shape.parameter1</a> and <a>Shape.parameter2</a> properties can be considered, in
addition to the width and height, while producing the Geometry. To be valid, the generated Geometry bounds must be equal to or less than the supplied width
and height.
</p>
<pre class="lang-js" id="defineFigure"><code>
go.Shape.defineFigureGenerator('FramedRectangle', (shape, w, h) => {
let param1 = shape ? shape.parameter1 : NaN;
let param2 = shape ? shape.parameter2 : NaN;
if (isNaN(param1))
param1 = 8; // default values PARAMETER 1 is for WIDTH
if (isNaN(param2))
param2 = 8; // default values PARAMETER 2 is for HEIGHT
const geo = new go.Geometry();
const fig = new go.PathFigure(0, 0, true);
geo.add(fig);
// outer rectangle, clockwise
fig.add(new go.PathSegment(go.SegmentType.Line, w, 0));
fig.add(new go.PathSegment(go.SegmentType.Line, w, h));
fig.add(new go.PathSegment(go.SegmentType.Line, 0, h).close());
if (param1 < w / 2 && param2 < h / 2) {
// inner rectangle, counter-clockwise
fig.add(new go.PathSegment(go.SegmentType.Move, param1, param2)); // subpath
fig.add(new go.PathSegment(go.SegmentType.Line, param1, h - param2));
fig.add(new go.PathSegment(go.SegmentType.Line, w - param1, h - param2));
fig.add(new go.PathSegment(go.SegmentType.Line, w - param1, param2).close());
}
geo.setSpots(0, 0, 1, 1, param1, param2, -param1, -param2);
return geo;
});
diagram.nodeTemplate =
new go.Part("Spot", {
selectionAdorned: false, // don't show the standard selection handle
resizable: true, resizeObjectName: "SHAPE", // user can resize the Shape
rotatable: true, rotateObjectName: "SHAPE", // user can rotate the Shape
// without rotating the label
})
.add(
new go.Shape('FramedRectangle', {
name: "SHAPE",
fill: new go.Brush("Linear", { 0.0: "white", 1.0: "gray" }),
desiredSize: new go.Size(100, 50)
})
.bind("parameter1", "p1")
.bind("parameter2", "p2"),
new go.TextBlock({ stroke: "blue" })
.bindObject("text", "", s => `${s.parameter1}, ${s.parameter2}`, null, "SHAPE")
);
diagram.model = new go.Model([
{ }, // unspecified parameter values treated as 8 by "FramedRectangle" figure
{ p1: 0 },
{ p1: 5 },
{ p1: 15 },
{ p1: 5, p2: 5 },
{ p1: 15, p2: 15 },
]);</code></pre>
<script>
goCode('defineFigure', 700, 300);
</script>
<p>
Note how the <a>Shape.parameter1</a> property, data bound to the "p1" property, controls how thick the sides are. The <a>Shape.parameter2</a> property, data
bound to the "p2" property, controls how thick the top and bottom are. You can see the effects by resizing a shape. Notice how it doesn't bother drawing the
empty area in the middle when there isn't enough width or height.
</p>
<p>
You can find the definitions for many figures at: <a href="../extensions/Figures.js" target="_blank">Figures.js</a> or
<a href="../extensionsJSM/Figures.ts" target="_blank">Figures.ts</a>
</p>
</div>
</div>
<footer class="bg-white text-gray-900 border-t border-t-gray-200">
<div class="w-full max-w-screen-lg mx-auto px-4 py-6">
<p id="version" class="text-xs text-gray-900 m-0"></p>
<div class="text-sm px-0 mb-4 grid grid-cols-2 sm:grid-cols-3 gap-y-10">
<div>
<h2 class="text-base font-semibold text-nwoods-primary">GoJS</h2>
<ul class="list-none space-y-4 md:space-y-1 px-0">
<li>
<a href="../samples/index.html">Samples</a>
</li>
<li>
<a href="../learn/index.html">Learn</a>
</li>
<li>
<a href="../intro/index.html">Intro</a>
</li>
<li>
<a href="../api/index.html">API</a>
</li>
<li>
<a href="../changelog.html">Changelog</a>
</li>
<li>
<a href="https://github.com/NorthwoodsSoftware/GoJS" target="_blank" rel="noopener">GitHub</a>
</li>
</ul>
</div>
<div>
<h2 class="text-base font-semibold text-nwoods-primary">Support</h2>
<ul class="list-none space-y-4 md:space-y-1 px-0">
<li>
<a href="https://nwoods.com/contact.html"
target="_blank" rel="noopener" onclick="getOutboundLink('https://nwoods.com/contact.html', 'contact');">Contact</a>
</li>
<li>
<a href="https://forum.nwoods.com/c/gojs" target="_blank" rel="noopener">Forum</a>
</li>
<li>
<a href="https://nwoods.com/app/activate.aspx?sku=gojs" target="_blank" rel="noopener">Activate</a>
</li>
<li>
<a href="https://nwoods.com/sales/index.html"
target="_blank" rel="noopener" onclick="getOutboundLink('https://nwoods.com/sales/index.html', 'buy');">Buy</a>
</li>
<li>
<a href="https://nwoods.com/register.html" target="_blank" rel="noopener">Register</a>
</li>
</ul>
</div>
<div>
<h2 class="text-base font-semibold text-nwoods-primary">Company</h2>
<ul class="list-none space-y-4 md:space-y-1 px-0">
<li>
<a target="_blank" href="https://nwoods.com" target="_blank" rel="noopener">Northwoods</a>
</li>
<li>
<a target="_blank" href="https://nwoods.com/about.html" target="_blank" rel="noopener">About Us</a>
</li>
<li>
<a target="_blank" href="https://nwoods.com/contact.html" target="_blank" rel="noopener">Contact Us</a>
</li>
<li>
<a target="_blank" href="https://nwoods.com/consulting.html" target="_blank" rel="noopener">Consulting</a>
</li>
<li>
<a target="_blank" href="https://twitter.com/northwoodsgo" target="_blank" rel="noopener">Twitter</a>
</li>
</ul>
</div>
</div>
<p class="text-sm text-gray-900 md:mb-6">
Copyright 1998-2025 <a href="https://nwoods.com">Northwoods Software</a>
</p>
</div>
</footer>
</body>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-S5QK8VSK84"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-S5QK8VSK84');
var getOutboundLink = function (url, label) {
gtag('event', 'click', {
'event_category': 'outbound',
'event_label': label,
'transport_type': 'beacon'
});
}
const params = new URL(document.location).searchParams
let a = params.get('a');
if (a) localStorage.setItem('a', a);
a = localStorage.getItem('a');
if (a) {
const links = [...document.body.getElementsByTagName("a")].filter((l) => l.href.includes('nwoods.com'));
for (const l of links) {
const url = new URL(l.href);
url.searchParams.set('a', a);
l.href = url;
}
}
</script>
<script src="../assets/js/prism.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gojs@3.1.0"></script>
<script src="../extensions/Figures.js"></script>
<script src="../assets/js/goDoc.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
if (window.go)
document
.getElementById('version')
.textContent = "GoJS version " + go.version;
if (window.goDoc)
window.goDoc();
var d = window.diagrams;
for (var i = 0; i < d.length; i++) {
var dargs = d[i];
goCodeExecute(dargs[0], dargs[1], dargs[2], dargs[3], dargs[4]);
}
if (window.extra)
window.extra();
}
);
</script>
</html>