EchartRender.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. <template>
  2. <div class="echart-render chart-box">
  3. <h3 class="chart-title">{{ chartTitle }}</h3>
  4. <v-chart
  5. :options="chartOption"
  6. :init-options="initOptions"
  7. v-if="chartOption"
  8. autoresize
  9. ref="vueChart"
  10. ></v-chart>
  11. <p class="chart-none" v-else>暂无数据</p>
  12. </div>
  13. </template>
  14. <script>
  15. import echarts from "echarts/lib/echarts";
  16. export default {
  17. name: "echart-render",
  18. props: {
  19. chartType: {
  20. type: String,
  21. required: true,
  22. validator(value) {
  23. return (
  24. [
  25. "bar",
  26. "barReverse",
  27. "pie",
  28. "line",
  29. "darkLine",
  30. "barGroup",
  31. "lineGroup"
  32. ].indexOf(value) !== -1
  33. );
  34. }
  35. },
  36. rendererType: {
  37. type: String,
  38. default: "canvas",
  39. validator(val) {
  40. return ["canvas", "svg"].indexOf(val) !== -1;
  41. }
  42. },
  43. animationIsOpen: {
  44. type: Boolean,
  45. default: true
  46. },
  47. chartData: {
  48. type: [Object, Array],
  49. required: true
  50. },
  51. chartTitle: {
  52. type: String,
  53. default: ""
  54. },
  55. chartColor: {
  56. type: Array,
  57. default() {
  58. return [
  59. "#22C0FF",
  60. "#41CD7D",
  61. "#FF7786",
  62. "#4E7CFF",
  63. "#6d32f9",
  64. "#dd7755"
  65. ];
  66. }
  67. }
  68. },
  69. data() {
  70. return {
  71. chartOption: null,
  72. initOptions: { renderer: "canvas" }
  73. };
  74. },
  75. mounted() {
  76. if (this.rendererType) this.initOptions.renderer = this.rendererType;
  77. this.getOptions();
  78. },
  79. methods: {
  80. getOptions() {
  81. const name = this.chartType[0].toUpperCase() + this.chartType.slice(1);
  82. this.chartOption = this[`get${name}Option`](this.chartData);
  83. },
  84. getDataURL(options) {
  85. return this.$refs.vueChart && this.$refs.vueChart.getDataURL(options);
  86. },
  87. getLineOption(datas) {
  88. let labels = [],
  89. vals = [];
  90. datas.map(item => {
  91. labels.push(item.name);
  92. vals.push(item.value);
  93. });
  94. const linearColor = new echarts.graphic.LinearGradient(0, 1, 0, 0, [
  95. {
  96. offset: 1,
  97. color: "rgba(34,192,255,1)"
  98. },
  99. {
  100. offset: 0,
  101. color: "rgba(34,192,255,0)"
  102. }
  103. ]);
  104. return {
  105. animation: this.animationIsOpen,
  106. grid: {
  107. top: "10%",
  108. bottom: "12%",
  109. left: "5%",
  110. right: "5%"
  111. },
  112. tooltip: {
  113. show: true,
  114. formatter: function(params) {
  115. return params.value + "%";
  116. }
  117. },
  118. xAxis: {
  119. type: "category",
  120. data: labels,
  121. splitLine: {
  122. show: true,
  123. lineStyle: {
  124. color: "rgba(231,234,241,1)"
  125. }
  126. },
  127. axisLine: {
  128. lineStyle: {
  129. color: "rgba(231,234,241,1)"
  130. }
  131. },
  132. axisLabel: {
  133. color: "#7C86A3",
  134. fontSize: 12,
  135. fontWeight: "bold"
  136. },
  137. axisTick: {
  138. show: false
  139. }
  140. },
  141. yAxis: {
  142. type: "value",
  143. splitLine: {
  144. show: true,
  145. lineStyle: {
  146. color: "rgba(231,234,241,1)"
  147. }
  148. },
  149. axisLine: {
  150. lineStyle: {
  151. color: "rgba(231,234,241,1)"
  152. }
  153. },
  154. axisLabel: {
  155. fontSize: 12,
  156. color: "#7C86A3",
  157. formatter: function(value, index) {
  158. return value + "%";
  159. }
  160. },
  161. axisTick: {
  162. show: false
  163. }
  164. },
  165. series: [
  166. {
  167. name: "数量",
  168. type: "line",
  169. smooth: true,
  170. data: vals,
  171. itemStyle: {
  172. color: "rgba(34, 192, 255, 1)"
  173. },
  174. lineStyle: {
  175. color: "rgba(34, 192, 255, 1)"
  176. },
  177. areaStyle: {
  178. color: linearColor
  179. }
  180. }
  181. ]
  182. };
  183. },
  184. getDarkLineOption(datas) {
  185. let labels = [],
  186. vals = [];
  187. datas.map(item => {
  188. labels.push(item.name);
  189. vals.push(item.value);
  190. });
  191. const linearColor = new echarts.graphic.LinearGradient(0, 1, 0, 0, [
  192. {
  193. offset: 1,
  194. color: "rgba(21, 91, 146,1)"
  195. },
  196. {
  197. offset: 0,
  198. color: "rgba(21, 91, 146,0)"
  199. }
  200. ]);
  201. return {
  202. animation: this.animationIsOpen,
  203. grid: {
  204. top: "10%",
  205. bottom: "12%",
  206. left: "3.5%",
  207. right: "3%"
  208. },
  209. tooltip: {
  210. show: true,
  211. formatter: function(params) {
  212. return params.value + "%";
  213. }
  214. },
  215. xAxis: {
  216. type: "category",
  217. data: labels,
  218. splitLine: {
  219. show: true,
  220. lineStyle: {
  221. color: "#3d3f55"
  222. }
  223. },
  224. axisLine: {
  225. lineStyle: {
  226. color: "#3d3f55"
  227. }
  228. },
  229. axisLabel: {
  230. color: "#9d9c9c",
  231. fontSize: 12,
  232. fontWeight: "bold"
  233. },
  234. axisTick: {
  235. show: false
  236. }
  237. },
  238. yAxis: {
  239. type: "value",
  240. splitLine: {
  241. show: true,
  242. lineStyle: {
  243. color: "#3d3f55"
  244. }
  245. },
  246. axisLine: {
  247. lineStyle: {
  248. color: "#3d3f55"
  249. }
  250. },
  251. axisLabel: {
  252. fontSize: 12,
  253. color: "#9d9c9c",
  254. formatter: function(value, index) {
  255. return value + "%";
  256. }
  257. },
  258. axisTick: {
  259. show: false
  260. }
  261. },
  262. series: [
  263. {
  264. name: "数量",
  265. type: "line",
  266. smooth: true,
  267. data: vals,
  268. symbol: "circle",
  269. symbolSize: 8,
  270. itemStyle: {
  271. color: "rgba(21, 91, 146, 1)"
  272. },
  273. lineStyle: {
  274. color: "rgba(21, 91, 146, 0.6)"
  275. },
  276. areaStyle: {
  277. color: linearColor
  278. }
  279. }
  280. ]
  281. };
  282. },
  283. getPieOption(datas) {
  284. if (!datas.chartLabels.length) return;
  285. const seriesData = datas.chartLabels.map(function(item, index) {
  286. return {
  287. name: item,
  288. value: datas.chartData[0][index]
  289. };
  290. });
  291. return {
  292. animation: this.animationIsOpen,
  293. grid: {
  294. top: "24%",
  295. bottom: "10%"
  296. },
  297. tooltip: {
  298. trigger: "item",
  299. formatter: "{a} <br/>{b} : {c} ({d}%)"
  300. },
  301. legend: {
  302. show: true,
  303. itemGap: 20,
  304. itemWidth: 20,
  305. textStyle: {
  306. fontSize: 16
  307. }
  308. },
  309. series: [
  310. {
  311. name: "数量",
  312. type: "pie",
  313. radius: "70%",
  314. data: seriesData,
  315. label: {
  316. show: false
  317. },
  318. itemStyle: {
  319. emphasis: {
  320. shadowBlur: 10,
  321. shadowOffsetX: 0,
  322. shadowColor: "rgba(0, 0, 0, 0.5)"
  323. }
  324. }
  325. }
  326. ]
  327. };
  328. },
  329. getBarOption(datas) {
  330. if (!datas.names.length) return;
  331. return {
  332. animation: this.animationIsOpen,
  333. color: this.chartColor,
  334. grid: {
  335. top: "20%",
  336. bottom: "10%",
  337. left: "8%",
  338. right: "5%"
  339. },
  340. tooltip: {
  341. show: true
  342. },
  343. xAxis: {
  344. type: "category",
  345. data: datas.names,
  346. axisLine: {
  347. lineStyle: {
  348. color: "rgba(231,234,241,1)"
  349. }
  350. },
  351. axisLabel: {
  352. color: "#7C86A3",
  353. fontSize: 12,
  354. fontWeight: "bold"
  355. },
  356. axisTick: {
  357. show: false
  358. }
  359. },
  360. yAxis: {
  361. type: "value",
  362. splitLine: {
  363. show: true,
  364. lineStyle: {
  365. color: "rgba(231,234,241,1)"
  366. }
  367. },
  368. axisLine: {
  369. lineStyle: {
  370. color: "rgba(231,234,241,1)"
  371. }
  372. },
  373. axisLabel: {
  374. color: "#7C86A3",
  375. fontSize: 12,
  376. fontWeight: "bold"
  377. },
  378. axisTick: {
  379. show: false
  380. }
  381. },
  382. series: [
  383. {
  384. name: this.chartTitle || "值",
  385. type: "bar",
  386. barMaxWidth: 24,
  387. data: datas.dataList,
  388. label: {
  389. show: true,
  390. position: "top",
  391. color: "#666"
  392. },
  393. itemStyle: {
  394. barBorderRadius: 4
  395. }
  396. }
  397. ]
  398. };
  399. },
  400. getBarReverseOption(datas) {
  401. if (!datas.names.length) return;
  402. return {
  403. animation: this.animationIsOpen,
  404. color: this.chartColor,
  405. grid: {
  406. top: "20%",
  407. bottom: "10%",
  408. left: "12%",
  409. right: "5%"
  410. },
  411. tooltip: {
  412. show: true
  413. },
  414. yAxis: {
  415. type: "category",
  416. data: datas.names,
  417. axisLine: {
  418. lineStyle: {
  419. color: "rgba(231,234,241,1)"
  420. }
  421. },
  422. splitLine: {
  423. show: true,
  424. lineStyle: {
  425. color: "rgba(231,234,241,1)"
  426. }
  427. },
  428. axisLabel: {
  429. color: "#7C86A3",
  430. fontSize: 12,
  431. fontWeight: "bold"
  432. },
  433. axisTick: {
  434. show: false
  435. }
  436. },
  437. xAxis: {
  438. type: "value",
  439. splitLine: {
  440. show: false,
  441. lineStyle: {
  442. color: "rgba(231,234,241,1)"
  443. }
  444. },
  445. axisLine: {
  446. lineStyle: {
  447. color: "rgba(231,234,241,1)"
  448. }
  449. },
  450. axisLabel: {
  451. color: "#7C86A3",
  452. fontSize: 12,
  453. fontWeight: "bold"
  454. },
  455. axisTick: {
  456. show: false
  457. }
  458. },
  459. series: [
  460. {
  461. name: this.chartTitle || "值",
  462. type: "bar",
  463. barMaxWidth: 24,
  464. data: datas.dataList,
  465. label: {
  466. show: true,
  467. position: "right",
  468. color: "#666"
  469. },
  470. itemStyle: {
  471. barBorderRadius: 4
  472. }
  473. }
  474. ]
  475. };
  476. },
  477. getBarGroupOption(datas) {
  478. if (!datas.names.length) return;
  479. const xAxis = datas.dataList.map(function(item) {
  480. return item.name;
  481. });
  482. const series = datas.names.map(function(name, index) {
  483. const data = datas.dataList.map(function(item) {
  484. return item.data[index];
  485. });
  486. return {
  487. name: name,
  488. type: "bar",
  489. data: data,
  490. barMaxWidth: 12,
  491. itemStyle: {
  492. barBorderRadius: 2
  493. }
  494. };
  495. });
  496. const options = {
  497. animation: this.animationIsOpen,
  498. color: this.chartColor,
  499. grid: {
  500. top: "20%",
  501. bottom: "10%",
  502. left: "8%",
  503. right: "5%"
  504. },
  505. tooltip: {
  506. show: true,
  507. trigger: "axis",
  508. axisPointer: {
  509. type: "shadow"
  510. },
  511. formatter: function(params) {
  512. const label = params[0].axisValueLabel;
  513. let infos = params.map(function(item) {
  514. return item.seriesName + ":" + item.value.toFixed(2) + "%";
  515. });
  516. infos.unshift(label);
  517. return infos.join("<br/>");
  518. }
  519. },
  520. legend: {
  521. data: datas.names,
  522. right: 0,
  523. itemWidth: 14,
  524. textStyle: {
  525. fontSize: 16
  526. }
  527. },
  528. xAxis: {
  529. type: "category",
  530. data: xAxis,
  531. axisLabel: {
  532. color: "#7C86A3",
  533. fontSize: 12,
  534. fontWeight: "bold"
  535. },
  536. axisTick: {
  537. show: false
  538. }
  539. },
  540. yAxis: {
  541. type: "value",
  542. splitLine: {
  543. show: true,
  544. lineStyle: {
  545. color: "rgba(231,234,241,1)"
  546. }
  547. },
  548. axisLine: {
  549. lineStyle: {
  550. color: "rgba(231,234,241,1)"
  551. }
  552. },
  553. axisLabel: {
  554. color: "#7C86A3",
  555. fontSize: 12,
  556. fontWeight: "bold",
  557. formatter: function(value, index) {
  558. return value + "%";
  559. }
  560. },
  561. axisTick: {
  562. show: false
  563. }
  564. },
  565. series: series
  566. };
  567. return options;
  568. },
  569. getLineGroupOption(datas) {
  570. if (!datas.length) return;
  571. const names = datas.map(function(item) {
  572. return item.name;
  573. });
  574. const xaxis = datas[0].dataList.map(function(item, index) {
  575. return index;
  576. });
  577. const series = datas.map(function(item) {
  578. return {
  579. name: item.name,
  580. type: "line",
  581. symbol: "circle",
  582. smooth: true,
  583. itemStyle: {
  584. emphasis: {
  585. color: "#333"
  586. }
  587. },
  588. data: item.dataList.map(function(num) {
  589. return num * num;
  590. })
  591. };
  592. });
  593. return {
  594. animation: this.animationIsOpen,
  595. grid: {
  596. top: "15%",
  597. bottom: "12%"
  598. },
  599. tooltip: {
  600. show: true,
  601. trigger: "axis",
  602. axisPointer: {
  603. type: "shadow"
  604. },
  605. formatter: function(params) {
  606. const label = params[0].axisValueLabel;
  607. let infos = params.map(function(item) {
  608. return item.seriesName + ":" + Math.sqrt(item.value);
  609. });
  610. infos.unshift(label);
  611. return infos.join("<br/>");
  612. }
  613. },
  614. legend: {
  615. data: names,
  616. right: 0,
  617. itemWidth: 14,
  618. textStyle: {
  619. fontSize: 16
  620. }
  621. },
  622. xAxis: {
  623. type: "category",
  624. data: xaxis,
  625. axisLabel: {
  626. show: false,
  627. fontSize: 14
  628. },
  629. axisTick: {
  630. show: false
  631. }
  632. },
  633. yAxis: {
  634. type: "value",
  635. interval: 1,
  636. splitLine: {
  637. show: false
  638. },
  639. axisLabel: {
  640. fontSize: 14,
  641. formatter: function(value) {
  642. const num = Math.sqrt(value);
  643. return num % 1 ? "" : parseInt(num);
  644. }
  645. },
  646. axisTick: {
  647. show: false
  648. }
  649. },
  650. dataZoom: [
  651. {
  652. type: "inside",
  653. start: 0,
  654. end: 30
  655. },
  656. {
  657. type: "slider",
  658. start: 0,
  659. end: 30
  660. }
  661. ],
  662. series: series
  663. };
  664. }
  665. }
  666. };
  667. </script>