效果图:
jsmind组件下载地址:https://files.cnblogs.com/files/fengyeqingxiang/jsmind.zip
后端代码,此处以C#编写的后台,Java或其他语言同理
using Web.Model.Design; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Web; using System.Web.Mvc; namespace Web.Controllers { public class DesignController : BaseController { BLL.Design.Design_DrawingData bll = new BLL.Design.Design_DrawingData(); #region 以树形式展示图纸目录 /// <summary> /// 视图 /// </summary> /// <returns></returns> public ActionResult DrawingTree() { if (CurrentUser == null)//验证用户是否登录 return new HttpUnauthorizedResult(); return View(); } #endregion /// <summary> /// 文件树视图,页面初始化获取树数据,以json形式返回 /// </summary> /// <returns></returns> public ActionResult GetDesignFileTreeData() { List<FileNode> listTree = InitTree(); return Json(listTree, JsonRequestBehavior.AllowGet); } /// <summary> /// 初始化加载树 /// </summary> /// <returns></returns> private List<FileNode> InitTree() { List<FileNode> listNodes = new List<FileNode>(); BLL.Design.Design_DrawingData home = new BLL.Design.Design_DrawingData(); var newTree = home.QueryList(); //数据库查找数据源,此处也可以定义虚拟数据 #region 一次性存储数据源,后面后面递归子集时多次使用 List<FileNode> nodeList = new List<FileNode>(); foreach (var item in newTree) { FileNode node2 = new FileNode(); node2.id = item.DrawingId;//要显示的id,此id一般为表的主键,具有唯一性 node2.topic = item.DrawingCode;//要显示的名称 node2.direction = item.Note;//思维导图伸向,目前只支持left/right node2.parentId = item.ParentDrawingId; node2.expanded = true;//该节点是否展开 if (item.FilePath!=null&&item.FilePath.Length>0) { node2.background = "#eee";//节点背景色 node2.foreground = "blue";//节点字体色 node2.topic = item.DrawingCode +"(<a href=\"javascript:showFile('"+item.FilePath+"');\">预览</a> <a href=\""+item.FilePath+"\" target=\"view_window\">下载</a>)"; } nodeList.Add(node2); } #endregion #region 装载数据源,此数据结果返回的是最终的所有结点树集合 List<FileNode> rootNode = new List<FileNode>(); foreach (var plist in newTree.Where(t => t.ParentDrawingId == 0)) { FileNode node = new FileNode(); node.id = plist.DrawingId; node.topic = plist.DrawingCode; node.direction = plist.Note;//思维导图伸向,目前只支持left/right node.parentId = plist.ParentDrawingId; node.background = "#eee";//节点背景颜色 node.foreground = "blue";//节点字体颜色 node.expanded = true; node.children = CreateChildTree(nodeList, node); rootNode.Add(node); } return rootNode; #endregion } /// <summary> /// 获取子集树 /// </summary> /// <param name="TreeList"></param> /// <param name="jt"></param> /// <returns></returns> private List<FileNode> CreateChildTree(List<FileNode> TreeList, FileNode filenode) { List<FileNode> nodeList = new List<FileNode>(); var children = TreeList.Where(t => t.parentId == filenode.id); foreach (var chl in children) { FileNode node = new FileNode(); node.id = chl.id; node.topic = chl.topic; node.direction = chl.direction;//思维导图伸向,目前只支持left/right node.parentId = chl.parentId; node.background = chl.background;//节点背景颜色 node.foreground = chl.foreground;//节点字体颜色 node.expanded = true; node.children = CreateChildTree(TreeList, node); nodeList.Add(node); } return nodeList; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Web.Model.Design { ///<summary> ///节点实体类 /// </summary> [Serializable] public class FileNode { public int id { get; set; }//对应jsmind唯一id public string topic { get; set; }//对应jsmind显示的名称 public string direction { get; set; }//对应jsmind思维导图的朝向 left/right public bool expanded { get; set; } //对应jsmind该节点是否展开true/false public string background { get; set; } //jsmind只识别background-color属性,此处定义“-”会编译不通过,待前台js批量替换处理 public string foreground { get; set; } //jsmind只识别foreground-color属性,此处定义“-”会编译不通过,待前台js批量替换处理 public int parentId { get; set; } //jsmind没有此属性,此处定义为了与数据库所属父节点字段对应,递归关联查询时会用到 public List<FileNode> children { get; set; }//对应jsmind当前节点的子节点集合 } }
前端页面代码,此处以asp.net mvc页面视图编写,都是插件获取后台返回的json,其他语言同理
@model List<Model.Design.Design_DrawingData> @{ ViewBag.Title = "jsmind思维导图展示树"; Layout = "~/Themes/default/Views/Shared/_Layout.cshtml "; ViewBag.PageSystemName = "DrawingTree"; } <link type="text/css" rel="stylesheet" href="~/Content/plugins/jsmind/style/jsmind.css" /> <section> <div class="popProjectBaseInfo"> <div class="box box-default box_baseinfo"> <div class="box-header with-border"> <h3 class="box-title">上传图纸</h3> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px; οnclick="show_data();">提取json</button> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px" onclick="remove_node();">删除节点</button> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px" onclick="zoomIn();">放大</button> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px" onclick="zoomOut();">缩小</button> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px" onclick="expand_all();">展开所有节点</button> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px" onclick="collapse_all();">合并所有节点</button> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px; οnclick="show_selected();">获取选择的节点</button> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px" onclick="add_node();">历史版本</button> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px" onclick="add_node();">图纸变更</button> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px" onclick="add_upfile();">上传图纸</button> <button type="button" class="btn add-btn-class pull-right" style="margin-right: 5px" onclick="add_node();">新增节点</button> </div> <div class="box-body content_block_content"> <div id="layout"> <div id="jsmind_container"></div> <div style="display: none"> <input class="file" type="file" id="image-chooser" accept="image/*" /> </div> </div> <script type="text/javascript" src="~/Content/plugins/jsmind/js/jsmind.js"></script> <script type="text/javascript" src="~/Content/plugins/jsmind/js/jsmind.draggable.js"></script> <script type="text/javascript" src="~/Content/plugins/jsmind/js/jsmind.screenshot.js"></script> <script type="text/javascript"> var _jm = null; function open_empty() { var options = { container: 'jsmind_container', theme: 'greensea', editable: true } _jm = jsMind.show(options); // _jm = jsMind.show(options,mind); } //思维导图区自适应高度 window.onload = function () { function auto_height() { //var h= document.documentElement.clientHeight-200; //var high = document.getElementById("box"); //high.style.height=h+"px"; document.getElementById("jsmind_container").style.height = document.documentElement.clientHeight-180 + "px"; } auto_height(); onresize = auto_height; } //预览图纸 function showFile(filepath) { layer.photos({ photos: { "data": [{ "src": filepath }] }, anim: 5 }); } //初始化获取树信息,加载到jsmin插件里 $(function () { $.get("/Design/GetDesignFileTreeData", function (data) { //因jsmind插件识别的json格式外侧不识别[],所以此处需要进行处理,将json解析成字符串删除两边[]后再转成json格式 var str = JSON.stringify(data); str = str.slice(1); //删除第一个字符[ str = str.substring(0, str.length - 1);//删除 最后一个字符] var newstr = "{\"id\":\"0\",\"topic\":\"XX项目\",\"children\":[" + str + "]}"; //定义jsmind中心节点数据,此节点不是数据库返回的数据 //下面处理jsmind识别颜色的属性,因后台返回的没有-color,此处批量处理jsmind才能识别 re = new RegExp("background", "g"); //定义正则表达式,g标识全部替换 newstr = newstr.replace(re, "background-color"); re = new RegExp("foreground", "g"); //定义正则表达式,g标识全部替换 newstr = newstr.replace(re, "foreground-color"); //最终将处理好的json字符串转成json格式 var jsonData = $.parseJSON(newstr); console.log(jsonData); //加载模型树 var mind = { "meta": { "name": "jsMind remote", "author": "563924009@qq.com", "version": "0.2" }, "format": "node_tree",//node_array为列表模式 "data": jsonData } _jm.show(mind); }) }) //提取jsmind页面展示的json数据 function show_data() { var mind_data = _jm.get_data(); var mind_string = jsMind.util.json.json2string(mind_data); prompt_info(mind_string); } //获取选择的节点id function get_selected_nodeid() { var selected_node = _jm.get_selected_node(); if (!!selected_node) { return selected_node.id; } else { return null; } } //新增节点 function add_node() { var selected_node = _jm.get_selected_node(); // as parent of new node if (!selected_node) { prompt_info('请选择一个节点!'); return; } layer_show('新增节点', '/Design/DrawingAdd?drawingId=' + selected_node.id, 600, 350); } //节点下上传文件 function add_upfile() { var selected_node = _jm.get_selected_node(); // as parent of new node if (!selected_node) { prompt_info('请选择一个节点!'); return; } var isLastNode = Object.keys(selected_node.children).length; if (isLastNode > 0) { if (selected_node.children[0].topic.indexOf('href') > 0) { layer.msg("该节点已上传文件!", { icon: 0 }); } else { layer_show('图纸上传', '/Design/Drawingupload?drawingId=' + selected_node.id, 650, 350); } } else { layer_show('图纸上传', '/Design/Drawingupload?drawingId=' + selected_node.id, 650, 350); } } //删除节点 function remove_node() { var selected_id = get_selected_nodeid(); if (!selected_id) { prompt_info('please select a node first.'); return; } _jm.remove_node(selected_id); } //画布缩小 function zoomIn() { if (_jm.view.zoomIn()) { zoomOutButton.disabled = false; } else { zoomInButton.disabled = true; }; }; //画布放大 function zoomOut() { if (_jm.view.zoomOut()) { zoomInButton.disabled = false; } else { zoomOutButton.disabled = true; }; }; //展开所有节点 function expand_all() { _jm.expand_all(); } //合并所有节点 function collapse_all() { _jm.collapse_all(); } //layer提示信息 function prompt_info(msg) { alert(msg); } </script> </div> </div> </div> </section>