Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
softend:test1:start [2016/01/27 15:17] – admin | softend:test1:start [2019/05/02 17:25] (aktuell) – Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | < | ||
+ | < | ||
+ | <meta charset=" | ||
+ | < | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | |||
+ | <main role=" | ||
+ | <div id=" | ||
+ | |||
+ | <div id=" | ||
+ | <p> | ||
+ | A mind map is a kind of spider diagram that organizes information around a central concept, with connecting branches. | ||
+ | </p> | ||
+ | <p> | ||
+ | The layout is controlled by moving the nodes closest to the tree's root node. | ||
+ | When one of these nodes is moved horizontally to the other side of the root, | ||
+ | all of its children will be sent to < | ||
+ | causing text to always be moved outwards from the root. | ||
+ | </p> | ||
+ | <p> | ||
+ | When a node is deleted the < | ||
+ | all of its children are deleted with it. When a node is dragged the < | ||
+ | property ensures that all its children are dragged with it. | ||
+ | Both of these are set during the the Diagram' | ||
+ | </p> | ||
+ | <p> | ||
+ | Additional commands are available on the context menus. | ||
+ | </p> | ||
+ | |||
+ | <button id=" | ||
+ | <button onclick=" | ||
+ | <button onclick=" | ||
+ | Diagram Model saved in JSON format: | ||
+ | <br> | ||
+ | < | ||
+ | " | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | {" | ||
+ | ] | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | function init() { | ||
+ | if (window.goSamples) goSamples(); | ||
+ | var $ = go.GraphObject.make; | ||
+ | |||
+ | myDiagram = | ||
+ | $(go.Diagram, | ||
+ | { | ||
+ | // when the user drags a node, also move/ | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | initialContentAlignment: | ||
+ | " | ||
+ | }); | ||
+ | |||
+ | // when the document is modified, add a " | ||
+ | myDiagram.addDiagramListener(" | ||
+ | var button = document.getElementById(" | ||
+ | if (button) button.disabled = !myDiagram.isModified; | ||
+ | var idx = document.title.indexOf(" | ||
+ | if (myDiagram.isModified) { | ||
+ | if (idx < 0) document.title += " | ||
+ | } else { | ||
+ | if (idx >= 0) document.title = document.title.substr(0, | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | // a node consists of some text with a line shape underneath | ||
+ | myDiagram.nodeTemplate = | ||
+ | $(go.Node, " | ||
+ | { selectionObjectName: | ||
+ | $(go.TextBlock, | ||
+ | { | ||
+ | name: " | ||
+ | minSize: new go.Size(30, 15), | ||
+ | editable: true | ||
+ | }, | ||
+ | // remember not only the text string but the scale and the font in the node data | ||
+ | new go.Binding(" | ||
+ | new go.Binding(" | ||
+ | new go.Binding(" | ||
+ | $(go.Shape, " | ||
+ | { | ||
+ | stretch: go.GraphObject.Horizontal, | ||
+ | strokeWidth: | ||
+ | // this line shape is the port -- what links connect with | ||
+ | portId: "", | ||
+ | }, | ||
+ | new go.Binding(" | ||
+ | // make sure links come in from the proper direction and go out appropriately | ||
+ | new go.Binding(" | ||
+ | new go.Binding(" | ||
+ | // remember the locations of each node in the node data | ||
+ | new go.Binding(" | ||
+ | // make sure text " | ||
+ | new go.Binding(" | ||
+ | ); | ||
+ | |||
+ | // selected nodes show a button for adding children | ||
+ | myDiagram.nodeTemplate.selectionAdornmentTemplate = | ||
+ | $(go.Adornment, | ||
+ | $(go.Panel, " | ||
+ | // this Adornment has a rectangular blue Shape around the selected node | ||
+ | $(go.Shape, { fill: null, stroke: " | ||
+ | $(go.Placeholder, | ||
+ | ), | ||
+ | // and this Adornment has a Button to the right of the selected node | ||
+ | $(" | ||
+ | { | ||
+ | alignment: go.Spot.Right, | ||
+ | alignmentFocus: | ||
+ | click: addNodeAndLink | ||
+ | }, | ||
+ | $(go.TextBlock, | ||
+ | { font: "bold 8pt sans-serif" | ||
+ | ) | ||
+ | ); | ||
+ | |||
+ | // the context menu allows users to change the font size and weight, | ||
+ | // and to perform a limited tree layout starting at that node | ||
+ | myDiagram.nodeTemplate.contextMenu = | ||
+ | $(go.Adornment, | ||
+ | $(" | ||
+ | $(go.TextBlock, | ||
+ | { click: function(e, obj) { changeTextSize(obj, | ||
+ | $(" | ||
+ | $(go.TextBlock, | ||
+ | { click: function(e, obj) { changeTextSize(obj, | ||
+ | $(" | ||
+ | $(go.TextBlock, | ||
+ | { click: function(e, obj) { toggleTextWeight(obj); | ||
+ | $(" | ||
+ | $(go.TextBlock, | ||
+ | { | ||
+ | click: function(e, obj) { | ||
+ | var adorn = obj.part; | ||
+ | adorn.diagram.startTransaction(" | ||
+ | layoutTree(adorn.adornedPart); | ||
+ | adorn.diagram.commitTransaction(" | ||
+ | } | ||
+ | } | ||
+ | ) | ||
+ | ); | ||
+ | |||
+ | // a link is just a Bezier-curved line of the same color as the node to which it is connected | ||
+ | myDiagram.linkTemplate = | ||
+ | $(go.Link, | ||
+ | { | ||
+ | curve: go.Link.Bezier, | ||
+ | fromShortLength: | ||
+ | toShortLength: | ||
+ | selectable: false | ||
+ | }, | ||
+ | $(go.Shape, | ||
+ | { strokeWidth: | ||
+ | new go.Binding(" | ||
+ | if (n.data.brush) return n.data.brush; | ||
+ | return " | ||
+ | }).ofObject()) | ||
+ | ); | ||
+ | |||
+ | // the Diagram' | ||
+ | myDiagram.contextMenu = | ||
+ | $(go.Adornment, | ||
+ | $(" | ||
+ | $(go.TextBlock, | ||
+ | { click: function(e, obj) { e.diagram.commandHandler.undo(); | ||
+ | new go.Binding(" | ||
+ | $(" | ||
+ | $(go.TextBlock, | ||
+ | { click: function(e, obj) { e.diagram.commandHandler.redo(); | ||
+ | new go.Binding(" | ||
+ | $(" | ||
+ | $(go.TextBlock, | ||
+ | { click: function(e, obj) { save(); } }), | ||
+ | $(" | ||
+ | $(go.TextBlock, | ||
+ | { click: function(e, obj) { load(); } }) | ||
+ | ); | ||
+ | |||
+ | |||
+ | myDiagram.addDiagramListener(" | ||
+ | var rootX = myDiagram.findNodeForKey(0).location.x; | ||
+ | myDiagram.selection.each(function(node) { | ||
+ | if (node.data.parent !== 0) return; // Only consider nodes connected to the root | ||
+ | var nodeX = node.location.x; | ||
+ | if (rootX < nodeX && node.data.dir !== " | ||
+ | node.data.dir = ' | ||
+ | myDiagram.model.updateTargetBindings(node.data); | ||
+ | layoutTree(node); | ||
+ | } else if (rootX > nodeX && node.data.dir !== " | ||
+ | node.data.dir = ' | ||
+ | myDiagram.model.updateTargetBindings(node.data); | ||
+ | layoutTree(node); | ||
+ | } | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | // read in the predefined graph using the JSON format data held in the " | ||
+ | load(); | ||
+ | } | ||
+ | |||
+ | function spotConverter(dir, | ||
+ | if (dir === " | ||
+ | return (from ? go.Spot.Left : go.Spot.Right); | ||
+ | } else { | ||
+ | return (from ? go.Spot.Right : go.Spot.Left); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function changeTextSize(obj, | ||
+ | var adorn = obj.part; | ||
+ | adorn.diagram.startTransaction(" | ||
+ | var node = adorn.adornedPart; | ||
+ | var tb = node.findObject(" | ||
+ | tb.scale *= factor; | ||
+ | adorn.diagram.commitTransaction(" | ||
+ | } | ||
+ | |||
+ | function toggleTextWeight(obj) { | ||
+ | var adorn = obj.part; | ||
+ | adorn.diagram.startTransaction(" | ||
+ | var node = adorn.adornedPart; | ||
+ | var tb = node.findObject(" | ||
+ | // assume " | ||
+ | var idx = tb.font.indexOf(" | ||
+ | if (idx < 0) { | ||
+ | tb.font = "bold " + tb.font; | ||
+ | } else { | ||
+ | tb.font = tb.font.substr(idx + 5); | ||
+ | } | ||
+ | adorn.diagram.commitTransaction(" | ||
+ | } | ||
+ | |||
+ | function addNodeAndLink(e, | ||
+ | var adorn = obj.part; | ||
+ | var diagram = adorn.diagram; | ||
+ | diagram.startTransaction(" | ||
+ | var oldnode = adorn.adornedPart; | ||
+ | var olddata = oldnode.data; | ||
+ | // copy the brush and direction to the new node data | ||
+ | var newdata = { text: " | ||
+ | diagram.model.addNodeData(newdata); | ||
+ | layoutTree(oldnode); | ||
+ | diagram.commitTransaction(" | ||
+ | } | ||
+ | |||
+ | function layoutTree(node) { | ||
+ | if (node.data.key === 0) { // adding to the root? | ||
+ | layoutAll(); | ||
+ | } else { // otherwise lay out only the subtree starting at this parent node | ||
+ | var parts = node.findTreeParts(); | ||
+ | layoutAngle(parts, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function layoutAngle(parts, | ||
+ | var layout = go.GraphObject.make(go.TreeLayout, | ||
+ | { angle: angle, | ||
+ | arrangement: | ||
+ | nodeSpacing: | ||
+ | layerSpacing: | ||
+ | layout.doLayout(parts); | ||
+ | } | ||
+ | |||
+ | function layoutAll() { | ||
+ | var root = myDiagram.findNodeForKey(0); | ||
+ | if (root === null) return; | ||
+ | myDiagram.startTransaction(" | ||
+ | // split the nodes and links into two collections | ||
+ | var rightward = new go.Set(go.Part); | ||
+ | var leftward = new go.Set(go.Part); | ||
+ | root.findLinksConnected().each(function(link) { | ||
+ | var child = link.toNode; | ||
+ | if (child.data.dir === " | ||
+ | leftward.add(root); | ||
+ | leftward.add(link); | ||
+ | leftward.addAll(child.findTreeParts()); | ||
+ | } else { | ||
+ | rightward.add(root); | ||
+ | rightward.add(link); | ||
+ | rightward.addAll(child.findTreeParts()); | ||
+ | } | ||
+ | }); | ||
+ | // do one layout and then the other without moving the shared root node | ||
+ | layoutAngle(rightward, | ||
+ | layoutAngle(leftward, | ||
+ | myDiagram.commitTransaction(" | ||
+ | } | ||
+ | |||
+ | // Show the diagram' | ||
+ | function save() { | ||
+ | document.getElementById(" | ||
+ | myDiagram.isModified = false; | ||
+ | } | ||
+ | function load() { | ||
+ | myDiagram.model = go.Model.fromJson(document.getElementById(" | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | </ |