C# ASP.NET遞歸循環生成嵌套json並用Echarts展示結構樹

一、需求:

做一個部門的結構樹,樣子大概是如下圖這樣展示:

圖片示例圖

二、分析:

做成這樣的一個效果圖,雖然可以寫但會比較麻煩,其實現在是有很多這樣的前端控件幫我們實現,只需要我們按照要求傳遞數據即可,這就不需要重複造輪子。

例如:Esay UI的tree控件,Echarts的圖表展示,這兩個都是常用的。

本文就是用Echarts來展示結構樹。

三、Echarts的基本使用

Echarts的使用很簡單,只需要從官網下載引入js文件,或直接引入CDN<script src="https://cdn.bootcss.com/echarts/4.4.0-rc.1/echarts.min.js"></script>
然後只需要在js裏調用,並傳JSON數據即可,直接看我下方代碼例子,應該都能看懂的,至於有關於Echarts的其他參數的配置說明,可以再自行查看官網。

//展示結構樹的容器
<div id="item" style="width:1200px; height: 500px;">
<script>
        //初始化echarts實例
        var myChart = echarts.init(document.getElementById('item'));
        //使用制定的配置項和數據顯示圖表
        //myChart.showLoading();    //顯示Loading標誌;

        //$.get('data/asset/data/flare.json', function (data) {
        //    myChart.hideLoading();    //得到數據後隱藏Loading標誌

        //    echarts.util.each(data.children, function (datum, index) {
        //        index % 2 === 0 && (datum.collapsed = true);
        //    });    //間隔展開子數據,animate,display,physics,scale,vis是展開的


        option = {
            calculable: false,
            tooltip: {
                // show:'true',//默認:true;是否顯示提示框組件,包括提示框浮層和 axisPointer。
                trigger: 'item',//默認:item;觸發類型。item:數據項圖形觸發,主要在散點圖,餅圖等無類目軸的圖表中使用。'axis':座標軸觸發,主要在柱狀圖,折線圖等會使用類目軸的圖表中使用。'none':什麼都不觸發。
                //formatter: '{b}:{c}',
                hideDelay: 0 // chart.refresh();刷新時會維持當時圖表的所有狀態,所以設置隱藏延遲爲0,否則在快速選擇另一個節點時(尤其是數據比較多時)導致無法顯示選擇中的tooltip
                //無法完全避免但是很大減輕了副作用
            },
            series: [
                {
                    name: '樹圖',
                    type: 'tree',
                    orient: 'vertical',  // vertical horizontal
                    rootLocation: { x: 'center', y: 30 }, // 根節點位置  {x: 100, y: 'center'}
                    nodePadding: 50,//節點間距
                    symbolSize: 50,//tree圖上的原型的大小
                    //symbol: 'circle',
                    //roam: true,//設置次參數後,針對該圖表可以放大和縮小,移動
                    initialTreeDepth: 3,//初始顯示節點深度
                    itemStyle: {
                        normal: {
                            label: {
                                show: true,
                                formatter: "{b}",
                                position: 'inside',
                                textStyle: {
                                    color: '#000',
                                    fontSize: 12,
                                    fontWeight: 'bolder'
                                }
                            },
                            lineStyle: {
                                color: '#48b',
                                shadowColor: '#000',
                                shadowBlur: 4,
                                shadowOffsetX: 3,
                                shadowOffsetY: 5,
                                type: 'curve' // 'curve'|'broken'|'solid'|'dotted'|'dashed'

                            }
                        },
                        emphasis: {
                            label: {
                                show: true
                            }
                        }
                    },

                    data: [
                        {
                            name: '根節點',
                            value6,
                            children: [
                                {
                                    name: '節點1',
                                    value4,
                                    children: [
                                        {
                                            name: '葉子節點1',
                                            value4
                                        },
                                        {
                                            name: '葉子節點2',
                                            value4
                                        },
                                        {
                                            name: '葉子節點3',
                                            value2
                                        }

                                    ]
                                },
                                {
                                    name: '節點2',
                                    value4,
                                    children: [{
                                        name: '葉子節點7',
                                        value4
                                    },
                                    {
                                        name: '葉子節點8',
                                        value4
                                    }]
                                },
                                {
                                    name: '節點3',
                                    value1,
                                    children: [
                                        {
                                            name: '葉子節點9',
                                            value4
                                        },
                                        {
                                            name: '葉子節點10',
                                            value4
                                        },
                                        {
                                            name: '葉子節點11',
                                            value2
                                        },
                                        {
                                            name: '葉子節點12',
                                            value2
                                        }
                                    ]
                                },
                                {
                                    name: '節點8',
                                    value1,
                                    children: [
                                        {
                                            name: '葉子節點9',
                                            value4
                                        },

                                        {
                                            name: '節點2',
                                            value4,
                                            children: [{
                                                name: '葉子節點7',
                                                value4
                                            },
                                            {
                                                name: '葉子節點8',
                                                value4
                                            }]
                                        }
                                    ]
                                }

                            ]
                        }
                    ]
                }
            ]
            };

        myChart.setOption(option);
    </script>



























































































































































Echarts官方示例

四、遞歸構建JSON

所以,從上面的Echarts使用可以知道,我們接下來需要做的就是生成一個對應結構的json傳遞到前端。
先說明一下,我的數據特點,ID是主鍵,不存在會有相同列的數據,NAME_SHORT就是一個展示名稱,BELONG_ID表示一個層級關係,相同根節點下的子節點,BELONG_ID相同,數據取自ID

1. 建立用來保存樹結構數據的目標對象

public  class TreeObject
    {
        public string name { getset; }
        public string value { getset; }
        public IList<TreeObject> children = new List<TreeObject>();
        public  void Addchildren(TreeObject node)
        
{
            this.children.Add(node);
        }
    }








2.查詢表獲得數據源

        /// <summary>
        ///數據庫的連接字符串
        /// </summary>
        private static readonly string connstr = @"server=.;database=userInfo;uid=sa;pwd=123456";;

public DataTable getTable(string cmdText)
        
{
            using (SqlConnection cnn = new SqlConnection(connstr))
            {
                using (SqlCommand comm = new SqlCommand(cmdText, cnn))
                {
                    comm.CommandType = CommandType.Text;
                    SqlDataAdapter da = new SqlDataAdapter();
                    da.SelectCommand = comm;
                    DataTable mytable = new DataTable();
                    da.Fill(mytable);
                    return mytable;
                }
            }
        }

 public DataTable GetDataTable()
        
{
            string sql = @"select ID,NAME_SHORT,BELONGTO_ID 
                            from UserInfo
                            order by BELONGTO_ID"

;
            DataTable dt = getTable(sql);
            return dt;
        }
























3.遞歸循環生成樹

       //全局變量用於保存數據
       public List<TreeObject> treeNodes = new List<TreeObject>();

        //建立樹的遞歸方法
        /// </summary>
        /// <param name="dtSource">數據源</param>
        /// <param name="parentNode">父節點</param>
        /// <param name="parentID">節點的歸屬ID</param>
        public void BindTree(DataTable dtSource, TreeObject parentNode, string parentID)
        
{
            DataRow[] rows = dtSource.Select(string.Format("BELONGTO_ID={0}", parentID));
            foreach (DataRow row in rows)
            {
                TreeObject tree = new TreeObject();
                tree.name = row["NAME_SHORT"].ToString();
                tree.value = row["ID"].ToString();
                //遞歸性質,函數內調用自身函數
                BindTree(dtSource, tree, row["ID"].ToString());
                //遞歸結束的終點條件
                if (parentNode == null)
                {
                    treeNodes.Add(tree);
                }
                else
                {
                    parentNode.children.Add(tree);
                }
            }
        }



























4.調用

//調用SQL,獲取數據源
DataTable dt = GetDataTable();
//調用遞歸函數,傳入數據源,根節點
BindTree(dt, null"0");
//反序列化對象,生成json字符串
string jsonData = JsonConvert.SerializeObject(treeNodes);
return jsonData;






5.效果

[{
    "name": 'A',
    "value": '10000',
    "children": [{
            "name": 'B1',
            "value": '10002',
            "children": [{
                    "children": [],
                    "name": 'C',
                    "value": '10007'
                },
                {
                    "children": [],
                    "name": 'D',
                    "value": '10008'
                },
                {
                    "children": [],
                    "name": 'E',
                    "value": '10009'
                }

            ]
        },
        {
            "name": 'B2',
            "value": '10003',
            "children": [{
                    "children": [],
                    "name": 'F',
                    "value": '10010'
                },
                {
                    "children": [],
                    "name": 'G',
                    "value": '10011'
                }
            ]
        },
        {
            "name": 'B3',
            "value": '10004',
            "children": [{
                    "children": [],
                    "name": 'H',
                    "value": '10012'
                },
                {
                    "children": [],
                    "name": 'I',
                    "value": '10013'
                },
                {
                    "children": [],
                    "name": 'J',
                    "value": '10014'
                }
            ]
        },
        {
            "name": 'B4',
            "value": '10005',
            "children": [{
                    "children": [],
                    "name": 'K',
                    "value": '10015'
                },

                {
                    "name": 'L',
                    "value": '10016',
                    "children": [{
                            "children": [],
                            "name": 'L1',
                            "value": '10017'
                        },
                        {
                            "children": [],
                            "name": 'L2',
                            "value": '10018'
                        }
                    ]
                }
            ]
        }

    ]
}]























































































圖片效果圖

五、總結

以上就是全部代碼了,從代碼來說,不難,整個過程就是引入Echarts,傳遞json數據。

因此最需要做的就是生成對應結構的json,而做這些循環嵌套,使用遞歸逐步深入還是比較簡單,可能先嚐試遞歸兩三層來找到遞歸的規律,這個還是需要根據自己數據結構來做。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章