gojs实现流程图(含绑定某数据)
作者:互联网
首先引用go-debug.js https://download.csdn.net/download/qq_37528703/12038175
html示例1:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Draggable Link</title>
<meta name="description" content="Drag a link to reconnect it. Nodes have custom Adornments for selection, resizing, and reshaping." />
<!-- Copyright 1998-2017 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<link type="text/css" rel="stylesheet" href="/syyj/jslib/miniui/themes/default/miniui.css" />
<script type="text/javascript" src="../js/go-debug.js"></script>
<script type="text/javascript" src="/syyj/jslib/jquery/jquery-1.8.3-min.js"></script>
<script type="text/javascript" src="/syyj/jslib/miniui/miniui.js"></script>
<script id="code">
var yaid;
function init() {
if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this
var objGo = go.GraphObject.make; // for conciseness in defining templates
myDiagram =
objGo(go.Diagram, "myDiagramDiv", // must name or refer to the DIV HTML element
{
grid: objGo(go.Panel, "Grid",
objGo(go.Shape, "LineH", { stroke: "lightgray", strokeWidth: 0.5 }),
objGo(go.Shape, "LineH", { stroke: "gray", strokeWidth: 0.5, interval: 10 }),
objGo(go.Shape, "LineV", { stroke: "lightgray", strokeWidth: 0.5 }),
objGo(go.Shape, "LineV", { stroke: "gray", strokeWidth: 0.5, interval: 10 })
),
allowDrop: true, // must be true to accept drops from the Palette
"draggingTool.dragsLink": true,
"draggingTool.isGridSnapEnabled": true,
"linkingTool.isUnconnectedLinkValid": true,
"linkingTool.portGravity": 20,
"relinkingTool.isUnconnectedLinkValid": true,
"relinkingTool.portGravity": 20,
"relinkingTool.fromHandleArchetype":
objGo(go.Shape, "Diamond", { segmentIndex: 0, cursor: "pointer", desiredSize: new go.Size(8, 8), fill: "tomato", stroke: "darkred" }),
"relinkingTool.toHandleArchetype":
objGo(go.Shape, "Diamond", { segmentIndex: -1, cursor: "pointer", desiredSize: new go.Size(8, 8), fill: "darkred", stroke: "tomato" }),
"linkReshapingTool.handleArchetype":
objGo(go.Shape, "Diamond", { desiredSize: new go.Size(7, 7), fill: "lightblue", stroke: "deepskyblue" }),
rotatingTool: objGo(TopRotatingTool), // defined below
"rotatingTool.snapAngleMultiple": 15,
"rotatingTool.snapAngleEpsilon": 15,
"undoManager.isEnabled": true,
"LinkDrawn": showLinkLabel, // this DiagramEvent listener is defined below
"LinkRelinked": showLinkLabel,
});
// when the document is modified, add a "*" to the title and enable the "Save" button
myDiagram.addDiagramListener("Modified", function(e) {
var button = document.getElementById("SaveButton");
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, idx);
}
});
// Define a function for creating a "port" that is normally transparent.
// The "name" is used as the GraphObject.portId, the "spot" is used to control how links connect
// and where the port is positioned on the node, and the boolean "output" and "input" arguments
// control whether the user can draw links from or to the port.
function makePort(name, spot, output, input) {
// the port is basically just a small transparent square
return objGo(go.Shape, "Circle",
{
fill: null, // not seen, by default; set to a translucent gray by showSmallPorts, defined below
stroke: null,
desiredSize: new go.Size(7, 7),
alignment: spot, // align the port on the main Shape
alignmentFocus: spot, // just inside the Shape
portId: name, // declare this object to be a "port"
fromSpot: spot, toSpot: spot, // declare where links may connect at this port
fromLinkable: output, toLinkable: input, // declare whether the user may draw links to/from here
cursor: "pointer" // show a different cursor to indicate potential link point
});
}
var nodeSelectionAdornmentTemplate =
objGo(go.Adornment, "Auto",
objGo(go.Shape, { fill: null, stroke: "deepskyblue", strokeWidth: 1.5, strokeDashArray: [4, 2] }),
objGo(go.Placeholder)
);
var nodeResizeAdornmentTemplate =
objGo(go.Adornment, "Spot",
{ locationSpot: go.Spot.Right },
objGo(go.Placeholder),
objGo(go.Shape, { alignment: go.Spot.TopLeft, cursor: "nw-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
objGo(go.Shape, { alignment: go.Spot.Top, cursor: "n-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
objGo(go.Shape, { alignment: go.Spot.TopRight, cursor: "ne-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
objGo(go.Shape, { alignment: go.Spot.Left, cursor: "w-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
objGo(go.Shape, { alignment: go.Spot.Right, cursor: "e-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
objGo(go.Shape, { alignment: go.Spot.BottomLeft, cursor: "se-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
objGo(go.Shape, { alignment: go.Spot.Bottom, cursor: "s-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" }),
objGo(go.Shape, { alignment: go.Spot.BottomRight, cursor: "sw-resize", desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "deepskyblue" })
);
var nodeRotateAdornmentTemplate =
objGo(go.Adornment,
{ locationSpot: go.Spot.Center, locationObjectName: "CIRCLE" },
objGo(go.Shape, "Circle", { name: "CIRCLE", cursor: "pointer", desiredSize: new go.Size(7, 7), fill: "lightblue", stroke: "deepskyblue" }),
objGo(go.Shape, { geometryString: "M3.5 7 L3.5 30", isGeometryPositioned: true, stroke: "deepskyblue", strokeWidth: 1.5, strokeDashArray: [4, 2] })
);
myDiagram.nodeTemplate =
objGo(go.Node, "Spot",
{ locationSpot: go.Spot.Center },
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
{ selectable: true, selectionAdornmentTemplate: nodeSelectionAdornmentTemplate },
{ resizable: true, resizeObjectName: "PANEL", resizeAdornmentTemplate: nodeResizeAdornmentTemplate },
{ rotatable: true, rotateAdornmentTemplate: nodeRotateAdornmentTemplate },
new go.Binding("angle").makeTwoWay(),
// the main object is a Panel that surrounds a TextBlock with a Shape
objGo(go.Panel, "Auto",
{ name: "PANEL" },
new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
objGo(go.Shape, "Rectangle", // default figure
{
portId: "", // the default port: if no spot on link data, use closest side
fromLinkable: true, toLinkable: true, cursor: "pointer",
fill: "white", // default color
strokeWidth: 2
},
new go.Binding("figure"),
new go.Binding("fill")),
objGo(go.TextBlock,
{
font: "bold 11pt Helvetica, Arial, sans-serif",
margin: 8,
maxSize: new go.Size(160, NaN),
wrap: go.TextBlock.WrapFit,
editable: true
},
new go.Binding("text").makeTwoWay())
),
// four small named ports, one on each side:
makePort("T", go.Spot.Top, false, true),
makePort("L", go.Spot.Left, true, true),
makePort("R", go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, true, false),
{ // handle mouse enter/leave events to show/hide the ports
mouseEnter: function(e, node) { showSmallPorts(node, true); },
mouseLeave: function(e, node) { showSmallPorts(node, false); }
}
);
function showSmallPorts(node, show) {
node.ports.each(function(port) {
if (port.portId !== "") { // don't change the default port, which is the big shape
port.fill = show ? "rgba(0,0,0,.3)" : null;
}
});
}
var linkSelectionAdornmentTemplate =
objGo(go.Adornment, "Link",
objGo(go.Shape,
// isPanelMain declares that this Shape shares the Link.geometry
{ isPanelMain: true, fill: null, stroke: "deepskyblue", strokeWidth: 0 }) // use selection object's strokeWidth
);
myDiagram.linkTemplate =
objGo(go.Link, // the whole link panel
{ selectable: true, selectionAdornmentTemplate: linkSelectionAdornmentTemplate },
{ relinkableFrom: true, relinkableTo: true, reshapable: true },
{
routing: go.Link.AvoidsNodes,
curve: go.Link.JumpOver,
corner: 5,
toShortLength: 4
},
new go.Binding("points").makeTwoWay(),
objGo(go.Shape, // the link path shape
{ isPanelMain: true, strokeWidth: 2 }),
objGo(go.Shape, // the arrowhead
{ toArrow: "Standard", stroke: null }),
objGo(go.Panel, "Auto", // the link label, normally not visible
{ visible: false, name: "LABEL", segmentIndex: 2, segmentFraction: 0.5 },
new go.Binding("visible", "visible").makeTwoWay(),
objGo(go.Shape, "RoundedRectangle", // the label shape
{ fill: "#F8F8F8", strokeWidth: 0 }),
objGo(go.TextBlock,"???" , // the label
{
textAlign: "center",
font: "10pt helvetica, arial, sans-serif",
stroke: "#333333",
editable: true
},
new go.Binding("text").makeTwoWay())
)
);
function showLinkLabel(e) {
var label = e.subject.findObject("LABEL");
if (label !== null) label.visible = (e.subject.fromNode.data.figure === "Diamond");
}
// initialize the Palette that is on the left side of the page
myPalette =
objGo(go.Palette, "myPaletteDiv", // must name or refer to the DIV HTML element
{
maxSelectionCount: 1,
nodeTemplateMap: myDiagram.nodeTemplateMap, // share the templates used by myDiagram
linkTemplate: // simplify the link template, just in this Palette
objGo(go.Link,
{ // because the GridLayout.alignment is Location and the nodes have locationSpot == Spot.Center,
// to line up the Link in the same manner we have to pretend the Link has the same location spot
locationSpot: go.Spot.Center,
selectionAdornmentTemplate:
objGo(go.Adornment, "Link",
{ locationSpot: go.Spot.Center },
objGo(go.Shape,
{ isPanelMain: true, fill: null, stroke: "deepskyblue", strokeWidth: 0 }),
objGo(go.Shape, // the arrowhead
{ toArrow: "Standard", stroke: null })
)
},
{
routing: go.Link.AvoidsNodes,
curve: go.Link.JumpOver,
corner: 5,
toShortLength: 4
},
new go.Binding("points"),
objGo(go.Shape, // the link path shape
{ isPanelMain: true, strokeWidth: 2 }),
objGo(go.Shape, // the arrowhead
{ toArrow: "Standard", stroke: null })
),
model: new go.GraphLinksModel([ // specify the contents of the Palette
{ text: "Start", figure: "RoundedRectangle", fill: "#00AD5F" },
{ text: "Step", figure:"Rectangle",fill: "lightyellow" },
{ text: "Sel", figure: "Diamond", fill: "lightskyblue" },
{ text: "End", figure: "RoundedRectangle", fill: "#CE0620" },
], [
// the Palette also has a disconnected Link, which the user can drag-and-drop
{ points: new go.List(go.Point).addAll([new go.Point(0, 0), new go.Point(30, 0), new go.Point(30, 40), new go.Point(60, 40)]) }
])
});
}
function TopRotatingTool() {
go.RotatingTool.call(this);
}
go.Diagram.inherit(TopRotatingTool, go.RotatingTool);
//获取url路径前缀
function getAddress() {
var curWWWPath = window.document.location.href;
var pathname = window.document.location.pathname;
var pos = curWWWPath.indexOf(pathname);
var localhostPath = curWWWPath.substring(0, pos);
return localhostPath+"/syyj";
}
/** @override */
TopRotatingTool.prototype.updateAdornments = function(part) {
go.RotatingTool.prototype.updateAdornments.call(this, part);
var adornment = part.findAdornment("Rotating");
if (adornment !== null) {
adornment.location = part.rotateObject.getDocumentPoint(new go.Spot(0.5, 0, 0, -30)); // above middle top
}
};
/** @override */
TopRotatingTool.prototype.rotate = function(newangle) {
go.RotatingTool.prototype.rotate.call(this, newangle + 90);
};
// end of TopRotatingTool class
//初始化流程图
function SetData(data){
yaid = data.yaid;
$.ajax({
url: getAddress()+"/sjzx/szya/queryLct?yaid="+data.yaid,
dataType: "json",
async: false,
success: function (data) {
load(data);
},
error: function (e) {
}
})
if(data.state=='0'){
$("#saveBut").show();
}
}
// Show the diagram's model in JSON format that the user may edit
function save() {
saveDiagramProperties(); // do this first, before writing to JSON
var model = myDiagram.model.toJson();
model=JSON.parse(model);
for(var i=0;i<model.linkDataArray.length;i++){
if((!model.linkDataArray[i].hasOwnProperty("from"))||(!model.linkDataArray[i].hasOwnProperty("to"))){
mini.alert("所有线段必须全部连接!");
return
}
}
var linkString = JSON.stringify(model.linkDataArray);
var nodeString = JSON.stringify(model.nodeDataArray);
var position = model.modelData.position;
myDiagram.isModified = false;
$.ajax({
url: getAddress()+"/sjzx/szya/saveLct",
dataType: "json",
data:{"linkString":linkString,"nodeString":nodeString,"position":position,"yaid":yaid},
async: false,
success: function (data) {
mini.alert(data.msg);
},
error: function (e) {
mini.alert("保存失败!");
}
})
}
function load(data) {
myDiagram.model = go.Model.fromJson(data);
loadDiagramProperties(); // do this after the Model.modelData has been brought into memory
}
function saveDiagramProperties() {
myDiagram.model.modelData.position = go.Point.stringify(myDiagram.position);
}
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);
}
</script>
</head>
<body οnlοad="init()">
<div id="sample">
<div style="width:100%; white-space:nowrap;">
<span style="display: inline-block; vertical-align: top; width:105px">
<div id="myPaletteDiv" style="border: solid 1px black; height: 650px"></div>
</span>
<span style="display: inline-block; vertical-align: top; width:90%">
<div id="myDiagramDiv" style="border: solid 1px black; height: 650px"></div>
</span>
</div>
<div id="saveBut" style="display: none;">
<button id="SaveButton" style="width:100px;height:30px;float: right;margin-right: 45%;margin-top: 10px;" οnclick="save()">保存</button>
</div>
</div>
</body>
</html>
java部分
controller
@RequestMapping("/saveLct")
@ResponseBody
public Map<String,Object> saveLct(@RequestParam Map<String,Object> map){ return szyaService.saveLct(map); }
service
//查询流程图
Map<String, Object> queryLct(Map<String, Object> map);
//保存流程图
Map<String, Object> saveLct(Map<String, Object> map);
serviceimpl
@Override
public Map<String,Object> queryLct(Map<String,Object> map){
Map<String,Object> resMap = new HashMap<String, Object>();
Map<String,Object> posMap = new HashMap<String, Object>();
List<Map<String,Object>> nodeList = szyaDao.queryNodeList(map);
List<Map<String,Object>> linkList = szyaDao.queryLinkList(map);
if(nodeList.size()!=0) {
for (int i = 0; i < nodeList.size(); i++) {
if (nodeList.get(i).get("size") == null) {
nodeList.get(i).remove("size");
}
nodeList.get(i).put("key", nodeList.get(i).get("key1"));
}
posMap.put("position", nodeList.get(0).get("position"));
resMap.put("modelData",posMap);
}
if(linkList.size()!=0) {
for (int i = 0; i < linkList.size(); i++) {
String[] pointsArry = null;
String pointsString = (String) linkList.get(i).get("points");
pointsArry = pointsString.split(",");
Double[] pointsDArray = new Double[pointsArry.length];
for (int j = 0; j < pointsArry.length; j++) {
pointsDArray[j] = Double.parseDouble(pointsArry[j]);
}
linkList.get(i).put("points", pointsDArray);
linkList.get(i).put("from", linkList.get(i).get("from1"));
linkList.get(i).put("to", linkList.get(i).get("to1"));
if (linkList.get(i).get("text") == null) {
linkList.get(i).remove("text");
}
linkList.get(i).put("visible",linkList.get(i).get("visible").equals("true")?true:false);
}
}
resMap.put("class","GraphLinksModel");
resMap.put("linkFromPortIdProperty","fromPort");
resMap.put("linkToPortIdProperty","toPort");
resMap.put("nodeDataArray",nodeList);
resMap.put("linkDataArray",linkList);
return resMap;
}
@Override
public Map<String,Object> saveLct(Map<String,Object> map){
Map<String,Object> resMap = new HashMap<String, Object>();
resMap.put("msg","保存成功!");
JSONArray jsonArray = JSONArray.fromObject(map.get("linkString"));
List<Map<String,Object>> linkList=(List<Map<String,Object>>)JSONArray.toCollection(jsonArray, Map.class);
JSONArray jsonArray2 = JSONArray.fromObject(map.get("nodeString"));
List<Map<String,Object>> nodeList=(List<Map<String,Object>>)JSONArray.toCollection(jsonArray2, Map.class);
try {
szyaDao.removeNodeList(map);
for (Map<String, Object> m : nodeList) {
m.put("position",(String)map.get("position"));
m.put("yaid", map.get("yaid"));
szyaDao.saveNodeList(m);
}
szyaDao.removeLinkList(map);
for (Map<String, Object> m : linkList) {
m.put("yaid", map.get("yaid"));
String str="";
List<Double> dlist = (List<Double>)m.get("points");
for(int i=0;i<dlist.size();i++){
if(i==dlist.size()-1) {
str += dlist.get(i);
}else{
str += dlist.get(i) + ",";
}
}
m.put("points",str);
szyaDao.saveLinkList(m);
}
}catch (Exception e){
e.printStackTrace();
resMap.put("msg","保存失败!");
return resMap;
}
return resMap;
}
dao
List<Map<String,Object>> queryNodeList(Map<String,Object> map);
List<Map<String,Object>> queryLinkList(Map<String,Object> map);
void saveLinkList(Map<String,Object> map);
void saveNodeList(Map<String,Object> map);
void removeLinkList(Map<String,Object> map);
void removeNodeList(Map<String,Object> map);
daoimpl
@Override
public List<Map<String, Object>> queryNodeList(Map<String, Object> map){
StringBuffer sql = new StringBuffer();
sql.append("select * from szya_lct_node where yaid = #{yaid}");
return this.queryForList(sql.toString(),map);
}
@Override
public List<Map<String, Object>> queryLinkList(Map<String, Object> map){
StringBuffer sql = new StringBuffer();
sql.append("select * from szya_lct_link where yaid = #{yaid}");
return this.queryForList(sql.toString(),map);
}
@Override
public void saveNodeList(Map<String,Object> map){
StringBuffer sql = new StringBuffer();
map.put("id",Md5Util.UUID());
if (ObjectUtils.isEmpty(map.get("size"))) {
map.put("size1",null);
}
map.put("size1",map.get("size"));
sql.append("insert into szya_lct_node (id,text,figure,fill,key1,size,loc,position,yaid) ");
sql.append("values(#{id},#{text},#{figure},#{fill},#{key},#{size1},#{loc},#{position},#{yaid})");
this.update(sql.toString(),map);
}
@Override
public void saveLinkList(Map<String,Object> map){
StringBuffer sql = new StringBuffer();
map.put("id",Md5Util.UUID());
if (ObjectUtils.isEmpty(map.get("text"))) {
map.put("text",null);
}
if (ObjectUtils.isEmpty(map.get("fromPort"))) {
map.put("fromPort",null);
}
if (ObjectUtils.isEmpty(map.get("toPort"))) {
map.put("toPort",null);
}
if (ObjectUtils.isEmpty(map.get("visible"))) {
map.put("visible","false");
}else{
map.put("visible","true");
}
sql.append("insert into szya_lct_link (id,text,visible,points,from1,to1,fromPort,toPort,yaid) ");
sql.append("values(#{id},#{text},#{visible},#{points},#{from},#{to},#{fromPort},#{toPort},#{yaid})");
this.update(sql.toString(),map);
}
@Override
public void removeNodeList(Map<String,Object> map){
StringBuffer sql = new StringBuffer();
sql.append("delete from szya_lct_node where yaid=#{yaid}");
this.update(sql.toString(),map);
}
@Override
public void removeLinkList(Map<String,Object> map){
StringBuffer sql = new StringBuffer();
sql.append("delete from szya_lct_link where yaid=#{yaid}");
this.update(sql.toString(),map);
}
示例1效果图
html示例2
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Flowchart</title>
<meta name="description" content="Interactive flowchart diagram implemented by GoJS in JavaScript for HTML." />
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
<script src="../js/go-debug.js"></script>
<link href='https://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
<!-- this is only for the GoJS Samples framework -->
<script id="code">
function init() {
if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this
var $ = go.GraphObject.make; // for conciseness in defining templates
myDiagram =
$(go.Diagram, "myDiagramDiv", // must name or refer to the DIV HTML element
{
"LinkDrawn": showLinkLabel, // this DiagramEvent listener is defined below
"LinkRelinked": showLinkLabel,
"undoManager.isEnabled": true // enable undo & redo
});
// when the document is modified, add a "*" to the title and enable the "Save" button
myDiagram.addDiagramListener("Modified", function(e) {
var button = document.getElementById("SaveButton");
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, idx);
}
});
// helper definitions for node templates
function nodeStyle() {
return [
// The Node.location comes from the "loc" property of the node data,
// converted by the Point.parse static method.
// If the Node.location is changed, it updates the "loc" property of the node data,
// converting back using the Point.stringify static method.
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
{
// the Node.location is at the center of each node
locationSpot: go.Spot.Center
}
];
}
// Define a function for creating a "port" that is normally transparent.
// The "name" is used as the GraphObject.portId,
// the "align" is used to determine where to position the port relative to the body of the node,
// the "spot" is used to control how links connect with the port and whether the port
// stretches along the side of the node,
// and the boolean "output" and "input" arguments control whether the user can draw links from or to the port.
function makePort(name, align, spot, output, input) {
var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);
// the port is basically just a transparent rectangle that stretches along the side of the node,
// and becomes colored when the mouse passes over it
return $(go.Shape,
{
fill: "transparent", // changed to a color in the mouseEnter event handler
strokeWidth: 0, // no stroke
width: horizontal ? NaN : 8, // if not stretching horizontally, just 8 wide
height: !horizontal ? NaN : 8, // if not stretching vertically, just 8 tall
alignment: align, // align the port on the main Shape
stretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),
portId: name, // declare this object to be a "port"
fromSpot: spot, // declare where links may connect at this port
fromLinkable: output, // declare whether the user may draw links from here
toSpot: spot, // declare where links may connect at this port
toLinkable: input, // declare whether the user may draw links to here
cursor: "pointer", // show a different cursor to indicate potential link point
mouseEnter: function(e, port) { // the PORT argument will be this Shape
if (!e.diagram.isReadOnly) port.fill = "rgba(255,0,255,0.5)";
},
mouseLeave: function(e, port) {
port.fill = "transparent";
}
});
}
function textStyle() {
return {
font: "bold 11pt Lato, Helvetica, Arial, sans-serif",
stroke: "#282c34"
}
}
// define the Node templates for regular nodes
myDiagram.nodeTemplateMap.add("", // the default category
$(go.Node, "Table", nodeStyle(),
// the main object is a Panel that surrounds a TextBlock with a rectangular Shape
$(go.Panel, "Auto",
$(go.Shape, "Rectangle",
{ fill: "#00AD5F", stroke: "#282c34", strokeWidth: 3.5 },
new go.Binding("figure", "figure")),
$(go.TextBlock, textStyle(),
{
margin: 8,
maxSize: new go.Size(160, NaN),
wrap: go.TextBlock.WrapFit,
editable: true
},
new go.Binding("text").makeTwoWay())
),
// four named ports, one on each side:
makePort("T", go.Spot.Top, go.Spot.TopSide, false, true),
makePort("L", go.Spot.Left, go.Spot.LeftSide, true, true),
makePort("R", go.Spot.Right, go.Spot.RightSide, true, true),
makePort("B", go.Spot.Bottom, go.Spot.BottomSide, true, false)
));
myDiagram.nodeTemplateMap.add("Conditional",
$(go.Node, "Table", nodeStyle(),
// the main object is a Panel that surrounds a TextBlock with a rectangular Shape
$(go.Panel, "Auto",
$(go.Shape, "Diamond",
{ fill: "#00B2BF", stroke: "#282c34", strokeWidth: 3.5 },
new go.Binding("figure", "figure")),
$(go.TextBlock, textStyle(),
{
margin: 8,
maxSize: new go.Size(160, NaN),
wrap: go.TextBlock.WrapFit,
editable: true
},
new go.Binding("text").makeTwoWay())
),
// four named ports, one on each side:
makePort("T", go.Spot.Top, go.Spot.Top, false, true),
makePort("L", go.Spot.Left, go.Spot.Left, true, true),
makePort("R", go.Spot.Right, go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
));
myDiagram.nodeTemplateMap.add("Start",
$(go.Node, "Table", nodeStyle(),
$(go.Panel, "Spot",
$(go.Shape, "Circle",
{ desiredSize: new go.Size(70, 70), fill: "#00AD5F", stroke: "#282c34", strokeWidth: 3.5 }),
$(go.TextBlock, "Start", textStyle(),
new go.Binding("text"))
),
// three named ports, one on each side except the top, all output only:
makePort("T", go.Spot.Top, go.Spot.Top, false, true),
makePort("L", go.Spot.Left, go.Spot.Left, true, true),
makePort("R", go.Spot.Right, go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
));
myDiagram.nodeTemplateMap.add("Step",
$(go.Node, "Table", nodeStyle(),
// the main object is a Panel that surrounds a TextBlock with a rectangular Shape
$(go.Panel, "Auto",
$(go.Shape, "Rectangle",
{ fill: "#FCE0A6", stroke: "#282c34", strokeWidth: 3.5 },
new go.Binding("figure", "figure")),
$(go.TextBlock, textStyle(),
{
margin: 8,
maxSize: new go.Size(160, NaN),
wrap: go.TextBlock.WrapFit,
editable: true
},
new go.Binding("text").makeTwoWay())
),
// four named ports, one on each side:
makePort("T", go.Spot.Top, go.Spot.Top, false, true),
makePort("L", go.Spot.Left, go.Spot.Left, true, true),
makePort("R", go.Spot.Right, go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
));
myDiagram.nodeTemplateMap.add("End",
$(go.Node, "Table", nodeStyle(),
// the main object is a Panel that surrounds a TextBlock with a rectangular Shape
$(go.Panel, "Auto",
$(go.Shape, "RoundedRectangle",
{ fill: "#CE0620", stroke: "#282c34", strokeWidth: 3.5 },
new go.Binding("figure", "figure")),
$(go.TextBlock, textStyle(),
{
margin: 8,
maxSize: new go.Size(160, NaN),
wrap: go.TextBlock.WrapFit,
editable: true
},
new go.Binding("text").makeTwoWay())
),
// four named ports, one on each side:
makePort("T", go.Spot.Top, go.Spot.Top, false, true),
makePort("L", go.Spot.Left, go.Spot.Left, true, true),
makePort("R", go.Spot.Right, go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
));
// taken from ../extensions/Figures.js:
go.Shape.defineFigureGenerator("File", function(shape, w, h) {
var geo = new go.Geometry();
var fig = new go.PathFigure(0, 0, true); // starting point
geo.add(fig);
fig.add(new go.PathSegment(go.PathSegment.Line, .75 * w, 0));
fig.add(new go.PathSegment(go.PathSegment.Line, w, .25 * h));
fig.add(new go.PathSegment(go.PathSegment.Line, w, h));
fig.add(new go.PathSegment(go.PathSegment.Line, 0, h).close());
var fig2 = new go.PathFigure(.75 * w, 0, false);
geo.add(fig2);
// The Fold
fig2.add(new go.PathSegment(go.PathSegment.Line, .75 * w, .25 * h));
fig2.add(new go.PathSegment(go.PathSegment.Line, w, .25 * h));
geo.spot1 = new go.Spot(0, .25);
geo.spot2 = go.Spot.BottomRight;
return geo;
});
myDiagram.nodeTemplateMap.add("Comment",
$(go.Node, "Auto", nodeStyle(),
$(go.Shape, "File",
{ fill: "#282c34", stroke: "#DEE0A3", strokeWidth: 3 }),
$(go.TextBlock, textStyle(),
{
margin: 8,
maxSize: new go.Size(200, NaN),
wrap: go.TextBlock.WrapFit,
textAlign: "center",
editable: true
},
new go.Binding("text").makeTwoWay())
// no ports, because no links are allowed to connect with a comment
));
// replace the default Link template in the linkTemplateMap
myDiagram.linkTemplate =
$(go.Link, // the whole link panel
{
routing: go.Link.AvoidsNodes,
curve: go.Link.JumpOver,
corner: 5, toShortLength: 4,
relinkableFrom: true,
relinkableTo: true,
reshapable: true,
resegmentable: true,
// mouse-overs subtly highlight links:
mouseEnter: function(e, link) { link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.2)"; },
mouseLeave: function(e, link) { link.findObject("HIGHLIGHT").stroke = "transparent"; },
selectionAdorned: false
},
new go.Binding("points").makeTwoWay(),
$(go.Shape, // the highlight shape, normally transparent
{ isPanelMain: true, strokeWidth: 8, stroke: "transparent", name: "HIGHLIGHT" }),
$(go.Shape, // the link path shape
{ isPanelMain: true, stroke: "gray", strokeWidth: 2 },
new go.Binding("stroke", "isSelected", function(sel) { return sel ? "dodgerblue" : "gray"; }).ofObject()),
$(go.Shape, // the arrowhead
{ toArrow: "standard", strokeWidth: 0, fill: "gray" }),
$(go.Panel, "Auto", // the link label, normally not visible
{ visible: false, name: "LABEL", segmentIndex: 2, segmentFraction: 0.5 },
new go.Binding("visible", "visible").makeTwoWay(),
$(go.Shape, "RoundedRectangle", // the label shape
{ fill: "#F8F8F8", strokeWidth: 0 }),
$(go.TextBlock, "Yes", // the label
{
textAlign: "center",
font: "10pt helvetica, arial, sans-serif",
stroke: "#333333",
editable: true
},
new go.Binding("text").makeTwoWay())
)
);
// Make link labels visible if coming out of a "conditional" node.
// This listener is called by the "LinkDrawn" and "LinkRelinked" DiagramEvents.
function showLinkLabel(e) {
var label = e.subject.findObject("LABEL");
if (label !== null) label.visible = (e.subject.fromNode.data.category === "Conditional");
}
// temporary links used by LinkingTool and RelinkingTool are also orthogonal:
myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;
myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal;
//load(); // load an initial diagram from some JSON text
// initialize the Palette that is on the left side of the page
myPalette =
$(go.Palette, "myPaletteDiv", // must name or refer to the DIV HTML element
{
// Instead of the default animation, use a custom fade-down
"animationManager.initialAnimationStyle": go.AnimationManager.None,
"InitialAnimationStarting": animateFadeDown, // Instead, animate with this function
nodeTemplateMap: myDiagram.nodeTemplateMap, // share the templates used by myDiagram
model: new go.GraphLinksModel([ // specify the contents of the Palette
{ text: "Start", figure: "RoundedRectangle", fill: "#00AD5F" },
{ category: "Step",figure: "Rectangle",text: "Step",fill: "lightyellow" },
{ category: "Conditional", text: "sel", figure: "Diamond",fill: "lightskyblue" },
{ category: "End", text: "End",figEndure: "RoundedRectangle", fill: "#CE0620" },
], [
// the Palette also has a disconnected Link, which the user can drag-and-drop
{ points: new go.List(go.Point).addAll([new go.Point(0, 0), new go.Point(30, 0), new go.Point(30, 40), new go.Point(60, 40)]) }
])
});
// This is a re-implementation of the default animation, except it fades in from downwards, instead of upwards.
function animateFadeDown(e) {
var diagram = e.diagram;
var animation = new go.Animation();
animation.isViewportUnconstrained = true; // So Diagram positioning rules let the animation start off-screen
animation.easing = go.Animation.EaseOutExpo;
animation.duration = 900;
// Fade "down", in other words, fade in from above
animation.add(diagram, 'position', diagram.position.copy().offset(0, 200), diagram.position);
animation.add(diagram, 'opacity', 0, 1);
animation.start();
}
} // end init
// Show the diagram's model in JSON format that the user may edit
function save() {
document.getElementById("mySavedModel").value = myDiagram.model.toJson();
myDiagram.isModified = false;
}
function load() {
myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value);
}
// print the diagram by opening a new window holding SVG images of the diagram contents for each page
function printDiagram() {
var svgWindow = window.open();
if (!svgWindow) return; // failure to open a new Window
var printSize = new go.Size(700, 960);
var bnds = myDiagram.documentBounds;
var x = bnds.x;
var y = bnds.y;
while (y < bnds.bottom) {
while (x < bnds.right) {
var svg = myDiagram.makeSVG({ scale: 1.0, position: new go.Point(x, y), size: printSize });
svgWindow.document.body.appendChild(svg);
x += printSize.width;
}
x = bnds.x;
y += printSize.height;
}
setTimeout(function() { svgWindow.print(); }, 1);
}
</script>
</head>
<body οnlοad="init()">
<div id="sample">
<div style="width:100%; white-space:nowrap;">
<span style="display: inline-block; vertical-align: top; width:105px">
<div id="myPaletteDiv" style="border: solid 1px black; height: 620px"></div>
</span>
<span style="display: inline-block; vertical-align: top; width:90%">
<div id="myDiagramDiv" style="border: solid 1px black; height: 620px"></div>
</span>
</div>
<p>
The FlowChart sample demonstrates several key features of GoJS,
namely <a href="../intro/palette.html">Palette</a>s,
<a href="../intro/links.html">Linkable nodes</a>, Drag/Drop behavior,
<a href="../intro/textBlocks.html">Text Editing</a>, and the use of
<a href="../intro/templateMaps.html">Node Template Maps</a> in Diagrams.
</p>
<p>
Mouse-over a Node to view its ports.
Drag from these ports to create new Links.
Selecting Links allows you to re-shape and re-link them.
Selecting a Node and then clicking its TextBlock will allow
you to edit text (except on the Start and End Nodes).
</p>
<button id="SaveButton" οnclick="save()">Save</button>
<button οnclick="load()">Load</button>
Diagram Model saved in JSON format:
<textarea id="mySavedModel" style="width:100%;height:300px">
{ "class": "go.GraphLinksModel",
"linkFromPortIdProperty": "fromPort",
"linkToPortIdProperty": "toPort",
"nodeDataArray": [
{"category":"Comment", "loc":"360 -10", "text":"Kookie Brittle", "key":-13},
{"key":-1, "category":"Start", "loc":"175 0", "text":"Start"},
{"key":0, "loc":"-5 75", "text":"Preheat oven to 375 F"},
{"key":1, "loc":"175 100", "text":"In a bowl, blend: 1 cup margarine, 1.5 teaspoon vanilla, 1 teaspoon salt"},
{"key":2, "loc":"175 200", "text":"Gradually beat in 1 cup sugar and 2 cups sifted flour"},
{"key":3, "loc":"175 290", "text":"Mix in 6 oz (1 cup) Nestle's Semi-Sweet Chocolate Morsels"},
{"key":4, "loc":"175 380", "text":"Press evenly into ungreased 15x10x1 pan"},
{"key":5, "loc":"355 85", "text":"Finely chop 1/2 cup of your choice of nuts"},
{"key":6, "loc":"175 450", "text":"Sprinkle nuts on top"},
{"key":7, "loc":"175 515", "text":"Bake for 25 minutes and let cool"},
{"key":8, "loc":"175 585", "text":"Cut into rectangular grid"},
{"key":-2, "category":"End", "loc":"175 660", "text":"Enjoy!"}
],
"linkDataArray": [
{"from":1, "to":2, "fromPort":"B", "toPort":"T"},
{"from":2, "to":3, "fromPort":"B", "toPort":"T"},
{"from":3, "to":4, "fromPort":"B", "toPort":"T"},
{"from":4, "to":6, "fromPort":"B", "toPort":"T"},
{"from":6, "to":7, "fromPort":"B", "toPort":"T"},
{"from":7, "to":8, "fromPort":"B", "toPort":"T"},
{"from":8, "to":-2, "fromPort":"B", "toPort":"T"},
{"from":-1, "to":0, "fromPort":"B", "toPort":"T"},
{"from":-1, "to":1, "fromPort":"B", "toPort":"T"},
{"from":-1, "to":5, "fromPort":"B", "toPort":"T"},
{"from":5, "to":4, "fromPort":"B", "toPort":"T"},
{"from":0, "to":4, "fromPort":"B", "toPort":"T"}
]}
</textarea>
<button οnclick="printDiagram()">Print Diagram Using SVG</button>
</div>
</body>
</html>
示例2代码根据1代码适当修改
示例2效果图
相关表设计
标签:map,流程图,绑定,Spot,Shape,go,new,gojs,true 来源: https://blog.csdn.net/qq_37528703/article/details/103597982