您现在的位置是:首页 > 技术教程 正文

使用Jsmind实现前端流程图功能

admin 阅读: 2024-04-01
后台-插件-广告管理-内容页头部广告(手机)

需求:实现流程图功能,根据状态不同显示不同的颜色,点击有对应的点击颜色

思想:根据jsmind构建思维导图,改变节点背景颜色,获取点击节点事件当点击节点是设置节点选中背景图片。

注意:由于jsmind更新各版本api都有很大改动,所以我使用的都是官方文档注明的基于各版本都支持的api

效果:

 这里的要素是根据接口返回的,具体接口数据如下:

 root是根节点,chrldren是子要素,可以根据自己的需求自行改造

代码:

先引入jsmind库(我引入的最新版本0.5)

npm install jsmind@latest --save

找到刚才引入vue中的jsmind的npm包,可以看到jsmind.css,在这里可以修改我们想要的样式,但是如果在这里修改是不会更新到git版本里面去,所以我们需要在src->style文件夹内新scss文件,这样我们改动样式可以更新到git版本控制中。

 新建一个scss文件内容如下:(自己新建了一个主题名字为034,可以自行更改)

  1. /**
  2. * @license BSD
  3. * @copyright 2014-2023 hizzgdev@163.com
  4. *
  5. * Project Home:
  6. * https://github.com/hizzgdev/jsmind/
  7. */
  8. /* important section */
  9. .jsmind-inner {
  10. position: relative;
  11. overflow: auto;
  12. width: 100%;
  13. height: 100%;
  14. outline: none;
  15. }
  16. /*box-shadow:0 0 2px #000;*/
  17. .jsmind-inner {
  18. moz-user-select: -moz-none;
  19. -moz-user-select: none;
  20. -o-user-select: none;
  21. -khtml-user-select: none;
  22. -webkit-user-select: none;
  23. -ms-user-select: none;
  24. user-select: none;
  25. }
  26. .jsmind-inner canvas {
  27. position: absolute;
  28. }
  29. /* z-index:1 */
  30. svg.jsmind {
  31. position: absolute;
  32. z-index: 1;
  33. }
  34. canvas.jsmind {
  35. position: absolute;
  36. z-index: 1;
  37. }
  38. /* z-index:2 */
  39. jmnodes {
  40. position: absolute;
  41. z-index: 2;
  42. background-color: rgba(0, 0, 0, 0);
  43. width: 100% !important;
  44. right: 40px;
  45. }
  46. /*background color is necessary*/
  47. jmnode {
  48. position: absolute;
  49. cursor: default;
  50. max-width: 400px;
  51. box-shadow: 0;
  52. }
  53. /* 自定义自己的主题 */
  54. jmnodes.theme-034 jmnode {
  55. width: 200px;
  56. height: 62px;
  57. text-align: left;
  58. color: #192C44;
  59. background-repeat: no-repeat;
  60. background-size: cover;
  61. padding: 7px 20px;
  62. font-size: 13px;
  63. border-radius: 4px;
  64. }
  65. /* 节点样式 */
  66. jmnodes.theme-034 jmnode:hover {}
  67. /* 鼠标悬停的节点样式 */
  68. jmnodes.theme-034 jmnode.selected {
  69. color: #192C44;
  70. background-color: transparent;
  71. }
  72. jmnodes.theme-034 .topicbody {
  73. pointer-events: none;
  74. .title {
  75. font-size: 12px;
  76. }
  77. .body {
  78. display: flex;
  79. align-items: center;
  80. margin-top: 6px;
  81. .left {
  82. width: 7px;
  83. height: 7px;
  84. border-radius: 50%;
  85. margin-right: 10px;
  86. }
  87. .right {
  88. font-size: 12px;
  89. }
  90. }
  91. }
  92. jmnodes.theme-034 .acitve {
  93. pointer-events: none;
  94. .title {
  95. font-size: 12px;
  96. color: white;
  97. }
  98. .body {
  99. display: flex;
  100. align-items: center;
  101. margin-top: 6px;
  102. color: white !important;
  103. .left {
  104. width: 7px;
  105. height: 7px;
  106. background-color: #fff !important;
  107. border-radius: 50%;
  108. margin-right: 10px;
  109. }
  110. .right {
  111. font-size: 12px;
  112. color: white !important;
  113. }
  114. }
  115. }
  116. /* 选中的节点样式 */
  117. jmnodes.theme-034 jmnode.root {
  118. width: 180px;
  119. height: 55px;
  120. text-align: center;
  121. padding: 10px;
  122. font-size: 16px;
  123. }
  124. jmnodes.theme-034 jmnode.root.selected {
  125. color: #192C44;
  126. }
  127. /* 根节点样式 */
  128. jmnodes.theme-034 jmexpander {}
  129. /* 展开/关闭节点的控制点样式 */
  130. jmnodes.theme-034 jmexpander:hover {}

