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"> <div id="sample"> <div style="width: 100%; display: flex; justify-content: space-between; border: solid 1px black"> <div id="myTasksDiv" style="width: 150px; margin-right: 2px; border-right: 1px solid black; position: relative; -webkit-tap-highlight-color: rgba(255, 255, 255, 0);"><canvas tabindex="0" width="186" height="500" style="position: absolute; top: 0px; left: 0px; z-index: 2; user-select: none; touch-action: none; width: 149px; height: 400px;">This text is displayed if your browser does not support the Canvas HTML element.</canvas><div style="position: absolute; overflow: auto; width: 149px; height: 400px; z-index: 1;"><div style="position: absolute; width: 1px; height: 1px;"></div></div></div> <div id="myGanttDiv" style="flex-grow: 1; height: 400px; position: relative; -webkit-tap-highlight-color: rgba(255, 255, 255, 0);"><canvas tabindex="0" width="1106" height="478" style="position: absolute; top: 0px; left: 0px; z-index: 2; user-select: none; touch-action: none; width: 885px; height: 383px;">This text is displayed if your browser does not support the Canvas HTML element.</canvas><div style="position: absolute; overflow: auto; width: 902px; height: 400px; z-index: 1;"><div style="position: absolute; width: 1104px; height: 484px;"></div></div></div> </div> <div id="slider"> <label>间距:</label> <input id="widthSlider" type="range" min="8" max="24" value="12" oninput="rescale()"> </div> <p> 此示例演示了一个简单的甘特图。甘特图用于说明项目进度表,表示项目终端和摘要元素的开始和结束日期。 您可以通过更改“间距”值来放大图表,该值使用节点宽度和位置的数据绑定函数来缩放图表。这代替了更改Diagram.scale。 </p> <p> The current model in JSON format: </p> <textarea id="mySavedModel" style="width:100%;height:250px">{ "class": "GraphLinksModel", "modelData": {"origin":1531540800000}, "nodeDataArray": [ {"key":0,"text":"Project X","start":0,"duration":85}, {"key":1,"text":"Task 1","color":"darkgreen","start":0,"duration":22}, {"key":11,"text":"Task 1.1","color":"green","duration":10,"start":0}, {"key":12,"text":"Task 1.2","color":"green","start":10,"duration":12}, {"key":121,"text":"Task 1.2.1","color":"lightgreen","duration":3,"start":10}, {"key":122,"text":"Task 1.2.2","color":"lightgreen","duration":5,"start":13}, {"key":123,"text":"Task 1.2.3","color":"lightgreen","duration":4,"start":18}, {"key":2,"text":"Task 2","color":"darkblue","start":10,"duration":40}, {"key":21,"text":"Task 2.1","color":"blue","duration":15,"start":10}, {"key":22,"text":"Task 2.2","color":"goldenrod","start":25,"duration":14}, {"key":221,"text":"Task 2.2.1","color":"yellow","duration":8,"start":25}, {"key":222,"text":"Task 2.2.2","color":"yellow","duration":6,"start":33}, {"key":23,"text":"Task 2.3","color":"darkorange","start":39,"duration":11}, {"key":231,"text":"Task 2.3.1","color":"orange","duration":11,"start":39}, {"key":3,"text":"Task 3","color":"maroon","start":50,"duration":35}, {"key":31,"text":"Task 3.1","color":"brown","duration":10,"start":50}, {"key":32,"text":"Task 3.2","color":"brown","start":60,"duration":25}, {"key":321,"text":"Task 3.2.1","color":"lightsalmon","duration":8,"start":60}, {"key":322,"text":"Task 3.2.2","color":"lightsalmon","duration":3,"start":68}, {"key":323,"text":"Task 3.2.3","color":"lightsalmon","duration":7,"start":71}, {"key":324,"text":"Task 3.2.4","color":"lightsalmon","duration":5,"start":71}, {"key":325,"text":"Task 3.2.5","color":"lightsalmon","duration":4,"start":76}, {"key":326,"text":"Task 3.2.6","color":"lightsalmon","duration":5,"start":80} ], "linkDataArray": [ {"from":0,"to":1}, {"from":1,"to":11}, {"from":1,"to":12}, {"from":12,"to":121}, {"from":12,"to":122}, {"from":12,"to":123}, {"from":0,"to":2}, {"from":2,"to":21}, {"from":2,"to":22}, {"from":22,"to":221}, {"from":22,"to":222}, {"from":2,"to":23}, {"from":23,"to":231}, {"from":0,"to":3}, {"from":3,"to":31}, {"from":3,"to":32}, {"from":32,"to":321}, {"from":32,"to":322}, {"from":32,"to":323}, {"from":32,"to":324}, {"from":32,"to":325}, {"from":32,"to":326}, {"from":11,"to":2,"category":"Dep"} ]}</textarea> <p class="text-xs">GoJS version 2.2.10. Copyright 1998-2022 by Northwoods Software.</p></div> <script id="code"> // Custom Layout for myGantt Diagram class GanttLayout extends go.Layout { constructor() { super(); this.cellHeight = GridCellHeight; } doLayout(coll) { coll = this.collectParts(coll); const diagram = this.diagram; diagram.startTransaction("Gantt Layout"); const bars = []; this.assignTimes(diagram, bars); this.arrangementOrigin = this.initialOrigin(this.arrangementOrigin); let y = this.arrangementOrigin.y; bars.forEach(node => { const tasknode = myTasks.findNodeForData(node.data); node.visible = tasknode.isVisible(); node.position = new go.Point(convertStartToX(node.data.start), y); if (node.visible) y += this.cellHeight; }); diagram.commitTransaction("Gantt Layout"); } // Update node data, to make sure each node has a start and a duration assignTimes(diagram, bars) { const roots = diagram.findTreeRoots(); roots.each(root => this.walkTree(root, 0, bars)); } walkTree(node, start, bars) { bars.push(node); const model = node.diagram.model; if (node.isTreeLeaf) { let dur = node.data.duration; if (dur === undefined || isNaN(dur)) { dur = convertDaysToUnits(1); // default task length? model.set(node.data, "duration", dur); } let st = node.data.start; if (st === undefined || isNaN(st)) { st = start; // use given START model.set(node.data, "start", st); } return st + dur; } else { // first recurse to fill in any missing data node.findTreeChildrenNodes().each(n => { start = this.walkTree(n, start, bars); }); // now can calculate this non-leaf node's data let min = Infinity; let max = -Infinity; const colors = new go.Set(); node.findTreeChildrenNodes().each(n => { min = Math.min(min, n.data.start); max = Math.max(max, n.data.start + n.data.duration); if (n.data.color) colors.add(n.data.color); }); model.set(node.data, "start", min); model.set(node.data, "duration", max - min); return max; } } } // end of GanttLayout var GridCellHeight = 20; // document units var GridCellWidth = 12; // document units per day var TimelineHeight = 24; // document units const MsPerDay = 24 * 60 * 60 * 1000; // By default the values for the data properties start and duration are in days, // and the start value is relative to the StartDate. // If you want the start and duration properties to be in a unit other than days, // you only need to change the implementation of convertDaysToUnits and convertUnitsToDays. function convertDaysToUnits(n) { return n; } function convertUnitsToDays(n) { return n; } function convertStartToX(start) { return convertUnitsToDays(start) * GridCellWidth; } function convertXToStart(x, node) { return convertDaysToUnits(x / GridCellWidth); } function convertDurationToW(duration) { return convertUnitsToDays(duration) * GridCellWidth; } function convertWToDuration(w) { return convertDaysToUnits(w / GridCellWidth); } function convertStartToPosition(start, node) { return new go.Point(convertStartToX(start), node.position.y || 0); } function convertPositionToStart(pos) { return convertXToStart(pos.x); } var StartDate = new Date(); // set from Model.modelData.origin function valueToText(n) { // N is in days since StartDate const startDate = StartDate; const startDateMs = startDate.getTime() + startDate.getTimezoneOffset() * 60000; const date = new Date(startDateMs + n * MsPerDay / GridCellWidth); return date.toLocaleDateString(); } function dateToValue(d) { // D is a Date const startDate = StartDate; const startDateMs = startDate.getTime() + startDate.getTimezoneOffset() * 60000; const dateInMs = d.getTime() + d.getTimezoneOffset() * 60000; const msSinceStart = dateInMs - startDateMs; return msSinceStart / MsPerDay * GridCellWidth; } // the custom figure used for task bars that have downward points at their ends go.Shape.defineFigureGenerator("RangeBar", (shape, w, h) => { const b = Math.min(5, w); const d = Math.min(5, h); return new go.Geometry() .add(new go.PathFigure(0, 0, true) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Line, w, h)) .add(new go.PathSegment(go.PathSegment.Line, w-b, h-d)) .add(new go.PathSegment(go.PathSegment.Line, b, h-d)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())); }); const $ = go.GraphObject.make; function standardContextMenus() { return { contextMenu: $("ContextMenu", $("ContextMenuButton", $(go.TextBlock, "Details..."), { click: (e, button) => { const task = button.part.adornedPart; console.log("show HTML panel with details about the task " + task.text); } } ), $("ContextMenuButton", $(go.TextBlock, "New Task"), { click: (e, button) => { const task = button.part.adornedPart; e.diagram.model.commit(m => { const newdata = { key: undefined, text: "New Task", color: task.data.color, duration: convertDaysToUnits(5) }; m.addNodeData(newdata); m.addLinkData({ from: task.key, to: newdata.key }); e.diagram.select(e.diagram.findNodeForData(newdata)); }); } } ) ) }; } // the left side of the whole diagram const myTasks = new go.Diagram("myTasksDiv", { initialContentAlignment: go.Spot.Right, padding: new go.Margin(TimelineHeight, 0, 0, 0), hasVerticalScrollbar: false, a.........完整代码请登录后点击上方下载按钮下载查看
网友评论0