joint+rappid实现工厂车间机器运转运行流程图代码
代码语言:html
所属分类:图表
代码描述:joint+rappid实现工厂车间机器运转运行流程图代码
代码标签: joint rappid 工厂 车间 机器 运转 运行 流程图 代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> :root { --accent-color: #0075f2; --text-color: #131e29; --liquid-color: #f6f740; } /* Switch */ .jj-switch { font-family: sans-serif; font-size: 14px; width: 100%; height: 100%; background: white; border: 1px solid #cad8e3; position: static; padding: 3px; box-sizing: border-box; border-radius: 4px; color: var(--text-color); } .jj-switch-label { width: 100%; text-align: center; margin: 0 0 2px 0; } .jj-switch-on { background: var(--accent-color); color: #dde6ed; border-radius: 4px 0 0 4px; border: 1px solid var(--accent-color); width: 50%; height: 22px; } .jj-switch-off { background: #131e29; color: #dde6ed; border-radius: 0 4px 4px 0; border: 1px solid #131e29; width: 50%; height: 22px; } .jj-switch-on:disabled, .jj-switch-off:disabled { background: #f2f5f8; color: #cad8e3; border: 1px solid #cad8e3; } /* Checkbox */ .jj-checkbox { width: 100%; height: 100%; background: white; border: 1px solid #cad8e3; position: static; box-sizing: border-box; border-radius: 4px; } .jj-checkbox-input { accent-color: var(--accent-color); } /* Slider */ .jj-slider { font-family: sans-serif; font-size: 14px; width: 100%; height: 100%; background: white; border: 1px solid #cad8e3; position: static; box-sizing: border-box; border-radius: 4px; padding: 3px; color: var(--text-color); } .jj-slider-input { accent-color: var(--accent-color); } .jj-slider-label { width: 100%; text-align: center; white-space: pre; } .jj-slider-output { width: 100%; text-align: center; white-space: pre; display: block; font-size: 11px; color: #40668c; } /* Application */ #paper-container { position: absolute; inset: 0 0 0 0; } #logo { position: absolute; top: 20px; right: 0; } #toolbar-container { position: absolute; top: 10px; left: 10px; font-family: sans-serif; color: var(--text-color); accent-color: var(--accent-color); } #toolbar-container [data-name="title"] { font-weight: 900; } </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> <!-- partial:index.partial.html --> <div id="paper-container"></div> <div id="toolbar-container"></div> <script > /*! JointJS+ v3.7.0 - HTML5 Diagramming Framework Copyright (c) 2023 client IO 2023-07-12 This Source Code Form is subject to the terms of the JointJS+ License , v. 2.0. If a copy of the JointJS+ License was not distributed with this file, You can obtain one at https://www.jointjs.com/license or from the JointJS+ archive as was distributed by client IO. See the LICENSE file.*/ const { dia, shapes, util, ui } = joint; const paperContainerEl = document.getElementById("paper-container"); const toolbarContainerEl = document.getElementById("toolbar-container"); // Custom view flags const POWER_FLAG = "POWER"; const LIGHT_FLAG = "LIGHT"; const FLOW_FLAG = "FLOW"; const OPEN_FLAG = "OPEN"; // Constants const LIQUID_COLOR = "#0EAD69"; const MAX_LIQUID_COLOR = "#ED2637"; const MIN_LIQUID_COLOR = "#FFD23F"; const START_LIQUID = 70; const PRESSURE_COLOR = "#1446A0"; const MAX_PRESSURE_COLOR = "#ED2637"; document.documentElement.style.setProperty("--liquid-color", LIQUID_COLOR); // Pump metrics const r = 30; const d = 10; const l = 3 * r / 4; const step = 20; class Pump extends dia.Element { defaults() { return { ...super.defaults, type: "Pump", size: { width: 100, height: 100 }, power: 0, attrs: { root: { magnetSelector: "body" }, body: { rx: "calc(w / 2)", ry: "calc(h / 2)", cx: "calc(w / 2)", cy: "calc(h / 2)", stroke: "gray", strokeWidth: 2, fill: "lightgray" }, label: { text: "Pump", textAnchor: "middle", textVerticalAnchor: "top", x: "calc(0.5*w)", y: "calc(h+10)", fontSize: 14, fontFamily: "sans-serif", fill: "#350100" }, rotorGroup: { transform: "translate(calc(w/2),calc(h/2))", event: "element:power:click", cursor: "pointer" }, rotorFrame: { r: 40, fill: "#eee", stroke: "#666", strokeWidth: 2 }, rotorBackground: { r: 34, fill: "#777", stroke: "#222", strokeWidth: 1, style: { transition: "fill 0.5s ease-in-out" } }, rotor: { // d: `M ${a} ${a} ${b} ${r} -${b} ${r} -${a} ${a} -${r} ${b} -${r} -${b} -${a} -${a} -${b} -${r} ${b} -${r} ${a} -${a} ${r} -${b} ${r} ${b} Z`, d: `M 0 0 V ${r} l ${-d} ${-l} Z M 0 0 V ${-r} l ${d} ${l} Z M 0 0 H ${r} l ${-l} ${d} Z M 0 0 H ${-r} l ${l} ${-d} Z`, stroke: "#222", strokeWidth: 3, fill: "#bbb" } }, ports: { groups: { pipes: { position: { name: "line", args: { start: { x: "calc(w / 2)", y: "calc(h)" }, end: { x: "calc(w / 2)", y: 0 } } }, markup: util.svg` <rect @selector="pipeBody" /> <rect @selector="pipeEnd" /> `, size: { width: 80, height: 30 }, attrs: { portRoot: { magnetSelector: "pipeEnd" }, pipeBody: { width: "calc(w)", height: "calc(h)", y: "calc(h / -2)", fill: { type: "linearGradient", stops: [ { offset: "0%", color: "gray" }, { offset: "30%", color: "white" }, { offset: "70%", color: "white" }, { offset: "100%", color: "gray" }], attrs: { x1: "0%", y1: "0%", x2: "0%", y2: "100%" } } }, pipeEnd: { width: 10, height: "calc(h+6)", y: "calc(h / -2 - 3)", stroke: "gray", strokeWidth: 3, fill: "white" } } } }, items: [ { id: "left", group: "pipes", z: 1, attrs: { pipeBody: { x: "calc(-1 * w)" }, pipeEnd: { x: "calc(-1 * w)" } } }, { id: "right", group: "pipes", z: 0, attrs: { pipeEnd: { x: "calc(w - 10)" } } }] } }; } preinitialize() { this.markup = util.svg /* xml */` <ellipse @selector="body" /> <g @selector="rotorGroup"> <circle @selector="rotorFrame" /> <circle @selector="rotorBackground" /> <path @selector="rotor" /> </g> <text @selector="label" /> `; } get power() { return this.get("power") || 0; } set power(value) { this.set("power", value); }} const PumpView = dia.ElementView.extend({ presentationAttributes: dia.ElementView.addPresentationAttributes({ power: [POWER_FLAG] }), initFlag: [dia.ElementView.Flags.RENDER, POWER_FLAG], powerAnimation: null, confirmUpdate(...args) { let flags = dia.ElementView.prototype.confirmUpdate.call(this, ...args); if (this.hasFlag(flags, POWER_FLAG)) { this.togglePower(); flags = this.removeFlag(flags, POWER_FLAG); } return flags; }, getSpinAnimation() { let { spinAnimation } = this; if (spinAnimation) return spinAnimation; const [rotorEl] = this.findBySelector("rotor"); // It's important to use start and end frames to make it work in Safari. const keyframes = { transform: ["rotate(0deg)", "rotate(360deg)"] }; spinAnimation = rotorEl.animate(keyframes, { fill: "forwards", duration: 1000, iterations: Infinity }); this.spinAnimation = spinAnimation; return spinAnimation; }, togglePower() { const { model } = this; this.getSpinAnimation().playbackRate = model.power; } }); class ControlValve extends dia.Element { defaults() { return { ...super.defaults, type: "ControlValve", size: { width: 60, height: 60 }, open: 1, attrs: { root: { magnetSelector: "body" }, body: { rx: "calc(w / 2)", ry: "calc(h / 2)", cx: "calc(w / 2)", cy: "calc(h / 2)", stroke: "gray", strokeWidth: 2, fill: { type: "radialGradient", stops: [ { offset: "80%", color: "white" }, { offset: "100%", color: "gray" }] } }, liquid: { // We use path instead of rect to make it possible to animate // the stroke-dasharray to show the liquid flow. d: "M calc(w / 2 + 12) calc(h / 2) h -24", stroke: LIQUID_COLOR, strokeWidth: 24, strokeDasharray: "3,1" }, cover: { x: "calc(w / 2 - 12)", y: "calc(h / 2 - 12)", width: 24, height: 24, stroke: "#333", strokeWidth: 2, fill: "#fff" }, coverFrame: { x: "calc(w / 2 - 15)", y: "calc(h / 2 - 15)", width: 30, height: 30, stroke: "#777", strokeWidth: 2, fill: "none", rx: 1, ry: 1 }, stem: { width: 10, height: 30, x: "calc(w / 2 - 5)", y: -30, stroke: "#333", strokeWidth: 2, fill: "#555" }, control: { d: "M 0 0 C 0 -30 60 -30 60 0 Z", transform: "translate(calc(w / 2 - 30), -20)", stroke: "#333", strokeWidth: 2, rx: 5, ry: 5, fill: "#666" }, label: { text: "Valve", textAnchor: "middle", textVerticalAnchor: "top", x: "calc(0.5*w)", y: "calc(h+10)", fontSize: 14, fontFamily: "sans-serif", fill: "#350100" } }, ports: { groups: { pipes: { position: { name: "absolute", args: { x: "calc(w / 2)", y: "calc(h / 2)" } }, markup: util.svg` <rect @selector="pipeBody" /> <rect @selector="pipeEnd" /> `, size: { width: 50, height: 30 }, attrs: { portRoot: { magnetSelector: "pipeEnd" }, pipeBody: { width: "calc(w)", height: "calc(h)", y: "calc(h / -2)", fill: { type: "linearGradient", stops: [ { offset: "0%", color: "gray" }, { offset: "30%", color: "white" }, { offset: "70%", color: "white" }, { offset: "100%", color: "gray" }], attrs: { x1: "0%", y1: "0%", x2: "0%", y2: "100%" } } }, pipeEnd: { width: 10, height: "calc(h+6)", y: "calc(h / -2 - 3)", stroke: "gray", strokeWidth: 3, fill: "white" } } } }, items: [ { id: "left", group: "pipes", z: 0, attrs: { pipeBody: { x: "calc(-1 * w)" }, pipeEnd: { x: "calc(-1 * w)" } } }, { id: "right", group: "pipes", z: 0, attrs: { pipeEnd: { x: "calc(w - 10)" } } }] } }; } preinitialize() { this.markup = util.svg /* xml */` <rect @selector="stem" /> <path @selector="control" /> <ellipse @selector="body" /> <rect @selector="coverFrame" /> <path @selector="liquid" /> <rect @selector="cover" /> <text @selector="label" /> `; }} const ControlValveView = dia.ElementView.extend({ presentationAttributes: dia.ElementView.addPresentationAttributes({ open: [OPEN_FLAG] }), initFlag: [dia.ElementView.Flags.RENDER, OPEN_FLAG], framePadding: 6, liquidAnimation: null, confirmUpdate(...args) { let flags = dia.ElementView.prototype.confirmUpdate.call(this, ...args); this.animateLiquid(); if (this.hasFlag(flags, OPEN_FLAG)) { this.updateCover(); flags = this.removeFlag(flags, OPEN_FLAG); } return flags; }, updateCover() { const { model } = this; const opening = Math.max(0, Math.min(1, model.get("open") || 0)); const [coverEl] = this.findBySelector("cover"); const [coverFrameEl] = this.findBySelector("coverFrame"); const frameWidth = Number(coverFrameEl.getAttribute("width")) - this.framePadding; const width = Math.round(frameWidth * (1 - opening)); coverEl.animate( { width: [`${width}px`] }, { fill: "forwards", duration: 200 }); }, animateLiquid() { if (this.liquidAnimation) return; const [liquidEl] = this.findBySelector("liquid"); this.liquidAnimation = liquidEl.animate( { // 24 matches the length of the liquid path strokeDashoffset: [0, 24] }, { fill: "forwards", iterations: Infinity, duration: 3000 }); } }); class HandValve extends dia.Element { defaults() { return { ...super.defaults, type: "HandValve", size: { width: 50, height: 50 }, power: 0, attrs: { root: { magnetSelector: "body" }, body: { rx: "calc(w / 2)", ry: "calc(h / 2)", cx: "calc(w / 2)", cy: "calc(h / 2)", stroke: "gray", strokeWidth: 2, fill: { type: "radialGradient", stops: [ { offset: "70%", color: "white" }, { offset: "100%", color: "gray" }] } }, stem: { width: 10, height: 30, x: "calc(w / 2 - 5)", y: -30, stroke: "#333", strokeWidth: 2, fill: "#555" }, handwheel: { width: 60, height: 10, x: "calc(w / 2 - 30)", y: -30, stroke: "#333", strokeWidth: 2, rx: 5, ry: 5, fill: "#666" }, label: { text: "Valve", textAnchor: "middle", textVerticalAnchor: "top", x: "calc(0.5*w)", y: "calc(h+10)", fontSize: "14", fontFamily: "sans-serif", fill: "#350100" } }, ports: { groups: { pipes: { position: { name: "absolute", args: { x: "calc(w / 2)", y: "calc(h / 2)" } }, markup: util.svg` <rect @selector="pipeBody" /> <rect @selector="pipeEnd" /> `, size: { width: 50, height: 30 }, attrs: { portRoot: { magnetSelector: "pipeEnd" }, pipeBody: { width: "calc(w)", height: "calc(h)", y: "calc(h / -2)", fill: { type: "linearGradient", stops: [ { offset: "0%", color: "gray" }, { offset: "30%", color: "white" }, { offset: "70%", color: "white" }, { offset: "100%", color: "gray" }], attrs: { x1: "0%", y1: "0%", x2: "0%", y2: "100%" } } }, pipeEnd: { width: 10, height: "calc(h+6)", y: "calc(h / -2 - 3)", stroke: "gray", strokeWidth: 3, fill: "white" } } } }, items: [ { id: "left", group: "pipes", z: 0, attrs: { pipeBody: { x: "calc(-1 * w)" }, pipeEnd: { x: "calc(-1 * w)" } } }, { id: "right", group: "pipes", z: 0, attrs: { pipeEnd: { x: "calc(w - 10)" } } }] } }; } preinitialize() { this.markup = util.svg /* xml */` <rect @selector="stem" /> <rect @selector="handwheel" /> <ellipse @selector="body" /> <text @selector="label" /> `; }} class LiquidTank extends dia.Element { defaults() { return { ...super.defaults, type: "LiquidTank", size: { width: 160, height: 300 }, attrs: { root: { magnetSelector: "body" }, legs: { fill: "none", stroke: "#350100", strokeWidth: 8, strokeLinecap: "round", d: "M 20 calc(h) l -5 10 M calc(w - 20) calc(h) l 5 10" }, body: { stroke: "gray", strokeWidth: 4, x: 0, y: 0, width: "calc(w)", height: "calc(h)", rx: 120, ry: 10, fill: { type: "linearGradient", stops: [ { offset: "0%", color: "gray" }, { offset: "30%", color: "white" }, { offset: "70%", color: "white" }, { offset: "100%", color: "gray" }] } }, top: { x: 0, y: 20, width: "calc(w)", height: 20, fill: "none", stroke: "gray", strokeWidth: 2 }, label: { text: "Tank 1", textAnchor: "middle", textVerticalAnchor: "top", x: "calc(w / 2)", y: "calc(h + 10)", fontSize: 14, fontFamily: "sans-serif", fill: "#350100" } } }; } preinitialize() { this.markup = util.svg /* xml */` <path @selector="legs"/> <rect @selector="body"/> <rect @selector="top"/> <text @selector="label" /> `; } get level() { return this.get("level") || 0; } set level(level) { const newLevel = Math.max(0, Math.min(100, level)); this.set("level", newLevel); }} const LEVEL_FLAG = "LEVEl"; const PanelView = dia.ElementView.extend({ presentationAttributes: dia.ElementView.addPresentationAttributes({ level: [LEVEL_FLAG], color: [LEVEL_FLAG] }), initFlag: [dia.ElementView.Flags.RENDER, LEVEL_FLAG], confirmUpdate(...args) { let flags = dia.ElementView.prototype.confirmUpdate.call(this, ...args); if (this.hasFlag(flags, LEVEL_FLAG)) { this.updateLevel(); flags = this.removeFlag(flags, LEVEL_FLAG); } return flags; }, updateLevel() { const { model } = this; const level = Math.max(0, Math.min(100, model.get("level") || 0)); const color = model.get("color") || "red"; const [liquidEl] = this.findBySelector("liquid"); const [windowEl] = this.findBySelector("frame"); const windowHeight = Number(windowEl.getAttribute("height")); const height = Math.round(windowHeight * level / 100); liquidEl.animate( { height: [`${height}px`], fill: [color] }, { fill: "forwards", duration: 1000 }); } }); class ConicTank extends dia.Element { defaults() { return { ...super.defaults, type: "ConicTank", size: { width: 160, height: 280 }, open: 1, power: 1, attrs: { root: { magnetSelector: "bottom" }, body: { stroke: "gray", strokeWidth: 4, x: 0, y: 0, width: "calc(w)", height: "calc(h)", rx: 120, ry: 10, fill: { type: "linearGradient", stops: [ { offset: "0%", color: "gray" }, { offset: "30%", color: "white" }, { offset: "70%", color: "white" }, { offset: "100%", color: "gray" }] } }, top: { x: 0, y: "calc(h / 2 - 10)", width: "calc(w)", height: 20, fill: "none", stroke: "gray", strokeWidth: 2 }, rotorGroup: { transform: "translate(calc(w/2), calc(h/4))", event: "element:power:click", cursor: "pointer" }, rotorFrame: { r: 40, fill: "#eee", stroke: "#666", strokeWidth: 2, y: 0 }, rotorBackground: { r: 34, fill: "#777", stroke: "#222", strokeWidth: 1, style: { transition: "fill 0.5s ease-in-out" } }, rotor: { // d: `M ${a} ${a} ${b} ${r} -${b} ${r} -${a} ${a} -${r} ${b} -${r} -${b} -${a} -${a} -${b} -${r} ${b} -${r} ${a} -${a} ${r} -${b} ${r} ${b} Z`, d: `M 0 0 V ${r} l ${-d} ${-l} Z M 0 0 V ${-r} l ${d} ${l} Z M 0 0 H ${r} l ${-l} ${d} Z M 0 0 H ${-r} l ${l} ${-d} Z`, stroke: "#222", strokeWidth: 3, fill: "#bbb" }, liquidGroup: { transform: "translate(3, 70)" }, liquid: { // We use path instead of rect to make it possible to animate // the stroke-dasharray to show the liquid flow. d: "M calc(w / 2 + 12) calc(h / 2) h -24", stroke: LIQUID_COLOR, strokeWidth: 24, strokeDasharray: "3,1" }, cover: { x: "calc(w / 2 - 12)", y: "calc(h / 2 - 12)", width: 24, height: 24, stroke: "#333", strokeWidth: 2, fill: "#fff" }, coverFrame: { x: "calc(w / 2 - 15)", y: "calc(h / 2 - 15)", width: 30, height: 30, stroke: "#777", strokeWidth: 2, fill: "none", rx: 1, ry: 1 } }, ports: { groups: { pipes: { position: { name: "absolute", args: { x: "calc(w / 2)", y: "calc(h / 2)" } }, markup: util.svg` <rect @selector="pipeBody" /> <rect @selector="pipeEnd" /> `, size: { width: 50, height: 30 }, attrs: { portRoot: { magnetSelector: "pipeEnd" }, pipeBody: { width: "calc(w)", height: "calc(h)", y: "calc(h / -2)", fill: { type: "linearGradient", stops: [ { offset: "0%", color: "gray" }, { offset: "30%", color: "white" }, { offset: "70%", color: "white" }, { offset: "100%", color: "gray" }], attrs: { x1: "0%", y1: "0%", x2: "0%", y2: "100%" } } }, pipeEnd: { width: 10, height: "calc(h+6)", y: "calc(h / -2 - 3)", stroke: "gray", strokeWidth: 3, fill: "white" } } } }, items: [ { id: "left", group: "pipes", z: -1, attrs: { pipeBody: { x: "calc(-2.5 * w)" }, pipeEnd: { x: "calc(-2.5 * w)" } } }, { id: "right", group: "pipes", z: -1, attrs: { pipeBody: { x: "calc(1.3 * w)" }, pipeEnd: { x: "calc(2.3 * w)" } } }] } }; } preinitialize() { this.markup = util.svg /* xml */` <rect @selector="body"/> <g @selector="rotorGroup"> <circle @selector="rotorFrame" /> <circle @selector="rotorBackground" /> <path @selector="rotor" /> </g> <g @selector="liquidGroup"> <rect @selector="coverFrame" /> <path @selector="liquid" /> <rect @selector="cover" /> </g> <rect @selector="top"/> `; } get power() { return this.get("power") || 0; } get open() { return this.get("open") || 0; } set power(value) { this.set("power", value); }} const ConicTankView = dia.ElementView.extend({ presentationAttributes: dia.ElementView.addPresentationAttributes({ power: [POWER_FLAG, OPEN_FLAG] }), initFlag: [dia.ElementView.Flags.RENDER, POWER_FLAG, OPEN_FLAG], powerAnimation: null, framePadding: 6, liquidAnimation: null, confirmUpdate(...args) { let flags = dia.ElementView.prototype.confirmUpdate.call(this, ...args); this.animateLiquid(); if (this.hasFlag(flags, POWER_FLAG)) { this.togglePower(); flags = this.removeFlag(flags, POWER_FLAG); } if (this.hasFlag(flags, OPEN_FLAG)) { this.updateCover(); flags = this.removeFlag(flags, POWER_FLAG); } return flags; }, getSpinAnimation() { let { spinAnimation } = this; if (spinAnimation) return spinAnimation; const [rotorEl] = this.findBySelector("rotor"); // It's important to use start and end frames to make it work in Safari. const keyframes = { transform: ["rotate(360deg)", "rotate(0deg)", "rotate(90deg)", "rotate(180deg)"] }; spinAnimation = rotorEl.animate(keyframes, { fill: "forwards", duration: 2000, iterations: Infinity }); this.spinAnimation = spinAnimation; return spinAnimation; }, togglePower() { const { model } = this; this.getSpinAnimation().playbackRate = model.power; }, updateCover() { const { model } = this; const opening = Math.max(0, Math.min(1, model.get("open") || 0)); const [coverEl] = this.findBySelector("cover"); const [coverFrameEl] = this.findBySelector("coverFrame"); const frameWidth = Number(coverFrameEl.getAttribute("width")) - this.framePadding; const width = Math.round(frameWidth * (1 - opening)); coverEl.animate( { width: [`${width}px`] }, { fill: "forwards", duration: 200 }); }, anima.........完整代码请登录后点击上方下载按钮下载查看
网友评论0