EchartRender.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. <template>
  2. <div class="echart-render chart-box">
  3. <h3 class="chart-title">{{ chartTitle }}</h3>
  4. <v-chart
  5. :options="chartOption"
  6. v-if="chartOption"
  7. autoresize
  8. ref="vueChart"
  9. ></v-chart>
  10. <p class="chart-none" v-else>暂无数据</p>
  11. </div>
  12. </template>
  13. <script>
  14. import echarts from "echarts/lib/echarts";
  15. export default {
  16. name: "echart-render",
  17. props: {
  18. chartType: {
  19. type: String,
  20. required: true,
  21. validator(value) {
  22. return (
  23. ["bar", "pie", "line", "barGroup", "lineGroup"].indexOf(value) !== -1
  24. );
  25. }
  26. },
  27. chartData: {
  28. type: [Object, Array],
  29. required: true
  30. },
  31. chartTitle: {
  32. type: String,
  33. default: ""
  34. }
  35. },
  36. data() {
  37. return {
  38. chartOption: null
  39. };
  40. },
  41. mounted() {
  42. this.getOptions();
  43. },
  44. methods: {
  45. getOptions() {
  46. const name = this.chartType[0].toUpperCase() + this.chartType.slice(1);
  47. this.chartOption = this[`get${name}Option`](this.chartData);
  48. },
  49. getLineOption(datas) {
  50. let labels = [],
  51. vals = [];
  52. datas.map(item => {
  53. labels.push(item.name);
  54. vals.push(item.value);
  55. });
  56. const linearColor = new echarts.graphic.LinearGradient(0, 1, 0, 0, [
  57. {
  58. offset: 1,
  59. color: "rgba(34,192,255,1)"
  60. },
  61. {
  62. offset: 0,
  63. color: "rgba(34,192,255,0)"
  64. }
  65. ]);
  66. return {
  67. grid: {
  68. top: "10%",
  69. bottom: "12%",
  70. left: "5%",
  71. right: "5%"
  72. },
  73. tooltip: {
  74. show: true,
  75. formatter: function(params) {
  76. return params.value + "%";
  77. }
  78. },
  79. xAxis: {
  80. type: "category",
  81. data: labels,
  82. splitLine: {
  83. show: true,
  84. lineStyle: {
  85. color: "rgba(231,234,241,1)"
  86. }
  87. },
  88. axisLine: {
  89. lineStyle: {
  90. color: "rgba(231,234,241,1)"
  91. }
  92. },
  93. axisLabel: {
  94. color: "#7C86A3",
  95. fontSize: 12,
  96. fontWeight: "bold"
  97. },
  98. axisTick: {
  99. show: false
  100. }
  101. },
  102. yAxis: {
  103. type: "value",
  104. splitLine: {
  105. show: true,
  106. lineStyle: {
  107. color: "rgba(231,234,241,1)"
  108. }
  109. },
  110. axisLine: {
  111. lineStyle: {
  112. color: "rgba(231,234,241,1)"
  113. }
  114. },
  115. axisLabel: {
  116. fontSize: 12,
  117. color: "#7C86A3",
  118. formatter: function(value, index) {
  119. return value + "%";
  120. }
  121. },
  122. axisTick: {
  123. show: false
  124. }
  125. },
  126. series: [
  127. {
  128. name: "数量",
  129. type: "line",
  130. smooth: true,
  131. data: vals,
  132. itemStyle: {
  133. color: "rgba(34, 192, 255, 1)"
  134. },
  135. lineStyle: {
  136. color: "rgba(34, 192, 255, 1)"
  137. },
  138. areaStyle: {
  139. color: linearColor
  140. }
  141. }
  142. ]
  143. };
  144. },
  145. getPieOption(datas) {
  146. if (!datas.chartLabels.length) return;
  147. var seriesData = datas.chartLabels.map(function(item, index) {
  148. return {
  149. name: item,
  150. value: datas.chartData[0][index]
  151. };
  152. });
  153. return {
  154. grid: {
  155. top: "24%",
  156. bottom: "10%"
  157. },
  158. tooltip: {
  159. trigger: "item",
  160. formatter: "{a} <br/>{b} : {c} ({d}%)"
  161. },
  162. legend: {
  163. show: true,
  164. itemGap: 20,
  165. itemWidth: 20,
  166. textStyle: {
  167. fontSize: 16
  168. }
  169. },
  170. series: [
  171. {
  172. name: "数量",
  173. type: "pie",
  174. radius: "70%",
  175. data: seriesData,
  176. label: {
  177. show: false
  178. },
  179. itemStyle: {
  180. emphasis: {
  181. shadowBlur: 10,
  182. shadowOffsetX: 0,
  183. shadowColor: "rgba(0, 0, 0, 0.5)"
  184. }
  185. }
  186. }
  187. ]
  188. };
  189. },
  190. getBarOption(datas) {
  191. if (!datas.names.length) return;
  192. return {
  193. grid: {
  194. top: "15%",
  195. bottom: "18%"
  196. },
  197. tooltip: {
  198. show: true
  199. },
  200. xAxis: {
  201. type: "category",
  202. data: datas.names,
  203. axisLabel: {
  204. fontSize: 14,
  205. fontWeight: "bold"
  206. },
  207. axisTick: {
  208. show: false
  209. }
  210. },
  211. yAxis: {
  212. type: "value",
  213. splitLine: {
  214. show: true,
  215. lineStyle: {
  216. color: "#e0e0e0"
  217. }
  218. },
  219. axisLine: {
  220. lineStyle: {
  221. color: "#333"
  222. }
  223. },
  224. axisLabel: {
  225. fontSize: 14
  226. },
  227. axisTick: {
  228. show: false
  229. }
  230. },
  231. series: [
  232. {
  233. name: "差值和",
  234. type: "bar",
  235. barWidth: 30,
  236. data: datas.dataList,
  237. label: {
  238. show: true,
  239. position: "top",
  240. color: "#333",
  241. fontWeight: 600
  242. }
  243. }
  244. ]
  245. };
  246. },
  247. getBarGroupOption(datas) {
  248. if (!datas.names.length) return;
  249. var onePageMaxBarNum = 20;
  250. var barNum = datas.names.length * datas.dataList.length;
  251. var xAxis = datas.dataList.map(function(item) {
  252. return item.name;
  253. });
  254. var series = datas.names.map(function(name, index) {
  255. var data = datas.dataList.map(function(item) {
  256. return item.data[index];
  257. });
  258. return {
  259. name: name,
  260. type: "bar",
  261. data: data,
  262. barMaxWidth: 30,
  263. barMinHeight: 2
  264. // label: {
  265. // show: true,
  266. // position: "top",
  267. // fontSize: 12,
  268. // color: "#333",
  269. // formatter: function(params) {
  270. // return params.value.toFixed(2) + "%";
  271. // }
  272. // }
  273. };
  274. });
  275. var options = {
  276. grid: {
  277. top: "15%",
  278. bottom: "10%"
  279. },
  280. tooltip: {
  281. show: true,
  282. trigger: "axis",
  283. axisPointer: {
  284. type: "shadow"
  285. },
  286. formatter: function(params) {
  287. var label = params[0].axisValueLabel;
  288. var infos = params.map(function(item) {
  289. return item.seriesName + ":" + item.value.toFixed(2) + "%";
  290. });
  291. infos.unshift(label);
  292. return infos.join("<br/>");
  293. }
  294. },
  295. legend: {
  296. data: datas.names,
  297. right: 0,
  298. itemWidth: 14,
  299. textStyle: {
  300. fontSize: 16
  301. }
  302. },
  303. xAxis: {
  304. type: "category",
  305. data: xAxis,
  306. axisLabel: {
  307. fontSize: 14,
  308. fontWeight: "bold"
  309. },
  310. axisTick: {
  311. show: false
  312. }
  313. },
  314. yAxis: {
  315. type: "value",
  316. splitLine: {
  317. show: false
  318. },
  319. axisLabel: {
  320. fontSize: 14,
  321. formatter: function(value, index) {
  322. return value + "%";
  323. }
  324. },
  325. axisTick: {
  326. show: false
  327. }
  328. },
  329. series: series
  330. };
  331. if (barNum > onePageMaxBarNum) {
  332. var zoomInitRange = Math.floor((onePageMaxBarNum * 100) / barNum);
  333. options.grid.bottom = "16%";
  334. options.dataZoom = [
  335. {
  336. type: "inside",
  337. start: 0,
  338. end: zoomInitRange
  339. },
  340. {
  341. type: "slider",
  342. start: 0,
  343. end: zoomInitRange
  344. }
  345. ];
  346. }
  347. return options;
  348. },
  349. getLineGroupOption(datas) {
  350. if (!datas.length) return;
  351. var names = datas.map(function(item) {
  352. return item.name;
  353. });
  354. var xaxis = datas[0].dataList.map(function(item, index) {
  355. return index;
  356. });
  357. var series = datas.map(function(item) {
  358. return {
  359. name: item.name,
  360. type: "line",
  361. symbol: "circle",
  362. smooth: true,
  363. itemStyle: {
  364. emphasis: {
  365. color: "#333"
  366. }
  367. },
  368. data: item.dataList.map(function(num) {
  369. return num * num;
  370. })
  371. };
  372. });
  373. return {
  374. grid: {
  375. top: "15%",
  376. bottom: "12%"
  377. },
  378. tooltip: {
  379. show: true,
  380. trigger: "axis",
  381. axisPointer: {
  382. type: "shadow"
  383. },
  384. formatter: function(params) {
  385. var label = params[0].axisValueLabel;
  386. var infos = params.map(function(item) {
  387. return item.seriesName + ":" + Math.sqrt(item.value);
  388. });
  389. infos.unshift(label);
  390. return infos.join("<br/>");
  391. }
  392. },
  393. legend: {
  394. data: names,
  395. right: 0,
  396. itemWidth: 14,
  397. textStyle: {
  398. fontSize: 16
  399. }
  400. },
  401. xAxis: {
  402. type: "category",
  403. data: xaxis,
  404. axisLabel: {
  405. show: false,
  406. fontSize: 14
  407. },
  408. axisTick: {
  409. show: false
  410. }
  411. },
  412. yAxis: {
  413. type: "value",
  414. interval: 1,
  415. splitLine: {
  416. show: false
  417. },
  418. axisLabel: {
  419. fontSize: 14,
  420. formatter: function(value) {
  421. var num = Math.sqrt(value);
  422. return num % 1 ? "" : parseInt(num);
  423. }
  424. },
  425. axisTick: {
  426. show: false
  427. }
  428. },
  429. dataZoom: [
  430. {
  431. type: "inside",
  432. start: 0,
  433. end: 30
  434. },
  435. {
  436. type: "slider",
  437. start: 0,
  438. end: 30
  439. }
  440. ],
  441. series: series
  442. };
  443. }
  444. }
  445. };
  446. </script>