您好,登錄后才能下訂單哦!
小編給大家分享一下vue使用echarts畫組織結構圖的案例,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
vue使用echarts畫組織結構圖的案例
用div+css是可以實現的,但是沒有什么動畫效果,我的css3又很差勁,而且項目中已經使用到了折線圖、餅狀圖、柱狀圖之類的圖表,用的還是百度的echarts,所以這個組織結構圖之類的需求也就用了百度的echarts來實現了。
以前用echarts寫折線圖、柱狀圖、餅狀圖的較多,它的API還算比較熟悉,但是畫組織結構這樣的樹狀圖就很苦逼了,沒用過啊,而且設計給的樹狀圖的展示效果跟echarts樹狀圖的展示效果相去甚遠,我滴孩,又得一通費時費力的研究,設計圖如下:
如圖所示,一個樹節點中可能會有兩種不同的背景色,還有兩種不同的文字顏色,每個節點展示的還是圓角矩形。有同學說了,echarts有設置圓角的API啊,直接設置不就完事了。我想說的是,它是提供的有這樣的API,但是按照正常的套路實現不了啊。
從圖上還可以看到一個幾乎實現不了的效果,就是連接每個節點之間的線的拐角處都是直角而不是平滑的,而且echarts沒有給出可以設置拐角處是直角的API,只是給了一個curveness(API的描述是樹圖邊的曲度),這玩意兒使用了之后,也還是實現不了的。
從網上查了資料,有人說可以修改echarts的源碼,這種解決辦法我不推薦,是因為在vue或react項目中,echarts是需要通過安裝在package.json中的,如果是多人并行開發,那么別人安裝的echarts就不是你修改后的echarts,這就是問題所在。
最后用echarts畫出來的效果還是很不錯的,唯一沒有實現的就是連接每個節點的線的拐角處不是直角,有好的解決辦法的,還望不吝賜教,謝謝!展示一下最終的成果:
說了那么多,還是上代碼吧,該代碼是基于vue的,如果要使用在react中,稍微修改一下就可以了。
組件tree.vue:
<template> <div :class="className" : /> </template> <script> import echarts from "echarts"; require("echarts/theme/macarons"); import { debounce } from "@/utils"; export default { props: { className: { type: String, default: "chart" }, width: { type: String, default: "100%" }, height: { type: String, default: "500px" }, chartData: { type: Object, required: true } }, data() { return { chart: null, }; }, watch: { chartData: { deep: true, handler(val) { this.setOptions(val); } } }, mounted() { this.initChart(); //是否需要自適應-加了防抖函數 this.__resizeHandler = debounce(() => { if (this.chart) { this.chart.resize(); } }, 100); window.addEventListener("resize", this.__resizeHandler); // 監聽側邊欄的變化以實現自適應縮放 const sidebarElm = document.getElementsByClassName("sidebar-container")[0]; sidebarElm.addEventListener("transitionend", this.sidebarResizeHandler); }, beforeDestroy() { if (!this.chart) { return; } window.removeEventListener("resize", this.__resizeHandler); this.chart.dispose(); this.chart = null; const sidebarElm = document.getElementsByClassName("sidebar-container")[0]; sidebarElm.removeEventListener("transitionend", this.sidebarResizeHandler); }, methods: { initChart() { this.chart = echarts.init(this.$el, "macarons"); this.setOptions(this.chartData); const nodes = this.chart._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 = window.innerHeight; const width = window.innerWidth - 1000; const currentHeight = 85 * allNode; const currentWidth = 220 * allNode; const newHeight = Math.max(currentHeight, height); const newWidth = Math.max(currentWidth, width); const tree_ele = this.$el; // tree_ele.style.height = newHeight + 'px'; //設置高度自適應 tree_ele.style.width = newWidth + 'px'; //設置寬度自適應 this.chart.resize(); this.chart.on('click', this.chartData.clickCallback); //節點點擊事件 }, setOptions(data) { this.chart.setOption({ //提供數據視圖、還原、下載的工具 // toolbox: { // show : true, // feature : { // mark : {show: true}, // dataView : {show: true, readOnly: false}, // restore : {show: true}, // saveAsImage : {show: true} // } // }, series: [ { name: "統一授信視圖", type: "tree", orient: "TB", //豎向或水平 TB代表豎向 LR代表水平 top: '10%', initialTreeDepth: 10, //樹圖初始展開的層級(深度) expandAndCollapse: false, //點擊節點時不收起子節點,default: true symbolSize: [135, 65], itemStyle: { color: 'transparent', borderWidth: 0, }, lineStyle: { color: '#D5D5D5', width: 1, curveness: 1, }, data: [data] } ] }); }, sidebarResizeHandler(e) { if (e.propertyName === "width") { this.__resizeHandler(); } } } }; </script>
使用tree.vue的方法:
<template> <tree :chartData="treeData" /> </template> <script> import tree from './tree'; export default { data() { return { treeData: { label: { backgroundColor: '#F4F4F4', borderRadius: [0, 0, 5, 5], formatter: [ '{first|綜合授信額度}', '{second|(CR20190912000013)\n獲批金額:100\n幣種:人民幣}', ].join('\n'), rich: { first: { backgroundColor: '#078E34', color: '#fff', align: 'center', width: 135, height: 30, borderRadius: [5, 5, 0, 0], }, second: { color: '#888', align: 'center', lineHeight: 17, }, } }, children: [ { label: { formatter: [ '{first|渠道額度}', ].join('\n'), rich: { first: { backgroundColor: '#3AC082', color: '#fff', align: 'center', width: 135, height: 65, borderRadius: 5, }, } }, children: [{ label: { formatter: [ '{first|保理額度}', ].join('\n'), rich: { first: { backgroundColor: '#3AC082', color: '#fff', align: 'center', width: 135, height: 65, borderRadius: 5, }, } }, children: [{ label: { backgroundColor: '#F4F4F4', borderRadius: [0, 0, 5, 5], formatter: [ '{first|反向保理}', '{second|(CR20190912000013)\n獲批金額:100\n幣種:人民幣}', ].join('\n'), rich: { first: { backgroundColor: '#078E34', color: '#fff', align: 'center', width: 135, height: 30, borderRadius: [5, 5, 0, 0], }, second: { color: '#888', align: 'center', lineHeight: 17, }, } }, }] }] }, { label: { formatter: [ '{first|擔保/(樂)集團/其他額度}', ].join('\n'), rich: { first: { backgroundColor: '#3AC082', color: '#fff', align: 'center', width: 135, height: 65, borderRadius: 5, }, } }, children: [{ label: { formatter: [ '{first|保理額度}', ].join('\n'), rich: { first: { backgroundColor: '#3AC082', color: '#fff', align: 'center', width: 135, height: 65, borderRadius: 5, }, } }, children: [{ label: { backgroundColor: '#F4F4F4', borderRadius: [0, 0, 5, 5], formatter: [ '{first|正向保理}', '{second|(CR20190912000013)\n獲批金額:100\n幣種:人民幣}', ].join('\n'), rich: { first: { backgroundColor: '#B8D87E', color: '#fff', align: 'center', width: 135, height: 30, borderRadius: [5, 5, 0, 0], }, second: { color: '#888', align: 'center', lineHeight: 17, }, } }, }] }, { label: { formatter: [ '{first|租賃額度}', ].join('\n'), rich: { first: { backgroundColor: '#3AC082', color: '#fff', align: 'center', width: 135, height: 65, borderRadius: 5, }, } }, children: [ { label: { backgroundColor: '#F4F4F4', borderRadius: [0, 0, 5, 5], formatter: [ '{first|車輛租賃}', '{second|(CR20190912000013)\n獲批金額:100\n幣種:人民幣}', ].join('\n'), rich: { first: { backgroundColor: '#FF6C6A', color: '#fff', align: 'center', width: 135, height: 30, borderRadius: [5, 5, 0, 0], }, second: { color: '#888', align: 'center', lineHeight: 17, }, } }, }, ] }] } ] } } }, components: { tree, } }; </script>
看著代碼不多,但是實現起來,各種查echarts的API和網上的資料,而且,由于效果圖中一個節點處的文字可能會換行,文字的顏色也不同,同時有些節點處的背景色還會有兩種,以及每個節點處顯示的樣式和文字都是不固定的,所以我們可能還要面臨著將接口返回的數據再改造處理成我們想要的數據的繁瑣問題,就如同傳遞給樹節點的treeData的格式一樣,相當麻煩,如果每個節點的樣式都是一樣的,那就好辦多了,如官網的一個樹狀圖的例子:https://www.echartsjs.com/examples/zh/editor.html?c=tree-vertical
從echarts的v4.7.0版本開始,給配置項series中加入一個API:edgeShape:'polyline'可實現樹形圖表連接每個節點的線的拐角處呈直角。
以上是“vue使用echarts畫組織結構圖的案例”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。