vue文件代码如下:

  1. <template>
  2. <div class="jsmind">
  3. <el-card>
  4. <div class="content" id="jsmind_container"></div>
  5. </el-card>
  6. </div>
  7. </template>
  8. <script>
  9. import JSMind from "jsmind";
  10. import "@/style/jsmind.scss";
  11. import { nest034getJsmind } from "@/api/datapretreatment";
  12. export default {
  13. components: {},
  14. data() {
  15. return {
  16. mindData: "", //jsmind相关配置
  17. jm: "", //jsmind对象
  18. curcodeInfo: null, //当前选中节点信息
  19. };
  20. },
  21. created() {},
  22. mounted() {
  23. this.handleMind();
  24. },
  25. watch: {
  26. curcodeInfo: {
  27. handler() {},
  28. },
  29. },
  30. computed: {},
  31. methods: {
  32. // 初始化jsmind-----主题需要去jsmind的style里面去修改自定义主题样式
  33. initjsmind() {
  34. // 初始化配置
  35. var options = {
  36. container: "jsmind_container",
  37. theme: "034",
  38. editable: false,
  39. view: {
  40. engine: "canvas", // 思维导图各节点之间线条的绘制引擎
  41. hmargin: 10, // 思维导图距容器外框的最小水平距离
  42. vmargin: 20, // 思维导图距容器外框的最小垂直距离
  43. line_width: 2, // 思维导图线条的粗细
  44. line_color: "#C6DDFFFF", // 思维导图线条的颜色
  45. },
  46. layout: {
  47. hspace: 80, // 节点之间的水平间距
  48. vspace: 10, // 节点之间的垂直间距
  49. pspace: 10, // 节点与连接线之间的水平间距(用于容纳节点收缩/展开控制器)
  50. },
  51. };
  52. this.jm = new JSMind(options);
  53. const mind = {
  54. /* 元数据,定义思维导图的名称、作者、版本等信息 */
  55. meta: {
  56. name: "流程图",
  57. author: "dingguowei",
  58. version: "0.2",
  59. },
  60. /* 数据格式声明 */
  61. format: "node_tree",
  62. /* 数据内容 */
  63. data: this.mindData,
  64. };
  65. this.jm.show(mind);
  66. var that = this;
  67. // 增加监听点击节点事件,获取当前选中的节点
  68. this.jm.add_event_listener(function (type, node) {
  69. if (that.jm.get_selected_node() !== null) {
  70. // 设置curcodeInfo属性,监听节点是否为根节点,根节点不会改变curcodeInfo也就不会查询右侧日志,只有子节点会改变topic
  71. if (that.jm.get_selected_node().isroot === false) {
  72. // 恢复上一个节点的状态
  73. if (that.curcodeInfo !== null) {
  74. that.curcodeInfo.topic.className = "topicbody";
  75. }
  76. // 不为根节点
  77. that.curcodeInfo = that.jm.get_selected_node();
  78. // 更新节点背景颜色
  79. that.curcodeInfo.topic.className = "acitve";
  80. that.jm.update_node(that.curcodeInfo.id);
  81. that.refresh(that.curcodeInfo);
  82. }
  83. }
  84. });
  85. },
  86. // 配置mind信息
  87. async handleMind() {
  88. var that = this;
  89. await nest034getJsmind().then((res) => {
  90. let mindData = {
  91. id: res.data.root.name,
  92. topic: res.data.root.name,
  93. "background-image": that.getbgcimg(res.data.root.status),
  94. children: [],
  95. };
  96. res.data.root.children.map((item) => {
  97. mindData.children.push({
  98. id: item.name,
  99. topic: this.gethtml(item),
  100. "background-image": that.getbgcimg(item.status),
  101. activeimg: that.getbgcimg(item.status, true),
  102. noacitveimg: that.getbgcimg(item.status),
  103. });
  104. });
  105. that.mindData = mindData;
  106. that.initjsmind();
  107. });
  108. // 获取节点 ID
  109. var node_id = this.jm.get_node("温度").id;
  110. // 选中节点
  111. this.jm.select_node(node_id);
  112. },
  113. // 获取背景图片
  114. getbgcimg(val, acitve) {
  115. let url = "";
  116. if (acitve) {
  117. switch (val) {
  118. case "processing":
  119. url = "./img/jsmind/curprocessing.png";
  120. break;
  121. case "error":
  122. url = "./img/jsmind/curerror.png";
  123. break;
  124. case "finse":
  125. url = "./img/jsmind/curfinse.png";
  126. break;
  127. case "notstart":
  128. url = "./img/jsmind/curnotstart.png";
  129. break;
  130. default:
  131. url = "./img/jsmind/curfinse.png";
  132. break;
  133. }
  134. return url;
  135. } else {
  136. switch (val) {
  137. case "processing":
  138. url = "./img/jsmind/processing.png";
  139. break;
  140. case "error":
  141. url = "./img/jsmind/error.png";
  142. break;
  143. case "finse":
  144. url = "./img/jsmind/finse.png";
  145. break;
  146. case "notstart":
  147. url = "./img/jsmind/notstart.png";
  148. break;
  149. default:
  150. url = "./img/jsmind/finse.png";
  151. break;
  152. }
  153. return url;
  154. }
  155. },
  156. // 生成html
  157. gethtml(val) {
  158. let divObj = document.createElement("div");
  159. divObj.className = "topicbody";
  160. // 要素名称
  161. let title = document.createElement("div");
  162. title.className = "title";
  163. title.innerHTML = val.name;
  164. divObj.appendChild(title);
  165. // 要素状态
  166. let body = document.createElement("div");
  167. body.className = "body";
  168. let left = document.createElement("div");
  169. left.className = "left";
  170. left.style.backgroundColor = {
  171. processing: "#015DF3FF",
  172. finse: "#00C553FF",
  173. notstart: "#C7C7C7FF",
  174. error: "#F98100FF",
  175. }[val.status];
  176. body.appendChild(left);
  177. let right = document.createElement("div");
  178. right.className = "right";
  179. right.innerHTML = {
  180. processing: "进行中",
  181. finse: "已完成",
  182. notstart: "未开始",
  183. error: "异常报警",
  184. }[val.status];
  185. right.style.color = {
  186. processing: "#015DF3FF",
  187. finse: "#00C553FF",
  188. notstart: "#C7C7C7FF",
  189. error: "#F98100FF",
  190. }[val.status];
  191. body.appendChild(right);
  192. divObj.appendChild(body);
  193. return divObj;
  194. },
  195. // 更新视图
  196. refresh(node) {
  197. this.mindData.children.map((item) => {
  198. if (item.id === node.id) {
  199. item["background-image"] = item["activeimg"];
  200. } else {
  201. item["background-image"] = item["noacitveimg"];
  202. }
  203. });
  204. const mind = {
  205. /* 元数据,定义思维导图的名称、作者、版本等信息 */
  206. meta: {
  207. name: "流程图",
  208. author: "dingguowei",
  209. version: "0.2",
  210. },
  211. /* 数据格式声明 */
  212. format: "node_tree",
  213. /* 数据内容 */
  214. data: this.mindData,
  215. };
  216. this.jm.show(mind);
  217. },
  218. },
  219. };
  220. </script>
  221. <style lang="scss" scoped>
  222. .jsmind {
  223. width: 100%;
  224. // height: 460px;
  225. .content {
  226. height: 420px;
  227. width: 100%;
  228. }
  229. }
  230. </style>

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