UNPKG

markgojs

Version:

Interactive diagrams, charts, and graphs, such as trees, flowcharts, orgcharts, UML, BPMN, or business diagrams

1,438 lines (1,271 loc) 265 kB
'use strict'; /* * Copyright (C) 1998-2019 by Northwoods Software Corporation. All Rights Reserved. */ import * as go from "../release/go"; // This file holds definitions of all standard shape figures -- string values for Shape.figure. // The following functions and variables are used throughout this file: /** * @constructor * @param {string} name * @param {number} def * @param {number=} min defaults to zero * @param {number=} max defaults to Infinity * @class * This FigureParamter class describes various properties each parameter uses in figures. */ export class FigureParameter { nameIn: string; def: number; min: number; max: number; constructor(name: string, def: number, min?: number, max?: number) { this.nameIn = name; this.def = def; if (min === undefined/*notpresent*/) min = 0.0; if (max === undefined/*notpresent*/) max = Infinity; (<any>go.Shape)["_FigureParameters"] = {}; } /** @type {string} */ private _name = this.nameIn; /** @type {number} */ private _defaultValue = this.def; /** @type {number} */ private _minimum = this.min; /** @type {number} */ private _maximum = this.max; // Public properties /** * Gets or sets the name of the figure. * @name FigureParamater#name * @function. * @return {string} */ get name(): string { return this._name; } set name(val: string) { if (typeof val !== "string" || val === "") throw new Error("Shape name must be a valid string."); this._name = val; } /** * Gets or sets the default value for the parameter. * @name FigureParameter#defaultValue * @function * @return {number} */ get defaultValue(): number { return this._defaultValue; } set defaultValue(val: number) { if (typeof val !== "number" || isNaN(val)) throw new Error("The default value must be a real number, not: " + val); this._defaultValue = val; } /** * Gets or sets the minimum value allowed for the figure parameter. * @name FigureParameter#minimum * @function. * @return {number} */ get minimum(): number { return this._minimum; } set minimum(val: number) { if (typeof val !== "number" || isNaN(val)) throw new Error("Minimum must be a real number, not: " + val); this._minimum = val; } /** * Gets or sets the maximum value allowed for the figure parameter. * @name FigureParameter#maximum * @function. * @return {number} */ get maximum(): number { return this._maximum; } set maximum(val: number) { if (typeof val !== "number" || isNaN(val)) throw new Error("Maximum must be a real number, not: " + val); this._maximum = val; } /** * This static function gets a FigureParameter for a particular figure name. * @param {String} figurename * @param {number} index, currently must be either 0 or 1 * @return {FigureParameter} */ public getFigureParameter(figurename: string, index: number): FigureParameter { var arr = (<any>go.Shape)["_FigureParameters"][figurename]; if (!arr) return null; return /** @type {FigureParmeter} */ (arr[index]); }; /** * This static function sets a FigureParameter for a particular figure name. * @param {String} figurename * @param {number} index, currently must be either 0 or 1 * @param {FigureParameter} figparam */ public setFigureParameter(figurename: string, index: number, figparam: FigureParameter) { if (!(figparam instanceof FigureParameter)) throw new Error("Third argument to Shape.setFigureParameter is not FigureParameter: " + figparam); if (figparam.defaultValue < figparam.minimum || figparam.defaultValue > figparam.maximum) throw new Error("defaultValue must be between minimum and maximum, not: " + figparam.defaultValue); var arr = (<any>go.Shape)["_FigureParameters"][figurename]; if (!arr) { arr = []; (<any>go.Shape)["_FigureParameters"][figurename] = arr; } arr[index] = figparam; }; } /** @ignore */ var _CachedPoints: Array<go.Point> = []; /** * @ignore * @param {number} x * @param {number} y * @return {Point} */ function tempPointAt(x: number, y: number): go.Point { var temp = _CachedPoints.pop(); if (temp === undefined) return new go.Point(x, y); temp.x = x; temp.y = y; return temp; }; /** * @ignore * @return {Point} */ function tempPoint(): go.Point { var temp = _CachedPoints.pop(); if (temp === undefined) return new go.Point(); return temp; }; /** * @ignore * @param {Point} temp */ function freePoint(temp: go.Point) { _CachedPoints.push(temp); }; /** * @ignore * @param {number} p1x * @param {number} p1y * @param {number} p2x * @param {number} p2y * @param {number} q1x * @param {number} q1y * @param {number} q2x * @param {number} q2y * @param {Point} result * @return {Point} */ function getIntersection(p1x: number, p1y: number, p2x: number, p2y: number, q1x: number, q1y: number, q2x: number, q2y: number, result: go.Point): go.Point { var dx1 = p1x - p2x; var dx2 = q1x - q2x; var x; var y; if (dx1 === 0 || dx2 === 0) { if (dx1 === 0) { var m2 = (q1y - q2y) / dx2; var b2 = q1y - m2 * q1x; x = p1x; y = m2 * x + b2; } else { var m1 = (p1y - p2y) / dx1; var b1 = p1y - m1 * p1x; x = q1x; y = m1 * x + b1; } } else { var m1 = (p1y - p2y) / dx1; var m2 = (q1y - q2y) / dx2; var b1 = p1y - m1 * p1x; var b2 = q1y - m2 * q1x; x = (b2 - b1) / (m1 - m2); y = m1 * x + b1; } result.x = x; result.y = y; return result; }; /** * @ignore * @param {number} startx * @param {number} starty * @param {number} c1x * @param {number} c1y * @param {number} c2x * @param {number} c2y * @param {number} endx * @param {number} endy * @param {number} fraction * @param {Point} curve1cp1 // modified result control point * @param {Point} curve1cp2 // modified result control point * @param {Point} midpoint // modified result * @param {Point} curve2cp1 // modified result control point * @param {Point} curve2cp2 // modified result control point */ function breakUpBezier(startx: number, starty: number, c1x: number, c1y: number, c2x: number, c2y: number, endx: number, endy: number, fraction: number, curve1cp1: go.Point, curve1cp2: go.Point, midpoint: go.Point, curve2cp1: go.Point, curve2cp2: go.Point) { var fo = 1 - fraction; var so = fraction; var m1x = (startx * fo + c1x * so); var m1y = (starty * fo + c1y * so); var m2x = (c1x * fo + c2x * so); var m2y = (c1y * fo + c2y * so); var m3x = (c2x * fo + endx * so); var m3y = (c2y * fo + endy * so); var m12x = (m1x * fo + m2x * so); var m12y = (m1y * fo + m2y * so); var m23x = (m2x * fo + m3x * so); var m23y = (m2y * fo + m3y * so); var m123x = (m12x * fo + m23x * so); var m123y = (m12y * fo + m23y * so); curve1cp1.x = m1x; curve1cp1.y = m1y; curve1cp2.x = m12x; curve1cp2.y = m12y; midpoint.x = m123x; midpoint.y = m123y; curve2cp1.x = m23x; curve2cp1.y = m23y; curve2cp2.x = m3x; curve2cp2.y = m3y; }; var GeneratorEllipseSpot1 = new go.Spot(0.156, 0.156); var GeneratorEllipseSpot2 = new go.Spot(0.844, 0.844); var KAPPA = 4 * ((Math.sqrt(2) - 1) / 3); // PREDEFINED figures, built into the v2.0 library: go.Shape.defineFigureGenerator("Rectangle", (shape, w, h) => { // predefined in 2.0 var geo = new go.Geometry(go.Geometry.Rectangle); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; return geo; }); go.Shape.defineFigureGenerator("Square", (shape, w, h) => { // predefined in 2.0 var geo = new go.Geometry(go.Geometry.Rectangle); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; geo.defaultStretch = go.GraphObject.Uniform; return geo; }); FigureParameter.prototype.setFigureParameter("RoundedRectangle", 0, new FigureParameter("CornerRounding", 5)); go.Shape.defineFigureGenerator("RoundedRectangle", (shape, w, h) => { // predefined in 2.0 var param1 = shape ? shape.parameter1 : NaN; if (isNaN(param1) || param1 < 0) param1 = 5; // default corner param1 = Math.min(param1, w / 3); param1 = Math.min(param1, h / 3); var cpOffset = param1 * KAPPA; var geo = new go.Geometry() .add(new go.PathFigure(param1, 0, true) .add(new go.PathSegment(go.PathSegment.Line, w - param1, 0)) .add(new go.PathSegment(go.PathSegment.Bezier, w, param1, w - cpOffset, 0, w, cpOffset)) .add(new go.PathSegment(go.PathSegment.Line, w, h - param1)) .add(new go.PathSegment(go.PathSegment.Bezier, w - param1, h, w, h - cpOffset, w - cpOffset, h)) .add(new go.PathSegment(go.PathSegment.Line, param1, h)) .add(new go.PathSegment(go.PathSegment.Bezier, 0, h - param1, cpOffset, h, 0, h - cpOffset)) .add(new go.PathSegment(go.PathSegment.Line, 0, param1)) .add(new go.PathSegment(go.PathSegment.Bezier, param1, 0, 0, cpOffset, cpOffset, 0).close())); if (cpOffset > 1) { geo.spot1 = new go.Spot(0, 0, cpOffset, cpOffset); geo.spot2 = new go.Spot(1, 1, -cpOffset, -cpOffset); } return geo; }); go.Shape.defineFigureGenerator("Border", "RoundedRectangle"); // predefined in 2.0 go.Shape.defineFigureGenerator("Ellipse", (shape, w, h) => { // predefined in 2.0 var geo = new go.Geometry(go.Geometry.Ellipse); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; geo.spot1 = GeneratorEllipseSpot1; geo.spot2 = GeneratorEllipseSpot2; return geo; }); go.Shape.defineFigureGenerator("Circle", (shape, w, h) => { // predefined in 2.0 var geo = new go.Geometry(go.Geometry.Ellipse); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; geo.spot1 = GeneratorEllipseSpot1; geo.spot2 = GeneratorEllipseSpot2; geo.defaultStretch = go.GraphObject.Uniform; return geo; }); go.Shape.defineFigureGenerator("TriangleRight", (shape, w, h) => { // predefined in 2.0 return new go.Geometry() .add(new go.PathFigure(0, 0) .add(new go.PathSegment(go.PathSegment.Line, w, 0.5 * h)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())) .setSpots(0, 0.25, 0.5, 0.75); }); go.Shape.defineFigureGenerator("TriangleDown", (shape, w, h) => { // predefined in 2.0 return new go.Geometry() .add(new go.PathFigure(0, 0) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Line, 0.5 * w, h).close())) .setSpots(0.25, 0, 0.75, 0.5); }); go.Shape.defineFigureGenerator("TriangleLeft", (shape, w, h) => { // predefined in 2.0 return new go.Geometry() .add(new go.PathFigure(w, h) .add(new go.PathSegment(go.PathSegment.Line, 0, 0.5 * h)) .add(new go.PathSegment(go.PathSegment.Line, w, 0).close())) .setSpots(0.5, 0.25, 1, 0.75); }); go.Shape.defineFigureGenerator("TriangleUp", (shape, w, h) => { // predefined in 2.0 return new go.Geometry() .add(new go.PathFigure(w, h) .add(new go.PathSegment(go.PathSegment.Line, 0, h)) .add(new go.PathSegment(go.PathSegment.Line, 0.5 * w, 0).close())) .setSpots(0.25, 0.5, 0.75, 1); }); go.Shape.defineFigureGenerator("Triangle", "TriangleUp"); // predefined in 2.0 go.Shape.defineFigureGenerator("Diamond", (shape, w, h) => { // predefined in 2.0 return new go.Geometry() .add(new go.PathFigure(0.5 * w, 0) .add(new go.PathSegment(go.PathSegment.Line, 0, 0.5 * h)) .add(new go.PathSegment(go.PathSegment.Line, 0.5 * w, h)) .add(new go.PathSegment(go.PathSegment.Line, w, 0.5 * h).close())) .setSpots(0.25, 0.25, 0.75, 0.75); }); go.Shape.defineFigureGenerator("LineH", (shape, w, h) => { // predefined in 2.0 var geo = new go.Geometry(go.Geometry.Line); geo.startX = 0; geo.startY = h / 2; geo.endX = w; geo.endY = h / 2; return geo; }); go.Shape.defineFigureGenerator("LineV", (shape, w, h) => { // predefined in 2.0 var geo = new go.Geometry(go.Geometry.Line); geo.startX = w / 2; geo.startY = 0; geo.endX = w / 2; geo.endY = h; return geo; }); go.Shape.defineFigureGenerator("BarH", "Rectangle"); // predefined in 2.0 go.Shape.defineFigureGenerator("BarV", "Rectangle"); // predefined in 2.0 go.Shape.defineFigureGenerator("MinusLine", "LineH"); // predefined in 2.0 go.Shape.defineFigureGenerator("PlusLine", (shape, w, h) => { // predefined in 2.0 return new go.Geometry() .add(new go.PathFigure(0, h / 2, false) .add(new go.PathSegment(go.PathSegment.Line, w, h / 2)) .add(new go.PathSegment(go.PathSegment.Move, w / 2, 0)) .add(new go.PathSegment(go.PathSegment.Line, w / 2, h))); }); go.Shape.defineFigureGenerator("XLine", (shape, w, h) => { // predefined in 2.0 return new go.Geometry() .add(new go.PathFigure(0, h, false) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Move, 0, 0)) .add(new go.PathSegment(go.PathSegment.Line, w, h))); }); // OPTIONAL figures, not predefined in the v2.0 library: go.Shape.defineFigureGenerator("AsteriskLine", (shape, w, h) => { var offset = .2 / Math.SQRT2; return new go.Geometry() .add(new go.PathFigure(offset * w, (1 - offset) * h, false) .add(new go.PathSegment(go.PathSegment.Line, (1 - offset) * w, offset * h)) .add(new go.PathSegment(go.PathSegment.Move, offset * w, offset * h)) .add(new go.PathSegment(go.PathSegment.Line, (1 - offset) * w, (1 - offset) * h)) .add(new go.PathSegment(go.PathSegment.Move, 0, h / 2)) .add(new go.PathSegment(go.PathSegment.Line, w, h / 2)) .add(new go.PathSegment(go.PathSegment.Move, w / 2, 0)) .add(new go.PathSegment(go.PathSegment.Line, w / 2, h))); }); go.Shape.defineFigureGenerator("CircleLine", (shape, w, h) => { var rad = w / 2; var geo = new go.Geometry() .add(new go.PathFigure(w, w / 2, false) // clockwise .add(new go.PathSegment(go.PathSegment.Arc, 0, 360, rad, rad, rad, rad).close())); geo.spot1 = GeneratorEllipseSpot1; geo.spot2 = GeneratorEllipseSpot2; geo.defaultStretch = go.GraphObject.Uniform; return geo; }); go.Shape.defineFigureGenerator("Line1", (shape, w, h) => { var geo = new go.Geometry(go.Geometry.Line); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; return geo; }); go.Shape.defineFigureGenerator("Line2", (shape, w, h) => { var geo = new go.Geometry(go.Geometry.Line); geo.startX = w; geo.startY = 0; geo.endX = 0; geo.endY = h; return geo; }); go.Shape.defineFigureGenerator("Curve1", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(0, 0, false) .add(new go.PathSegment(go.PathSegment.Bezier, w, h, KAPPA * w, 0, w, (1 - KAPPA) * h))); }); go.Shape.defineFigureGenerator("Curve2", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(0, 0, false) .add(new go.PathSegment(go.PathSegment.Bezier, w, h, 0, KAPPA * h, (1 - KAPPA) * w, h))); }); go.Shape.defineFigureGenerator("Curve3", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(w, 0, false) .add(new go.PathSegment(go.PathSegment.Bezier, 0, h, w, KAPPA * h, KAPPA * w, h))); }); go.Shape.defineFigureGenerator("Curve4", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(w, 0, false) .add(new go.PathSegment(go.PathSegment.Bezier, 0, h, (1 - KAPPA) * w, 0, 0, (1 - KAPPA) * h))); }); go.Shape.defineFigureGenerator("TriangleDownLeft", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(0, 0, true) .add(new go.PathSegment(go.PathSegment.Line, w, h)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())) .setSpots(0, 0.5, 0.5, 1); }); go.Shape.defineFigureGenerator("TriangleDownRight", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(w, 0, true) .add(new go.PathSegment(go.PathSegment.Line, w, h)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())) .setSpots(0.5, 0.5, 1, 1); }); go.Shape.defineFigureGenerator("TriangleUpLeft", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(0, 0, true) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())) .setSpots(0, 0, 0.5, 0.5); }); go.Shape.defineFigureGenerator("TriangleUpRight", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(0, 0, true) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Line, w, h).close())) .setSpots(0.5, 0, 1, 0.5); }); go.Shape.defineFigureGenerator("RightTriangle", "TriangleDownLeft"); FigureParameter.prototype.setFigureParameter("Parallelogram1", 0, new FigureParameter("Indent", 10, -Infinity, Infinity)); go.Shape.defineFigureGenerator("Parallelogram1", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; // Topleft corner's x distance from leftmost point if (isNaN(param1)) param1 = 10; // default value else if (param1 < -w) param1 = -w; else if (param1 > w) param1 = w; var indent = Math.abs(param1); if (param1 === 0) { var geo = new go.Geometry(go.Geometry.Rectangle); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; return geo; } else { var geo = new go.Geometry(); if (param1 > 0) { geo.add(new go.PathFigure(indent, 0) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Line, w - indent, h)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())); } else { // param1 < 0 geo.add(new go.PathFigure(0, 0) .add(new go.PathSegment(go.PathSegment.Line, w - indent, 0)) .add(new go.PathSegment(go.PathSegment.Line, w, h)) .add(new go.PathSegment(go.PathSegment.Line, indent, h).close())); } if (indent < w / 2) { geo.setSpots(indent / w, 0, (w - indent) / w, 1); } return geo; } }); FigureParameter.prototype.setFigureParameter("Parallelogram2", 0, new FigureParameter("IndentFraction", 0.2, -0.999, 0.999)); go.Shape.defineFigureGenerator("Parallelogram2", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; // Topleft corner's x distance from leftmost point if (isNaN(param1)) param1 = 0.1; // default value else if (param1 < -1) param1 = -1; else if (param1 > 1) param1 = 1; var indent = Math.abs(param1) * w; if (param1 === 0) { var geo = new go.Geometry(go.Geometry.Rectangle); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; return geo; } else { var geo = new go.Geometry(); if (param1 > 0) { geo.add(new go.PathFigure(indent, 0) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Line, w - indent, h)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())); } else { // param1 < 0 geo.add(new go.PathFigure(0, 0) .add(new go.PathSegment(go.PathSegment.Line, w - indent, 0)) .add(new go.PathSegment(go.PathSegment.Line, w, h)) .add(new go.PathSegment(go.PathSegment.Line, indent, h).close())); } if (indent < w / 2) { geo.setSpots(indent / w, 0, (w - indent) / w, 1); } return geo; } }); go.Shape.defineFigureGenerator("Parallelogram", "Parallelogram1"); FigureParameter.prototype.setFigureParameter("Trapezoid1", 0, new FigureParameter("Indent", 10, -Infinity, Infinity)); go.Shape.defineFigureGenerator("Trapezoid1", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; // Distance from topleft of bounding rectangle, // in % of the total width, of the topleft corner if (isNaN(param1)) param1 = 10; // default value else if (param1 < -w) param1 = -w / 2; else if (param1 > w) param1 = w / 2; var indent = Math.abs(param1); if (param1 === 0) { var geo = new go.Geometry(go.Geometry.Rectangle); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; return geo; } else { var geo = new go.Geometry(); if (param1 > 0) { geo.add(new go.PathFigure(indent, 0) .add(new go.PathSegment(go.PathSegment.Line, w - indent, 0)) .add(new go.PathSegment(go.PathSegment.Line, w, h)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())); } else { // param1 < 0 geo.add(new go.PathFigure(0, 0) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Line, w - indent, h)) .add(new go.PathSegment(go.PathSegment.Line, indent, h).close())); } if (indent < w / 2) { geo.setSpots(indent / w, 0, (w - indent) / w, 1); } return geo; } }); FigureParameter.prototype.setFigureParameter("Trapezoid2", 0, new FigureParameter("IndentFraction", 0.2, -0.999, 0.999)); go.Shape.defineFigureGenerator("Trapezoid2", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; // Distance from topleft of bounding rectangle, // in % of the total width, of the topleft corner if (isNaN(param1)) param1 = 0.2; // default value else if (param1 < 0.5) param1 = -0.5; else if (param1 > 0.5) param1 = 0.5; var indent = Math.abs(param1) * w; if (param1 === 0) { var geo = new go.Geometry(go.Geometry.Rectangle); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; return geo; } else { var geo = new go.Geometry(); if (param1 > 0) { geo.add(new go.PathFigure(indent, 0) .add(new go.PathSegment(go.PathSegment.Line, w - indent, 0)) .add(new go.PathSegment(go.PathSegment.Line, w, h)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())); } else { // param1 < 0 geo.add(new go.PathFigure(0, 0) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Line, w - indent, h)) .add(new go.PathSegment(go.PathSegment.Line, indent, h).close())); } if (indent < w / 2) { geo.setSpots(indent / w, 0, (w - indent) / w, 1); } return geo; } }); FigureParameter.prototype.setFigureParameter("ManualOperation", 0, new FigureParameter("Indent", 10, -Infinity, Infinity)); go.Shape.defineFigureGenerator("ManualOperation", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; // Distance from topleft of bounding rectangle, // in % of the total width, of the topleft corner if (isNaN(param1)) param1 = 10; // default value else if (param1 < -w) param1 = -w / 2; else if (param1 > w) param1 = w / 2; var indent = Math.abs(param1); if (param1 === 0) { var geo = new go.Geometry(go.Geometry.Rectangle); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; return geo; } else { var geo = new go.Geometry(); if (param1 > 0) { geo.add(new go.PathFigure(0, 0) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Line, w - indent, h)) .add(new go.PathSegment(go.PathSegment.Line, indent, h).close())); } else { // param1 < 0 geo.add(new go.PathFigure(indent, 0) .add(new go.PathSegment(go.PathSegment.Line, w - indent, 0)) .add(new go.PathSegment(go.PathSegment.Line, w, h)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())); } if (indent < w / 2) { geo.setSpots(indent / w, 0, (w - indent) / w, 1); } return geo; } }); go.Shape.defineFigureGenerator("Trapezoid", "Trapezoid1"); // The following functions are used by a group of regular figures that are defined below: /** @ignore */ var _CachedArrays: Array<any> = []; /** * @ignore * @return {Array} */ function tempArray(): Array<any> { var temp = _CachedArrays.pop(); if (temp === undefined) return []; return temp; }; /** * @ignore * @param {Array} a */ function freeArray(a: Array<any>) { a.length = 0; // clear any references to objects _CachedArrays.push(a); }; /** * @ignore * This allocates a temporary Array that should be freeArray()'ed by the caller. * @param {number} sides * @return {Array} */ function createPolygon(sides: number): Array<any> { // Point[] points = new Point[sides + 1]; var points = tempArray(); var radius = .5; var center = .5; var offsetAngle = Math.PI * 1.5; var angle = 0; // Loop through each side of the polygon for (var i = 0; i < sides; i++) { angle = 2 * Math.PI / sides * i + offsetAngle; points[i] = new go.Point((center + radius * Math.cos(angle)), (center + radius * Math.sin(angle))); } // Add the last line // points[points.length - 1] = points[0]; points.push(points[0]); return points; }; /** * @ignore * This allocates a temporary Array that should be freeArray()'ed by the caller. * @param {number} points * @return {Array} */ function createBurst(points: number): Array<any> { var star = createStar(points); var pts = tempArray(); // new Point[points * 3 + 1]; pts[0] = star[0]; for (var i = 1, count = 1; i < star.length; i += 2, count += 3) { pts[count] = star[i]; pts[count + 1] = star[i]; pts[count + 2] = star[i + 1]; } freeArray(star); return pts; }; /** * @ignore * This allocates a temporary Array that should be freeArray()'ed by the caller. * @param {number} points * @return {Array} */ function createStar(points: number): Array<any> { // First, create a regular polygon var polygon = createPolygon(points); // Calculate the points inbetween var pts = tempArray(); // new Point[points * 2 + 1]; var half = Math.floor(polygon.length / 2); var count = polygon.length - 1; var offset = (points % 2 === 0) ? 2 : 1; for (var i = 0; i < count; i++) { // Get the intersection of two lines var p0 = polygon[i]; var p1 = polygon[i + 1]; var q21 = polygon[(half + i - 1) % count]; var q2off = polygon[(half + i + offset) % count]; pts[i * 2] = p0; pts[i * 2 + 1] = getIntersection(p0.x, p0.y, q21.x, q21.y, p1.x, p1.y, q2off.x, q2off.y, new go.Point()); // ?? not currently managed } pts[pts.length] = pts[0]; freeArray(polygon); return pts; }; go.Shape.defineFigureGenerator("Pentagon", (shape, w, h) => { var points = createPolygon(5); var geo = new go.Geometry(); var fig = new go.PathFigure(points[0].x * w, points[0].y * h, true); geo.add(fig); for (var i = 1; i < 5; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, points[i].x * w, points[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, points[0].x * w, points[0].y * h).close()); freeArray(points); geo.spot1 = new go.Spot(.2, .22); geo.spot2 = new go.Spot(.8, .9); return geo; }); go.Shape.defineFigureGenerator("Hexagon", (shape, w, h) => { var points = createPolygon(6); var geo = new go.Geometry(); var fig = new go.PathFigure(points[0].x * w, points[0].y * h, true); geo.add(fig); for (var i = 1; i < 6; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, points[i].x * w, points[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, points[0].x * w, points[0].y * h).close()); freeArray(points); geo.spot1 = new go.Spot(.07, .25); geo.spot2 = new go.Spot(.93, .75); return geo; }); go.Shape.defineFigureGenerator("Heptagon", (shape, w, h) => { var points = createPolygon(7); var geo = new go.Geometry(); var fig = new go.PathFigure(points[0].x * w, points[0].y * h, true); geo.add(fig); for (var i = 1; i < 7; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, points[i].x * w, points[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, points[0].x * w, points[0].y * h).close()); freeArray(points); geo.spot1 = new go.Spot(.2, .15); geo.spot2 = new go.Spot(.8, .85); return geo; }); go.Shape.defineFigureGenerator("Octagon", (shape, w, h) => { var points = createPolygon(8); var geo = new go.Geometry(); var fig = new go.PathFigure(points[0].x * w, points[0].y * h, true); geo.add(fig); for (var i = 1; i < 8; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, points[i].x * w, points[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, points[0].x * w, points[0].y * h).close()); freeArray(points); geo.spot1 = new go.Spot(.15, .15); geo.spot2 = new go.Spot(.85, .85); return geo; }); go.Shape.defineFigureGenerator("Nonagon", (shape, w, h) => { var points = createPolygon(9); var geo = new go.Geometry(); var fig = new go.PathFigure(points[0].x * w, points[0].y * h, true); geo.add(fig); for (var i = 1; i < 9; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, points[i].x * w, points[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, points[0].x * w, points[0].y * h).close()); freeArray(points); geo.spot1 = new go.Spot(.17, .13); geo.spot2 = new go.Spot(.82, .82); return geo; }); go.Shape.defineFigureGenerator("Decagon", (shape, w, h) => { var points = createPolygon(10); var geo = new go.Geometry(); var fig = new go.PathFigure(points[0].x * w, points[0].y * h, true); geo.add(fig); for (var i = 1; i < 10; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, points[i].x * w, points[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, points[0].x * w, points[0].y * h).close()); freeArray(points); geo.spot1 = new go.Spot(.16, .16); geo.spot2 = new go.Spot(.84, .84); return geo; }); go.Shape.defineFigureGenerator("Dodecagon", (shape, w, h) => { var points = createPolygon(12); var geo = new go.Geometry(); var fig = new go.PathFigure(points[0].x * w, points[0].y * h, true); geo.add(fig); for (var i = 1; i < 12; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, points[i].x * w, points[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, points[0].x * w, points[0].y * h).close()); freeArray(points); geo.spot1 = new go.Spot(.16, .16); geo.spot2 = new go.Spot(.84, .84); return geo; }); go.Shape.defineFigureGenerator("FivePointedStar", (shape, w, h) => { var starPoints = createStar(5); var geo = new go.Geometry(); var fig = new go.PathFigure(starPoints[0].x * w, starPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < 10; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[i].x * w, starPoints[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[0].x * w, starPoints[0].y * h).close()); freeArray(starPoints); geo.spot1 = new go.Spot(.266, .333); geo.spot2 = new go.Spot(.733, .733); return geo; }); go.Shape.defineFigureGenerator("SixPointedStar", (shape, w, h) => { var starPoints = createStar(6); var geo = new go.Geometry(); var fig = new go.PathFigure(starPoints[0].x * w, starPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < 12; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[i].x * w, starPoints[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[0].x * w, starPoints[0].y * h).close()); freeArray(starPoints); geo.spot1 = new go.Spot(.17, .25); geo.spot2 = new go.Spot(.83, .75); return geo; }); go.Shape.defineFigureGenerator("SevenPointedStar", (shape, w, h) => { var starPoints = createStar(7); var geo = new go.Geometry(); var fig = new go.PathFigure(starPoints[0].x * w, starPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < 14; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[i].x * w, starPoints[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[0].x * w, starPoints[0].y * h).close()); freeArray(starPoints); geo.spot1 = new go.Spot(.222, .277); geo.spot2 = new go.Spot(.777, .666); return geo; }); go.Shape.defineFigureGenerator("EightPointedStar", (shape, w, h) => { var starPoints = createStar(8); var geo = new go.Geometry(); var fig = new go.PathFigure(starPoints[0].x * w, starPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < 16; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[i].x * w, starPoints[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[0].x * w, starPoints[0].y * h).close()); freeArray(starPoints); geo.spot1 = new go.Spot(.25, .25); geo.spot2 = new go.Spot(.75, .75); return geo; }); go.Shape.defineFigureGenerator("NinePointedStar", (shape, w, h) => { var starPoints = createStar(9); var geo = new go.Geometry(); var fig = new go.PathFigure(starPoints[0].x * w, starPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < 18; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[i].x * w, starPoints[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[0].x * w, starPoints[0].y * h).close()); freeArray(starPoints); geo.spot1 = new go.Spot(.222, .277); geo.spot2 = new go.Spot(.777, .666); return geo; }); go.Shape.defineFigureGenerator("TenPointedStar", (shape, w, h) => { var starPoints = createStar(10); var geo = new go.Geometry(); var fig = new go.PathFigure(starPoints[0].x * w, starPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < 20; i++) { fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[i].x * w, starPoints[i].y * h)); } fig.add(new go.PathSegment(go.PathSegment.Line, starPoints[0].x * w, starPoints[0].y * h).close()); freeArray(starPoints); geo.spot1 = new go.Spot(.281, .261); geo.spot2 = new go.Spot(.723, .748); return geo; }); go.Shape.defineFigureGenerator("FivePointedBurst", (shape, w, h) => { var burstPoints = createBurst(5); var geo = new go.Geometry(); var fig = new go.PathFigure(burstPoints[0].x * w, burstPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < burstPoints.length; i += 3) { fig.add(new go.PathSegment(go.PathSegment.Bezier, burstPoints[i + 2].x * w, burstPoints[i + 2].y * h, burstPoints[i].x * w, burstPoints[i].y * h, burstPoints[i + 1].x * w, burstPoints[i + 1].y * h)); } fig.segments.last().close(); freeArray(burstPoints); geo.spot1 = new go.Spot(.222, .277); geo.spot2 = new go.Spot(.777, .777); return geo; }); go.Shape.defineFigureGenerator("SixPointedBurst", (shape, w, h) => { var burstPoints = createBurst(6); var geo = new go.Geometry(); var fig = new go.PathFigure(burstPoints[0].x * w, burstPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < burstPoints.length; i += 3) { fig.add(new go.PathSegment(go.PathSegment.Bezier, burstPoints[i + 2].x * w, burstPoints[i + 2].y * h, burstPoints[i].x * w, burstPoints[i].y * h, burstPoints[i + 1].x * w, burstPoints[i + 1].y * h)); } fig.segments.last().close(); freeArray(burstPoints); geo.spot1 = new go.Spot(.170, .222); geo.spot2 = new go.Spot(.833, .777); return geo; }); go.Shape.defineFigureGenerator("SevenPointedBurst", (shape, w, h) => { var burstPoints = createBurst(7); var geo = new go.Geometry(); var fig = new go.PathFigure(burstPoints[0].x * w, burstPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < burstPoints.length; i += 3) { fig.add(new go.PathSegment(go.PathSegment.Bezier, burstPoints[i + 2].x * w, burstPoints[i + 2].y * h, burstPoints[i].x * w, burstPoints[i].y * h, burstPoints[i + 1].x * w, burstPoints[i + 1].y * h)); } fig.segments.last().close(); freeArray(burstPoints); geo.spot1 = new go.Spot(.222, .222); geo.spot2 = new go.Spot(.777, .777); return geo; }); go.Shape.defineFigureGenerator("EightPointedBurst", (shape, w, h) => { var burstPoints = createBurst(8); var geo = new go.Geometry(); var fig = new go.PathFigure(burstPoints[0].x * w, burstPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < burstPoints.length; i += 3) { fig.add(new go.PathSegment(go.PathSegment.Bezier, burstPoints[i + 2].x * w, burstPoints[i + 2].y * h, burstPoints[i].x * w, burstPoints[i].y * h, burstPoints[i + 1].x * w, burstPoints[i + 1].y * h)); } fig.segments.last().close(); freeArray(burstPoints); geo.spot1 = new go.Spot(.222, .222); geo.spot2 = new go.Spot(.777, .777); return geo; }); go.Shape.defineFigureGenerator("NinePointedBurst", (shape, w, h) => { var burstPoints = createBurst(9); var geo = new go.Geometry(); var fig = new go.PathFigure(burstPoints[0].x * w, burstPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < burstPoints.length; i += 3) { fig.add(new go.PathSegment(go.PathSegment.Bezier, burstPoints[i + 2].x * w, burstPoints[i + 2].y * h, burstPoints[i].x * w, burstPoints[i].y * h, burstPoints[i + 1].x * w, burstPoints[i + 1].y * h)); } fig.segments.last().close(); freeArray(burstPoints); geo.spot1 = new go.Spot(.222, .222); geo.spot2 = new go.Spot(.777, .777); return geo; }); go.Shape.defineFigureGenerator("TenPointedBurst", (shape, w, h) => { var burstPoints = createBurst(10); var geo = new go.Geometry(); var fig = new go.PathFigure(burstPoints[0].x * w, burstPoints[0].y * h, true); geo.add(fig); for (var i = 1; i < burstPoints.length; i += 3) { fig.add(new go.PathSegment(go.PathSegment.Bezier, burstPoints[i + 2].x * w, burstPoints[i + 2].y * h, burstPoints[i].x * w, burstPoints[i].y * h, burstPoints[i + 1].x * w, burstPoints[i + 1].y * h)); } fig.segments.last().close(); freeArray(burstPoints); geo.spot1 = new go.Spot(.222, .222); geo.spot2 = new go.Spot(.777, .777); return geo; }); FigureParameter.prototype.setFigureParameter("FramedRectangle", 0, new FigureParameter("ThicknessX", 8)); FigureParameter.prototype.setFigureParameter("FramedRectangle", 1, new FigureParameter("ThicknessY", 8)); go.Shape.defineFigureGenerator("FramedRectangle", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; var 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 var geo = new go.Geometry(); var fig = new go.PathFigure(0, 0, true); geo.add(fig); // outer rectangle, clockwise fig.add(new go.PathSegment(go.PathSegment.Line, w, 0)); fig.add(new go.PathSegment(go.PathSegment.Line, w, h)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, h).close()); if (param1 < w / 2 && param2 < h / 2) { // inner rectangle, counter-clockwise fig.add(new go.PathSegment(go.PathSegment.Move, param1, param2)); // subpath fig.add(new go.PathSegment(go.PathSegment.Line, param1, h - param2)); fig.add(new go.PathSegment(go.PathSegment.Line, w - param1, h - param2)); fig.add(new go.PathSegment(go.PathSegment.Line, w - param1, param2).close()); } geo.setSpots(0, 0, 1, 1, param1, param2, -param1, -param2); return geo; }); FigureParameter.prototype.setFigureParameter("Ring", 0, new FigureParameter("Thickness", 8)); go.Shape.defineFigureGenerator("Ring", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; if (isNaN(param1) || param1 < 0) param1 = 8; var rad = w / 2; var geo = new go.Geometry(); var fig = new go.PathFigure(w, w / 2, true); // clockwise geo.add(fig); fig.add(new go.PathSegment(go.PathSegment.Arc, 0, 360, rad, rad, rad, rad).close()); var rad2 = Math.max(rad - param1, 0); if (rad2 > 0) { // counter-clockwise fig.add(new go.PathSegment(go.PathSegment.Move, w / 2 + rad2, w / 2)) fig.add(new go.PathSegment(go.PathSegment.Arc, 0, -360, rad, rad, rad2, rad2).close()); } geo.spot1 = GeneratorEllipseSpot1; geo.spot2 = GeneratorEllipseSpot2; geo.defaultStretch = go.GraphObject.Uniform; return geo; }); go.Shape.defineFigureGenerator("Cloud", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(.08034461 * w, .1944299 * h, true) .add(new go.PathSegment(go.PathSegment.Bezier, .2008615 * w, .05349299 * h, -.09239631 * w, .07836421 * h, .1406031 * w, -.0542823 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .4338609 * w, .074219 * h, .2450511 * w, -.00697547 * h, .3776197 * w, -.01112067 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .6558228 * w, .07004196 * h, .4539471 * w, 0, .6066018 * w, -.02526587 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .8921095 * w, .08370865 * h, .6914277 * w, -.01904177 * h, .8921095 * w, -.01220843 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .9147671 * w, .3194596 * h, 1.036446 * w, .04105738 * h, 1.020377 * w, .3022052 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .9082935 * w, .562044 * h, 1.04448 * w, .360238 * h, .992256 * w, .5219009 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .9212406 * w, .8217117 * h, 1.032337 * w, .5771781 * h, 1.018411 * w, .8120651 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .7592566 * w, .9156953 * h, 1.028411 * w, .9571472 * h, .8556702 * w, 1.052487 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .5101666 * w, .9310455 * h, .7431877 * w, 1.009325 * h, .5624123 * w, 1.021761 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .2609328 * w, .9344623 * h, .4820677 * w, 1.031761 * h, .3030112 * w, 1.002796 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .08034461 * w, .870098 * h, .2329994 * w, 1.01518 * h, .03213784 * w, 1.01518 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .06829292 * w, .6545475 * h, -.02812061 * w, .9032597 * h, -.01205169 * w, .6835638 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .06427569 * w, .4265613 * h, -.01812061 * w, .6089503 * h, -.00606892 * w, .4555777 * h)) .add(new go.PathSegment(go.PathSegment.Bezier, .08034461 * w, .1944299 * h, -.01606892 * w, .3892545 * h, -.01205169 * w, .1944299 * h))) .setSpots(.1, .1, .9, .9); }); go.Shape.defineFigureGenerator("StopSign", (shape, w, h) => { var part = 1 / (Math.SQRT2 + 2); return new go.Geometry() .add(new go.PathFigure(part * w, 0, true) .add(new go.PathSegment(go.PathSegment.Line, (1 - part) * w, 0)) .add(new go.PathSegment(go.PathSegment.Line, w, part * h)) .add(new go.PathSegment(go.PathSegment.Line, w, (1 - part) * h)) .add(new go.PathSegment(go.PathSegment.Line, (1 - part) * w, h)) .add(new go.PathSegment(go.PathSegment.Line, part * w, h)) .add(new go.PathSegment(go.PathSegment.Line, 0, (1 - part) * h)) .add(new go.PathSegment(go.PathSegment.Line, 0, part * h).close())) .setSpots(part / 2, part / 2, 1 - part / 2, 1 - part / 2); }); FigureParameter.prototype.setFigureParameter("Pie", 0, new FigureParameter("Start", 0, -360, 360)); FigureParameter.prototype.setFigureParameter("Pie", 1, new FigureParameter("Sweep", 315, -360, 360)); go.Shape.defineFigureGenerator("Pie", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; var param2 = shape ? shape.parameter2 : NaN; if (isNaN(param1)) param1 = 0; // default values PARAMETER 1 is for Start Angle if (isNaN(param2)) param2 = 315; // default values PARAMETER 2 is for Sweep Angle var start = param1 % 360; if (start < 0) start += 360; var sweep = param2 % 360; var rad = Math.min(w, h) / 2; return new go.Geometry() .add(new go.PathFigure(rad, rad) // start point .add(new go.PathSegment(go.PathSegment.Arc, start, sweep, // angles rad, rad, // center rad, rad) // radius .close())); }); go.Shape.defineFigureGenerator("PiePiece", (shape, w, h) => { var factor = KAPPA / Math.SQRT2 * .5; var x1 = Math.SQRT2 / 2; var y1 = 1 - Math.SQRT2 / 2; return new go.Geometry() .add(new go.PathFigure(w, h, true) .add(new go.PathSegment(go.PathSegment.Bezier, x1 * w, y1 * h, w, (1 - factor) * h, (x1 + factor) * w, (y1 + factor) * h)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())); }); FigureParameter.prototype.setFigureParameter("ThickCross", 0, new FigureParameter("Thickness", 30)); go.Shape.defineFigureGenerator("ThickCross", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; if (isNaN(param1) || param1 < 0) param1 = 30; var t = Math.min(param1, w) / 2; var mx = w / 2; var my = h / 2; return new go.Geometry() .add(new go.PathFigure(mx - t, 0, true) .add(new go.PathSegment(go.PathSegment.Line, mx + t, 0)) .add(new go.PathSegment(go.PathSegment.Line, mx + t, my - t)) .add(new go.PathSegment(go.PathSegment.Line, w, my - t)) .add(new go.PathSegment(go.PathSegment.Line, w, my + t)) .add(new go.PathSegment(go.PathSegment.Line, mx + t, my + t)) .add(new go.PathSegment(go.PathSegment.Line, mx + t, h)) .add(new go.PathSegment(go.PathSegment.Line, mx - t, h)) .add(new go.PathSegment(go.PathSegment.Line, mx - t, my + t)) .add(new go.PathSegment(go.PathSegment.Line, 0, my + t)) .add(new go.PathSegment(go.PathSegment.Line, 0, my - t)) .add(new go.PathSegment(go.PathSegment.Line, mx - t, my - t).close())); }); FigureParameter.prototype.setFigureParameter("ThinCross", 0, new FigureParameter("Thickness", 10)); go.Shape.defineFigureGenerator("ThinCross", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; if (isNaN(param1) || param1 < 0) param1 = 10; var t = Math.min(param1, w) / 2; var mx = w / 2; var my = h / 2; return new go.Geometry() .add(new go.PathFigure(mx - t, 0, true) .add(new go.PathSegment(go.PathSegment.Line, mx + t, 0)) .add(new go.PathSegment(go.PathSegment.Line, mx + t, my - t)) .add(new go.PathSegment(go.PathSegment.Line, w, my - t)) .add(new go.PathSegment(go.PathSegment.Line, w, my + t)) .add(new go.PathSegment(go.PathSegment.Line, mx + t, my + t)) .add(new go.PathSegment(go.PathSegment.Line, mx + t, h)) .add(new go.PathSegment(go.PathSegment.Line, mx - t, h)) .add(new go.PathSegment(go.PathSegment.Line, mx - t, my + t)) .add(new go.PathSegment(go.PathSegment.Line, 0, my + t)) .add(new go.PathSegment(go.PathSegment.Line, 0, my - t)) .add(new go.PathSegment(go.PathSegment.Line, mx - t, my - t).close())); }); FigureParameter.prototype.setFigureParameter("ThickX", 0, new FigureParameter("Thickness", 30)); go.Shape.defineFigureGenerator("ThickX", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; if (isNaN(param1) || param1 < 0) param1 = 30; if (w === 0 || h === 0) { var geo = new go.Geometry(go.Geometry.Rectangle); geo.startX = 0; geo.startY = 0; geo.endX = w; geo.endY = h; return geo; } else { var w2 = w / 2; var h2 = h / 2; var a2 = Math.atan2(h, w); var dx = param1 - Math.min(Math.cos(a2) * param1 / 2, w2); var dy = param1 - Math.min(Math.sin(a2) * param1 / 2, h2); var geo = new go.Geometry(); var fig = new go.PathFigure(dx, 0, true); geo.add(fig); fig.add(new go.PathSegment(go.PathSegment.Line, w2, .2 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, w - dx, 0)); fig.add(new go.PathSegment(go.PathSegment.Line, w, dy)); fig.add(new go.PathSegment(go.PathSegment.Line, .8 * w, h2)); fig.add(new go.PathSegment(go.PathSegment.Line, w, h - dy)); fig.add(new go.PathSegment(go.PathSegment.Line, w - dx, h)); fig.add(new go.PathSegment(go.PathSegment.Line, w2, .8 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, dx, h)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, h - dy)); fig.add(new go.PathSegment(go.PathSegment.Line, .2 * w, h2)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, dy).close()); return geo; } }); FigureParameter.prototype.setFigureParameter("ThinX", 0, new FigureParameter("Thickness", 10)); go.Shape.defineFigureGenerator("ThinX", (shape, w, h) => { var param1 = shape ? shape.parameter1 : NaN; if (isNaN(param1) || param1 < 0) param1 = 10; var geo = new go.Geometry(); var fig = new go.PathFigure(.1 * w, 0, true); geo.add(fig); fig.add(new go.PathSegment(go.PathSegment.Line, .5 * w, .4 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, .9 * w, 0)); fig.add(new go.PathSegment(go.PathSegment.Line, w, .1 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, .6 * w, .5 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, w, .9 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, .9 * w, h)); fig.add(new go.PathSegment(go.PathSegment.Line, .5 * w, .6 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, .1 * w, h)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, .9 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, .4 * w, .5 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, .1 * h).close()); return geo; }); // adjust the width of the vertical beam FigureParameter.prototype.setFigureParameter("SquareIBeam", 0, new FigureParameter("BeamWidth", 0.2, 0.1, 0.9)); go.Shape.defineFigureGenerator("SquareIBeam", (shape, w, h) => { var geo = new go.Geometry(); var param1 = shape ? shape.parameter1 : NaN; // Width of the ibeam in % of the total width if (isNaN(param1)) param1 = .2; var fig = new go.PathFigure(0, 0, true); geo.add(fig); var fig = new go.PathFigure(0, 0, true); fig.add(new go.PathSegment(go.PathSegment.Line, w, 0)); fig.add(new go.PathSegment(go.PathSegment.Line, w, param1 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, (.5 + param1 / 2) * w, param1 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, (.5 + param1 / 2) * w, (1 - param1) * h)); fig.add(new go.PathSegment(go.PathSegment.Line, w, (1 - param1) * h)); fig.add(new go.PathSegment(go.PathSegment.Line, w, h)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, h)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, (1 - param1) * h)); fig.add(new go.PathSegment(go.PathSegment.Line, (.5 - param1 / 2) * w, (1 - param1) * h)); fig.add(new go.PathSegment(go.PathSegment.Line, (.5 - param1 / 2) * w, param1 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, param1 * h).close()); return geo; }); // parameter allows it easy to adjust the roundness of the curves that cut inward FigureParameter.prototype.setFigureParameter("RoundedIBeam", 0, new FigureParameter("SideCurved", .5, .05, .65)); go.Shape.defineFigureGenerator("RoundedIBeam", (shape, w, h) => { var geo = new go.Geometry(); var fig = new go.PathFigure(0, 0, true); geo.add(fig); var param1 = shape ? shape.parameter1 : NaN; if (isNaN(param1)) param1 = .5; // default value of Parameter1 // Parameter 1 is based off of the width // I guess I will call it "curved" // param=.5 = 50% curved // .65 has to be the max // .05 has to be min, starts to loose roundesss after that fig.add(new go.PathSegment(go.PathSegment.Line, w, 0)); // top bar fig.add(new go.PathSegment(go.PathSegment.Bezier, w, h, Math.abs((1 - param1)) * w, .25 * h, Math.abs((1 - param1)) * w, .75 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, h)); fig.add(new go.PathSegment(go.PathSegment.Bezier, 0, 0, param1 * w, .75 * h, param1 * w, .25 * h).close()); return geo; }); go.Shape.defineFigureGenerator("HalfEllipse", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(0, 0, true) .add(new go.PathSegment(go.PathSegment.Bezier, w, .5 * h, KAPPA * w, 0, w, (.5 - KAPPA / 2) * h)) .add(new go.PathSegment(go.PathSegment.Bezier, 0, h, w, (.5 + KAPPA / 2) * h, KAPPA * w, h).close())) .setSpots(0, 0.156, 0.844, 0.844); }); go.Shape.defineFigureGenerator("Crescent", (shape, w, h) => { return new go.Geometry() .add(new go.PathFigure(0, 0, true) .add(new go.PathSegment(go.PathSegment.Bezier, 0, h, w, 0, w,