echarts的樹圖tree做個類似工作流的營銷活動管理,而且每個節點可以新增子節點和修改當前節點。如下圖:
實現幾個知識點:橫向的echarts樹圖tree、點按鈕是新增節點、點按鈕其它地方是修改或查看、隨着節點增多寬高自適應。
橫向的echarts樹圖tree略過,參考官網。https://echarts.apache.org/zh/option.html#series-tree.type
1、節點加兩個點擊事件,並且節點內每行表示不同,這個得用到echarts的rich自定義富文本樣式:https://echarts.apache.org/zh/option.html#series-tree.label.rich
在series.label.rich下加自定義標籤和series.label.formatter加自定義標籤組合成的html,如:
1)series.label.rich加自定義標籤
rich:{
h6:{
color: '#333',
lineHeight: 16,
fontSize: 10
},
div:{
width: 80,
color: '#333',
fontSize: 10,
lineHeight: 16,
padding: [4, 5, 4, 5],
wordBreak: 'break-all'
},
a:{
backgroundColor: '#4986F7',
borderRadius: 20,
padding: [4, 7, 4, 7],
color: '#fff',
fontSize: 10,
},
span:{
backgroundColor: '#87aff8',
borderRadius: 20,
padding: [4, 7, 4, 7],
color: '#ebebeb',
fontSize: 10,
cursor: 'no-drop',
}
}
2)series.label.formatter自定義標籤組合html
formatter: function(param) { //param是節點的數據
return '{h6|'+param.data.code+'}\n{div|'+param.data.name+'}\n{div|'+param.data.purpose+'}\n{a|'+text+'}'
}
//code對應節點的第一行A1、name對應節點的第二行、purpose對應節點的第三行、text對應節點的按鈕;\n是換行用的
這樣就把節點的html做出來了。
接下來做同一個節點有兩個不同的點擊事件:
加點擊事件:
// 樹節點點擊數據 myChart.on('click', function(param) { //也可以註冊其他時間 hover 、mouseout等
debugger; // 這裏打個debugger用chrome的sources看param裏面有什麼數據,然後分析點擊節點按鈕和點擊節點其它地方有什麼不同,做不同的判斷然後分成不同的點擊事件 console.log(param); var data = param.data; var style = param.event.target.style; if (style.fill == '#4986F7' || style.fill == '#fff') { //點的是 +增加子活動 按鈕,根據上面rich配置a標籤來判斷 addNode(data); //新增節點的函數,往tree數據的json新增數據,然後重新加載樹圖的函數就好。 } else { // 點的是節點內,但 +增加子活動 按鈕外的地方 checkNode(data);//更改節點數據的函數,修改tree數據的json,然後重新加載樹圖的函數就好。
} });
節點加兩個不同的點擊事件完成。
接下來做寬高自適應:參考https://blog.csdn.net/yezitoo/article/details/89677773
const nodes = myChart._chartsViews[0]._data._graphicEls; let allNode = 0; for (let index = 0; index < nodes.length; index++) { const node = nodes[index]; if (node === undefined) { continue } allNode++; } const height = $('workflow0'+index).height(); //workflow0是每個樹圖tree的div容器
const width = $('workflow0'+index).width();
const currentHeight = 70 * allNode;
const currentWidth = 120 * allNode;
const newHeight = Math.max(currentHeight, height);
const newWidth = Math.max(currentWidth, width);
const tree_ele = document.getElementById('workflow0'+index);
tree_ele.style.height = newHeight + 'px';
tree_ele.style.width = newWidth + 'px';
myChart.resize();
點擊新增或更新節點時,記得重新加載樹圖tree的函數,需求全部完成。
全部代碼:
var myChart = echarts.init(document.getElementById('workflow0'+index));
var data = [itemData] //每個樹圖tree的數據json格式,一定要用[]括住var option = { tooltip: { //鼠標放上去顯示的內容
trigger: 'item', triggerOn: 'mousemove', formatter: function(params, ticket, callback) { return '營銷主題:'+params.data.name+'</br>'+'營銷目的:'+params.data.purpose+'</br>'; }, }, series:[ { type: 'tree', name: '自動營銷活動流程', data: data, top: '1%', left: 50, bottom: '1%', right: 50, edgeForkPosition: '50%', symbol: 'rect', symbolSize: ['90', '70'], edgeShape: 'polyline', edgeForkPosition: '50%', initialTreeDepth: -1, lineStyle: { width: 2 }, itemStyle: { normal: { color: '#f9f9f9', borderWidth: 1, borderColor: '#cccccc' } }, label: { height: 70, width: 80, position: 'inside', verticalAlign: 'middle', align: 'center', fontSize: 12, overflow: 'truncate', ellipsis: '...', formatter: function(param) { //status: 4:已提交;9:MOT未開啓;10:MOT已啓用;11:MOT暫停;12:MOT營銷上限;13:MOT已過期;99:已刪除 let text = '+增加子活動'; switch (param.data.status) { case '4': text = '已提交' break case '9': text = '+增加子活動' break case '10': text = 'MOT已啓用' break case '11': text = 'MOT暫停' break case '12': text = 'MOT營銷上限' break case '13': text = 'MOT已過期' break case '99': text = '已刪除' break case null: text = '已失效' break default: text = '+增加子活動' } if (param.data.name.length > 9) { param.data.name = param.data.name.substring(0,9)+'...'; } if (param.data.purpose.length > 9) { param.data.purpose = param.data.purpose.substring(0,9)+'...'; }if (param.data.status == 9) { //按鈕可以點 return '{h6|'+param.data.code+'}\n{div|'+param.data.name+'}\n{div|'+param.data.purpose+'}\n{a|'+text+'}' } else { //按鈕不可以點 return '{h6|'+param.data.code+'}\n{div|'+param.data.name+'}\n{div|'+param.data.purpose+'}\n{span|'+text+'}' } }, rich:{ h6:{ color: '#333', lineHeight: 16, fontSize: 10 }, div:{ width: 80, color: '#333', fontSize: 10, lineHeight: 16, padding: [4, 5, 4, 5], wordBreak: 'break-all' }, a:{ backgroundColor: '#4986F7', borderRadius: 20, padding: [4, 7, 4, 7], color: '#fff', fontSize: 10, }, span:{ backgroundColor: '#87aff8', borderRadius: 20, padding: [4, 7, 4, 7], color: '#ebebeb', fontSize: 10, cursor: 'no-drop', } } }, leaves: { label: { position: 'inside', // 節點的文字是放在節點裏面的 verticalAlign: 'middle', align: 'center' } }, emphasis: { focus: 'descendant' }, expandAndCollapse: false,//一定要false,echarts樹圖tree點擊節點不收縮或伸展,要不然點擊節點時節點會收縮或伸展 animationDuration: 550, animationDurationUpdate: 750 } ] }; myChart.setOption(option, true); // 樹節點點擊數據 myChart.on('click', function(param) { //也可以註冊其他時間 hover 、mouseout等 console.log(param); var data = param.data; var style = param.event.target.style; if (style.fill == '#4986F7' || style.fill == '#fff') { //點的是 +增加子活動 按鈕 addChildAutoMarketing(data); } else { // 點的是節點內,但 +增加子活動 按鈕外的地方 showNodeInfo(data); } }); // 樹容器寬高自適應 const nodes = myChart._chartsViews[0]._data._graphicEls; let allNode = 0; for (let index = 0; index < nodes.length; index++) { const node = nodes[index]; if (node === undefined) { continue } allNode++; } const height = $('workflow0'+index).height(); const width = $('workflow0'+index).width(); const currentHeight = 70 * allNode; const currentWidth = 120 * allNode; const newHeight = Math.max(currentHeight, height); const newWidth = Math.max(currentWidth, width); const tree_ele = document.getElementById('workflow0'+index); tree_ele.style.height = newHeight + 'px'; tree_ele.style.width = newWidth + 'px'; myChart.resize();
//節點數據:
var itemData = {
"activityId": "1166",
"code": "A1",
"name": "測試自動營銷活動1-A2.1",
"purpose": "測試自動營銷活動1-A2.1",
"status": "9",
"children": [{
"activityId": "1",
"code": "A1.1",
"name": "自動-A1.1",
"purpose": "自動-A1.1",
"status": "9",
"children": []
},
{
"activityId": "2",
"code": "A1.2",
"name": "自動A1.2",
"purpose": "自動A1.2",
"status": "9",
"children": []
}]
}