基於OrgChart技術流程圖[樹狀圖]
一.實現效果圖
二.數據集
經過處理後的數據集:
[
{"FACTORRISK":"0.6","FACTOREXPOSURE":"0.5","DIMNAME":"主動風險","STYLENMAE":"BARRA中國因子分解"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"資產選擇","STYLENMAE":"主動風險"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"共同因子","STYLENMAE":"主動風險"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"風格因子","STYLENMAE":"共同因子"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"行業因子","STYLENMAE":"共同因子"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"市場因子","STYLENMAE":"共同因子"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"協方差*2","STYLENMAE":"共同因子"}
]
此時數據已經變成了json數組
三.實現思路
其實思路很簡單就是將普通數據組裝成符合OrgChart數據格式(點擊這裏訪問OrgChart官方演示文檔)的json數據
1.創建數據封裝函數
function closureProcessing(obj, s, m,isCompany, str) {
var x1 = m || [];
for (var i = 0; i < obj.length; i++) {
if (obj[i].pId == s) {
x1.push(obj[i]);
x1.map(function (item, index) {
if (item.pId && isCompany) {
} else {
x1[index].children = [];
}
if (str) {
isCompany = true;
for (var i = 0; i < str.length; i++) {
if (item.id == str[i].pId && !item.pId) {
x1[index].children.push(str[i]);
}
}
}
return closureProcessing(obj, item.id, x1[index].children, str);
})
}
}
return x1;
}
2.將現有的數據處理成json數組
var data = [
{"FACTORRISK":"0.6","FACTOREXPOSURE":"0.5","DIMNAME":"主動風險","STYLENMAE":"BARRA中國因子分解"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"資產選擇","STYLENMAE":"主動風險"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"共同因子","STYLENMAE":"主動風險"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"風格因子","STYLENMAE":"共同因子"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"行業因子","STYLENMAE":"共同因子"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"市場因子","STYLENMAE":"共同因子"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"協方差*2","STYLENMAE":"共同因子"}
];
for (var i = 0; i < data.length; i++) {
var item = {};
if (data[i].PID == 0){
item ={
pId:data[i].PID,
id:data[i].ID,
name:data[i].DIMNAME,
title:'<div class="org_def"> </div><div class="org_def"> </div>'
};
}else {
item = {
pId: data[i].PID,
id: data[i].ID,
name: data[i].DIMNAME,
title: '<div class="rote_style">' + (isNaN(data[i].FACTOREXPOSURE) ? 'N/A' : data[i].FACTOREXPOSURE) + '</div><div class="radio_style">' + (isNaN(data[i].FACTORRISK) ? 'N/A' : data[i].FACTORRISK) + '</div>'
}
}
dataSource.push(item);
}
/* 處理後的json數組中的每個元素均爲
{
pId: "XX"
id: "XX"
name: "XX"
title: "XX"
children: [{…}]
relationship: "001"
}
並且children中的數據也是這種格式
*/
console.log(dataSource);
3.調用closureProcessing()函數,將json數組變爲json字符串
/**
最終會形成一個下面格式的json數據,children屬性裏面存放着所有的下級節點
{
pId: "0"
id: "1"
name: "BARRA中國因子分解"
title: "<div class="org_def"> </div><div class="org_def"> </div>"
children: [{…}]
relationship: "001"
}
*/
var treeData = closureProcessing(dataSource,0,[],isCompany)[0];
4.初始化畫布,並設置數據
var oc = $('#chart-container').orgchart({
'data' : treeData,
'nodeContent': 'title',
'nodeTitle':'name',
'toggleSiblingsResp': true,
// 'direction': 'T2B',
// visibleLevel【number】:默認展開幾級
'visibleLevel': 3,
parentNodeSymbol: null
});
至此,整個樹狀(組織結構)圖就開發完畢了,但是這樣實現出來的效果和圖中差距還是挺大的,因爲這樣實現以後沒有效果圖中的顏色和右上角的圖例.所以這裏還需要做些設置,但是這些設置都無關緊要了,直接放到源碼裏面處理.
四.源碼
1.HTML部分源碼(即展示樹狀圖用的畫布容器)
因爲這部分很簡單,所以只寫畫布相關的代碼,有興趣的自己補足運行!
<div>
<div id="legend"></div>
<div id="chart-container" style="width: 100%"></div>
</div>
2.CSS部分的樣式代碼
<style type="text/css">
.radio_style{
background-color: #64c2e5;
color: black;
width: auto;
height: 20px;
text-align: center;
}
.rote_style{
background-color: #f3ab11;
color: black;
width: auto;
height: 20px;
text-align: center;
}
.org_def{
width: auto;
height: 20px;
text-align: center;
}
.orgchart .node .content{
height: auto;
}
.orgchart table{
border: white;
}
.orgchart td.right {
border-right: 2px solid rgba(217, 83, 79, 0.8);
}
.orgchart td.top {
border-top: 2px solid rgba(217, 83, 79, 0.8);
}
.title{
border-left: 0px;
margin-bottom: 0px;
}
.orgchart{
background: white;
}
</style>
3.完整的js代碼
function closureProcessing(obj, s, m,isCompany, str) {
var x1 = m || [];
for (var i = 0; i < obj.length; i++) {
if (obj[i].pId == s) {
x1.push(obj[i]);
x1.map(function (item, index) {
if (item.pId && isCompany) {
} else {
x1[index].children = [];
}
if (str) {
isCompany = true;
for (var i = 0; i < str.length; i++) {
if (item.id == str[i].pId && !item.pId) {
x1[index].children.push(str[i]);
}
}
}
return closureProcessing(obj, item.id, x1[index].children, str);
})
}
}
return x1;
};
var contentBody = $("#chart-container");
var _legend = $("#legend");
var isCompany = false;
var dataSource = [];
var treeData = {};
var data = [
{"FACTORRISK":"0.6","FACTOREXPOSURE":"0.5","DIMNAME":"主動風險","STYLENMAE":"BARRA中國因子分解"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"資產選擇","STYLENMAE":"主動風險"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"共同因子","STYLENMAE":"主動風險"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"風格因子","STYLENMAE":"共同因子"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"行業因子","STYLENMAE":"共同因子"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"市場因子","STYLENMAE":"共同因子"},
{"FACTORRISK":"0.8","FACTOREXPOSURE":"0.4","DIMNAME":"協方差*2","STYLENMAE":"共同因子"}
];
for (var i = 0; i < data.length; i++) {
var item = {};
if (data[i].PID == 0){
item ={
pId:data[i].PID,
id:data[i].ID,
name:data[i].DIMNAME,
title:'<div class="org_def"> </div><div class="org_def"> </div>'
};
}else {
item = {
pId: data[i].PID,
id: data[i].ID,
name: data[i].DIMNAME,
title: '<div class="rote_style">' + (isNaN(data[i].FACTOREXPOSURE) ? 'N/A' : data[i].FACTOREXPOSURE) + '</div><div class="radio_style">' + (isNaN(data[i].FACTORRISK) ? 'N/A' : data[i].FACTORRISK) + '</div>'
};
}
dataSource.push(item);
}
console.log(dataSource);
treeData = closureProcessing(dataSource,0,[],isCompany)[0];
var html = '';
html += '<div>' +
'<table style="border: 0px;width: 20%;float: right">' +
'<tr><td class="rote_style">主動風險(波動率)</td></tr>' +
'<tr><td class="radio_style">風險貢獻率(主動風險%)</td></tr>' +
'</table>'+
'</div>';
_legend.append(html);
var oc = $('#chart-container').orgchart({
'data' : treeData,
'nodeContent': 'title',
'nodeTitle':'name',
'toggleSiblingsResp': true,
// 'direction': 'T2B',
// visibleLevel【number】:默認展開幾級
'visibleLevel': 3,
parentNodeSymbol: null
});
整個代碼中最關鍵的部分就是怎麼將數據處理爲我們想要的或者說符合OrgChart格式的json對象,只要能搞定這個關鍵點,那麼後面的都是小case了.
本作品採用知識共享署名 4.0 國際許可協議進行許可。