jsMind思維導圖模式展示數據


效果圖:

jsmind組件下載地址:https://files.cnblogs.com/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>
        /// 文件樹視圖,頁面初始化獲取樹數據,以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.topic = item.TreeName;//要顯示的名稱
                node2.direction = "right";//思維導圖伸向,目前只支持left/right
                node2.parentId = item.ParentId;
                node2.expanded = true;//該節點是否展開
                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.topic = plist.Code;
                node.direction = plist.Note;//思維導圖伸向,目前只支持left/right
                node.parentId = plist.ParentId;
                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;
        }
        /// <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.ToInt32(model.order) - 1;
                if (upId >= 0)
                {
                    //執行修改本身
                    model.order= upId;
                    bll.Update(model);
                    //執行修改相鄰的上一個
                    var list = bll.GetAllList("parentId='" + parentId+ "'  and order='" + upId + "' and id<>'"+Id+"'");
                    if (list.Count > 0)
                    {
                        var upModel = list[0];
                        upModel.order= upId + 1;
                        bll.Update(upModel);
                        targetId = upModel.id;
                    }
                }
            }
            else
            {
                upId = Convert.ToInt32(model.order) + 1;
                var list = bll.GetAllList("ParentDrawingId='" + parentId+ "'");
                if (upId < list.Count)
                {
                    //執行修改本身
                    model.order= upId;
                    bll.Update(model);
                    //執行修改相鄰的上一個
                    var newList = list.Where(c => c.order== upId && c.id!= model.id);
                    if (newList.Count() > 0)
                    {
                        var upModel = newList.FirstOrDefault();
                        upModel.order= upId - 1;
                        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.net mvc頁面視圖編寫,都是插件獲取后台返回的json,其他語言同理

@model  List<Model.Admin.TreeData>
@{
    ViewBag.Title = "上傳文件";
}
 
<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" style="overflow: hidden;">
        <div id="layout">
            <div id="jsmind_container"></div>
            <div style="display: none">
                <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 = str.replace(re, "background-color");
                re = new RegExp("foreground", "g"); //定義正則表達式,g標識全部替換
                newstr = newstr.replace(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 = str.replace(re, "background-color");
            re = new RegExp("foreground", "g"); //定義正則表達式,g標識全部替換
            newstr = newstr.replace(re, "foreground-color");
            var jsonData = $.parseJSON(newstr);
            //delete jsonData["direction"];
            console.log(jsonData);
            //開始新增
            var nodeid = newNode.id;
            var topic = newNode.topic;
            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 {
                layer.confirm('確認要刪除嗎?', function (index) {
                    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 });
                        } else {
                            layer.msg('操作失敗!', { time: 1000 });
                        }
                    });
                });
            }
        }
        //節點查看
        function show_selected() {
            var selected_node = _jm.get_selected_node(); // as parent of new node
            if (!selected_node) { layer.msg('請選擇一個節點!'); return; }
            if (selected_node.id == 0) { layer.msg('根節點不支持查看!'); return; }
 
            var layer_height = 420;
            if (selected_node.data.leave > 0) layer_height = 280;
            if (selected_node.data.leave == 1) layer_height = 420;
            layer_show('節點查看', '/Admin/Show?Id=' + selected_node.id, 600, layer_height);
        }
 
        //展開選擇的節點
        function expand() {
            var selected_id = get_selected_nodeid();
            if (!selected_id) { layer.msg('please select a node first.'); return; }
 
            _jm.expand_node(selected_id);
        }
        //合並選擇的節點
        function collapse() {
            var selected_id = get_selected_nodeid();
            if (!selected_id) { layer.msg('please select a node first.'); return; }
 
            _jm.collapse_node(selected_id);
        }
        //展開所有節點
        function expand_all() {
            _jm.expand_all();
            $("#jsmind_container").offset({ top: ((0 - jm)), left: 100 }); //將中心點調至屏幕中心
        }
        //合並所有節點
        function collapse_all() {
            _jm.collapse_all();
            $("#jsmind_container").offset({ top: ((0 - jm)), left: 100 }); //將中心點調至屏幕中心
        }
        //畫布縮小
        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 dragFunc(id) {
            var Drag = document.getElementById(id);
            Drag.onmousedown = function (event) {
                var ev = event || window.event;
                event.stopPropagation();
                var disX = ev.clientX - Drag.offsetLeft;
                var disY = ev.clientY - Drag.offsetTop;
                document.onmousemove = function (event) {
                    var ev = event || window.event;
                    Drag.style.left = ev.clientX - disX + "px";
                    Drag.style.top = ev.clientY - disY + "px";
                    Drag.style.cursor = "move";
                };
            };
            Drag.onmouseup = function () {
                document.onmousemove = null;
                this.style.cursor = "default";
            };
        };
 
 
        //通過JS屏蔽自帶右鍵菜單
        document.oncontextmenu = function (e) {
            return false;
        }
 
        //動態化展示右鍵菜單
        function showmenu(selected_node) {
            var selected_node = _jm.get_selected_node(); // as parent of new node
          
            if (!selected_node) {
                $("#divmenu ul li:not(.pub)").hide();
                $("#divmenu ul li[class='pub']").show();
            }
            else {
                if ((selected_node.isroot || false)) {
                    $("#divmenu ul li:not(.add)").hide();
                    $("#divmenu ul li[class='add']").show();
                }
                else if (selected_node.data.leave == 1) {
                    if (selected_node.children.length > 0) {
                        $(".pub,.update,.view,.history,.delete").hide();
                        $(".sel,.upload,.add,.move").show();
                    } else {
                        $(".pub,.update,.view,.history").hide();
                        $(".sel,.upload,.add,.move,.delete").show();
                    }
                }
                else {
                    if (selected_node.children.length > 0) {
                        $(".pub,.view,.history,.update,.delete").hide();
                        $(".upload,.sel,.add,.move").show();
                    }
                    else {
                        if (selected_node.data.filepath == "null" || selected_node.data.filepath == undefined) {
                            $(".upload,.sel,.delete,.add,.move").show();
                            $(".pub,.view,.history,.update").hide();
                        } else {
                            $(".view,.delete,.update,.history,.move").show();
                            $(".pub,.sel,.upload,.add").hide();
                        }
                    }
                }
            }
            return true;
        }
 
 
        //搜索
        function search() {
            var count = 0;
            if($.trim($("#keywords").val()).length == 0) { 
                InitJsMind();
            } else {
                //InitJsMind();
                $('jmnode').each(function (i, e) {
                    var code = $(this).attr("code");
                    if (code != undefined) {
                        code = $(this).attr("code").toLowerCase();
                        var filenode = "<span>" + $("#keywords").val().toLowerCase() + "</span>";
                        if ($(this).html().toLowerCase().indexOf($("#keywords").val().toLowerCase()) != -1 || $(this).html().toLowerCase().indexOf(filenode) != -1 || code.indexOf($("#keywords").val().toLowerCase()) != -1) {
                            $(this).addClass("root selected");
                            $(this).css("opacity","0.9");
                            count = parseInt(count) + 1;
                            if (count == 1) {
                                auto_height();//恢復位置
                                console.log(code);
                                var jm2 = $(this).css("top").replace("px", ""); //獲取當前點位置
                                $("#jsmind_container").offset({ top: ((0 - parseInt(jm2))+($("body").height()/2)), left: ($("body").width() / 10) }); //將中心點調至屏幕中心
                            }
                        } else {
                            $(this).removeClass("root selected");
                            $(this).css("opacity", "0.1");  //沒找到的元素透明的設高
                        }
                    }
                });
                if (count == 0) {
                    layer.msg('未檢索到任何數據!');
                }
            }
        }
        //鼠標滾輪縮放
        window.onmousewheel = document.onmousewheel = function (e) {
            e = e || window.event;
            if (e.wheelDelta) {  //判斷瀏覽器IE,谷歌滑輪事件               
                if (e.wheelDelta > 0) { //當滑輪向上滾動時  
                    _jm.view.zoomIn()
                }
                if (e.wheelDelta < 0) { //當滑輪向下滾動時  
                    _jm.view.zoomOut();
                }
            } else if (e.detail) {  //Firefox滑輪事件  
                if (e.detail > 0) { //當滑輪向下滾動時  
                    _jm.view.zoomOut();
                }
                if (e.detail < 0) { //當滑輪向上滾動時  
                    _jm.view.zoomIn()
                }
            }
        }
    </script>
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM