feat: 后端全量更新 - 含所有本次需求
- Contract.php: 返回合约账户余额(balance_contract) - My.php: 地址管理增加BTC/ETH - AppContract.php: 一键平仓(closeall) - AppProxy.php: 代理专属注册链接 + 分级权限(L1/L2) - site.php: 手续费减半(0.018→0.009) - agent_permission_setup.sql: 代理权限SQL - crypto_news_crawler.py: 新闻自动采集脚本
This commit is contained in:
Executable
+601
@@ -0,0 +1,601 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Flowgrammer</title>
|
||||
<!-- Copyright 1998-2020 by Northwoods Software Corporation. -->
|
||||
<meta name="description" content="An editor for a flowchart-like diagram with a restricted syntax -- add nodes by dropping them onto existing nodes or links." />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<script src="../release/go.js"></script>
|
||||
<script src="../extensions/ParallelLayout.js"></script>
|
||||
<script src="../assets/js/goSamples.js"></script> <!-- this is only for the GoJS Samples framework -->
|
||||
<script>
|
||||
// two custom figures, for "For Each" loops
|
||||
go.Shape.defineFigureGenerator("ForEach", function(shape, w, h) {
|
||||
var param1 = shape ? shape.parameter1 : NaN; // length of triangular area in direction that it is pointing
|
||||
if (isNaN(param1)) param1 = 10;
|
||||
var d = Math.min(h/2, param1);
|
||||
var geo = new go.Geometry();
|
||||
var fig = new go.PathFigure(w, h-d, true);
|
||||
geo.add(fig);
|
||||
fig.add(new go.PathSegment(go.PathSegment.Line, w/2, h));
|
||||
fig.add(new go.PathSegment(go.PathSegment.Line, 0, h-d));
|
||||
fig.add(new go.PathSegment(go.PathSegment.Line, 0, 0));
|
||||
fig.add(new go.PathSegment(go.PathSegment.Line, w, 0).close());
|
||||
geo.spot1 = go.Spot.TopLeft;
|
||||
geo.spot2 = new go.Spot(1, 1, 0, Math.min(-d+2, 0));
|
||||
return geo;
|
||||
});
|
||||
|
||||
go.Shape.defineFigureGenerator("EndForEach", function(shape, w, h) {
|
||||
var param1 = shape ? shape.parameter1 : NaN; // length of triangular area in direction that it is pointing
|
||||
if (isNaN(param1)) param1 = 10;
|
||||
var d = Math.min(h/2, param1);
|
||||
var geo = new go.Geometry();
|
||||
var fig = new go.PathFigure(w, d, true);
|
||||
geo.add(fig);
|
||||
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, d));
|
||||
fig.add(new go.PathSegment(go.PathSegment.Line, w/2, 0).close());
|
||||
geo.spot1 = new go.Spot(0, 0, 0, Math.min(d, 0));
|
||||
geo.spot2 = go.Spot.BottomRight;
|
||||
return geo;
|
||||
});
|
||||
|
||||
function init() {
|
||||
if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this
|
||||
var $ = go.GraphObject.make;
|
||||
|
||||
// initialize main Diagram
|
||||
myDiagram =
|
||||
$(go.Diagram, "myDiagramDiv",
|
||||
{
|
||||
allowMove: false,
|
||||
allowCopy: false,
|
||||
"SelectionDeleting": function(e) { // before a delete happens
|
||||
// handle deletions by excising the node and reconnecting the link where the node had been
|
||||
new go.List(e.diagram.selection).each(function(part) { deletingNode(part); });
|
||||
},
|
||||
layout: $(ParallelLayout, { angle: 90, layerSpacing: 21, nodeSpacing: 30 }),
|
||||
"ExternalObjectsDropped": function(e) { // handle drops from the Palette
|
||||
var newnode = e.diagram.selection.first();
|
||||
if (!newnode) return;
|
||||
if (!(newnode instanceof go.Group) && newnode.linksConnected.count === 0) {
|
||||
// when the selection is dropped but not hooked up to the rest of the graph, delete it
|
||||
e.diagram.removeParts(e.diagram.selection, false);
|
||||
} else {
|
||||
e.diagram.commandHandler.scrollToPart(newnode);
|
||||
}
|
||||
},
|
||||
"undoManager.isEnabled": true
|
||||
});
|
||||
|
||||
// dragged nodes are translucent so that the user can see highlighting of links and nodes
|
||||
myDiagram.findLayer("Tool").opacity = 0.5;
|
||||
|
||||
// some common styles for most of the node templates
|
||||
function nodeStyle() {
|
||||
return {
|
||||
deletable: false,
|
||||
locationSpot: go.Spot.Center,
|
||||
mouseDragEnter: function(e, node) {
|
||||
var sh = node.findObject("SHAPE");
|
||||
if (sh) sh.fill = "lime";
|
||||
},
|
||||
mouseDragLeave: function(e, node) {
|
||||
var sh = node.findObject("SHAPE");
|
||||
if (sh) sh.fill = "white";
|
||||
},
|
||||
mouseDrop: dropOntoNode
|
||||
};
|
||||
}
|
||||
|
||||
function shapeStyle() {
|
||||
return { name: "SHAPE", fill: "white" };
|
||||
}
|
||||
|
||||
function textStyle() {
|
||||
return [
|
||||
{ name: "TEXTBLOCK", textAlign: "center", editable: true },
|
||||
new go.Binding("text").makeTwoWay()
|
||||
];
|
||||
}
|
||||
|
||||
// define the Node templates
|
||||
myDiagram.nodeTemplate = // regular action steps
|
||||
$(go.Node, "Auto", nodeStyle(),
|
||||
{ deletable: true }, // override nodeStyle()
|
||||
{ minSize: new go.Size(10, 20) },
|
||||
$(go.Shape, shapeStyle()),
|
||||
$(go.TextBlock, textStyle(),
|
||||
{ margin: 4 })
|
||||
);
|
||||
|
||||
myDiagram.nodeTemplateMap.add("Start",
|
||||
$(go.Node, "Auto", nodeStyle(),
|
||||
{ desiredSize: new go.Size(32, 32) },
|
||||
$(go.Shape, "Circle", shapeStyle()),
|
||||
$(go.TextBlock, textStyle(), "Start")
|
||||
));
|
||||
|
||||
myDiagram.nodeTemplateMap.add("End",
|
||||
$(go.Node, "Auto", nodeStyle(),
|
||||
{ desiredSize: new go.Size(32, 32) },
|
||||
$(go.Shape, "Circle", shapeStyle()),
|
||||
$(go.TextBlock, textStyle(), "End")
|
||||
));
|
||||
|
||||
myDiagram.nodeTemplateMap.add("For",
|
||||
$(go.Node, "Auto", nodeStyle(),
|
||||
{ minSize: new go.Size(64, 32) },
|
||||
$(go.Shape, "ForEach", shapeStyle()),
|
||||
$(go.TextBlock, textStyle(), "For Each",
|
||||
{ margin: 4 })
|
||||
));
|
||||
|
||||
myDiagram.nodeTemplateMap.add("EndFor",
|
||||
$(go.Node, nodeStyle(),
|
||||
$(go.Shape, "EndForEach", shapeStyle(),
|
||||
{ desiredSize: new go.Size(4, 4) })
|
||||
));
|
||||
|
||||
myDiagram.nodeTemplateMap.add("While",
|
||||
$(go.Node, "Auto", nodeStyle(),
|
||||
{ minSize: new go.Size(32, 32) },
|
||||
$(go.Shape, "ForEach", shapeStyle(),
|
||||
{ angle: -90, spot2: new go.Spot(1, 1, -6, 0) }),
|
||||
$(go.TextBlock, textStyle(), "While",
|
||||
{ margin: 4 })
|
||||
));
|
||||
|
||||
myDiagram.nodeTemplateMap.add("EndWhile",
|
||||
$(go.Node, nodeStyle(),
|
||||
$(go.Shape, "Circle", shapeStyle(),
|
||||
{ desiredSize: new go.Size(4, 4) })
|
||||
));
|
||||
|
||||
myDiagram.nodeTemplateMap.add("If",
|
||||
$(go.Node, "Auto", nodeStyle(),
|
||||
{ minSize: new go.Size(64, 32) },
|
||||
$(go.Shape, "Diamond", shapeStyle()),
|
||||
$(go.TextBlock, textStyle(), "If")
|
||||
));
|
||||
|
||||
myDiagram.nodeTemplateMap.add("EndIf",
|
||||
$(go.Node, nodeStyle(),
|
||||
$(go.Shape, "Diamond", shapeStyle(),
|
||||
{ desiredSize: new go.Size(4, 4) })
|
||||
));
|
||||
|
||||
myDiagram.nodeTemplateMap.add("Switch",
|
||||
$(go.Node, "Auto", nodeStyle(),
|
||||
{ minSize: new go.Size(64, 32) },
|
||||
$(go.Shape, "TriangleUp", shapeStyle()),
|
||||
$(go.TextBlock, textStyle(), "Switch")
|
||||
));
|
||||
|
||||
myDiagram.nodeTemplateMap.add("Merge",
|
||||
$(go.Node, nodeStyle(),
|
||||
$(go.Shape, "TriangleDown", shapeStyle(),
|
||||
{ desiredSize: new go.Size(4, 4) })
|
||||
));
|
||||
|
||||
function groupColor(cat) {
|
||||
switch (cat) {
|
||||
case "If": return "rgba(255,0,0,0.05)";
|
||||
case "For": return "rgba(0,255,0,0.05)";
|
||||
case "While": return "rgba(0,0,255,0.05)";
|
||||
default: return "rgba(0,0,0,0.05)";
|
||||
}
|
||||
}
|
||||
|
||||
// define the Group template, required but unseen
|
||||
myDiagram.groupTemplate =
|
||||
$(go.Group, "Auto",
|
||||
{
|
||||
locationSpot: go.Spot.Center,
|
||||
avoidableMargin: 10, // extra space on the sides
|
||||
layout: $(ParallelLayout, { angle: 90, layerSpacing: 24, nodeSpacing: 30 }),
|
||||
mouseDragEnter: function(e, group) {
|
||||
var sh = group.findObject("SHAPE");
|
||||
if (sh) { sh.width = Math.max(20, group.actualBounds.width-20); sh.stroke = "lime"; }
|
||||
},
|
||||
mouseDragLeave: function(e, group) {
|
||||
var sh = group.findObject("SHAPE");
|
||||
if (sh) sh.stroke = null;
|
||||
},
|
||||
mouseDrop: dropOntoNode
|
||||
},
|
||||
$(go.Shape, "RoundedRectangle",
|
||||
{ fill: "rgba(0,0,0,0.05)", strokeWidth: 0, spot1: go.Spot.TopLeft, spot2: go.Spot.BottomRight },
|
||||
new go.Binding("fill", "cat", groupColor)),
|
||||
$(go.Placeholder),
|
||||
$(go.Shape, "LineH",
|
||||
{
|
||||
name: "SHAPE",
|
||||
height: 0, alignment: go.Spot.Bottom,
|
||||
stroke: null, strokeWidth: 8
|
||||
})
|
||||
);
|
||||
|
||||
myDiagram.linkTemplate =
|
||||
$(go.Link,
|
||||
{
|
||||
selectable: false,
|
||||
deletable: false,
|
||||
routing: go.Link.Orthogonal, corner: 5,
|
||||
toShortLength: 2,
|
||||
// links cannot be deleted
|
||||
// If a node from the Palette is dragged over this node, its outline will turn green
|
||||
mouseDragEnter: function(e, link) { if (!isLoopBack(link)) link.isHighlighted = true; },
|
||||
mouseDragLeave: function(e, link) { link.isHighlighted = false; },
|
||||
// if a node from the Palette is dropped on a link, the link is replaced by links to and from the new node
|
||||
mouseDrop: dropOntoLink
|
||||
},
|
||||
$(go.Shape, { isPanelMain: true, stroke: "transparent", strokeWidth: 8 },
|
||||
new go.Binding("stroke", "isHighlighted", function(h) { return h ? "lime" : "transparent"; }).ofObject()),
|
||||
$(go.Shape, { isPanelMain: true, stroke: "black", strokeWidth: 1.5 }),
|
||||
$(go.Shape, { toArrow: "Standard", strokeWidth: 0 }),
|
||||
// $(go.TextBlock, { segmentIndex: -2, segmentFraction: 0.75, editable: true },
|
||||
// new go.Binding("text").makeTwoWay(),
|
||||
// new go.Binding("background", "text", function(t) { return t ? "white" : null; }))
|
||||
);
|
||||
|
||||
function isLoopBack(link) {
|
||||
if (!link) return false;
|
||||
if (link.fromNode.containingGroup !== link.toNode.containingGroup) return false;
|
||||
var cat = link.fromNode.category;
|
||||
return (cat === "EndFor" || cat === "EndWhile" || cat === "EndIf");
|
||||
}
|
||||
|
||||
// A node dropped onto a Merge node is spliced into a link coming into that node;
|
||||
// otherwise it is spliced into a link that is coming out of that node.
|
||||
function dropOntoNode(e, oldnode) {
|
||||
if (oldnode instanceof go.Group) {
|
||||
var merge = oldnode.layout.mergeNode;
|
||||
if (merge) {
|
||||
var it = merge.findLinksOutOf();
|
||||
while (it.next()) {
|
||||
var link = it.value;
|
||||
if (link.fromNode.containingGroup !== link.toNode.containingGroup) {
|
||||
dropOntoLink(e, link);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (oldnode instanceof go.Node) {
|
||||
var cat = oldnode.category;
|
||||
if (cat === "Merge" || cat === "End" || cat === "EndFor" || cat === "EndWhile" || cat === "EndIf") {
|
||||
var link = oldnode.findLinksInto().first();
|
||||
if (link) dropOntoLink(e, link);
|
||||
} else {
|
||||
var link = oldnode.findLinksOutOf().first();
|
||||
if (link) dropOntoLink(e, link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Splice a node into a link.
|
||||
// If the new node is of category "For" or "While" or "If", create a Group and splice it in,
|
||||
// and add the new node to that group, and add any other desired nodes and links to that group.
|
||||
function dropOntoLink(e, oldlink) {
|
||||
if (!(oldlink instanceof go.Link)) return;
|
||||
var diagram = e.diagram;
|
||||
var newnode = diagram.selection.first();
|
||||
if (!(newnode instanceof go.Node)) return;
|
||||
if (!newnode.isTopLevel) return;
|
||||
if (isLoopBack(oldlink)) {
|
||||
// can't add nodes into links going back to the "For" node
|
||||
diagram.remove(newnode);
|
||||
return;
|
||||
}
|
||||
|
||||
var fromnode = oldlink.fromNode;
|
||||
var tonode = oldlink.toNode;
|
||||
if (newnode.category === "") { // add simple step into chain of actions
|
||||
newnode.containingGroup = oldlink.containingGroup;
|
||||
// Reconnect the existing link to the new node
|
||||
oldlink.toNode = newnode;
|
||||
// Then add links from the new node to the old node
|
||||
if (newnode.category === "If") {
|
||||
diagram.model.addLinkData({ from: newnode.key, to: tonode.key });
|
||||
diagram.model.addLinkData({ from: newnode.key, to: tonode.key });
|
||||
} else {
|
||||
diagram.model.addLinkData({ from: newnode.key, to: tonode.key });
|
||||
}
|
||||
} else if (newnode.category === "For" || newnode.category === "While") { // add loop group
|
||||
// add group for loop
|
||||
var groupdata = { isGroup: true, cat: newnode.category };
|
||||
diagram.model.addNodeData(groupdata);
|
||||
var group = diagram.findNodeForData(groupdata);
|
||||
group.containingGroup = oldlink.containingGroup;
|
||||
diagram.select(group);
|
||||
|
||||
newnode.containingGroup = group;
|
||||
|
||||
var enddata = { category: "End" + newnode.category };
|
||||
diagram.model.addNodeData(enddata);
|
||||
var endnode = diagram.findNodeForData(enddata);
|
||||
endnode.containingGroup = group;
|
||||
endnode.location = e.documentPoint;
|
||||
|
||||
diagram.model.addLinkData({ from: newnode.key, to: endnode.key });
|
||||
diagram.model.addLinkData({ from: endnode.key, to: newnode.key });
|
||||
|
||||
// Reconnect the existing link to the new node
|
||||
oldlink.toNode = newnode;
|
||||
// Then add a link from the end node to the old node
|
||||
diagram.model.addLinkData({ from: endnode.key, to: tonode.key });
|
||||
} else if (newnode.category === "If") { // add Conditional group
|
||||
// add group for conditional
|
||||
var groupdata = { isGroup: true, cat: newnode.category };
|
||||
diagram.model.addNodeData(groupdata);
|
||||
var group = diagram.findNodeForData(groupdata);
|
||||
group.containingGroup = oldlink.containingGroup;
|
||||
diagram.select(group);
|
||||
|
||||
newnode.containingGroup = group;
|
||||
|
||||
var enddata = { category: "EndIf" };
|
||||
diagram.model.addNodeData(enddata);
|
||||
var endnode = diagram.findNodeForData(enddata);
|
||||
endnode.containingGroup = group;
|
||||
endnode.location = e.documentPoint;
|
||||
|
||||
var truedata = { from: newnode.key, to: endnode.key, text: "true" };
|
||||
diagram.model.addLinkData(truedata);
|
||||
var truelink = diagram.findLinkForData(truedata);
|
||||
var falsedata = { from: newnode.key, to: endnode.key, text: "false" };
|
||||
diagram.model.addLinkData(falsedata);
|
||||
var falselink = diagram.findLinkForData(falsedata);
|
||||
|
||||
// Reconnect the existing link to the new node
|
||||
oldlink.toNode = newnode;
|
||||
// Then add a link from the new node to the old node
|
||||
diagram.model.addLinkData({ from: endnode.key, to: tonode.key });
|
||||
} else if (newnode.category === "Switch") { // add multi-way Switch group
|
||||
// add group for loop
|
||||
var groupdata = { isGroup: true, cat: newnode.category };
|
||||
diagram.model.addNodeData(groupdata);
|
||||
var group = diagram.findNodeForData(groupdata);
|
||||
group.containingGroup = oldlink.containingGroup;
|
||||
diagram.select(group);
|
||||
|
||||
newnode.containingGroup = group;
|
||||
|
||||
var enddata = { category: "Merge" };
|
||||
diagram.model.addNodeData(enddata);
|
||||
var endnode = diagram.findNodeForData(enddata);
|
||||
endnode.containingGroup = group;
|
||||
endnode.location = e.documentPoint;
|
||||
|
||||
var yesdata = { text: "yes,\ndo it" };
|
||||
diagram.model.addNodeData(yesdata);
|
||||
var yesnode = diagram.findNodeForData(yesdata);
|
||||
yesnode.containingGroup = group;
|
||||
yesnode.location = e.documentPoint;
|
||||
diagram.model.addLinkData({ from: newnode.key, to: yesnode.key, text: "yes" });
|
||||
diagram.model.addLinkData({ from: yesnode.key, to: endnode.key });
|
||||
|
||||
var nodata = { text: "no,\ndon't" };
|
||||
diagram.model.addNodeData(nodata);
|
||||
var nonode = diagram.findNodeForData(nodata);
|
||||
nonode.containingGroup = group;
|
||||
nonode.location = e.documentPoint;
|
||||
diagram.model.addLinkData({ from: newnode.key, to: nonode.key, text: "no" });
|
||||
diagram.model.addLinkData({ from: nonode.key, to: endnode.key });
|
||||
|
||||
var maybedata = { text: "??" };
|
||||
diagram.model.addNodeData(maybedata);
|
||||
var maybenode = diagram.findNodeForData(maybedata);
|
||||
maybenode.containingGroup = group;
|
||||
maybenode.location = e.documentPoint;
|
||||
diagram.model.addLinkData({ from: newnode.key, to: maybenode.key, text: "maybe" });
|
||||
diagram.model.addLinkData({ from: maybenode.key, to: endnode.key });
|
||||
|
||||
// Reconnect the existing link to the new node
|
||||
oldlink.toNode = newnode;
|
||||
// Then add a link from the end node to the old node
|
||||
diagram.model.addLinkData({ from: endnode.key, to: tonode.key });
|
||||
}
|
||||
diagram.layoutDiagram(true);
|
||||
}
|
||||
|
||||
function deletingNode(node) { // excise node from the chain that it is in
|
||||
if (!(node instanceof go.Node)) return;
|
||||
if (node instanceof go.Group) {
|
||||
var externals = node.findExternalLinksConnected();
|
||||
var next = null;
|
||||
externals.each(function(link) {
|
||||
if (link.fromNode.isMemberOf(node)) next = link.toNode;
|
||||
});
|
||||
if (next) {
|
||||
externals.each(function(link) {
|
||||
if (link.toNode.isMemberOf(node)) link.toNode = next;
|
||||
});
|
||||
}
|
||||
} else if (node.category === "") {
|
||||
var next = node.findNodesOutOf().first();
|
||||
if (next) {
|
||||
new go.List(node.findLinksInto()).each(function(link) { link.toNode = next; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialize Palette
|
||||
myPalette =
|
||||
$(go.Palette, "myPaletteDiv",
|
||||
{
|
||||
maxSelectionCount: 1,
|
||||
nodeTemplateMap: myDiagram.nodeTemplateMap,
|
||||
model: new go.GraphLinksModel([
|
||||
{ text: "Action" },
|
||||
{ text: "For Each", category: "For" },
|
||||
{ text: "While", category: "While" },
|
||||
{ text: "If", category: "If" },
|
||||
{ text: "Switch", category: "Switch" }
|
||||
])
|
||||
});
|
||||
|
||||
// initialize Overview
|
||||
myOverview =
|
||||
$(go.Overview, "myOverviewDiv",
|
||||
{
|
||||
observed: myDiagram,
|
||||
contentAlignment: go.Spot.Center
|
||||
});
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
// save a model to and load a model from Json text, displayed below the Diagram
|
||||
function save() {
|
||||
var str = myDiagram.model.toJson();
|
||||
document.getElementById("mySavedModel").value = str;
|
||||
}
|
||||
function load() {
|
||||
var str = document.getElementById("mySavedModel").value;
|
||||
myDiagram.model = go.Model.fromJson(str);
|
||||
}
|
||||
function newDiagram() {
|
||||
myDiagram.model = go.GraphObject.make(go.GraphLinksModel,
|
||||
{
|
||||
nodeDataArray:
|
||||
[
|
||||
{"key":1, "text":"S", "category":"Start"},
|
||||
{"key":2, "text":"E", "category":"End"}
|
||||
],
|
||||
linkDataArray:
|
||||
[
|
||||
{"from":1, "to":2}
|
||||
]
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Use a Flexbox to make the Palette/Overview/Diagram responsive and size things relatively */
|
||||
#myFlexDiv {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
}
|
||||
#myPODiv {
|
||||
display: flex;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
#myFlexDiv {
|
||||
flex-flow: row;
|
||||
}
|
||||
#myPODiv {
|
||||
width: 105px;
|
||||
height: 100%;
|
||||
margin-right: 3px;
|
||||
flex-flow: column;
|
||||
}
|
||||
#myPaletteDiv {
|
||||
height: 80%;
|
||||
}
|
||||
#myOverviewDiv {
|
||||
margin-top: 3px;
|
||||
flex: 1;
|
||||
}
|
||||
#myDiagramDiv {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
#myFlexDiv {
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
}
|
||||
#myPODiv {
|
||||
width: 90%;
|
||||
height: 105px;
|
||||
margin-bottom: 3px;
|
||||
flex-flow: row;
|
||||
}
|
||||
#myPaletteDiv {
|
||||
width: 75%;
|
||||
}
|
||||
#myOverviewDiv {
|
||||
margin-left: 3px;
|
||||
flex: 1;
|
||||
}
|
||||
#myDiagramDiv {
|
||||
width: 90%;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<div id="sample">
|
||||
<div id="myFlexDiv">
|
||||
<div id="myPODiv">
|
||||
<div id="myPaletteDiv" style="background-color: floralwhite; border: solid 1px black"></div>
|
||||
<div id="myOverviewDiv" style="background-color: whitesmoke; border: solid 1px black"></div>
|
||||
</div>
|
||||
<div id="myDiagramDiv" style="border: solid 1px black"></div>
|
||||
</div>
|
||||
<p>
|
||||
The Flowgrammer sample demonstrates how one can build a flowchart with a constrained syntax.
|
||||
You can drag and drop Nodes onto Links and Nodes in the diagram in order to splice them into the graph.
|
||||
There is visual feedback during the dragging process.
|
||||
Nodes dropped onto the diagram's background are automatically deleted.
|
||||
Edit text by clicking on the text of selected nodes.
|
||||
Deleting an action or step Node excises it from the chain of steps that it is in.
|
||||
The "For", "While", and "If" are not deletable, but you can select and delete the Group holding the
|
||||
whole body of the loop or conditional.
|
||||
The "Start" and "End" nodes and Links are not deletable.
|
||||
</p>
|
||||
<p>
|
||||
The automatic layout of the diagram is accomplished with the <a>ParallelLayout</a> extension.
|
||||
</p>
|
||||
<div id="buttons">
|
||||
<button id="loadModel" onclick="load()">Load</button>
|
||||
<button id="saveModel" onclick="save()">Save</button>
|
||||
<button onclick="newDiagram()">New Diagram</button>
|
||||
</div>
|
||||
<textarea id="mySavedModel" style="width:100%;height:200px">
|
||||
{ "class": "GraphLinksModel",
|
||||
"nodeDataArray": [
|
||||
{"key":1, "text":"S", "category":"Start"},
|
||||
{"key":-1, "isGroup":true, "cat":"For"},
|
||||
{"key":2, "text":"For Each", "category":"For", "group":-1},
|
||||
{"key":3, "text":"Action 1", "group":-1},
|
||||
{"key":-2, "isGroup":true, "cat":"If", "group":-1},
|
||||
{"key":4, "text":"If", "category":"If", "group":-2},
|
||||
{"key":5, "text":"Action 2", "group":-2},
|
||||
{"key":6, "text":"Action 3", "group":-2},
|
||||
{"key":-3, "isGroup":true, "cat":"For", "group":-2},
|
||||
{"key":7, "text":"For Each\n(nested)", "category":"For", "group":-3},
|
||||
{"key":8, "text":"Action 4", "group":-3},
|
||||
{"key":9, "text":"", "category":"EndFor", "group":-3},
|
||||
{"key":10, "text":"", "category":"EndIf", "group":-2},
|
||||
{"key":11, "text":"Action 5", "group":-1},
|
||||
{"key":12, "text":"", "category":"EndFor", "group":-1},
|
||||
{"key":13, "text":"E", "category":"End"}
|
||||
],
|
||||
"linkDataArray": [
|
||||
{"from":1, "to":2},
|
||||
{"from":2, "to":3},
|
||||
{"from":3, "to":4},
|
||||
{"from":4, "to":5, "text":"true"},
|
||||
{"from":4, "to":6, "text":"false"},
|
||||
{"from":6, "to":7},
|
||||
{"from":7, "to":8},
|
||||
{"from":8, "to":9},
|
||||
{"from":5, "to":10},
|
||||
{"from":9, "to":10},
|
||||
{"from":9, "to":7},
|
||||
{"from":10, "to":11},
|
||||
{"from":11, "to":12},
|
||||
{"from":12, "to":2},
|
||||
{"from":12, "to":13}
|
||||
]}
|
||||
</textarea>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user