gojs实现时序图效果代码
代码语言:html
所属分类:图表
代码描述:gojs实现时序图效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <script src="//repo.bfw.wiki/bfwrepo/js/go.js"></script> <div id="allSampleContent" class="p-4 w-full"> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro" rel="stylesheet" type="text/css"> <script id="code"> function init() { // Since 2.2 you can also author concise templates with method chaining instead of GraphObject.make // For details, see https://gojs.net/latest/intro/buildingObjects.html const $ = go.GraphObject.make; myDiagram = $(go.Diagram, "myDiagramDiv", // must be the ID or reference to an HTML DIV { allowCopy: false, linkingTool: $(MessagingTool), // defined below "resizingTool.isGridSnapEnabled": true, draggingTool: $(MessageDraggingTool), // defined below "draggingTool.gridSnapCellSize": new go.Size(1, MessageSpacing / 4), "draggingTool.isGridSnapEnabled": true, // automatically extend Lifelines as Activities are moved or resized "SelectionMoved": ensureLifelineHeights, "PartResized": ensureLifelineHeights, "undoManager.isEnabled": true }); // when the document is modified, add a "*" to the title and enable the "Save" button myDiagram.addDiagramListener("Modified", e => { const button = document.getElementById("SaveButton"); if (button) button.disabled = !myDiagram.isModified; const idx = document.title.indexOf("*"); if (myDiagram.isModified) { if (idx < 0) document.title += "*"; } else { if (idx >= 0) document.title = document.title.slice(0, idx); } }); // define the Lifeline Node template. myDiagram.groupTemplate = $(go.Group, "Vertical", { locationSpot: go.Spot.Bottom, locationObjectName: "HEADER", minLocation: new go.Point(0, 0), maxLocation: new go.Point(9999, 0), selectionObjectName: "HEADER" }, new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Panel, "Auto", { name: "HEADER" }, $(go.Shape, "Rectangle", { fill: $(go.Brush, "Linear", { 0: "#bbdefb", 1: go.Brush.darkenBy("#bbdefb", 0.1) }), stroke: null }), $(go.TextBlock, { margin: 5, font: "400 10pt Source Sans Pro, sans-serif" }, new go.Binding("text", "text")) ), $(go.Shape, { figure: "LineV", fill: null, stroke: "gray", strokeDashArray: [3, 3], width: 1, alignment: go.Spot.Center, portId: "", fromLinkable: true, fromLinkableDuplicates: true, toLinkable: true, toLinkableDuplicates: true, cursor: "pointer" }, new go.Binding("height", "duration", computeLifelineHeight)) ); // define the Activity Node template myDiagram.nodeTemplate = $(go.Node, { locationSpot: go.Spot.Top, locationObjectName: "SHAPE", minLocation: new go.Point(NaN, LinePrefix - ActivityStart), maxLocation: new go.Point(NaN, 19999), selectionObjectName: "SHAPE", resizable: true, resizeObjectName: "SHAPE", resizeAdornmentTemplate: $(go.Adornment, "Spot", $(go.Placeholder), $(go.Shape, // only a bottom resize handle { alignment: go.Spot.Bottom, cursor: "col-resize", desiredSize: new go.Size(6, 6), fill: "yellow" }) ) }, new go.Binding("location", "", computeActivityLocation).makeTwoWay(backComputeActivityLocation), $(go.Shape, "Rectangle", { name: "SHAPE", fill: "white", stroke: "black", width: ActivityWidth, // allow Activities to be resized down to 1/4 of a time unit minSize: new go.Size(ActivityWidth, computeActivityHeight(0.25)) }, new go.Binding("height", "duration", computeActivityHeight).makeTwoWay(backComputeActivityHeight)) ); // define the Message Link template. myDiagram.linkTemplate = $(MessageLink, // defined below { selectionAdorned: true, curviness: 0 }, $(go.Shape, "Rectangle", { stroke: "black" }), $(go.Shape, { toArrow: "OpenTriangle", stroke: "black" }), $(go.TextBlock, { font: "400 9pt Source Sans Pro, sans-serif", segmentIndex: 0, segmentOffset: new go.Point(NaN, NaN), isMultiline: false, editable: true }, new go.Binding("text", "text").makeTwoWay()) ); // create the graph by reading the JSON data saved in "mySavedModel" textarea element load(); } function ensureLifelineHeights(e) { // iterate over all Activities (ignore Groups) const arr = myDiagram.model.nodeDataArray; let max = -1; for (let i = 0; i < arr.length; i++) { const act = arr[i]; if (act.isGroup) continue; max = Math.max(max, act.start + act.duration); } if (max > 0) { // now iterate over only Groups for (let i = 0; i < arr.length; i++) { const gr = arr[i]; if (!gr.isGroup) continue; if (max > gr.duration) { // this only extends, never shrinks myDiagram.model.setDataProperty(gr, "duration", max); } } } } // some parameters const LinePrefix = 20; // vertical starting point in document for all Messages and Activations const LineSuffix = 30; // vertical length beyond the last message time const MessageSpacing = 20; // vertical distance between Messages at different steps const ActivityWidth = 10; // width of each vertical activity bar const ActivityStart = 5; // height before start message time const ActivityEnd = 5; // height beyond end message time function computeLifelineHeight(duration) { return LinePrefix + duration * MessageSpacing + LineSuffix; } function computeActivityLocation(act) { const groupdata = myDiagram.model.findNodeDataForKey(act.group); if (groupdata === null) return new go.Point(); // get location of Lifeline's starting point const grouploc = go.Point.parse(groupdata.loc); return new go.Point(grouploc.x, convertTimeToY(act.start) - ActivityStart); } function backComputeActivityLocation(loc, act) { myDiagram.model.setDataProperty(act, "start", convertYToTime(loc.y + ActivityStart)); } function computeActivityHeight(duration) { return ActivityStart + duration * MessageSpacing + ActivityEnd; } function backComputeActivityHeight(height) { return (height - ActivityStart - ActivityEnd) / MessageSpacing; } // time is just an abstract small non-negative integer // here we map between an abstract time and a vertical position function convertTimeToY(t) { return t * MessageSpacing + LinePrefix; } function convertYToTime(y) { return (y - LinePrefix) / MessageSpacing; } // a custom routed Link class MessageLink extends go.Link { constructor() { super(); this.time = 0; // use this "time" value when this is the temporaryLink } getLinkPoint(node, port, spot, from, ortho, othernode, otherport) { const p = port.getDocumentPoint(go.Spot.Center); const r = port.getDocumentBounds(); const op = otherport.getDocumentPoint(go.Spot.Center); const data = this.data; const time = data !== null ? data.time : this.time; // if not bound, assume this has its own "time" property const aw = this.findActivityWidth(node, time); const x = (op.x > p.x ? p.x + aw / 2 : p.x - aw / 2); const y = convertTimeToY(time); return new go.Point(x, y); } findActivityWidth(node, time) { let aw = ActivityWidth; if (node instanceof go.Group) { // see if there is an Activity Node at this point -- if not, connect the link directly with the Group's l.........完整代码请登录后点击上方下载按钮下载查看
网友评论0