index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. <template>
  2. <view class="page">
  3. <view class="chart" v-if="testData.length">
  4. <cusEcharts :option="testOption"></cusEcharts>
  5. </view>
  6. <view class="chart" v-if="kxData.length">
  7. <cusEcharts :option="kxOption"></cusEcharts>
  8. </view>
  9. <view class="chart" v-if="kxData2.length">
  10. <cusEcharts :option="kxOption2"></cusEcharts>
  11. </view>
  12. </view>
  13. </template>
  14. <script>
  15. import * as echarts from "echarts";
  16. import aqiData from '@/static/js/aqi-beijing.js'
  17. export default {
  18. data(){
  19. return {
  20. testData:[],
  21. testOption:null,
  22. kxData:[],
  23. kxOption:null,
  24. kxData2:[],
  25. kxOption2:null
  26. }
  27. },
  28. mounted() {
  29. this.init();
  30. },
  31. methods:{
  32. init(){
  33. this.initTestChart();
  34. this.initKxChart();
  35. this.initKxChart2();
  36. },
  37. initTestChart(){
  38. this.testData = [150, 230, 224, 218, 135, 147, 260];
  39. this.testOption = {
  40. xAxis: {
  41. type: 'category',
  42. data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  43. },
  44. yAxis: {
  45. type: 'value'
  46. },
  47. series: [
  48. {
  49. data: this.testData,
  50. type: 'line'
  51. }
  52. ]
  53. };
  54. },
  55. initKxChart(){
  56. this.kxData = [270,220,350,210,280,400];
  57. const offsetX = 4;
  58. const offsetY = 2;
  59. // 绘制左侧面
  60. const CubeLeft = echarts.graphic.extendShape({
  61. shape: {
  62. x: 0,
  63. y: 0,
  64. },
  65. buildPath: function (ctx, shape) {
  66. // 会canvas的应该都能看得懂,shape是从custom传入的
  67. const xAxisPoint = shape.xAxisPoint;
  68. const c0 = [shape.x, shape.y];
  69. const c1 = [shape.x - offsetX, shape.y - offsetY];
  70. const c2 = [xAxisPoint[0] - offsetX, xAxisPoint[1] - offsetY];
  71. const c3 = [xAxisPoint[0], xAxisPoint[1]];
  72. ctx
  73. .moveTo(c0[0], c0[1])
  74. .lineTo(c1[0], c1[1])
  75. .lineTo(c2[0], c2[1])
  76. .lineTo(c3[0], c3[1])
  77. .closePath();
  78. },
  79. });
  80. // 绘制右侧面
  81. const CubeRight = echarts.graphic.extendShape({
  82. shape: {
  83. x: 0,
  84. y: 0,
  85. },
  86. buildPath: function (ctx, shape) {
  87. const xAxisPoint = shape.xAxisPoint;
  88. const c1 = [shape.x, shape.y];
  89. const c2 = [xAxisPoint[0], xAxisPoint[1]];
  90. const c3 = [xAxisPoint[0] + offsetX, xAxisPoint[1] - offsetY];
  91. const c4 = [shape.x + offsetX, shape.y - offsetY];
  92. ctx
  93. .moveTo(c1[0], c1[1])
  94. .lineTo(c2[0], c2[1])
  95. .lineTo(c3[0], c3[1])
  96. .lineTo(c4[0], c4[1])
  97. .closePath();
  98. },
  99. });
  100. // 绘制顶面
  101. const CubeTop = echarts.graphic.extendShape({
  102. shape: {
  103. x: 0,
  104. y: 0,
  105. },
  106. buildPath: function (ctx, shape) {
  107. const c1 = [shape.x, shape.y];
  108. const c2 = [shape.x + offsetX, shape.y - offsetY]; //右点
  109. const c3 = [shape.x, shape.y - offsetX];
  110. const c4 = [shape.x - offsetX, shape.y - offsetY];
  111. ctx
  112. .moveTo(c1[0], c1[1])
  113. .lineTo(c2[0], c2[1])
  114. .lineTo(c3[0], c3[1])
  115. .lineTo(c4[0], c4[1])
  116. .closePath();
  117. },
  118. });
  119. // 注册三个面图形
  120. echarts.graphic.registerShape("CubeLeft", CubeLeft);
  121. echarts.graphic.registerShape("CubeRight", CubeRight);
  122. echarts.graphic.registerShape("CubeTop", CubeTop);
  123. this.kxOption = {
  124. tooltip: {
  125. trigger: 'axis',
  126. backgroundColor: 'rgba(13,5,30,.6)',
  127. borderWidth: 1,
  128. borderColor: '#4ddd8f',
  129. padding: 5,
  130. textStyle: {
  131. color: '#fff'
  132. }
  133. },
  134. legend: {
  135. right: 170,
  136. top: 15,
  137. textStyle: {
  138. fontSize: 12,
  139. color: '#A7BFDE'
  140. },
  141. itemWidth: 6,
  142. itemHeight: 8
  143. },
  144. grid: {
  145. left: '4%',
  146. right: '3%',
  147. top: '25%',
  148. bottom: '8%',
  149. containLabel: true,
  150. },
  151. xAxis: {
  152. type: 'category',
  153. data: ['3月', '4月', '5月', '6月', '7月', '8月'],
  154. axisPointer: {
  155. type: 'shadow'
  156. },
  157. axisTick: {
  158. show: true,
  159. length: 4,
  160. lineStyle: {
  161. color: 'rgba(199,211,229,0.5)'
  162. }
  163. },
  164. axisLine: {
  165. show: true,
  166. lineStyle: {
  167. color: 'rgba(199,211,229,0.5)'
  168. }
  169. },
  170. axisLabel: {
  171. color: '#c7d3e5'
  172. }
  173. },
  174. yAxis: {
  175. name:'(单位)',
  176. type: 'value',
  177. nameTextStyle: {
  178. fontSize: 12,
  179. color: '#C6D7F1',
  180. fontWeight: 400,
  181. },
  182. nameGap: 25,
  183. axisLine: {
  184. show: false,
  185. lineStyle: {
  186. width: 1,
  187. color: '#545454'
  188. }
  189. },
  190. splitLine: {
  191. show: true,
  192. lineStyle: {
  193. color: 'rgba(199,211,229,0.3)',
  194. width: 1,
  195. type: 'dashed'
  196. }
  197. },
  198. axisTick: {
  199. show: false
  200. },
  201. axisLabel: {
  202. fontSize: 12,
  203. color: '#c7d3e5'
  204. }
  205. },
  206. series: [
  207. {
  208. name: "国内",
  209. type: "custom",
  210. renderItem: (params, api) => {
  211. const location = api.coord([api.value(0), api.value(1)]);
  212. const xAxisPoint = api.coord([api.value(0), 0]);
  213. const distance = 7;
  214. return {
  215. type: "group",
  216. children: [{
  217. type: "CubeLeft",
  218. shape: {
  219. api,
  220. xValue: api.value(0),
  221. yValue: api.value(1),
  222. x: location[0] + distance,
  223. y: location[1],
  224. xAxisPoint: [xAxisPoint[0] + distance, xAxisPoint[1]],
  225. },
  226. style: {
  227. fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
  228. offset: 0,
  229. color: '#0B5FA9',
  230. },
  231. {
  232. offset: 1,
  233. color: 'rgba(11,95,169,0)'
  234. }
  235. ]),
  236. },
  237. },
  238. {
  239. type: "CubeRight",
  240. shape: {
  241. api,
  242. xValue: api.value(0),
  243. yValue: api.value(1),
  244. x: location[0] + distance,
  245. y: location[1],
  246. xAxisPoint: [xAxisPoint[0] + distance, xAxisPoint[1]],
  247. },
  248. style: {
  249. fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
  250. offset: 0,
  251. color: '#088BFF',
  252. },
  253. {
  254. offset: 1,
  255. color: 'rgba(8,139,255,0)'
  256. }
  257. ]),
  258. },
  259. },
  260. {
  261. type: "CubeTop",
  262. shape: {
  263. api,
  264. xValue: api.value(0),
  265. yValue: api.value(1),
  266. x: location[0] + distance,
  267. y: location[1],
  268. xAxisPoint: [xAxisPoint[0] + distance, xAxisPoint[1]],
  269. },
  270. style: {
  271. fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
  272. offset: 0,
  273. color: '#61B5FF',
  274. },
  275. {
  276. offset: 1,
  277. color: '#61B5FF'
  278. }
  279. ]),
  280. },
  281. },
  282. ],
  283. };
  284. },
  285. itemStyle: {
  286. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
  287. offset: 0,
  288. color: "#00BFF4",
  289. },
  290. {
  291. offset: 1,
  292. color: "#A5E2FF",
  293. },
  294. ]),
  295. },
  296. data: [410,330,210,210,480,190],
  297. },
  298. {
  299. name: "出口",
  300. type: "custom",
  301. renderItem: (params, api) => {
  302. const location = api.coord([api.value(0), api.value(1)]);
  303. const xAxisPoint = api.coord([api.value(0), 0]);
  304. const distance = 7;
  305. return {
  306. type: "group",
  307. children: [{
  308. type: "CubeLeft",
  309. shape: {
  310. api,
  311. xValue: api.value(0),
  312. yValue: api.value(1),
  313. x: location[0] - distance,
  314. y: location[1],
  315. xAxisPoint: [xAxisPoint[0] - distance, xAxisPoint[1]],
  316. },
  317. style: {
  318. fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
  319. offset: 0,
  320. color: '#28A9A2',
  321. },
  322. {
  323. offset: 1,
  324. color: 'rgba(40,169,162,0)'
  325. }
  326. ]),
  327. },
  328. },
  329. {
  330. type: "CubeRight",
  331. shape: {
  332. api,
  333. xValue: api.value(0),
  334. yValue: api.value(1),
  335. x: location[0] - distance,
  336. y: location[1],
  337. xAxisPoint: [xAxisPoint[0] - distance, xAxisPoint[1]],
  338. },
  339. style: {
  340. fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
  341. offset: 0,
  342. color: '#35FFF4',
  343. },
  344. {
  345. offset: 1,
  346. color: 'rgba(53,255,244,0)'
  347. }
  348. ]),
  349. },
  350. },
  351. {
  352. type: "CubeTop",
  353. shape: {
  354. api,
  355. xValue: api.value(0),
  356. yValue: api.value(1),
  357. x: location[0] - distance,
  358. y: location[1],
  359. xAxisPoint: [xAxisPoint[0] - distance, xAxisPoint[1]],
  360. },
  361. style: {
  362. fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
  363. offset: 0,
  364. color: '#7EFFF8',
  365. },
  366. {
  367. offset: 1,
  368. color: '#7EFFF8'
  369. }
  370. ]),
  371. },
  372. },
  373. ],
  374. };
  375. },
  376. itemStyle: {
  377. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
  378. offset: 0,
  379. color: "#6AAAFF",
  380. },
  381. {
  382. offset: 1,
  383. color: "#046EFE",
  384. },
  385. ]),
  386. },
  387. data: this.kxData,
  388. }
  389. ],
  390. };
  391. },
  392. initKxChart2(){
  393. this.kxData2 = [0];
  394. let data = aqiData;
  395. this.kxOption2 = {
  396. title: {
  397. text: 'Beijing AQI',
  398. left: '1%'
  399. },
  400. tooltip: {
  401. trigger: 'axis'
  402. },
  403. grid: {
  404. left: '10%',
  405. right: '150px',
  406. bottom: '20%'
  407. },
  408. xAxis: {
  409. data: data.map(function (item) {
  410. return item[0];
  411. })
  412. },
  413. yAxis: {},
  414. dataZoom: [
  415. {
  416. startValue: '2014-06-01'
  417. },
  418. {
  419. type: 'inside'
  420. }
  421. ],
  422. visualMap: {
  423. top: 50,
  424. right: 10,
  425. pieces: [
  426. {
  427. gt: 0,
  428. lte: 50,
  429. color: '#93CE07'
  430. },
  431. {
  432. gt: 50,
  433. lte: 100,
  434. color: '#FBDB0F'
  435. },
  436. {
  437. gt: 100,
  438. lte: 150,
  439. color: '#FC7D02'
  440. },
  441. {
  442. gt: 150,
  443. lte: 200,
  444. color: '#FD0100'
  445. },
  446. {
  447. gt: 200,
  448. lte: 300,
  449. color: '#AA069F'
  450. },
  451. {
  452. gt: 300,
  453. color: '#AC3B2A'
  454. }
  455. ],
  456. outOfRange: {
  457. color: '#999'
  458. }
  459. },
  460. series: {
  461. name: 'Beijing AQI',
  462. type: 'line',
  463. data: data.map(function (item) {
  464. return item[1];
  465. }),
  466. markLine: {
  467. silent: true,
  468. lineStyle: {
  469. color: '#333'
  470. },
  471. data: [
  472. {
  473. yAxis: 50
  474. },
  475. {
  476. yAxis: 100
  477. },
  478. {
  479. yAxis: 150
  480. },
  481. {
  482. yAxis: 200
  483. },
  484. {
  485. yAxis: 300
  486. }
  487. ]
  488. }
  489. }
  490. }
  491. },
  492. }
  493. }
  494. </script>
  495. <style scoped lang="less">
  496. .chart{
  497. width: 100%;
  498. height: 300px;
  499. margin-top: 50px;
  500. &:first-child{
  501. margin-top: 0;
  502. }
  503. }
  504. </style>