UNPKG

gojs

Version:

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

746 lines (743 loc) 31.7 kB
<html> <head> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-1506307-6"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-1506307-6'); </script> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Electric Circuit</title> <meta name="description" content="" /> <meta charset="UTF-8"> <script src="./go.js"></script> <script src="./goeditor-data-interaction.js"></script> <script src="./goeditor-setup.js"></script> <script src="./storage/gcs.js"></script> <script src="https://apis.google.com/js/api.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/dropbox.js/2.5.7/Dropbox-sdk.min.js"></script> <script src="https://js.live.net/v7.2/OneDrive.js"></script> <script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="3sm2ko6q7u1gbix"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script> <script src="./DataInspector.js"></script> <script src="../../extensions/figures.js"></script> <script src="./WireDragTool.js"></script> <link rel="stylesheet" type="text/css" href="./DataInspector.css" /> <link rel="stylesheet" type="text/css" href="./storage/GoCloudStorageUI.css" /> <link rel="stylesheet" type="text/css" href="./goeditor.css" /> <script> function init() { setupEditorApplication(); nodeGenerationMap = new go.Map(); categories = [""]; // Circuit Figures // Figures for different shaped lines go.Shape.defineFigureGenerator("Off", function (shape, w, h) { // 1 Connector Switch Up, same as line2 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("On", function (shape, w, h) { // 1 Connector Switch Down var geo = new go.Geometry(go.Geometry.Line); geo.startX = w; geo.startY = h; geo.endX = 0; geo.endY = h; return geo; }); go.Shape.defineFigureGenerator("Up", function (shape, w, h) { // 2 Connector Switch Up var geo = new go.Geometry(go.Geometry.Line); geo.startX = 0; geo.startY = h / 2; geo.endX = w; geo.endY = 0; return geo; }); go.Shape.defineFigureGenerator("Down", function (shape, w, h) { // 2 Connector Switch Down var geo = new go.Geometry(go.Geometry.Line); geo.startX = 0; geo.startY = h / 2; geo.endX = w; geo.endY = h; return geo; }); go.Shape.defineFigureGenerator("Ground2", function (shape, w, h) { // Different ground figure than one predefined in figures.js var geo = new go.Geometry(); var fig = new go.PathFigure(0, 0, false); geo.add(fig); fig.add(new go.PathSegment(go.PathSegment.Line, w, 0)); fig.add(new go.PathSegment(go.PathSegment.Move, w / 8, h / 4)); fig.add(new go.PathSegment(go.PathSegment.Line, 7 * w / 8, h / 4)); fig.add(new go.PathSegment(go.PathSegment.Move, w / 4, h / 2)); fig.add(new go.PathSegment(go.PathSegment.Line, 3 * w / 4, h / 2)); return geo; }); go.Shape.defineFigureGenerator("Transistor", function (shape, w, h) { var geo = new go.Geometry(); var KAPPA = 4 * ((Math.sqrt(2) - 1) / 3); var cpOffset = KAPPA * .5; var radius = .5; var centerx = .5; var centery = .5; var fig = new go.PathFigure((centerx - radius) * w, centery * h, false); geo.add(fig); // circle fig.add(new go.PathSegment(go.PathSegment.Bezier, centerx * w, (centery - radius) * h, (centerx - radius) * w, (centery - cpOffset) * h, (centerx - cpOffset) * w, (centery - radius) * h)); fig.add(new go.PathSegment(go.PathSegment.Bezier, (centerx + radius) * w, centery * h, (centerx + cpOffset) * w, (centery - radius) * h, (centerx + radius) * w, (centery - cpOffset) * h)); fig.add(new go.PathSegment(go.PathSegment.Bezier, centerx * w, (centery + radius) * h, (centerx + radius) * w, (centery + cpOffset) * h, (centerx + cpOffset) * w, (centery + radius) * h)); fig.add(new go.PathSegment(go.PathSegment.Bezier, (centerx - radius) * w, centery * h, (centerx - cpOffset) * w, (centery + radius) * h, (centerx - radius) * w, (centery + cpOffset) * h)); // vertical middle-line fig.add(new go.PathSegment(go.PathSegment.Move, w / 4, h / 4)); fig.add(new go.PathSegment(go.PathSegment.Line, w / 4, 3 * h / 4)); // line middle to top-right fig.add(new go.PathSegment(go.PathSegment.Move, w / 4, 3 * h / 8)); fig.add(new go.PathSegment(go.PathSegment.Line, 7 * w / 8, h / 8)); // line middle to bottom-right fig.add(new go.PathSegment(go.PathSegment.Move, w / 4, 5 * h / 8)); fig.add(new go.PathSegment(go.PathSegment.Line, 7 * w / 8, 7 * h / 8)); // line middle to left fig.add(new go.PathSegment(go.PathSegment.Move, w / 4, h / 2)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, h / 2)); return geo; }); go.Shape.defineFigureGenerator("Fuse", function (shape, w, h) { // Fuse var geo = new go.Geometry(); var fig = new go.PathFigure(0, 0, false); geo.add(fig); // box fig.add(new go.PathSegment(go.PathSegment.Move, w / 8, h / 4)); fig.add(new go.PathSegment(go.PathSegment.Line, 7 * w / 8, h / 4)); fig.add(new go.PathSegment(go.PathSegment.Line, 7 * w / 8, 3 * h / 4)); fig.add(new go.PathSegment(go.PathSegment.Line, w / 8, 3 * h / 4)); fig.add(new go.PathSegment(go.PathSegment.Line, w / 8, h / 4)); // line across, may change to wave fig.add(new go.PathSegment(go.PathSegment.Move, 0, h / 2)); fig.add(new go.PathSegment(go.PathSegment.Line, w, h / 2)); return geo; }); // General Styling function nodeStyle() { return [new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding("isShadowed", "isSelected").ofObject(), new go.Binding("angle").makeTwoWay(), { selectionAdorned: false, shadowOffset: new go.Point(0, 0), shadowBlur: 15, shadowColor: "red", rotatable: true, toolTip: sharedToolTip }]; } function shapeStyle() { return { name: "NODESHAPE", desiredSize: new go.Size(40, 40), strokeWidth: 2, fill: "lightgray", stroke: "darkslategray" }; } function portStyle(input) { return { desiredSize: new go.Size(5, 5), fill: "black", fromSpot: go.Spot.Right, fromLinkable: !input, toSpot: go.Spot.Left, toLinkable: input, cursor: "pointer" }; } myDiagram.nodeTemplate = // Generic nodeTemplate to make junctions $(go.Node, "Auto", nodeStyle(), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding("segmentIndex").makeTwoWay(), new go.Binding("segmentFraction").makeTwoWay(), { name: "junction" }, $(go.Shape, "Rectangle", portStyle(true), { portId: "inout", toSpot: go.Spot.AllSides, fromSpot: go.Spot.AllSides, fromLinkable: true }) ); function initialProperties(e) { e.subject.each(function (node) { if (node.category === "dcvoltagesource" && node.data.Voltage === undefined) node.data.Voltage = 1; if (node.category === "resistor" && node.data.Resistance === undefined) node.data.Resistance = 1; if (node.category === "capacitor" && node.data.Capacitance === undefined) node.data.Capacitance = 1; if (node.category === "inductor" && node.data.Inductance === undefined) node.data.Inductance = 1; if (node.category === "acvoltagesource" && node.data.Amplitude === undefined) node.data.Amplitude = 1; node.data.Interval = 100; node.data.Count = 0; node.data.Color = 'black'; }); } myDiagram.addDiagramListener("ExternalObjectsDropped", function (e) { initialProperties(e); }); myDiagram.addDiagramListener("ClipboardPasted", function (e) { initialProperties(e); }); myDiagram.addDiagramListener("BackgroundDoubleClicked", function (e) { e.diagram.startTransaction("create junction"); var model = myDiagram.model; var pos = e.diagram.lastInput.documentPoint; var label = { category: "junction" }; // Create empty NodeData model.addNodeData(label); var node = e.diagram.findNodeForData(label); node.location = pos; e.diagram.commitTransaction("create junction"); }); // Shows tooltip when hover over node var sharedToolTip = $(go.Adornment, "Auto", $(go.Shape, "RoundedRectangle", { fill: "lightyellow" }), $(go.TextBlock, { margin: 2 }, new go.Binding("text", "", function (d) { return d.category; }))); // Node templates var dcVoltTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "DCvoltageSource", shapeStyle()), $(go.Shape, "Rectangle", shapeStyle(), { fill: "transparent", stroke: "transparent" }), // Creates invisible background box so easier to click on $(go.Shape, "Rectangle", portStyle(true), { portId: "in", alignment: new go.Spot(0.02, 0.5) }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out", alignment: new go.Spot(0.98, 0.5) }) ); var acVoltTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "ACvoltageSource", shapeStyle()), $(go.Shape, "Rectangle", shapeStyle(), { fill: "transparent", stroke: "transparent" }), $(go.Shape, "Rectangle", portStyle(true), { portId: "in", alignment: new go.Spot(0.5, 0.99), toSpot: go.Spot.Bottom }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out", alignment: new go.Spot(0.5, 0.01), fromSpot: go.Spot.Top }) ); var capacitorTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "Capacitor", shapeStyle()), $(go.Shape, "Rectangle", shapeStyle(), { fill: "transparent", stroke: "transparent" }), $(go.Shape, "Rectangle", portStyle(true), { portId: "in", alignment: new go.Spot(0.02, 0.5) }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out", alignment: new go.Spot(0.98, 0.5) }) ); var resistorTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "Resistor", shapeStyle(), { desiredSize: new go.Size(55, 35) }), $(go.Shape, "Rectangle", portStyle(true), { portId: "in", alignment: new go.Spot(0, 0.5) }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out", alignment: new go.Spot(.7, .5) }) ); var lightbulbTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "Circle", shapeStyle()), $(go.Shape, "Rectangle", portStyle(true), { portId: "in", alignment: go.Spot.Left }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out", alignment: go.Spot.Right }) ); var diodeTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "Diode", shapeStyle()), $(go.Shape, "Rectangle", shapeStyle(), { fill: "transparent", stroke: "transparent" }), $(go.Shape, "Rectangle", portStyle(true), { portId: "in", alignment: new go.Spot(0.02, 0.5) }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out", alignment: new go.Spot(0.98, 0.5) }) ); var inductorTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "Inductor", shapeStyle()), $(go.Shape, "Rectangle", portStyle(true), { portId: "in", alignment: new go.Spot(0.05, 1) }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out", alignment: new go.Spot(0.95, 1) }) ); var transistorTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "Transistor", shapeStyle()), $(go.Shape, "Rectangle", shapeStyle(), { fill: "transparent", stroke: "transparent" }), $(go.Shape, "Rectangle", portStyle(true), { portId: "collector", alignment: new go.Spot(0.02, 0.5), toSpot: go.Spot.Left }), $(go.Shape, "Rectangle", portStyle(true), { portId: "base", alignment: new go.Spot(0.86, 0.15), toSpot: go.Spot.TopRight }), $(go.Shape, "Rectangle", portStyle(false), { portId: "emitter", alignment: new go.Spot(0.86, 0.85), fromSpot: go.Spot.BottomRight }) ); var switchTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "Off", shapeStyle(), new go.Binding("figure", "state").makeTwoWay(), { desiredSize: new go.Size(50, 20) }), $(go.Shape, "Rectangle", shapeStyle(), { fill: "transparent", stroke: "transparent", desiredSize: new go.Size(50, 20) }), $(go.Shape, "Rectangle", portStyle(true), { portId: "in", alignment: new go.Spot(0, 0.95) }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out", alignment: new go.Spot(1, 0.95) }), { // If double clicked, it will swap the switch from on and off doubleClick: function (e, obj) { e.diagram.startTransaction("Toggle Switch"); var shp = obj.findObject("NODESHAPE"); if (shp.figure == "Off") // Off to on shp.figure = "On"; else // On to off shp.figure = "Off"; e.diagram.commitTransaction("Toggle Switch"); } } ); var switch2Temp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "Up", shapeStyle(), new go.Binding("figure", "state").makeTwoWay(), { desiredSize: new go.Size(50, 20) }), $(go.Shape, "Rectangle", shapeStyle(), { fill: "transparent", stroke: "transparent", desiredSize: new go.Size(50, 20) }), $(go.Shape, "Rectangle", portStyle(true), { portId: "in", alignment: new go.Spot(0, 0.5) }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out1", name: "out1", alignment: new go.Spot(1, 0.05) }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out2", name: "out2", alignment: new go.Spot(1, 0.95) }), { // If double clicked, it will swap the switch from top to bottom doubleClick: function (e, obj) { e.diagram.startTransaction("Toggle Switch"); var shp = obj.findObject("NODESHAPE"); if (shp.figure == "Up") // Up to down shp.figure = "Down"; else // Down to up shp.figure = "Up"; e.diagram.commitTransaction("Toggle Switch"); } } ); var groundTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "Ground", shapeStyle()), $(go.Shape, "Rectangle", shapeStyle(), { fill: "transparent", stroke: "transparent" }), $(go.Shape, "Rectangle", portStyle(true), { portId: "", alignment: go.Spot.Top, toSpot: go.Spot.Top }) ); var fuseTemp = $(go.Node, "Spot", nodeStyle(), $(go.Shape, "Fuse", shapeStyle()), $(go.Shape, "Rectangle", shapeStyle(), { fill: "transparent", stroke: "transparent" }), $(go.Shape, "Rectangle", portStyle(true), { portId: "in", alignment: go.Spot.Left }), $(go.Shape, "Rectangle", portStyle(false), { portId: "out", alignment: go.Spot.Right }) ); var junTemp = $(go.Node, "Spot", nodeStyle(), { rotatable: false }, $(go.Shape, "Rectangle", shapeStyle(), { desiredSize: new go.Size(15, 15), fill: "transparent", stroke: "transparent" }), // transparent box that makes junctions easier to click on $(go.Shape, "Rectangle", portStyle(true), { portId: "inout", toSpot: go.Spot.AllSides, fromSpot: go.Spot.AllSides, fromLinkable: true }), // linkable in and out of this port ); function createJunction(e, obj) { // Creates Junction node when user double clicks on a link var adorn = obj.part; e.handled = true; e.diagram.startTransaction("Link Label"); var model = myDiagram.model; var pos = e.documentPoint; var posX = pos.x; var posY = pos.y; var label = {}; // Create empty NodeData model.addNodeData(label); var node = e.diagram.findNodeForData(label); // Finds the created node from the NodeData node.labeledLink = obj; // and sets the labeledLink to the link that was clicked on index = obj.findClosestSegment(pos); // Finds the index node.segmentIndex = index; var startPoint = obj.points.elt(index); // Grabs the point at the start and end of the segment var endPoint = obj.points.elt(index + 1); // Finds dif between pos and startPoint and divided by dif of endPoint and startPoint if (startPoint.x - endPoint.x === 0) // Segment is horizontal node.segmentFraction = (pos.y - startPoint.y) / (endPoint.y - startPoint.y); else // Segment is vertical node.segmentFraction = (pos.x - startPoint.x) / (endPoint.x - startPoint.x); e.diagram.commitTransaction("Link Label"); } // Link template myDiagram.linkTemplate = $(go.Link, { routing: go.Link.AvoidsNodes, curve: go.Link.JumpOver, corner: 3, relinkableFrom: true, relinkableTo: true, selectionAdorned: false, // Links are not adorned when selected so that their color remains visible. shadowOffset: new go.Point(0, 0), shadowBlur: 5, shadowColor: "red", resizable: true, reshapable: true, name: "", }, new go.Binding("isShadowed", "isSelected").ofObject(), $(go.Shape, { name: "SHAPE", strokeWidth: 2, stroke: "black" }), { doubleClick: function (e, obj) { createJunction(e, obj); } } ); // Adds the templates to the map myDiagram.nodeTemplateMap.add("dcvoltagesource", dcVoltTemp); myDiagram.nodeTemplateMap.add("acvoltagesource", acVoltTemp); myDiagram.nodeTemplateMap.add("capacitor", capacitorTemp); myDiagram.nodeTemplateMap.add("resistor", resistorTemp); myDiagram.nodeTemplateMap.add("inductor", inductorTemp); myDiagram.nodeTemplateMap.add("lightbulb", lightbulbTemp); myDiagram.nodeTemplateMap.add("diode", diodeTemp); myDiagram.nodeTemplateMap.add("transistor", transistorTemp); myDiagram.nodeTemplateMap.add("switch", switchTemp); myDiagram.nodeTemplateMap.add("switch2", switch2Temp); myDiagram.nodeTemplateMap.add("ground", groundTemp); myDiagram.nodeTemplateMap.add("fuse", fuseTemp); myDiagram.nodeTemplateMap.add("junction", junTemp); var palette = new go.Palette("palette"); // Creates a new Palette in the HTML DIV element "palette" // Copies the template to the palette palette.nodeTemplateMap = myDiagram.nodeTemplateMap; // Adds the nodes to the palette palette.model.nodeDataArray = [ { category: "dcvoltagesource" }, { category: "acvoltagesource" }, { category: "capacitor" }, { category: "resistor" }, { category: "inductor" }, { category: "lightbulb" }, { category: "diode" }, { category: "transistor" }, { category: "switch" }, { category: "switch2" }, { category: "ground" }, { category: "fuse" }, // { category: "junction" } ]; // Generates links and makes it so links connect by ports myDiagram.model = $(go.GraphLinksModel, { linkLabelKeysProperty: "junctions", linkFromPortIdProperty: "fromPort", linkToPortIdProperty: "toPort" }); loop(); inspector = new Inspector('myInspectorDiv', myDiagram, { properties: { 'key': { show: false }, 'segmentIndex': { show: false }, 'segmentFraction': { show: false }, 'name': { show: Inspector.showIfNode }, 'category': { show: Inspector.showIfNode, readOnly: true }, 'angle': { show: Inspector.showIfPresent, type: 'select', choices: function (node, propName) { return ['0', '90', '180', '270']; } }, 'loc': { show: Inspector.showIfNode }, 'Voltage': { show: Inspector.showIfPresent }, 'Resistance': { show: Inspector.showIfPresent }, 'Capacitance': { show: Inspector.showIfPresent }, 'Inductance': { show: Inspector.showIfPresent }, 'Amplitude': { show: Inspector.showIfPresent }, 'Interval': { show: Inspector.showIfPresent }, 'state': { show: Inspector.showIfPresent, type: 'select', choices: function (node, propName) { if (node.category === 'switch') return ['On', 'Off']; else if (node.category === 'switch2') return ['Up', 'Down']; } } } } ); myDiagram.toolManager.mouseMoveTools.insertAt(2, $(WireDragTool, { isEnabled: false, // disabled by the checkbox delay: 0, // always canStart(), so PanningTool never gets the chance to run })); /*12DY@9dkd)dk*/ } // end init </script> </head> <body onload="init();"> <div> <nav> <span id="currentStorageSpan"></span> <ul id="fileMenus"> <li> <a href="#">File</a> <ul> <li><a href="#" onclick="handlePromise('New')">New <p class="shortcut">(Ctrl + D)</p></a></li> <li><a href="#" onclick="handlePromise('Load')">Open... <p class="shortcut">(Ctrl + O)</p></a></li> <li><a href="#" onclick="handlePromise('Save')">Save <p class="shortcut">(Ctrl + S)</p></a></li> <li><a href="#" onclick="handlePromise('SaveAs')">Save As...</a></li> <li><a href="#" onclick="handlePromise('Delete')">Remove... <p class="shortcut">(Ctrl + R)</p></a></li> <li><a href="#">Import Data From >>></a> <ul> <li><a href="#" onclick="authorizeGoogleUserForDataImport()">Google Sheet</a></li> <li><a href="#" onclick="document.getElementById('file-input').click()">Local CSV File</a> </ul> </li> <li><a href="#" onclick="makeDiagramImage()">Export PNG</a></li> <li><a href="#" onclick="updateCurrentStorageSpan()">Change Storage Service</a></li> </ul> </li> </ul> <p id="isAutoSavingP"><input type="checkbox" id="isAutoSavingCheckbox" unchecked /> <label for="isAutoSavingCheckbox">Autosave Enabled</label></p> <p id="ge-header">Electric Circuit v1.0</p> <div id="ge-filename">(Unsaved file)</div> </nav> <input type="file" id="file-input" style="display: none;" /> <div id="container" style="display: flex;"> <div id="palette" style="border: solid 1px black; width: 115px; height:798px; float: left;"></div> <div id="myDiagramDiv" style="background: #969699; width: 100%; height:800px; float: left;"></div> <div id="ge-inspector-div" style="background: #212121; flex-grow: 1; height: 800px; float: right;"> <div id="myInspectorDiv" class="inspector"> </div> </div> </div> <div id="ge-footer"> <span>Built with the <a href="https://gojs.net">GoJS Diagramming Library</a>, by <a href="https://nwoods.com"> Northwoods Software</a>.</span> </div> <p> This editor allows one to build interactive electric circuits. Drag and drop parts from the palette or double click on the background to create a junction. </p> <p> Drag from the preset ports on the parts to another part's ports to draw wires. Double-click on wires to create a junction on the wire. Hit W to toggle the wire creating tool </p> <p> Select an element to change its properties based on what part it is. Also the ability to double click switches to change their state, or edit them through data inspector. </p> <script> function loop() { setTimeout(function () { updateStatus(); loop(); }, 25); // Updates every 25 milliseconds } function updateStatus() { var oldskip = myDiagram.skipsUndoManager; myDiagram.skipsUndoManager = true; myDiagram.nodes.each(function (node) { // Does the volt sources first if (node.category == "dcvoltagesource") { doDCVolt(node); } if (node.category == "acvoltagesource") { doACVolt(node); } }); myDiagram.nodes.each(function (node) { if (node.name === "junction") doJunction(node); // special case for labellink junctions switch (node.category) { case "capacitor": doAll(node); break; case "resistor": doAll(node); break; case "inductor": doAll(node); break; case "switch": doSwitch(node); break; case "switch2": doSwitch2(node); break; case "diode": doAll(node); break; case "lightbulb": doLightBulb(node); break; case "transistor": doAll(node); break; case "ground": doGround(node); break; case "fuse": doAll(node); break; case "junction": doJunction2(node); break; case "dcvoltsource": break; case "acvoltsource": break; } }) myDiagram.skipsUndoManager = oldskip; } function uniqueChildren(link, children) { // fills up a set with all the unique children of the given link, used for determining if it loops back to itself link.labelNodes.each(function (nodes) { // checks all the labelnodes for a child branch back to the volt source if (!children.has(nodes.data.key)) { children.add(nodes.data.key); nodes.findLinksOutOf().each(function (links) { uniqueChildren(links, children); }); } }); var node = link.toNode; if (!children.has(node.data.key)) { children.add(node.data.key); if (node.category != "junction" && node.findObject("NODESHAPE") != null) { if (node.findObject("NODESHAPE").figure == "Up") { // only checks out1 when switch is up node.findLinksOutOf("out1").each(function (links) { uniqueChildren(links, children); }); } else if (node.findObject("NODESHAPE").figure == "Down") { // only checks out2 when switch is down node.findLinksOutOf("out2").each(function (links) { uniqueChildren(links, children); }); } else if (node.findObject("NODESHAPE").figure != "Off") { // only checks when switch is down node.findLinksOutOf().each(function (links) { uniqueChildren(links, children); }); } } else { // all other cases node.findLinksOutOf().each(function (links) { uniqueChildren(links, children); }); } } } function setOutputLinks(node, color) { // Changes the output links that is connected to a node var key = node.data.key; node.findLinksOutOf().each(function (link) { var children = new Set([]); uniqueChildren(link, children); if (children.has(key)) link.findObject("SHAPE").stroke = color; else link.findObject("SHAPE").stroke = "black"; }); } function linkIsOn(link) { // Determines if previous wire is on or off return link.findObject("SHAPE").stroke === "blue"; } function setNodeColor(node, color) { if (node.findObject("NODESHAPE") == null) return; if (node.findLinksInto().first() === null) { // Used when deleting the last wire into a node to avoid it continuing to appear on node.findObject("NODESHAPE").fill = "red"; node.findObject("NODESHAPE").stroke = "red"; } node.findLinksInto().each(function (link) { if (link.findObject("SHAPE").stroke === color) { node.findObject("NODESHAPE").fill = color; node.findObject("NODESHAPE").stroke = color; } }); } function doJunction(node) { if (node.labeledLink != null) { var color = node.labeledLink.findObject("SHAPE").stroke; // Grabs the color from the link it is on if (color === "black") // if there is no input from the labeledlink, check for links into var color = node.findLinksInto().any(linkIsOn) ? "blue" : "black"; setOutputLinks(node, color); node.labeledLink.findObject("SHAPE").stroke = color; } } function doJunction2(node) { // standard draggable junction var color = node.findLinksInto().any(linkIsOn) ? "blue" : "black"; setOutputLinks(node, color); } function doDCVolt(node) { var color = node.findLinksInto().any(linkIsOn) ? "blue" : "black"; var children = new Set([]); var key = node.data.key; node.findLinksOutOf().each(function (link) { uniqueChildren(link, children); }); if (children.has(key)) { setOutputLinks(node, "blue"); setNodeColor(node, "blue"); } else { setOutputLinks(node, "black"); setNodeColor(node, "black"); } } function doACVolt(node) { var color = node.data.Color; node.data.Count += 25; if (node.data.Count >= node.data.Interval) { if (color === 'blue') color = 'black'; else if (color === 'black') color = 'blue'; node.data.Color = color; node.data.Count = 0; } var children = new Set([]); var key = node.data.key; node.findLinksOutOf().each(function (link) { uniqueChildren(link, children); }); if (children.has(key)) { setOutputLinks(node, color); setNodeColor(node, color); } else { setOutputLinks(node, "black"); setNodeColor(node, "black"); } } function doSwitch(node) { var color = node.findLinksInto().any(linkIsOn) ? "blue" : "black"; if (node.findObject("NODESHAPE").figure == "On") { // Allows the output to go through if the switch is down setOutputLinks(node, color); } else { setOutputLinks(node, "black"); } setNodeColor(node, color); } function doSwitch2(node) { var color = node.findLinksInto().any(linkIsOn) ? "blue" : "black"; var nodeFig = node.findObject("NODESHAPE").figure; if (nodeFig === "Up") { node.findLinksOutOf().each(function (link) { if (link.fromPort.name === "out1") { // Only emits to the top port link.path.stroke = color; } if (link.fromPort.name === "out2") { // Force set the bottom port off link.path.stroke = "black"; } }); } else if (nodeFig === "Down") { node.findLinksOutOf().each(function (link) { if (link.fromPort.name === "out1") { // Force set the top port off link.path.stroke = "black"; } if (link.fromPort.name === "out2") { // Only emits to the bottom port link.path.stroke = color; } }); } setNodeColor(node, color) } function doLightBulb(node) { var color = node.findLinksInto().any(linkIsOn) ? "yellow" : "lightgray"; // Sets the light bulb to either yellow or lightgray instead of blue/black var color2 = node.findLinksInto().any(linkIsOn) ? "blue" : "black"; if (node.findLinksInto().first() === null) { node.findObject("NODESHAPE").fill = "lightgray"; } node.findLinksInto().each(function (link) { node.findObject("NODESHAPE").fill = color; }); setOutputLinks(node, color2); } // Does nothing for now function doGround(node) { var color = node.findLinksInto().any(linkIsOn) ? "blue" : "black"; node.findLinksInto().each(function (link) { if (link.findObject("SHAPE").stroke === color) { node.findObject("NODESHAPE").fill = color; node.findObject("NODESHAPE").stroke = color; } }); } // does the rest/generic actions function doAll(node) { var color = node.findLinksInto().any(linkIsOn) ? "blue" : "black"; setOutputLinks(node, color); setNodeColor(node, color); } function toggleWire() { var tool = myDiagram.toolManager.findTool("WireDragTool"); if (tool !== null) tool.isEnabled = !tool.isEnabled; if (tool.isEnabled) document.getElementById('ge-footer').innerText = "Wire Dragging Tool Enabled"; else document.getElementById('ge-footer').innerHTML = "<span>Built with the <a href=\"https://gojs.net\">GoJS Diagramming Library</a>, by <a href=\"https://nwoods.com\"> Northwoods Software</a>.</span>"; } /* Post-Init files go here ijiwd8up@90n */ </script> </div> </body> </html>