area-line-chart-2.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. <template>
  2. <div class="chart" :id="id"></div>
  3. </template>
  4. <script>
  5. import util from "@/helper/util.js";
  6. import partten from "@/helper/partten.js";
  7. import * as echarts from "echarts";
  8. export default {
  9. name: "multiple-bar-chart",
  10. componentName: "multiple-bar-chart",
  11. props: {
  12. width: {
  13. type: String,
  14. default: "100%",
  15. },
  16. height: {
  17. type: String,
  18. default: "800px",
  19. },
  20. lineData: {
  21. type: Array,
  22. default: () => [
  23. {
  24. text: "日发电量",
  25. yAxisIndex: 0,
  26. value: [
  27. {
  28. text: "1",
  29. value: 1,
  30. },
  31. {
  32. text: "2",
  33. value: 2,
  34. },
  35. {
  36. text: "3",
  37. value: 1,
  38. },
  39. {
  40. text: "4",
  41. value: 3,
  42. },
  43. {
  44. text: "5",
  45. value: 3,
  46. },
  47. {
  48. text: "6",
  49. value: 3,
  50. },
  51. {
  52. text: "7",
  53. value: 3,
  54. },
  55. {
  56. text: "8",
  57. value: 3,
  58. },
  59. {
  60. text: "9",
  61. value: 3,
  62. },
  63. {
  64. text: "10",
  65. value: 3,
  66. },
  67. {
  68. text: "11",
  69. value: 3,
  70. },
  71. {
  72. text: "12",
  73. value: 3,
  74. },
  75. {
  76. text: "13",
  77. value: 3,
  78. },
  79. {
  80. text: "14",
  81. value: 3,
  82. },
  83. {
  84. text: "15",
  85. value: 3,
  86. },
  87. {
  88. text: "16",
  89. value: 3,
  90. },
  91. ],
  92. },
  93. {
  94. text: "上网电量",
  95. yAxisIndex: 1,
  96. value: [
  97. {
  98. text: "1",
  99. value: 1,
  100. },
  101. {
  102. text: "2",
  103. value: 2,
  104. },
  105. {
  106. text: "3",
  107. value: 1,
  108. },
  109. {
  110. text: "4",
  111. value: 3,
  112. },
  113. {
  114. text: "5",
  115. value: 4,
  116. },
  117. {
  118. text: "6",
  119. value: 5,
  120. },
  121. {
  122. text: "7",
  123. value: 6,
  124. },
  125. {
  126. text: "8",
  127. value: 7,
  128. },
  129. {
  130. text: "9",
  131. value: 8,
  132. },
  133. {
  134. text: "10",
  135. value: 7,
  136. },
  137. {
  138. text: "11",
  139. value: 9,
  140. },
  141. {
  142. text: "12",
  143. value: 2,
  144. },
  145. {
  146. text: "13",
  147. value: 3,
  148. },
  149. {
  150. text: "14",
  151. value: 5,
  152. },
  153. {
  154. text: "15",
  155. value: 12,
  156. },
  157. {
  158. text: "16",
  159. value: 11,
  160. },
  161. ],
  162. },
  163. ],
  164. },
  165. areaData: {
  166. type: Array,
  167. default: () => [
  168. {
  169. name: "1",
  170. start: 0,
  171. end: 100,
  172. state: "green",
  173. },
  174. {
  175. name: "1",
  176. start: 100,
  177. end: 200,
  178. state: "red",
  179. },
  180. {
  181. name: "1",
  182. start: 200,
  183. end: 300,
  184. state: "yellow",
  185. },
  186. {
  187. name: "2",
  188. start: 300,
  189. end: 800,
  190. state: "green",
  191. },
  192. {
  193. name: "3",
  194. start: 800,
  195. end: 9000,
  196. state: "green",
  197. },
  198. ],
  199. },
  200. // 单位
  201. units: {
  202. type: Array,
  203. default: () => ["健康趋势", "风机健康状态数量"],
  204. },
  205. // 显示 legend
  206. showLegend: {
  207. type: Boolean,
  208. default: true,
  209. },
  210. // 颜色
  211. color: {
  212. type: Array,
  213. default: () => ["#323E6F", "#1DA0D7", "#02BB4C", "#DB5520", "#EDB32F", "#EDEB2F"],
  214. },
  215. },
  216. data() {
  217. return {
  218. id: "",
  219. chart: null,
  220. };
  221. },
  222. computed: {
  223. legend() {
  224. let data = [];
  225. this.lineData.forEach((value, index) => {
  226. data.push(value.text);
  227. });
  228. return data;
  229. },
  230. xAxisData() {
  231. let data = [];
  232. if (this.lineData.length > 0)
  233. this.lineData[0].value.forEach((value, index) => {
  234. data.push(value.text);
  235. });
  236. return data;
  237. },
  238. yAxisData() {
  239. let result = [];
  240. this.units.forEach((value, index) => {
  241. let data = {
  242. type: "value",
  243. name: value,
  244. axisLabel: {
  245. formatter: "{value} ",
  246. color: partten.getColor("gray"),
  247. },
  248. axisLine: {
  249. type: "dashed",
  250. lineStyle: {
  251. color: partten.getColor("gray"),
  252. },
  253. width: 5,
  254. },
  255. axisTick: {
  256. show: false,
  257. },
  258. splitLine: {
  259. lineStyle: {
  260. type: "dashed",
  261. dashOffset: 10,
  262. color: partten.getColor("gray") + 80,
  263. },
  264. },
  265. };
  266. result.push(data);
  267. });
  268. result.push({
  269. data: [this.areaData[0].name],
  270. axisLabel: { show: false },
  271. });
  272. return result;
  273. },
  274. areaChartData() {
  275. let data = [];
  276. for (var i = 0; i < this.areaData.length; i++) {
  277. let item = this.areaData[i];
  278. var color = item.state;
  279. data.push({
  280. name: item.name,
  281. value: [item.start, item.end, item.end - item.start],
  282. itemStyle: {
  283. normal: {
  284. color: color,
  285. },
  286. },
  287. exData: item,
  288. });
  289. }
  290. return data;
  291. },
  292. areaMax() {
  293. let max = 0;
  294. this.areaData.forEach((value) => {
  295. if (max < value.end) max = value.end;
  296. });
  297. return max;
  298. },
  299. },
  300. methods: {
  301. renderItem(params, api) {
  302. var start = api.coord([api.value(0)]);
  303. var end = api.coord([api.value(1)]);
  304. var height = api.size([0, 1])[1];
  305. var rectShape = echarts.graphic.clipRectByRect(
  306. {
  307. x: start[0],
  308. y: start[1] - height / 2,
  309. width: end[0] - start[0],
  310. height: height,
  311. },
  312. {
  313. x: params.coordSys.x,
  314. y: params.coordSys.y,
  315. width: params.coordSys.width,
  316. height: params.coordSys.height,
  317. }
  318. );
  319. return (
  320. rectShape && {
  321. type: "rect",
  322. transition: ["shape"],
  323. shape: rectShape,
  324. style: api.style(),
  325. }
  326. );
  327. },
  328. initChart() {
  329. let that = this;
  330. let chart = echarts.init(this.$el);
  331. let option = {
  332. color: this.color,
  333. grid: {
  334. left: 40,
  335. right: 40,
  336. bottom: 40,
  337. top: 32,
  338. containLabel: true,
  339. },
  340. tooltip: {
  341. show: true,
  342. trigger: "axis",
  343. axisPointer: {
  344. type: "cross",
  345. },
  346. backgroundColor: "rgba(0,0,0,0.4)",
  347. borderColor: partten.getColor("gray"),
  348. textStyle: {
  349. color: "#fff",
  350. fontSize: 14,
  351. },
  352. },
  353. legend: {
  354. show: this.showLegend,
  355. data: this.legend,
  356. right: 120,
  357. icon: "ract",
  358. itemWidth: 8,
  359. itemHeight: 8,
  360. inactiveColor: partten.getColor("gray"),
  361. textStyle: {
  362. color: partten.getColor("grayl"),
  363. fontSize: 12,
  364. },
  365. },
  366. xAxis: [
  367. {
  368. type: "category",
  369. axisLabel: {
  370. color: partten.getColor("gray"),
  371. },
  372. axisLine: {
  373. show: false,
  374. },
  375. axisTick: {
  376. show: false,
  377. },
  378. data: this.xAxisData,
  379. },
  380. {
  381. show: false,
  382. min: 0,
  383. max: this.areaMax,
  384. axisLabel: {
  385. show: false,
  386. formatter: function(val) {
  387. return Math.max(0, val - 0) + " ms";
  388. },
  389. },
  390. },
  391. ],
  392. yAxis: this.yAxisData,
  393. series: [],
  394. };
  395. // line data
  396. if (this.lineData.length > 0) {
  397. this.lineData.forEach((value, index) => {
  398. option.series.push({
  399. name: value.text,
  400. type: "line",
  401. data: value.value,
  402. smooth: true, //平滑展示
  403. yAxisIndex: value.yAxisIndex,
  404. // lineStyle: {
  405. // color: partten.getColor("green"),
  406. // },
  407. // itemStyle: {
  408. // color: partten.getColor("green"),
  409. // },
  410. });
  411. });
  412. }
  413. // 区域
  414. if (this.areaData && this.areaData.length > 0) {
  415. option.series.push({
  416. type: "custom",
  417. renderItem: this.renderItem,
  418. yAxisIndex: this.units.length,
  419. xAxisIndex: 1,
  420. itemStyle: {
  421. opacity: 0.2,
  422. },
  423. tooltip: {
  424. show: false,
  425. formatter: function(params) {
  426. return params.marker + params.name + ": " + params.value[2] + "s";
  427. },
  428. },
  429. encode: {
  430. x: [1, 2],
  431. y: 0,
  432. },
  433. data: this.areaChartData,
  434. });
  435. }
  436. chart.setOption(option);
  437. return chart;
  438. },
  439. },
  440. emits: {
  441. areaClick: null,
  442. },
  443. created() {
  444. this.id = "pie-chart-" + util.newGUID();
  445. },
  446. mounted() {
  447. this.$nextTick(() => {
  448. this.$el.style.width = this.width;
  449. this.$el.style.height = this.height;
  450. let that = this;
  451. let chart = this.initChart();
  452. chart.on("click", function(e, p) {
  453. if (e.seriesType == "custom") {
  454. that.$emit("areaClick", { data: e.data.exData });
  455. }
  456. });
  457. });
  458. },
  459. updated() {
  460. this.$nextTick(() => {
  461. this.initChart();
  462. });
  463. },
  464. };
  465. </script>
  466. <style lang="less">
  467. .chart {
  468. width: 100%;
  469. height: 100%;
  470. display: inline-block;
  471. }
  472. </style>