1
0

lineCharts.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  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. import dayjs from "dayjs";
  9. export default {
  10. name: "windChartCom",
  11. componentName: "windChartCom",
  12. props: {
  13. width: {
  14. type: String,
  15. default: "100%",
  16. },
  17. height: {
  18. type: String,
  19. default: "450px",
  20. },
  21. interval: {
  22. type: Number,
  23. default: 7,
  24. },
  25. // 单位
  26. units: {
  27. type: Array,
  28. default: () => ["", ""],
  29. },
  30. // 单位数据
  31. unitDatas: {
  32. type: Array,
  33. default: () => [
  34. { flag: false, min: 0, max: 0 },
  35. { flag: false, min: 0, max: 0 },
  36. ],
  37. },
  38. // 传入数据
  39. list: {
  40. type: Array,
  41. default: () => [
  42. {
  43. title: "绿线",
  44. smooth: true,
  45. value: [
  46. {
  47. text: "",
  48. value: 0,
  49. },
  50. {
  51. text: "0:00",
  52. value: 20,
  53. },
  54. {
  55. text: "10:00",
  56. value: 1,
  57. },
  58. {
  59. text: "11:00",
  60. value: 40,
  61. },
  62. {
  63. text: "12:00",
  64. value: 10,
  65. },
  66. {
  67. text: "13:00",
  68. value: 15,
  69. },
  70. {
  71. text: "14:00",
  72. value: 30,
  73. },
  74. {
  75. text: "15:00",
  76. value: 40,
  77. },
  78. {
  79. text: "",
  80. value: 10,
  81. },
  82. ],
  83. },
  84. {
  85. title: "黄线",
  86. smooth: true,
  87. value: [
  88. {
  89. text: "",
  90. value: 0,
  91. },
  92. {
  93. text: "0:00",
  94. value: 40,
  95. },
  96. {
  97. text: "10:00",
  98. value: 20,
  99. },
  100. {
  101. text: "11:00",
  102. value: 20,
  103. },
  104. {
  105. text: "12:00",
  106. value: 10,
  107. },
  108. {
  109. text: "13:00",
  110. value: 40,
  111. },
  112. {
  113. text: "14:00",
  114. value: 50,
  115. },
  116. {
  117. text: "15:00",
  118. value: 40,
  119. },
  120. {
  121. text: "",
  122. value: 10,
  123. },
  124. ],
  125. },
  126. ],
  127. },
  128. showLegend: {
  129. type: Boolean,
  130. default: false,
  131. },
  132. animate: {
  133. type: Boolean,
  134. default: true,
  135. },
  136. showXdata: {
  137. type: Boolean,
  138. default: false,
  139. },
  140. ratio: {
  141. type: Number,
  142. default: 1,
  143. },
  144. },
  145. data() {
  146. return {
  147. id: "",
  148. chart: null,
  149. color: [
  150. "#1985de",
  151. "#ff8300",
  152. "#06a746",
  153. "#3eede7",
  154. "#eb0f7c",
  155. "#dfdc0a",
  156. "#de0feb",
  157. "#cca4e3",
  158. ],
  159. newlist: null,
  160. emptyData: [],
  161. leftOffset: 20,
  162. seletedData: {},
  163. };
  164. },
  165. watch: {
  166. list: {
  167. handler(newValue, oldValue) {
  168. this.newlist = newValue;
  169. this.$nextTick(() => {
  170. this.newlist = this.list;
  171. this.initChart();
  172. });
  173. },
  174. deep: true,
  175. },
  176. "$store.state.themeName"() {
  177. this.initChart();
  178. },
  179. },
  180. computed: {
  181. getTimeStanp() {
  182. // 当日0点时间
  183. var timeStamp = [];
  184. let stamp = new Date(new Date().setHours(0, 0, 0, 0)).getTime();
  185. for (let i = 0; i < 96; i++) {
  186. timeStamp.push(dayjs(stamp).format("HH:mm"));
  187. this.emptyData.push("0");
  188. stamp = parseInt(stamp) + 15 * 60 * 1000;
  189. }
  190. timeStamp.push("24:00");
  191. return timeStamp;
  192. },
  193. colorValue() {
  194. return partten.getColor(this.color);
  195. },
  196. datas() {
  197. return this.newlist.map((t) => {
  198. return t.title;
  199. });
  200. },
  201. legend() {
  202. if (this.newlist) {
  203. return this.newlist.map((t) => {
  204. return t.title;
  205. });
  206. } else {
  207. return [];
  208. }
  209. },
  210. xdata() {
  211. var data;
  212. this.newlist.forEach((value, index) => {
  213. if (value.value != null && value.value.length > 0) {
  214. data = value;
  215. }
  216. });
  217. return data?.value.map((t, index) => {
  218. // if (index === this.newlist[0]?.value.length - 1) {
  219. // return "24:00";
  220. // } else {
  221. return dayjs(t.dateTime).format("MM-DD HH:mm");
  222. // }
  223. });
  224. },
  225. series() {
  226. let result = [];
  227. this.list.forEach((value, index) => {
  228. result.push({
  229. name: value.name || value.title,
  230. type: "line",
  231. smooth: value.smooth,
  232. symbol: "circle",
  233. showSymbol: true,
  234. zlevel: index,
  235. lineStyle: {
  236. normal: {
  237. color: this.color[index],
  238. width: 1,
  239. },
  240. },
  241. yAxisIndex: value.yAxisIndex,
  242. data: value.value.map((t) => {
  243. if (value.noRatio) {
  244. return t.value ? t.value.toFixed(2) : 0.0;
  245. } else {
  246. return t.value === "" && t.value !== 0
  247. ? ""
  248. : (t.value / this.ratio).toFixed(2);
  249. }
  250. }),
  251. });
  252. });
  253. return result;
  254. },
  255. yAxis() {
  256. let result = [];
  257. let i = 0;
  258. this.units.forEach((value, index) => {
  259. var option = {
  260. type: "value",
  261. // name: this.units[index],
  262. nameTextStyle: {
  263. color: this.color[index],
  264. fontSize: 12,
  265. },
  266. splitNumber: 11,
  267. // position:'left',
  268. axisLabel: {
  269. formatter: "{value}",
  270. textStyle: {
  271. color: this.color[index],
  272. fontSize: 12,
  273. },
  274. },
  275. axisLine: {
  276. lineStyle: {
  277. color: this.color[this.unitDatas[index].codex],
  278. width: 1,
  279. },
  280. },
  281. boundaryGap: false,
  282. //分格线
  283. splitLine: {
  284. show: false,
  285. lineStyle: {
  286. color: "#2D3338",
  287. width: 1, //轴线的宽度
  288. type: "dashed",
  289. },
  290. },
  291. };
  292. if (this.unitDatas[index].flag) {
  293. i++;
  294. option.min = this.unitDatas[index].min;
  295. option.max = this.unitDatas[index].max;
  296. if (i % 2 != 0) {
  297. option.position = "left";
  298. option.offset = (i - 1) * 35;
  299. if (i >= 3) {
  300. option.offset = (i - 2) * 35;
  301. }
  302. if (i >= 5) {
  303. option.offset = (i - 3) * 35;
  304. }
  305. if (i >= 7) {
  306. option.offset = (i - 4) * 35;
  307. }
  308. } else {
  309. if (i >= 4) {
  310. option.offset = (i - 3) * 35;
  311. }
  312. if (i >= 6) {
  313. option.offset = (i - 4) * 35;
  314. }
  315. if (i >= 8) {
  316. option.offset = (i - 5) * 35;
  317. }
  318. }
  319. result.push(option);
  320. } else if (index == 0) {
  321. if (!this.unitDatas[0].flag) {
  322. option.axisLine.lineStyle.color = "#525252";
  323. option.axisLabel.textStyle.color = "#828484";
  324. }
  325. if (
  326. this.unitDatas[index].min == 0 &&
  327. this.unitDatas[index].max == 0
  328. ) {
  329. result.push(option);
  330. } else {
  331. option.min = this.unitDatas[index].min;
  332. option.max = this.unitDatas[index].max;
  333. result.push(option);
  334. }
  335. }
  336. this.leftOffset = 35;
  337. if (i == 0) {
  338. this.leftOffset = 35;
  339. }
  340. });
  341. return result;
  342. },
  343. },
  344. methods: {
  345. childMethod(index) {
  346. this.chart.dispatchAction({
  347. type: "highlight",
  348. seriesIndex: 0,
  349. dataIndex: 0,
  350. });
  351. return this.chart.getModel().getComponent("yAxis", index).axis.scale
  352. ._extent[1];
  353. },
  354. changDateVisible(option) {
  355. this.seletedData = option;
  356. this.initChart();
  357. },
  358. resize() {},
  359. initChart() {
  360. const chart = echarts.init(this.$el, null, {
  361. renderer: "canvas",
  362. useDirtyRect: false,
  363. });
  364. let option = {
  365. animation: this.animate,
  366. color: this.color,
  367. tooltip: {
  368. trigger: "axis",
  369. backgroundColor: "rgba(0,0,0,0.4)",
  370. borderColor: partten.getColor("gray"),
  371. textStyle: {
  372. color: "#fff",
  373. fontSize: 14,
  374. },
  375. },
  376. legend:
  377. {
  378. show: this.showLegend,
  379. data: this.legend,
  380. padding: [10, 10],
  381. left: "center",
  382. bottom: -10,
  383. icon: "ract",
  384. itemWidth: 6,
  385. itemHeight: 6,
  386. inactiveColor: partten.getColor("gray"),
  387. textStyle: {
  388. color: partten.getColor("grayl"),
  389. fontSize: 12,
  390. },
  391. selected: this.seletedData,
  392. } || {},
  393. grid: {
  394. top: 16,
  395. left: this.leftOffset,
  396. right: 40,
  397. bottom: 30,
  398. containLabel: true,
  399. },
  400. xAxis:
  401. [
  402. {
  403. type: "category",
  404. boundaryGap: false,
  405. axisLabel: {
  406. interval: this.interval,
  407. formatter: "{value}",
  408. textStyle: {
  409. color: "#828484",
  410. fontSize: 12,
  411. },
  412. },
  413. axisTick: {
  414. alignWithLabel: true,
  415. },
  416. data: this.showXdata ? this.getTimeStanp : this.xdata,
  417. },
  418. ] || [],
  419. yAxis: this.yAxis || [],
  420. dataZoom: [
  421. {
  422. type: "slider",
  423. bottom: 0,
  424. height: 20,
  425. handleSize: "90%",
  426. start: 0,
  427. end: 100,
  428. handleColor: "#555B66",
  429. borderColor: "#545454",
  430. backgroundColor: "rgba(0, 70, 199, 0.2)",
  431. fillerColor: "#343A46",
  432. textStyle: { color: "white" },
  433. labelFormatter: (value) => {
  434. if (value) {
  435. return this.xdata[value];
  436. }
  437. },
  438. },
  439. ],
  440. series: this.series || {},
  441. };
  442. chart.clear();
  443. if (Object.values(this.series).length) {
  444. chart.setOption(option);
  445. }
  446. this.resize = function () {
  447. chart.resize();
  448. };
  449. window.addEventListener("resize", this.resize);
  450. this.chart = chart;
  451. },
  452. },
  453. created() {
  454. this.$nextTick(() => {
  455. this.id = "pie-chart-" + util.newGUID();
  456. });
  457. this.newlist = this.list;
  458. },
  459. mounted() {
  460. this.$nextTick(() => {
  461. this.$el.style.width = this.width;
  462. this.$el.style.height = this.height;
  463. this.initChart();
  464. });
  465. },
  466. updated() {
  467. this.$nextTick(() => {
  468. this.initChart();
  469. });
  470. },
  471. unmounted() {
  472. window.removeEventListener("resize", this.resize);
  473. },
  474. };
  475. </script>
  476. <style lang="less">
  477. .chart {
  478. width: 100%;
  479. height: 100%;
  480. display: inline-block;
  481. }
  482. </style>