joint+rappid实现sysml参数图拖拽设计代码
代码语言:html
所属分类:图表
代码描述:joint+rappid实现sysml参数图拖拽设计代码
代码标签: joint rappid sysml 参数图 拖拽 设计 代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> #stencil-container { position: absolute; left: 0; top: 0; width: 100px; bottom: 0; } #paper-container { position: absolute; right: 0; top: 0; left: 100px; bottom: 0; } #logo { position: absolute; bottom: 20px; right: 0; } .invalid-drop-target { stroke: #940027; } </style> <link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/rappid.3.7.3.css"> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/lodash.4.17.21.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/jquery-3.2.1.min.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/backbone-min.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/rappid.3.7.3.js"></script> </head> <body translate="no"> <div id="stencil-container"></div> <div id="paper-container"></div> <script > const { dia, shapes, ui, highlighters, util, layout } = joint; const SHAPES_GAP = 20; const colors = { constraintBlockFill: "#7A3D57", constraintPropertyFill: "#E3A4BD", systemPropertyFill: "#FC7100" }; const paperContainerElemenet = document.getElementById("paper-container"); const stencilContainerElement = document.getElementById("stencil-container"); joint.shapes.standard.Rectangle.define("ConstraintBlock", { attrs: { body: { rx: 10, ry: 10, fill: colors.constraintBlockFill, strokeWidth: 0 }, label: { fill: "white" } } }); joint.shapes.standard.Rectangle.define("SystemProperty", { attrs: { body: { fill: colors.systemPropertyFill, strokeWidth: 0 }, label: { fill: "white" } } }); const portDefinition = { label: { position: { name: "manual", args: { x: -42, y: -8 } }, markup: [ { tagName: "text", selector: "label" }] }, attrs: { portBody: { magnet: true, width: 100, height: 24, x: -50, y: -12, fill: colors.constraintPropertyFill }, label: { text: "name : Type", fill: colors.constraintBlockFill, pointerEvents: "none" } }, markup: [ { tagName: "rect", selector: "portBody" }] }; // Paper const graph = new dia.Graph({}, { cellNamespace: shapes }); const paper = new dia.Paper({ model: graph, cellViewNamespace: shapes, width: "100%", height: "100%", gridSize: 20, drawGrid: { name: "mesh" }, async: true, sorting: dia.Paper.sorting.APPROX, background: { color: "#F3F7F6" }, defaultRouter: { name: "manhattan", args: { padding: 20 } }, defaultLink: () => new joint.shapes.standard.Link(), magnetThreshold: "onleave", linkPinning: false, validateConnection: function ( sourceView, sourceMagnet, targetView, targetMagnet) { if (sourceView === targetView) { return false; } const target = targetView.model; const targetType = target.get("type"); // TODO: don't forget to prevent duplicities… return ( targetType === "ConstraintBlock" && targetMagnet !== null || targetType === "SystemProperty"); }, snapLinks: { radius: 10 } }); paperContainerElemenet.appendChild(paper.el); // Stencil const stencil = new ui.Stencil({ paper, usePaperGrid: true, width: 100, height: "100%", paperOptions: () => { return { model: new dia.Graph({}, { cellNamespace: shapes }), cellViewNamespace: shapes, background: { color: "#FCFCFC" } }; }, layout: { resizeToFit: false }, dragStartClone: cell => { const clone = cell.clone(); const type = cell.get("type"); if (type === "ConstraintBlock") { clone.attr("label/text", ": Type"); } else if (type === "SystemProperty") { clone.attr("label/text", "name : Type"); } return clone; } }); stencil.render(); stencilContainerElement.appendChild(stencil.el); const stencilElements = [ { type: "ConstraintBlock", size: { width: 280, height: 120 }, attrs: { label: { text: null } } }, { type: "standard.Rectangle", size: { width: 100, height: 24 }, attrs: { body: { fill: colors.constraintPropertyFill } }, port: util.cloneDeep(portDefinition) }, { type: "SystemProperty", size: { width: 140, height: 40 } }]; function layoutStencil(stencil) { const paper = stencil.getPaper(); const graph = stencil.getGraph(); const layoutResult = layout.GridLayout.layout(graph.getElements(), { rowGap: SHAPES_GAP, columnGap: SHAPES_GAP }); const fittingBBox = paper.getArea().clone(); fittingBBox.height = Infinity; paper.transformToFitContent({ padding: 10, useModelGeometry: true, fittingBBox }); } stencil.load(stencilElements); layoutStencil(stencil); stencil.on({ "element:dragstart": (cloneView, evt) => { const clone = cloneView.model; evt.data.isPort = clone.get("port"); }, "element:dragstart element:drag": (cloneView, evt, cloneArea) => { if (!evt.data.isPort) { return; } const [dropTarget] = graph.findModelsFromPoint(cloneArea.center()); if (dropTarget) { evt.data.dropTarget = dropTarget; highlighters.mask.add( dropTarget.findView(paper), "body", "valid-drop-target", { layer: dia.Paper.Layers.BACK, attrs: { stroke: "#9580ff", "stroke-width": 2 } }); highlighters.addClass.removeAll(cloneView.paper, "invalid-drop-target"); } else { evt.data.dropTarget = null; highlighters.addClass.add(cloneView, "body", "invalid-drop-target", { className: "invalid-drop-target" }); highlighters.mask.removeAll(paper, "valid-drop-target"); } }, "element:dragend": (cloneView, evt, cloneArea) => { if (!evt.data.isPort) { return; } const clone = cloneView.model; const { dropTarget } = evt.data; if (dropTarget && dropTarget.get("type") === "ConstraintBlock") { stencil.cancelDrag(); dropTarget.addPort({ args: cloneArea.center().difference(dropTarget.position()).toJSON(), ...clone.get("port") }); } else { // An invalid drop target. Animate.........完整代码请登录后点击上方下载按钮下载查看
网友评论0