UNPKG

markgojs

Version:

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

917 lines (847 loc) 29.7 kB
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Floor Plan Editor</title> <!-- Copyright 1998-2019 by Northwoods Software Corporation. --> <meta charset="UTF-8"> <script src="../release/go.js"></script> <script src="DrawCommandHandler.js"></script> <script src="RotateMultipleTool.js"></script> <script src="ResizeMultipleTool.js"></script> <script src="GuidedDraggingTool.js"></script> <style type="text/css"> #menuBar { border: none; border: 0px; margin: 0px; padding: 0px; font: 67.5% 'Lucida Sans Unicode', 'Bitstream Vera Sans', 'Trebuchet Unicode MS', 'Lucida Grande', Verdana, Helvetica, sans-serif; font-size: 12px; font-weight: bold; width: auto; } #menuBar ul { background: #ededed; height: 25px; list-style: none; margin: 0; padding: 0; } #menuBar li { float: left; padding: 0px; } #menuBar li a { background: #ededed; display: block; font-weight: normal; line-height: 25px; margin: 0px; padding: 0px 5px; text-align: center; text-decoration: none; } #menuBar > ul > li > a { color: black; } #menuBar ul ul a { color: black; } #menuBar li > a:hover, #menuBar ul li:hover > a { background: #007FFF; color: white; text-decoration: none; } #menuBar li ul { background: #9CCB19; display: none; height: auto; padding: 0px; margin: 0px; border: 0px; position: absolute; width: 150px; z-index: 200; } #menuBar li:hover ul { display: block; } #menuBar li li { background: #ededed; display: block; float: none; margin: 0px; padding: 0px; width: 150px; } #menuBar li:hover li a { background: none; } #menuBar li ul a { display: block; height: 25px; font-size: 12px; font-style: normal; margin: 0px; padding: 0px 10px 0px 15px; text-align: left; } #menuBar li ul a:hover, #menuBar li ul li:hover > a { background: #007FFF; border: 0px; color: white; text-decoration: none; } /*sub-sublist*/ #nav li:hover ul ul { display: none; } #nav li li:hover ul { background:#9CCB19; margin-left: 150px; margin-top: -25px; display: block; } /*sub-sub-sublist*/ #nav li li:hover ul ul { display: none; } #nav li li li:hover ul { background:#9CCB19; margin-left: 150px; margin-top: -25px; display: block; color: #0276FD; } input { text-align: center; font-size: large; float: left; } #myOverviewDiv { background-color: lightgray; } #currentFile { background: #1874CD; width:100%; text-align:center; font-family:Arial; font-weight:bold; font-size:14px; padding:3px 0px; color: white; } .draggable { display: inline-block; vertical-align: top; border: 1px solid gray; background-color: #e2e2e2; position: absolute; top:40%; left:50%; width:300px; height: 200px; z-index: 500; } .handle { background-color: #9CCB19; text-align: center; font: bold 12px sans-serif; } .elementText { font-family:Arial; font-size:medium; margin-left: 10px; margin-top: 20px; margin-bottom:10px; } .mySavedFiles { font-family:Arial; font-size:medium; width:250px; margin-left: 25px; } .elementBtn { margin-top:20px; font-family:Arial; font-size:medium; margin-left:20px; } </style> <script id="code"> /*function checkLocalStorage () { try { window.localStorage.setItem('item', 'item'); window.localStorage.removeItem('item'); return true; } catch (e) { return false; } }*/ function init() { // hides open HTML Element var openDocument = document.getElementById("openDocument"); openDocument.style.visibility = "hidden"; // hides remove HTML Element var removeDocument = document.getElementById("removeDocument"); removeDocument.style.visibility = "hidden"; var $ = go.GraphObject.make; // for more concise visual tree definitions myDiagram = $(go.Diagram, "myDiagramDiv", { allowDrop: true, // accept drops from palette allowLink: false, // no user-drawn links commandHandler: new DrawCommandHandler(), // defined in DrawCommandHandler.js // default to having arrow keys move selected nodes "commandHandler.arrowKeyBehavior": "move", // allow Ctrl-G to call groupSelection() "commandHandler.archetypeGroupData": { text: "Group", isGroup: true }, rotatingTool: new RotateMultipleTool(), // defined in RotateMultipleTool.js resizingTool: new ResizeMultipleTool(), // defined in ResizeMultipleTool.js draggingTool: new GuidedDraggingTool(), // defined in GuidedDraggingTool.js "draggingTool.horizontalGuidelineColor": "blue", "draggingTool.verticalGuidelineColor": "blue", "draggingTool.centerGuidelineColor": "green", "draggingTool.guidelineWidth": 1, // notice whenever the selection may have changed "ChangedSelection": enableAll, // defined below, to enable/disable commands // notice when the Paste command may need to be reenabled "ClipboardChanged": enableAll, // notice when an object has been dropped from the palette "ExternalObjectsDropped": function(e) { document.getElementById("myDiagramDiv").focus(); // assume keyboard focus should be on myDiagram myDiagram.toolManager.draggingTool.clearGuidelines(); // remove any guidelines } }); // sets the qualities of the tooltip var tooltiptemplate = $(go.Adornment, go.Panel.Auto, $(go.Shape, "RoundedRectangle", { fill: "whitesmoke", stroke: "gray" }), $(go.TextBlock, { margin: 3, editable: true }, // converts data about the part into a string new go.Binding("text", "", function(data) { if (data.item != undefined) return data.item; return "(unnamed item)"; })) ); // Define the generic furniture and structure Nodes. // The Shape gets it Geometry from a geometry path string in the bound data. myDiagram.nodeTemplate = $(go.Node, "Spot", { locationObjectName: "SHAPE", locationSpot: go.Spot.Center, toolTip: tooltiptemplate, selectionAdorned: false // use a Binding on the Shape.stroke to show selection }, // remember the location of this Node new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), // move a selected part into the Foreground layer, so it isn't obscured by any non-selected parts new go.Binding("layerName", "isSelected", function(s) { return s ? "Foreground" : ""; }).ofObject(), // can be resided according to the user's desires { resizable: true, resizeObjectName: "SHAPE" }, { rotatable: true, rotateObjectName: "SHAPE" }, $(go.Shape, { name: "SHAPE", // the following are default values; // actual values may come from the node data object via data-binding geometryString: "F1 M0 0 L20 0 20 20 0 20 z", fill: "rgb(130, 130, 256)" }, // this determines the actual shape of the Shape new go.Binding("geometryString", "geo"), // allows the color to be determined by the node data new go.Binding("fill", "color"), // selection causes the stroke to be blue instead of black new go.Binding("stroke", "isSelected", function(s) { return s ? "dodgerblue" : "black"; }).ofObject(), // remember the size of this node new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), // can set the angle of this Node new go.Binding("angle", "angle").makeTwoWay() ) ); myDiagram.nodeTemplate.contextMenu = $(go.Adornment, "Vertical", $("ContextMenuButton", $(go.TextBlock, "Rename", { margin: 3 }), { click: function(e, obj) { rename(obj); } }), $("ContextMenuButton", $(go.TextBlock, "Cut", { margin: 3 }), { click: function(e, obj) { myDiagram.commandHandler.cutSelection(); } }), $("ContextMenuButton", $(go.TextBlock, "Copy", { margin: 3 }), { click: function(e, obj) { myDiagram.commandHandler.copySelection(); } }), $("ContextMenuButton", $(go.TextBlock, "Rotate +45", { margin: 3 }), { click: function(e, obj) { myDiagram.commandHandler.rotate(45); } }), $("ContextMenuButton", $(go.TextBlock, "Rotate -45", { margin: 3 }), { click: function(e, obj) { myDiagram.commandHandler.rotate(-45); } }), $("ContextMenuButton", $(go.TextBlock, "Rotate +90", { margin: 3 }), { click: function(e, obj) { myDiagram.commandHandler.rotate(90); } }), $("ContextMenuButton", $(go.TextBlock, "Rotate -90", { margin: 3 }), { click: function(e, obj) { myDiagram.commandHandler.rotate(-90); } }), $("ContextMenuButton", $(go.TextBlock, "Rotate 180", { margin: 3 }), { click: function(e, obj) { myDiagram.commandHandler.rotate(180); } }) ); // group settings from basic.html to lock things together myDiagram.groupTemplate = $(go.Group, go.Panel.Auto, { ungroupable: true, // enable Ctrl-Shift-G to ungroup a selected Group toolTip: tooltiptemplate }, $(go.Shape, "Rectangle", // the Group is not seen but can be selected due to the transparent fill { fill: "transparent", stroke: "lightgray", strokeWidth: 1 }), $(go.Placeholder) ); // make grouped Parts unselectable myDiagram.addDiagramListener("SelectionGrouped", function(e) { // e.subject should be the new Group e.subject.memberParts.each(function(part) { part.selectable = false; }); }); myDiagram.addDiagramListener("SelectionUngrouped", function(e) { // e.parameter should be collection of ungrouped former members e.parameter.each(function(part) { part.selectable = true; part.isSelected = true; }); }); myDiagram.addDiagramListener("SelectionCopied", function(e) { // selection collection will be modified during this loop, // so make a copy of it first var sel = myDiagram.selection.toArray(); for (var i = 0; i < sel.length; i++) { var part = sel[i]; // don't have any members of Groups be selected or selectable if (part instanceof go.Group) { var mems = new go.Set().addAll(part.memberParts); mems.each(function(member) { member.isSelected = false; member.selectable = false; }); } } }); // change the title to indicate that the diagram has been modified myDiagram.addDiagramListener("Modified", function(e) { var currentFile = document.getElementById("currentFile"); var idx = currentFile.textContent.indexOf("*"); if (myDiagram.isModified) { if (idx < 0) currentFile.textContent = currentFile.textContent + "*"; } else { if (idx >= 0) currentFile.textContent = currentFile.textContent.substr(0, idx); } }); // the Palette // brushes for furniture structures var wood = $(go.Brush, "Linear", { 0: "#964514", 1: "#5E2605" }); var wall = $(go.Brush, "Linear", { 0: "#A8A8A8", 1: "#545454" }); var blue = $(go.Brush, "Linear", { 0: "#42C0FB", 1: "#009ACD" }); var metal = $(go.Brush, "Linear", { 0: "#A8A8A8", 1: "#474747" }); var green = $(go.Brush, "Linear", { 0: "#9CCB19", 1: "#698B22" }); // default structures and furniture myPalette = $(go.Palette, "myPaletteDiv", { nodeTemplate: myDiagram.nodeTemplate, // shared with the main Diagram "contextMenuTool.isEnabled": false, // but disable context menus allowZoom: false, layout: $(go.GridLayout, { cellSize: new go.Size(1, 1), spacing: new go.Size(5, 5) }), // initialize the Palette with a few furniture and structure nodes model: $(go.GraphLinksModel, { nodeDataArray: [ { key: 1, geo: "F1 M0 0 L5,0 5,40 0,40 0,0z x M0,0 a40,40 0 0,0 -40,40 ", item: "left door", color: wall }, { key: 2, geo: "F1 M0 0 L5,0 5,40 0,40 0,0z x M5,0 a40,40 0 0,1 40,40 ", item: "right door", color: wall }, { key: 3, angle: 90, geo: "F1 M0,0 L0,100 12,100 12,0 0,0z", item: "wall", color: wall }, { key: 4, angle: 90, geo: "F1 M0,0 L0,50 10,50 10,0 0,0 x M5,0 L5,50z", item: "window", color: "whitesmoke" }, { key: 5, geo: "F1 M0,0 L50,0 50,12 12,12 12,50 0,50 0,0 z", item: "corner", color: wall }, { key: 6, geo: "F1 M0 0 L40 0 40 40 0 40 0 0 x M0 10 L40 10 x M 8 10 8 40 x M 32 10 32 40 z", item: "arm chair", color: blue }, { key: 7, geo: "F1 M0 0 L80,0 80,40 0,40 0 0 x M0,10 L80,10 x M 7,10 7,40 x M 73,10 73,40 z", item: "couch", color: blue }, { key: 8, geo: "F1 M0 0 L30 0 30 30 0 30 z", item: "Side Table", color: wood }, { key: 9, geo: "F1 M0 0 L80,0 80,90 0,90 0,0 x M0,7 L80,7 x M 0,30 80,30 z", item: "queen bed", color: green }, { key: 10, geo: "F1 M5 5 L30,5 35,30 0,30 5,5 x F M0 0 L 35,0 35,5 0,5 0,0 z", item: "chair", color: wood }, { key: 11, geo: "F1 M0 0 L50,0 50,90 0,90 0,0 x M0,7 L50,7 x M 0,30 50,30 z", item: "twin bed", color: green }, { key: 12, geo: "F1 M0 0 L0 60 80 60 80 0z", item: "kitchen table", color: wood }, { key: 13, geo: "F1 M 0,0 a35,35 0 1,0 1,-1 z", item: "round table", color: wood }, { key: 14, geo: "F1 M 0,0 L35,0 35,30 0,30 0,0 x M 5,5 L 30, 5 30,25 5,25 5,5 x M 17,2 L 17,10 19,10 19,2 17,2 z", item: "kitchen sink", color: metal }, { key: 15, geo: "F1 M0,0 L55,0, 55,50, 0,50 0,0 x M 40,7 a 7,7 0 1 0 0.00001 0z x M 40,10 a 4,4 0 1 0 0.00001 0z x M 38,27 a 7,7 0 1 0 0.00001 0z x M 38,30 a 4,4 0 1 0 0.00001 0z x M 16,27 a 7,7 0 1 0 0.00001 0z xM 16,30 a 4,4 0 1 0 0.00001 0z x M 14,7 a 7,7 0 1 0 0.00001 0z x M 14,10 a 4,4 0 1 0 0.00001 0z", item: "stove", color: metal }, { key: 16, geo: "F1 M0,0 L55,0, 55,50, 0,50 0,0 x F1 M0,51 L55,51 55,60 0,60 0,51 x F1 M5,60 L10,60 10,63 5,63z", item: "refrigerator", color: metal }, { key: 17, geo: "F1 M0,0 100,0 100,40 0,40z", item: "bookcase", color: wood }, { key: 18, geo: "F1 M0,0 70,0 70,50 0,50 0,0 x F1 M15,58 55,58 55,62 15,62 x F1 M17,58 16,50 54,50 53,58z", item: "desk", color: wood }, ] // end nodeDataArray }) // end model }); // end Palette // the Overview myOverview = $(go.Overview, "myOverviewDiv", { observed: myDiagram, maxScale: 0.5 }); // change color of viewport border in Overview myOverview.box.elt(0).stroke = "dodgerblue"; // start off with an empty document myDiagram.isModified = false; newDocument(); if (!checkLocalStorage()) { var currentFile = document.getElementById("currentFile"); currentFile.textContent = "Sorry! No web storage support. If you're using Internet Explorer / Microsoft Edge, you must load the page from a server for local storage to work."; } } // end init // enable or disable a particular button function enable(name, ok) { var button = document.getElementById(name); if (button) button.disabled = !ok; } // enable or disable all context-sensitive command buttons function enableAll() { var cmdhnd = myDiagram.commandHandler; enable("Rename", myDiagram.selection.count > 0); enable("Undo", cmdhnd.canUndo()); enable("Redo", cmdhnd.canRedo()); enable("Cut", cmdhnd.canCutSelection()); enable("Copy", cmdhnd.canCopySelection()); enable("Paste", cmdhnd.canPasteSelection()); enable("Delete", cmdhnd.canDeleteSelection()); enable("SelectAll", cmdhnd.canSelectAll()); enable("AlignLeft", cmdhnd.canAlignSelection()); enable("AlignRight", cmdhnd.canAlignSelection()); enable("AlignTop", cmdhnd.canAlignSelection()); enable("AlignBottom", cmdhnd.canAlignSelection()); enable("AlignCenterX", cmdhnd.canAlignSelection()); enable("AlignCenterY", cmdhnd.canAlignSelection()); enable("AlignRow", cmdhnd.canAlignSelection()); enable("AlignColumn", cmdhnd.canAlignSelection()); enable("AlignGrid", cmdhnd.canAlignSelection()); enable("Rotate45", cmdhnd.canRotate(45)); enable("Rotate_45", cmdhnd.canRotate(-45)); enable("Rotate90", cmdhnd.canRotate(90)); enable("Rotate_90", cmdhnd.canRotate(-90)); enable("Rotate180", cmdhnd.canRotate(180)); } // Commands for this application // changes the item of the object function rename(obj) { if (!obj) obj = myDiagram.selection.first(); if (!obj) return; myDiagram.startTransaction("rename"); var newName = prompt("Rename " + obj.part.data.item + " to:", obj.part.data.item); myDiagram.model.setDataProperty(obj.part.data, "item", newName); myDiagram.commitTransaction("rename"); } // shows/hides gridlines // to be implemented onclick of a button function updateGridOption() { myDiagram.startTransaction("grid"); var grid = document.getElementById("grid"); myDiagram.grid.visible = (grid.checked === true); myDiagram.commitTransaction("grid"); } // enables/disables guidelines when dragging function updateGuidelinesOption() { // no transaction needed, because we are modifying a tool for future use var guide = document.getElementById("guidelines") if (guide.checked === true) { myDiagram.toolManager.draggingTool.isGuidelineEnabled = true; } else { myDiagram.toolManager.draggingTool.isGuidelineEnabled = false; } } // enables/disables snapping tools, to be implemented by buttons function updateSnapOption() { // no transaction needed, because we are modifying tools for future use var snap = document.getElementById("snap"); if (snap.checked === true) { myDiagram.toolManager.draggingTool.isGridSnapEnabled = true; myDiagram.toolManager.resizingTool.isGridSnapEnabled = true; } else { myDiagram.toolManager.draggingTool.isGridSnapEnabled = false; myDiagram.toolManager.resizingTool.isGridSnapEnabled = false; } } // user specifies the amount of space between nodes when making rows and column function askSpace() { var space = prompt("Desired space between nodes (in pixels):", "0"); return space; } // update arrowkey function function arrowMode() { // no transaction needed, because we are modifying the CommandHandler for future use var move = document.getElementById("move"); var select = document.getElementById("select"); var scroll = document.getElementById("scroll"); if (move.checked === true) { myDiagram.commandHandler.arrowKeyBehavior = "move"; } else if (select.checked === true) { myDiagram.commandHandler.arrowKeyBehavior = "select"; } else if (scroll.checked === true) { myDiagram.commandHandler.arrowKeyBehavior = "scroll"; } } var UnsavedFileName = "(Unsaved File)"; function checkLocalStorage() { try { window.localStorage.setItem('item', 'item'); window.localStorage.removeItem('item'); return true; } catch (e) { return false; } } function getCurrentFileName() { var currentFile = document.getElementById("currentFile"); var name = currentFile.textContent; if (name[name.length-1] === "*") return name.substr(0, name.length-1); return name; } function setCurrentFileName(name) { var currentFile = document.getElementById("currentFile"); if (myDiagram.isModified) { name += "*"; } currentFile.textContent = name; } function newDocument() { // checks to see if all changes have been saved if (myDiagram.isModified) { var save = confirm("Would you like to save changes to " + getCurrentFileName() + "?"); if (save) { saveDocument(); } } setCurrentFileName(UnsavedFileName); // loads an empty diagram myDiagram.model = new go.GraphLinksModel(); myDiagram.undoManager.isEnabled = true; myDiagram.addModelChangedListener(function(e) { if (e.isTransactionFinished) enableAll(); }); myDiagram.isModified = false; } // saves the current floor plan to local storage function saveDocument() { if (checkLocalStorage()) { var saveName = getCurrentFileName(); if (saveName === UnsavedFileName) { saveDocumentAs(); } else { saveDiagramProperties() window.localStorage.setItem(saveName, myDiagram.model.toJson()); myDiagram.isModified = false; } } } // saves floor plan to local storage with a new name function saveDocumentAs() { if (checkLocalStorage()) { var saveName = prompt("Save file as...", getCurrentFileName()); if (saveName && saveName !== UnsavedFileName) { setCurrentFileName(saveName); saveDiagramProperties() window.localStorage.setItem(saveName, myDiagram.model.toJson()); myDiagram.isModified = false; } } } // checks to see if all changes have been saved -> shows the open HTML element function openDocument() { if (checkLocalStorage()) { if (myDiagram.isModified) { var save = confirm("Would you like to save changes to " + getCurrentFileName() + "?"); if (save) { saveDocument(); } } openElement("openDocument", "mySavedFiles"); } } // shows the remove HTML element function removeDocument() { if (checkLocalStorage()) { openElement("removeDocument", "mySavedFiles2"); } } // these functions are called when panel buttons are clicked function loadFile() { var listbox = document.getElementById("mySavedFiles"); // get selected filename var fileName = undefined; for (var i = 0; i < listbox.options.length; i++) { if (listbox.options[i].selected) fileName = listbox.options[i].text; // selected file } if (fileName !== undefined) { // changes the text of "currentFile" to be the same as the floor plan now loaded setCurrentFileName(fileName); // actually load the model from the JSON format string var savedFile = window.localStorage.getItem(fileName); myDiagram.model = go.Model.fromJson(savedFile); loadDiagramProperties(); myDiagram.undoManager.isEnabled = true; myDiagram.addModelChangedListener(function(e) { if (e.isTransactionFinished) enableAll(); }); myDiagram.isModified = false; // eventually loadDiagramProperties will be called to finish // restoring shared saved model/diagram properties } closeElement("openDocument"); } // Store shared model state in the Model.modelData property // (will be loaded by loadDiagramProperties) function saveDiagramProperties() { myDiagram.model.modelData.position = go.Point.stringify(myDiagram.position); } // Called by loadFile. function loadDiagramProperties(e) { // set Diagram.initialPosition, not Diagram.position, to handle initialization side-effects var pos = myDiagram.model.modelData.position; if (pos) myDiagram.initialPosition = go.Point.parse(pos); } // deletes the selected file from local storage function removeFile() { var listbox = document.getElementById("mySavedFiles2"); // get selected filename var fileName = undefined; for (var i = 0; i < listbox.options.length; i++) { if (listbox.options[i].selected) fileName = listbox.options[i].text; // selected file } if (fileName !== undefined) { // removes file from local storage window.localStorage.removeItem(fileName); // the current document remains open, even if its storage was deleted } closeElement("removeDocument"); } function updateFileList(id) { // displays cached floor plan files in the listboxes var listbox = document.getElementById(id); // remove any old listing of files var last; while (last = listbox.lastChild) listbox.removeChild(last); // now add all saved files to the listbox for (key in window.localStorage) { var storedFile = window.localStorage.getItem(key); if (!storedFile) continue; var option = document.createElement("option"); option.value = key; option.text = key; listbox.add(option, null) } } function openElement(id, listid) { var panel = document.getElementById(id); if (panel.style.visibility === "hidden") { updateFileList(listid); panel.style.visibility = "visible"; } } // hides the open/remove elements when the "cancel" button is pressed function closeElement(id) { var panel = document.getElementById(id); if (panel.style.visibility === "visible") { panel.style.visibility = "hidden"; } } </script> </head> <body onload="init()"> <div> <div id="currentFile">(Unsaved File)</div> <div id="menuBar"> <ul id="nav"> <li><a href="#">File</a> <ul> <li><a href="#" onclick="newDocument()">New</a></li> <li><a href="#" onclick="openDocument()">Open...</a></li> <li><a href="#" onclick="saveDocument()">Save</a></li> <li><a href="#" onclick="saveDocumentAs()">Save As...</a></li> <li><a href="#" onclick="removeDocument()">Delete...</a></li> </ul> </li> <li><a href="#">Edit</a> <ul> <li><a id="Rename" href="#" onclick="rename()">Rename</a></li> <li><a id="A1" href="#" onclick="myDiagram.commandHandler.undo()">Undo</a></li> <li><a id="Redo" href="#" onclick="myDiagram.commandHandler.redo()">Redo</a></li> <li><a id="Cut" href="#" onclick="myDiagram.commandHandler.cutSelection()">Cut</a></li> <li><a id="Copy" href="#" onclick="myDiagram.commandHandler.copySelection()">Copy</a></li> <li><a id="Paste" href="#" onclick="myDiagram.commandHandler.pasteSelection()">Paste</a></li> <li><a id="Delete" href="#" onclick="myDiagram.commandHandler.deleteSelection()">Delete</a></li> <li><a id="SelectAll" href="#" onclick="myDiagram.commandHandler.selectAll()">Select All</a></li> </ul> </li> <li><a href="#">Align</a> <ul > <li><a id="AlignLeft" href="#" onclick="myDiagram.commandHandler.alignLeft()">Left Sides</a></li> <li><a id="AlignRight" href="#" onclick="myDiagram.commandHandler.alignRight()">Right Sides</a></li> <li><a id="AlignTop" href="#" onclick="myDiagram.commandHandler.alignTop()">Tops</a></li> <li><a id="AlignBottom" href="#" onclick="myDiagram.commandHandler.alignBottom()">Bottoms</a></li> <li><a id="AlignCenterX" href="#" onclick="myDiagram.commandHandler.alignCenterX()">Center X</a></li> <li><a id="AlignCenterY" href="#" onclick="myDiagram.commandHandler.alignCenterY()">Center Y</a></li> </ul> </li> <li><a href="#">Space</a> <ul > <li><a id="AlignRow" href="#" onclick="myDiagram.commandHandler.alignRow(askSpace())">In Row...</a></li> <li><a id="AlignColumn" href="#" onclick="myDiagram.commandHandler.alignColumn(askSpace())">In Column...</a></li> </ul> </li> <li><a href="#">Rotate</a> <ul> <li><a id="Rotate45" href="#" onclick="myDiagram.commandHandler.rotate(45)">45°</a></li> <li><a id="Rotate_45" href="#" onclick="myDiagram.commandHandler.rotate(-45)">-45°</a></li> <li><a id="Rotate90" href="#" onclick="myDiagram.commandHandler.rotate(90)">90°</a></li> <li><a id="Rotate_90" href="#" onclick="myDiagram.commandHandler.rotate(-90)">-90°</a></li> <li><a id="Rotate180" href="#" onclick="myDiagram.commandHandler.rotate(180)">180°</a></li> </ul> </li> <li><a href="#">Options</a> <ul> <li><a href="#"><input id="grid" type="checkbox" name="options" value="grid" onclick="updateGridOption()">Grid</a></li> <li><a href="#"><input id="guidelines" type="checkbox" name="options" value="0" checked="checked" onclick="updateGuidelinesOption()">Guidelines</a></li> <li><a href="#"><input id="snap" type="checkbox" name="options" value="0" onclick="updateSnapOption()">Snapping</a></li> <li><a href="#">Arrow Keys >></a> <form > <ul> <li><a href="#"><input type="radio" name="arrow" id="move" onclick="arrowMode()" checked="checked">Move</a></li> <li><a href="#"><input type="radio" name="arrow" id="select" onclick="arrowMode()">Select</a></li> <li><a href="#"><input type="radio" name="arrow" id="scroll" onclick="arrowMode()">Scroll</a></li> </ul> </form> </li> </ul> </li> <li><a href="#" onclick="window.open('FloorPlanMonitor.html')">Monitor</a></li> </ul> </div><!--END menu bar --> <div id="PaletteAndDiagram" style="position: relative; overflow: hidden; width: 100%;"> <div id="sideBar" style="float:left; width:23%; min-height: 500px; text-align:center"> <div class="handle">Palette:</div> <div id="myPaletteDiv" style="border:solid 1px gray; width: 100%; min-height: 625px"></div> <div class="handle">Overview:</div> <div id="myOverviewDiv" style="border:solid 1px gray; width: 100%; height:225px;"></div> </div> <div id="myDiagramDiv" style="position: absolute; border: solid 1px gray; width:77%; height: 100%; min-height:500px; margin-left:23%; background-color:white"></div> </div> <div id="openDocument" class="draggable"> <div id="openDraggableHandle" class="handle">Open File</div> <div id="openText" class="elementText">Choose file to open...</div> <select id="mySavedFiles" class="mySavedFiles" ></select> <br /> <button id="openBtn" class="elementBtn" type="button" onclick="loadFile()" style="margin-left:70px">Open</button> <button id="cancelBtn"class="elementBtn" type="button" onclick="closeElement('openDocument')" >Cancel</button> </div> <div id="removeDocument" class="draggable"> <div id="removeDraggableHandle" class="handle">Delete File</div> <div id="removeText" class="elementText">Choose file to remove...</div> <select id="mySavedFiles2" class="mySavedFiles" ></select> <br /> <button id="removeBtn" class="elementBtn" type="button" onclick="removeFile()" style="margin-left:70px">Remove</button> <button id="cancelBtn2"class="elementBtn" type="button" onclick="closeElement('removeDocument')">Cancel</button> </div> <p> This sample demonstrates several custom <a>Tool</a>s, defined in their own files: <a href="GuidedDraggingTool.js">GuidedDraggingTool.js</a>, <a href="ResizeMultipleTool.js">ResizeMultipleTool.js</a>, <a href="RotateMultipleTool.js">RotateMultipleTool.js</a>, and a custom <a>CommandHandler</a>: <a href="DrawCommandHandler.js">DrawCommandHandler.js</a>. </p> </div> </body> </html>