jsMind思维导图模式展⽰数据效果图:
jsmind组件下载地址:filesblogs/files/fengyeqingxiang/jsmind.zip
后端代码,此处以C#编写的后台,Java或其他语⾔同理
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 TreeDataController : BaseController
{
BLL.TreeData bll = new BLL.TreeData();
#region 以树形式展⽰图纸⽬录
/// <summary>
/// 视图
/// </summary>
/// <returns></returns>
public ActionResult DrawingTree()
{
if (CurrentUser == null)//验证⽤户是否登录
return new HttpUnauthorizedResult();
return View();
}
#endregion
/// <summary>
sofia/// ⽂件树视图,页⾯初始化获取树数据,以json形式返回
/// </summary>
/// <returns></returns>
public ActionResult GetTreeData()
{
List<FileNode> listTree = InitTree();
return Json(listTree, JsonRequestBehavior.AllowGet);
}
/// <summary>
/// 初始化加载树
/// </summary>
/// <returns></returns>
private List<FileNode> InitTree()
{
List<FileNode> listNodes = new List<FileNode>();
var newTree = bll.QueryList(); //数据库查数据源,此处也可以定义虚拟数据
#region ⾸次加载检测不到数据时默认插⼊项⽬节点
if (newTree.Count == 0)
{
bll.Add(new Model.TreeData()
{
BgColor = "#eee";//节点背景颜⾊
FgColor="#eee";//节点字体颜⾊
Level = 0,
Order = 0,
TreeName = "项⽬名称",
TreeCode = "节点编码",
ParentId = 0,
UpdateTime = DateTime.Now,
FilePath=null
});
}
#endregion
#region ⼀次性存储数据源,后⾯后⾯递归⼦集时多次使⽤
List<FileNode> nodeList = new List<FileNode>();
foreach (var item in newTree)
{
FileNode node2 = new FileNode();
node2.id = item.Id;//要显⽰的id,此id⼀般为表的主键,具有唯⼀性
node2.direction = "right";//思维导图伸向,⽬前只⽀持left/right
node2.parentId = item.ParentId;
nodeList.Add(node2);
}
#endregion
#region 装载数据源,此数据结果返回的是最终的所有结点树集合
List<FileNode> rootNode = new List<FileNode>();
foreach (var plist in newTree.Where(t => t.ParentId== 0))
{
FileNode node = new FileNode();
node.id = plist.Id;
node.direction = plist.Note;//思维导图伸向,⽬前只⽀持left/right
node.parentId = plist.ParentId;
node.background = "#eee";//节点背景颜⾊
node.foreground = "blue";//节点字体颜⾊
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.direction = chl.direction;//思维导图伸向,⽬前只⽀持left/right
node.parentId = chl.parentId;
node.background = chl.background;//节点背景颜⾊
node.foreground = chl.foreground;//节点字体颜⾊
node.children = CreateChildTree(TreeList, node);
nodeList.Add(node);
}
return nodeList;
}
/// <summary>
/// 根据选择的节点ID和⽅向参数,获取同级的上⼀个节点ID或下⼀个节点ID
/// </summary>
/// <returns>上⼀个或下⼀个节点排序号</returns>
[HttpPost]
public JsonResult GetMoveOrder()
{
var id = GetQueryString("id");
var parentId = GetQueryInt("parent", 0);
var direction = GetQueryString("direction");
var model = bll.GetModel(Convert.ToInt32(id));
int upId = -1;
int targetId = -1;//最终返回的相邻的上/下的节点ID
if (direction == "up") //向上移动
{
upId = Convert.der) - 1;
if (upId >= 0)
{
//执⾏修改本⾝
bll.Update(model);
//执⾏修改相邻的上⼀个
var list = bll.GetAllList("parentId='" + parentId+ "'  and order='" + upId + "' and id<>'"+Id+"'");                    if (list.Count > 0)
{
var upModel = list[0];
bll.Update(upModel);
targetId = upModel.id;
}
}
}
else
{
upId = Convert.der) + 1;
var list = bll.GetAllList("ParentDrawingId='" + parentId+ "'");
if (upId < list.Count)
{
//执⾏修改本⾝
bll.Update(model);
//执⾏修改相邻的上⼀个
var newList = list.Where(c => c.order== upId && c.id!= model.id);
if (newList.Count() > 0)
{
var upModel = newList.FirstOrDefault();
bll.Update(upModel);
targetId = upModel.DrawingId;
}
}
}
return Json(new
{
result = targetId.ToString()
}, JsonRequestBehavior.AllowGet);
}
}
}
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 mvc页⾯视图编写,都是插件获取后台返回的json,其他语⾔同理
@model  List<Model.Admin.TreeData>
@{
ViewBag.Title = "上传⽂件";
start here}
<div class="bim-cont">
<div class="bim-forms bg-none">
<form class="form-inline">
<div class="form-group">
<input type="hidden"  id="moveDirection" value="up"/>
<input type="text" class="form-control" id="keywords" placeholder="请输⼊节点名称">
</div>
<button type="button" class="btn js-btn-class margin"οnclick="search()">检索</button>
</form>
</div>
<div class="box table-responsive border-top-none" id="contentbody" >
<div id="layout">
<div id="jsmind_container"></div>
<div >
<input class="file" type="file" id="image-chooser" accept="image/*"/>
</div>
</div>
</div>
</div>
<!--右侧菜单-->
<div id="divmenu" class="menu">
<ul>
<li οnclick="expand_all()" class="pub">展开所有</li>
<li οnclick="collapse_all()" class="pub">合并所有</li>
<li οnclick="zoomIn()" class="pub">画布放⼤</li>
<li οnclick="zoomOut()" class="pub">画布缩⼩</li>
<li οnclick="add_node();" class="add">新增节点</li>
<li οnclick="add_upfile();" class="upload">上传⽂件</li>
<li οnclick="show_selected();" class="sel">查看节点</li>
<li οnclick="remove_node()" class="delete">删除</li>
<li οnclick="move_node('up')" class="move">上移</li>
<li οnclick="move_node('down')" class="move">下移</li>
</ul>
</div>
@section Styles{
<link type="text/css" rel="stylesheet" href="~/Content/plugins/jsmind/style/jsmind.css"/>
<style>
.bim-forms {
border-bottom: solid 1px #f5f1f1;
}
.bim-forms .btn {
padding: 6px 12px;
}
.menu {
width: 100px;
font-size: 14px;
font-family: "微软雅⿊";
border: 1px solid #ccc;
z-index: 9999;
position: absolute;
display: none;
background: #f2f2f2;
}
.
menu ul {
margin: 0px;
padding: 0px;
text-align: center;
list-style-type: none;
}
.menu ul li {
padding: 3px 0px;
font-size: 12px;
}
.menu ul li:hover {
background: #e1dddd;
}
.menu ul li a:link {
color: #000;
text-decoration: none;
}
</style>
}
@section Scripts{
<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: false
}
_jm = jsMind.show(options);
}
var jm = 0;
function auto_height() {
if (jm == 0) jm = $(".root").offset().top - ($("#jsmind_container").parent().height() / 2) - ($("body").height() / 2) -140; //获取中⼼点位置
var cavHeight = $("#jsmind_container").find("canvas").height();//-3703
$("#jsmind_container").height(cavHeight); //将画布⾼度设置与拖动层
$("#jsmind_container").offset({ top: ((0 - jm)), left: ($("body").width() / 10) }); //将中⼼点调⾄屏幕中⼼
}
//预览⽂件
function showFile(filepath) {
layer.photos({ photos: { "data": [{ "src": filepath }] }, anim: 5 });
}
$(function () {
//初始化装载数据
open_empty();
InitJsMind();
dragFunc("jsmind_container");
//监听右侧菜单点击事件,发⽣点击则隐藏菜单层
$("#divmenu").click(function (event) {
var $this = $(event.target);
$("#divmenu").hide();
});
//画布添加⿏标点击事件
$('#jsmind_container').mousedown(function (e) {
if (e.which == 1) {  // 1 = ⿏标左键 left; 2 = ⿏标中键; 3 = ⿏标右键
$("#divmenu").hide();
}
});
$("#contentbody").bind("contextmenu", function () {
var div = $("#divmenu");
if (showmenu()) div.css({ "left": document.body.scrollLeft + event.clientX - 125, "top": document.body.scrollTop + event.clientY - 60 }).show();
return false;
});
});
//页⾯初始化获取树数据
function InitJsMind() {
$.get("/Admin/GetTreeData", function (data) {
var str = JSON.stringify(data);
str = str.slice(1); //删除第⼀个字符[
str = str.substring(0, str.length - 1);//删除最后⼀个字符]
re = new RegExp("background", "g"); //定义正则表达式,g标识全部替换
var newstr = place(re, "background-color");
re = new RegExp("foreground", "g"); //定义正则表达式,g标识全部替换
newstr = place(re, "foreground-color");
var jsonData = $.parseJSON(newstr);
console.log(jsonData);
//加载模型树
var mind = {
"meta": {
"name": "",
"author": "",
"version": "0"
},
"format": "node_tree",//node_array
"data": jsonData
}
_jm.show(mind);
auto_height();
})
}
//新增节点
function add_node() {
var selected_node = _jm.get_selected_node(); // as parent of new node
if (!selected_node) { layer.msg('请选择⼀个节点!'); return; }
var fHeight = 280;
if (selected_node.data.leave == 0) { //根节点新增时因为字段多,⾼度单独做调整
fHeight = 420;
}
layer_show('新增节点', '/Admin/Add?Id=' + selected_node.id, 600, fHeight);
}
//新增、变更节点完成后⼦页⾯调此⽅法
function append_node(newNode) {
_jm.enable_edit();//新增前置为可编辑状态
var selected_node = _jm.get_selected_node(); // as parent of new node
if (!selected_node) { prompt_info('请先选择⼀个节点.'); return; }
//处理json数据
var str = JSON.stringify(newNode);
re = new RegExp("background", "g"); //定义正则表达式,g标识全部替换
var newstr = place(re, "background-color");
re = new RegExp("foreground", "g"); //定义正则表达式,g标识全部替换
newstr = place(re, "foreground-color");
var jsonData = $.parseJSON(newstr);
//delete jsonData["direction"];
console.log(jsonData);
//开始新增
var nodeid = newNode.id;
var topic = pic;
var node = _jm.add_node(selected_node, nodeid, topic, jsonData);
_jm.disable_edit();//新增前置为不可编辑状态
}
//⽂件变更
function update_nodes() {
var selected_node = _jm.get_selected_node(); // as parent of new node
if (!selected_node) { layer.msg('请选择⼀个节点!'); return; }
var isLastNode = Object.keys(selected_node.children).length;
if (isLastNode > 0) {
layer.msg('请选择⽂件节点进⾏变更!');
} else {
if (selected_node.id == 0) {  //中⼼根节点不能直接上传⽂件
layer.msg("根节点不可上传!", { icon: 0 });
}
else {
layer_show('⽂件变更', '/Admin/Update?Id=' + selected_node.id, 700, 540);
}
}
}
//⽂件变更后⼦页⾯调⽗页⾯⽅法
汪涵不知道何洁三胎
function update_node(nodeid, topic) {
_jm.enable_edit();//置为可编辑状态
_jm.update_node(nodeid, topic);
_jm.disable_edit();//置为不可编辑状态
}
//上移、下移节点,direction(top,bottom)
function move_node(direction) {
var selected_node = _jm.get_selected_node();
$("#moveDirection").val(direction);
$.post("/Admin/GetMoveOrder", { Id: selected_node.id, parentId: selected_node.data.parentId, direction: direction }, function (d) { if (d.result != -1) {
_jm.enable_edit();//置为可编辑状态
_jm.move_node(selected_node.id, d.result);
_jm.disable_edit();//置为不可编辑状态
} else {
if (direction=="up") {
layer.msg("已经是最顶级!", { icon: 0 });
} else {
layer.msg("已经是最下级!", { icon: 0 });
}
}
});
}
//上传⽂件
function add_upfile() {
var selected_node = _jm.get_selected_node();
if (!selected_node) { layer.msg('请选择⼀个节点!'); return; }
var isLastNode = Object.keys(selected_node.children).length;
if (isLastNode > 0) {
layer_show('⽂件上传', '/Admin/upload?Id=' + selected_node.id, 700, 540);
} else {
if (selected_node.id == 0) {  //中⼼根节点不能直接上传⽂件
layer.msg("根节点不可上传!", { icon: 0 });
} else {
layer_show('⽂件上传', '/Admin/upload?Id=' + selected_node.id, 700, 540);
}
}
}
/
/删除节点
function remove_node() {
var selected_node = _jm.get_selected_node(); // as parent of new node
if (!selected_node) { layer.msg('请选择⼀个节点!'); return; }
var isLastNode = selected_node.children.length;
if (isLastNode > 0) {
layer.msg('存在⼦集,不能删除!');
} else {
bigbang fxxk it
jQuery.post("/Admin/Delete?Id=" + selected_node.id, function (msg) {
if (msg == 1) {
/
/InitJsMind();
_jm.enable_edit();//新增前置为可编辑状态
_jm.remove_node(selected_node.id);
_jm.disable_edit();//新增前置为不可编辑状态
layer.msg('已删除!', { icon: 1, time: 1000 });