index.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. <template>
  2. <div class="app-container">
  3. <el-row>
  4. <el-col :span="24">
  5. <div class="cell">
  6. <div class="cell-title">
  7. <div class="title-left">
  8. <div class="title">数据中台</div>
  9. </div>
  10. </div>
  11. <div class="cell-body">
  12. <el-row type="flex">
  13. <el-col :span="24">
  14. <div class="header">
  15. <div class="icon"></div>
  16. <div class="title">经营概况</div>
  17. </div>
  18. <div class="content">
  19. <div class="con-con con-bg-1">
  20. <div class="con-title">民宿总数</div>
  21. <div class="con-num">{{ total_number_of_accommodation }}</div>
  22. </div>
  23. <div class="con-con con-bg-2">
  24. <div class="con-title">今日访问量</div>
  25. <div class="con-num">{{ todays_traffic }}</div>
  26. <div v-if="more_traffic_today_than_yesterday >= 0" class="con-num">较昨天 ▲ {{ more_traffic_today_than_yesterday }}</div>
  27. <div v-else class="con-num">较昨天 ▼ {{ more_traffic_today_than_yesterday }}</div>
  28. </div>
  29. <div class="con-con con-bg-3">
  30. <div class="con-title">今日销售额</div>
  31. <div class="con-num">{{ todays_sales }}</div>
  32. <div v-if="sales_are_higher_today_than_yesterday >= 0" class="con-num">较昨天 ▲ {{ sales_are_higher_today_than_yesterday }}
  33. </div>
  34. <div v-else class="con-num">较昨天 ▼ {{ sales_are_higher_today_than_yesterday }}</div>
  35. </div>
  36. <div class="con-con con-bg-4">
  37. <div class="con-title">今日订单量</div>
  38. <div class="con-num">{{ order_quantity_today }}</div>
  39. <div v-if="todays_order_volume_is_higher_than_yesterday >= 0" class="con-num">较昨天 ▲
  40. {{ todays_order_volume_is_higher_than_yesterday }}
  41. </div>
  42. <div v-else class="con-num">较昨天 ▼ {{ todays_order_volume_is_higher_than_yesterday }}</div>
  43. </div>
  44. </div>
  45. </el-col>
  46. </el-row>
  47. <el-row type="flex">
  48. <el-col :span="6">
  49. <div class="header">
  50. <div class="icon"></div>
  51. <div class="title">订单状态占比</div>
  52. </div>
  53. <div class="content">
  54. <div ref="chartPie" style="width: 400px; height: 330px;"></div>
  55. </div>
  56. </el-col>
  57. <el-col :span="6">
  58. <div class="header">
  59. <div class="icon"></div>
  60. <div class="title">民宿统计</div>
  61. </div>
  62. <div class="content">
  63. <div ref="chartBar" style="width: 400px; height: 330px;"></div>
  64. </div>
  65. </el-col>
  66. <el-col :span="12">
  67. <div class="head">
  68. <div class="header">
  69. <div class="icon"></div>
  70. <div class="title">访问量趋势</div>
  71. </div>
  72. <div class="ctrs">
  73. <el-button-group>
  74. <el-button size="mini" :class="{ active: activeVisitButton === 'activeVisitButton1' }"
  75. @click="toggleVisitButton('activeVisitButton1')">今日</el-button>
  76. <el-button size="mini" :class="{ active: activeVisitButton === 'activeVisitButton2' }"
  77. @click="toggleVisitButton('activeVisitButton2')">本周</el-button>
  78. <el-button size="mini" :class="{ active: activeVisitButton === 'activeVisitButton3' }"
  79. @click="toggleVisitButton('activeVisitButton3')">本月</el-button>
  80. </el-button-group>
  81. <el-date-picker ref="datePickerRef" v-model="visit_date" type="daterange" align="right" unlink-panels
  82. range-separator="~" @change="visit_date_change" start-placeholder="开始日期" end-placeholder="结束日期"
  83. class="custom-date-picker" format="yyyy-MM-dd" value-format="yyyy-MM-dd">
  84. </el-date-picker>
  85. </div>
  86. </div>
  87. <div class="content">
  88. <div ref="chartArea" style="width: 100%; height: 330px; box-sizing: border-box;"></div>
  89. </div>
  90. </el-col>
  91. </el-row>
  92. <el-row type="flex">
  93. <el-col :span="12">
  94. <div class="head">
  95. <div class="header">
  96. <div class="icon"></div>
  97. <div class="title">用户画像</div>
  98. </div>
  99. <div class="ctrs">
  100. <el-button-group>
  101. <el-button size="mini" :class="{ active: activeUserButton === 'activeUserButton1' }"
  102. @click="toggleUserButton('activeUserButton1')">今日</el-button>
  103. <el-button size="mini" :class="{ active: activeUserButton === 'activeUserButton2' }"
  104. @click="toggleUserButton('activeUserButton2')">本月</el-button>
  105. <el-button size="mini" :class="{ active: activeUserButton === 'activeUserButton3' }"
  106. @click="toggleUserButton('activeUserButton3')">本年</el-button>
  107. </el-button-group>
  108. </div>
  109. </div>
  110. <div class="content">
  111. <div class="left-pie">
  112. <div ref="chartUserPie" style="width: 100%; height: 330px; box-sizing: border-box;"></div>
  113. </div>
  114. <div class="right-bar">
  115. <div ref="chartUserBar" style="width: 100%; height: 330px; box-sizing: border-box;"></div>
  116. </div>
  117. </div>
  118. </el-col>
  119. <el-col :span="6">
  120. <div class="head">
  121. <div class="header">
  122. <div class="icon"></div>
  123. <div class="title">订单量排行</div>
  124. </div>
  125. <div class="ctrs">
  126. <el-button-group>
  127. <el-button size="mini" :class="{ active: activeOrderButton === 'activeOrderButton1' }"
  128. @click="toggleOrderButton('activeOrderButton1')">今日</el-button>
  129. <el-button size="mini" :class="{ active: activeOrderButton === 'activeOrderButton2' }"
  130. @click="toggleOrderButton('activeOrderButton2')">本月</el-button>
  131. <el-button size="mini" :class="{ active: activeOrderButton === 'activeOrderButton3' }"
  132. @click="toggleOrderButton('activeOrderButton3')">本年</el-button>
  133. </el-button-group>
  134. </div>
  135. </div>
  136. <div class="content">
  137. <el-table :data="tableOrderData" style="width: 100%" height="330">
  138. <el-table-column fixed prop="rark" label="排行" align="center" width="80px">
  139. </el-table-column>
  140. <el-table-column prop="hotelName" label="民宿名称" align="center">
  141. </el-table-column>
  142. <el-table-column prop="bookNum" label="订单量" align="center">
  143. </el-table-column>
  144. </el-table>
  145. </div>
  146. </el-col>
  147. <el-col :span="6">
  148. <div class="head">
  149. <div class="header">
  150. <div class="icon"></div>
  151. <div class="title">销售额排行榜</div>
  152. </div>
  153. <div class="ctrs">
  154. <el-button-group>
  155. <el-button size="mini" :class="{ active: activeSellButton === 'activeSellButton1' }"
  156. @click="toggleSellButton('activeSellButton1')">今日</el-button>
  157. <el-button size="mini" :class="{ active: activeSellButton === 'activeSellButton2' }"
  158. @click="toggleSellButton('activeSellButton2')">本月</el-button>
  159. <el-button size="mini" :class="{ active: activeSellButton === 'activeSellButton3' }"
  160. @click="toggleSellButton('activeSellButton3')">本年</el-button>
  161. </el-button-group>
  162. </div>
  163. </div>
  164. <div class="content">
  165. <el-table :data="tableSellData" style="width: 100%" height="330">
  166. <el-table-column fixed prop="rark" label="排行" align="center" width="80px">
  167. </el-table-column>
  168. <el-table-column prop="hotelName" label="民宿名称" align="center">
  169. </el-table-column>
  170. <el-table-column prop="salesAmount" label="销售额" align="center">
  171. </el-table-column>
  172. </el-table>
  173. </div>
  174. </el-col>
  175. </el-row>
  176. </div>
  177. </div>
  178. </el-col>
  179. </el-row>
  180. </div>
  181. </template>
  182. <script>
  183. import * as echarts from 'echarts';
  184. import {
  185. getOrderData,
  186. getHomestayStatistics,
  187. getOrderVolumeRanking,
  188. getQuerySalesRankings,
  189. getManagementProfile,
  190. getIdcvisitsToday,
  191. getIdcvisitsDiyQuery
  192. } from '@/api/data';
  193. import {
  194. getDateComponents
  195. } from '@/js/common';
  196. export default {
  197. data() {
  198. return {
  199. total_number_of_accommodation: 0,
  200. todays_traffic: 0,
  201. more_traffic_today_than_yesterday: 0,
  202. todays_sales: 0,
  203. sales_are_higher_today_than_yesterday: '0.00',
  204. order_quantity_today: 0,
  205. todays_order_volume_is_higher_than_yesterday: 0,
  206. tableOrderData: [], // 订单量排行数据
  207. tableSellData: [], // 销售量排行数据
  208. chartOrderPieData: [], // 订单状态占比数据
  209. chartUserPieData: [{
  210. value: 335,
  211. name: '男'
  212. },
  213. {
  214. value: 310,
  215. name: '女'
  216. }
  217. ],
  218. chartBarData: [], // 民宿统计数据
  219. chartUserBarData: [{ // 用户画像数据
  220. value: 335,
  221. name: '24岁及以下'
  222. },
  223. {
  224. value: 310,
  225. name: '25-30岁'
  226. },
  227. {
  228. value: 234,
  229. name: '31-35岁'
  230. },
  231. {
  232. value: 135,
  233. name: '36-40岁'
  234. },
  235. {
  236. value: 1548,
  237. name: '41岁及以上'
  238. }
  239. ],
  240. chartPie: null,
  241. chartBar: null,
  242. chartArea: null,
  243. visit_date: null,
  244. activeVisitButton: 'activeVisitButton2',
  245. activeUserButton: 'activeUserButton2',
  246. activeOrderButton: 'activeOrderButton2',
  247. activeSellButton: 'activeSellButton2',
  248. index_visit: 2 // 访问量趋势按钮位置,1当日,2本周,3本月
  249. }
  250. },
  251. created() {
  252. },
  253. mounted() {
  254. // 获取订单状态占比数据
  255. this.getOrderData()
  256. // 查询各县民宿数量 民宿统计
  257. this.getHomestayStatistics()
  258. // 查询订单量排行
  259. this.getOrderVolumeRanking(2)
  260. // 查询销售额排行
  261. this.getQuerySalesRankings(2)
  262. // 查询经营概况
  263. this.getManagementProfile()
  264. // 今日访问量
  265. this.getIdcvisitsToday()
  266. // 访问量趋势
  267. this.getIdcvisitsDiyQuery()
  268. this.pieUser()
  269. this.barUser()
  270. // 自适应窗口大小
  271. window.addEventListener('resize', () => {
  272. this.chartPie.resize();
  273. this.chartBar.resize();
  274. });
  275. },
  276. methods: {
  277. visit_date_change() {
  278. if (this.visit_date !== null) {
  279. this.index_visit = 4
  280. this.getIdcvisitsDiyQuery()
  281. } else {
  282. this.index_visit = 2
  283. this.getIdcvisitsDiyQuery()
  284. }
  285. },
  286. // 日访问量
  287. getIdcvisitsToday() {
  288. getIdcvisitsToday().then((res) => {
  289. this.todays_traffic = res.data.todayCount
  290. this.more_traffic_today_than_yesterday = res.data.compare
  291. }).catch((err) => {
  292. this.$message.error(err.message);
  293. })
  294. },
  295. // 访问趋势
  296. getIdcvisitsDiyQuery() {
  297. var data = {
  298. type: this.index_visit
  299. }
  300. if (this.visit_date && this.index_visit == 4) {
  301. data.startTime = this.visit_date[0]
  302. data.endTime = this.visit_date[1]
  303. }
  304. getIdcvisitsDiyQuery(data).then((res) => {
  305. var dataDate = [];
  306. var dataData = [];
  307. for (var i = 0; i < res.data.length; i++) {
  308. dataDate.push(res.data[i].day.substring(5))
  309. dataData.push(res.data[i].visitNumber)
  310. }
  311. this.area(dataDate, dataData)
  312. }).catch((err) => {
  313. this.$message.error(err.message);
  314. })
  315. },
  316. toggleVisitButton(buttonName) {
  317. if (buttonName === 'activeVisitButton1') {
  318. this.index_visit = 1
  319. this.getIdcvisitsDiyQuery()
  320. } else if (buttonName === 'activeVisitButton2') {
  321. this.index_visit = 2
  322. this.getIdcvisitsDiyQuery()
  323. } else if (buttonName === 'activeVisitButton3') {
  324. this.index_visit = 3
  325. this.getIdcvisitsDiyQuery()
  326. } else {
  327. this.$message.error('未知时间')
  328. }
  329. this.activeVisitButton = buttonName;
  330. },
  331. toggleUserButton(buttonName) {
  332. this.activeUserButton = buttonName;
  333. },
  334. // 销售排行不同时间切换
  335. toggleSellButton(buttonName) {
  336. if (buttonName === 'activeSellButton1') {
  337. this.getQuerySalesRankings(1)
  338. } else if (buttonName === 'activeSellButton2') {
  339. this.getQuerySalesRankings(2)
  340. } else if (buttonName === 'activeSellButton3') {
  341. this.getQuerySalesRankings(3)
  342. } else {
  343. this.$message.error('未知时间')
  344. }
  345. this.activeSellButton = buttonName;
  346. },
  347. getManagementProfile() {
  348. getManagementProfile().then((res) => {
  349. // console.log(res);
  350. if (typeof res.code == 'undefined' || res.code == '') {
  351. this.$message.error('返回数据格式问题,code未获取到!');
  352. return;
  353. }
  354. if (res.code === 200) {
  355. // bookNumyDay;//昨日订单量
  356. // salesAmountyDay;//昨日销售量
  357. const tempdata = res.data
  358. this.total_number_of_accommodation = tempdata.hotelSum // 民宿总数
  359. // 销售额
  360. this.todays_sales = tempdata.salesAmountDay // 今日销售量
  361. this.sales_are_higher_today_than_yesterday = tempdata.salesAmountGrowth.toFixed(2) // 销售量增长量
  362. // 订单量
  363. this.order_quantity_today = tempdata.bookNumDay // 今日订单量
  364. this.todays_order_volume_is_higher_than_yesterday = tempdata.bookNumGrowth // 订单量增长量
  365. } else {
  366. this.$message.error(res.message);
  367. }
  368. }).catch((err) => {
  369. // console.log(err);
  370. this.$message.error(err.message);
  371. })
  372. },
  373. /**
  374. * 查询销售额排行
  375. */
  376. getQuerySalesRankings(param) {
  377. getQuerySalesRankings(param).then((res) => {
  378. // console.log(res);
  379. if (typeof res.code == 'undefined' || res.code == '') {
  380. this.$message.error('返回数据格式问题,code未获取到!');
  381. return;
  382. }
  383. if (res.code === 200) {
  384. this.tableSellData = []
  385. for (var i = 0; i < res.data.length; i++) {
  386. this.tableSellData.push({
  387. rark: res.data[i].rank,
  388. bookNum: res.data[i].bookNum,
  389. hotelName: res.data[i].hotelName,
  390. salesAmount: res.data[i].salesAmount.toFixed(2)
  391. })
  392. }
  393. } else {
  394. this.$message.error(res.message);
  395. }
  396. }).catch((err) => {
  397. // console.log(err);
  398. this.$message.error(err.message);
  399. })
  400. },
  401. // 订单排行不同时间切换
  402. toggleOrderButton(buttonName) {
  403. if (buttonName === 'activeOrderButton1') {
  404. this.getOrderVolumeRanking(1)
  405. } else if (buttonName === 'activeOrderButton2') {
  406. this.getOrderVolumeRanking(2)
  407. } else if (buttonName === 'activeOrderButton3') {
  408. this.getOrderVolumeRanking(3)
  409. } else {
  410. this.$message.error('未知时间')
  411. }
  412. this.activeOrderButton = buttonName;
  413. },
  414. /**
  415. * 查询订单量排行
  416. */
  417. getOrderVolumeRanking(param) {
  418. getOrderVolumeRanking(param).then((res) => {
  419. // console.log(res);
  420. if (typeof res.code == 'undefined' || res.code == '') {
  421. this.$message.error('返回数据格式问题,code未获取到!');
  422. return;
  423. }
  424. if (res.code === 200) {
  425. this.tableOrderData = []
  426. for (var i = 0; i < res.data.length; i++) {
  427. this.tableOrderData.push({
  428. rark: res.data[i].rank,
  429. bookNum: res.data[i].bookNum,
  430. hotelName: res.data[i].hotelName,
  431. salesAmount: res.data[i].salesAmount
  432. })
  433. }
  434. } else {
  435. this.$message.error(res.message);
  436. }
  437. }).catch((err) => {
  438. // console.log(err);
  439. this.$message.error(err.message);
  440. })
  441. },
  442. /**
  443. * 查询各县民宿数量 民宿统计
  444. */
  445. getHomestayStatistics() {
  446. getHomestayStatistics().then((res) => {
  447. // console.log(res);
  448. if (typeof res.code == 'undefined' || res.code == '') {
  449. this.$message.error('返回数据格式问题,code未获取到!');
  450. return;
  451. }
  452. if (res.code === 200) {
  453. this.chartBarData = []
  454. for (var i = 0; i < res.data.length; i++) {
  455. this.chartBarData.push({
  456. value: res.data[i].hotelNum,
  457. name: res.data[i].hposition
  458. })
  459. }
  460. this.bar()
  461. } else {
  462. this.$message.error(res.message);
  463. }
  464. }).catch((err) => {
  465. // console.log(err);
  466. this.$message.error(err.message);
  467. })
  468. },
  469. // 查询各县民宿数量 民宿统计
  470. bar() {
  471. this.chartBar = echarts.init(this.$refs.chartBar);
  472. this.chartBar.setOption({
  473. tooltip: {
  474. trigger: 'axis',
  475. axisPointer: {
  476. type: 'line',
  477. label: {
  478. backgroundColor: '#6a7985'
  479. }
  480. }
  481. },
  482. legend: {
  483. type: 'plain',
  484. orient: 'horizontal',
  485. left: 'center',
  486. top: 'bottom'
  487. },
  488. grid: {
  489. left: 0,
  490. top: 0,
  491. right: 15,
  492. bottom: 0,
  493. containLabel: true
  494. },
  495. xAxis: {
  496. type: 'value'
  497. },
  498. yAxis: {
  499. type: 'category',
  500. axisLabel: {
  501. show: true,
  502. interval: 0,
  503. // rotate: 30
  504. formatter: function(params) {
  505. var newParamsName = ""; // 最终拼接成的字符串
  506. var paramsNameNumber = params.length; // 实际标签的字数
  507. var provideNumber = 6; // 每行能显示的字的个数
  508. var rowNumber = Math.ceil(paramsNameNumber / provideNumber); // 换行的话,需要显示几行,向上取整
  509. /**
  510. * 判断标签的个数是否大于规定的个数, 如果大于,则进行换行处理 如果不大于,即等于或小于,就返回原标签
  511. */
  512. // 条件等同于rowNumber>1
  513. if (paramsNameNumber > provideNumber) {
  514. /** 循环每一行,p表示行 */
  515. for (var p = 0; p < rowNumber; p++) {
  516. var tempStr = ""; // 表示每一次截取的字符串
  517. var start = p * provideNumber; // 开始截取的位置
  518. var end = start + provideNumber; // 结束截取的位置
  519. // 此处特殊处理最后一行的索引值
  520. if (p == rowNumber - 1) {
  521. // 最后一次不换行
  522. tempStr = params.substring(start, paramsNameNumber);
  523. } else {
  524. // 每一次拼接字符串并换行
  525. // tempStr = params.substring(start, end) + "\n";
  526. tempStr = params.substring(start, end) + "…";
  527. }
  528. newParamsName += tempStr; // 最终拼成的字符串
  529. break;
  530. }
  531. } else {
  532. // 将旧标签的值赋给新标签
  533. newParamsName = params;
  534. }
  535. //将最终的字符串返回
  536. return newParamsName
  537. }
  538. },
  539. data: this.chartBarData.map(item => item.name)
  540. },
  541. series: [{
  542. type: 'bar',
  543. data: this.chartBarData,
  544. itemStyle: {
  545. color: '#8080FF'
  546. }
  547. }]
  548. });
  549. },
  550. /**
  551. * 获取订单状态占比数据
  552. */
  553. getOrderData() {
  554. getOrderData().then((res) => {
  555. // console.log(res);
  556. if (typeof res.code == 'undefined' || res.code == '') {
  557. this.$message.error('返回数据格式问题,code未获取到!');
  558. return;
  559. }
  560. if (res.code === 200) {
  561. this.chartOrderPieData = []
  562. for (var i = 0; i < res.data.length; i++) {
  563. this.chartOrderPieData.push({
  564. value: res.data[i].statusNum,
  565. name: res.data[i].orderStatusName
  566. })
  567. }
  568. this.orderPie()
  569. } else {
  570. this.$message.error(res.message);
  571. }
  572. }).catch((err) => {
  573. // console.log(err);
  574. this.$message.error(err.message);
  575. })
  576. },
  577. // 订单状态占比 饼图
  578. orderPie() {
  579. this.chartPie = echarts.init(this.$refs.chartPie);
  580. this.chartPie.setOption({
  581. tooltip: {
  582. trigger: "item",
  583. },
  584. legend: {
  585. orient: 'horizontal',
  586. left: 'center',
  587. top: 'bottom'
  588. },
  589. grid: {
  590. left: '3%',
  591. right: '4%',
  592. bottom: '28%',
  593. top: '3%'
  594. },
  595. series: [{
  596. type: 'pie',
  597. radius: ['30%', '50%'],
  598. data: this.chartOrderPieData,
  599. label: {
  600. show: true,
  601. position: 'outer',
  602. distance: 0,
  603. formatter: '{c}'
  604. },
  605. emphasis: {
  606. label: {
  607. show: true,
  608. fontWeight: 'bold'
  609. }
  610. }
  611. }]
  612. });
  613. },
  614. // 饼图
  615. pieUser() {
  616. this.chartUserPie = echarts.init(this.$refs.chartUserPie);
  617. this.chartUserPie.setOption({
  618. tooltip: {
  619. trigger: "item",
  620. },
  621. title: {
  622. text: '客户性别占比',
  623. left: 'center',
  624. textAlign: 'left',
  625. textStyle: {
  626. fontSize: 14
  627. }
  628. },
  629. legend: {
  630. orient: 'horizontal',
  631. bottom: 10
  632. },
  633. grid: {
  634. left: '3%',
  635. right: '4%',
  636. bottom: '3%',
  637. top: '3%'
  638. },
  639. series: [{
  640. type: 'pie',
  641. radius: ['30%', '50%'],
  642. data: this.chartUserPieData,
  643. label: {
  644. show: true,
  645. position: 'outer',
  646. distance: 0,
  647. formatter: '{c}'
  648. },
  649. emphasis: {
  650. label: {
  651. show: true,
  652. fontWeight: 'bold'
  653. }
  654. }
  655. }]
  656. });
  657. },
  658. // 柱形图
  659. barUser() {
  660. this.chartUserBar = echarts.init(this.$refs.chartUserBar);
  661. this.chartUserBar.setOption({
  662. tooltip: {
  663. trigger: 'axis',
  664. axisPointer: {
  665. type: 'line',
  666. label: {
  667. backgroundColor: '#6a7985'
  668. }
  669. }
  670. },
  671. title: {
  672. text: '人群年龄占比',
  673. left: 'center',
  674. textStyle: {
  675. fontSize: 14
  676. }
  677. },
  678. legend: {
  679. type: 'plain',
  680. orient: 'horizontal',
  681. bottom: 10
  682. },
  683. grid: {
  684. left: '8%',
  685. right: '5%',
  686. bottom: '3%',
  687. containLabel: true
  688. },
  689. xAxis: {
  690. type: 'value',
  691. },
  692. yAxis: {
  693. type: 'category',
  694. axisLabel: {
  695. show: true,
  696. interval: 0,
  697. // rotate: 60
  698. },
  699. data: this.chartUserBarData.map(item => item.name)
  700. },
  701. series: [{
  702. type: 'bar',
  703. data: this.chartUserBarData,
  704. itemStyle: {
  705. color: '#8080FF'
  706. }
  707. }]
  708. });
  709. },
  710. // 面积图
  711. area(dataDate, dataData) {
  712. this.chartArea = echarts.init(this.$refs.chartArea);
  713. this.chartArea.setOption({
  714. tooltip: {
  715. trigger: 'axis',
  716. axisPointer: {
  717. type: 'shadow',
  718. label: {
  719. backgroundColor: '#6a7985'
  720. }
  721. }
  722. },
  723. grid: {
  724. left: '8%',
  725. right: '5%',
  726. bottom: '3%',
  727. containLabel: true
  728. },
  729. xAxis: {
  730. type: 'category',
  731. data: dataDate,
  732. },
  733. yAxis: {
  734. type: 'value',
  735. },
  736. series: [{
  737. type: 'line',
  738. areaStyle: {},
  739. data: dataData,
  740. itemStyle: {
  741. color: '#4CBAFF'
  742. }
  743. }],
  744. });
  745. },
  746. }
  747. }
  748. </script>
  749. <style lang="scss" scoped>
  750. .app-container {
  751. background-color: #EFF2F7;
  752. padding: 10px;
  753. .el-row {
  754. .el-col {
  755. padding: 10px;
  756. .cell {
  757. padding: 30px;
  758. border-radius: 10px;
  759. background-color: #FFFFFF;
  760. // box-shadow: 5px 5px 15px #979797;
  761. box-shadow: 0px 3px 21px 0px rgba(60, 108, 254, 0.16);
  762. .cell-title {
  763. display: flex;
  764. align-items: center;
  765. margin-bottom: 30px;
  766. padding-bottom: 30px;
  767. border-bottom: 1px solid #CCCCCC;
  768. .title-left {
  769. display: flex;
  770. align-items: center;
  771. cursor: pointer;
  772. box-sizing: border-box;
  773. .title {
  774. text-align: center;
  775. font-size: 22px;
  776. font-family: Microsoft YaHei-3970(82674968);
  777. font-weight: bold;
  778. }
  779. }
  780. }
  781. .cell-body {
  782. background-color: #EFF2F7;
  783. padding: 6px;
  784. .el-row {
  785. .el-col {
  786. margin: 6px;
  787. border-radius: 6px;
  788. background-color: #FFFFFF;
  789. .head {
  790. display: flex;
  791. justify-content: space-between;
  792. }
  793. .header {
  794. display: flex;
  795. .icon {
  796. width: 5px;
  797. height: 20px;
  798. background-color: #8080FF;
  799. margin-right: 8px;
  800. }
  801. .title {
  802. font-size: 18px;
  803. font-weight: 500;
  804. }
  805. }
  806. .ctrs {
  807. display: flex;
  808. justify-content: space-between;
  809. .custom-date-picker {
  810. width: 260px;
  811. font-size: 14px;
  812. height: 28px;
  813. margin-left: 10px;
  814. }
  815. }
  816. .content {
  817. display: flex;
  818. justify-content: space-around;
  819. padding-top: 20px;
  820. color: #FFFFFF;
  821. .left-pie {
  822. width: 50%;
  823. }
  824. .right-bar {
  825. width: 50%;
  826. }
  827. .con-con {
  828. width: 300px;
  829. height: 130px;
  830. padding: 15px 50px;
  831. border-radius: 10px;
  832. display: flex;
  833. flex-direction: column;
  834. justify-content: space-around;
  835. .con-title {
  836. font-size: 20px;
  837. font-weight: 600;
  838. }
  839. .con-num {
  840. font-size: 18px;
  841. font-weight: 600;
  842. }
  843. }
  844. .con-bg-1 {
  845. background: linear-gradient(to right, #0BBEFE, #7DFDD9);
  846. }
  847. .con-bg-2 {
  848. background: linear-gradient(to right, #09BDFE, #01A7F0);
  849. }
  850. .con-bg-3 {
  851. background: linear-gradient(to right, #F286A0, #FCC587);
  852. }
  853. .con-bg-4 {
  854. background: linear-gradient(to right, #FAC2EB, #A28DD1);
  855. }
  856. ::v-deep .el-table__row .cell {
  857. white-space: nowrap !important;
  858. }
  859. ::v-deep .el-table__row:nth-child(1) td:nth-child(1) .cell,
  860. ::v-deep .el-table__row:nth-child(2) td:nth-child(1) .cell,
  861. ::v-deep .el-table__row:nth-child(3) td:nth-child(1) .cell,
  862. ::v-deep .el-table__row:nth-child(4) td:nth-child(1) .cell,
  863. ::v-deep .el-table__row:nth-child(5) td:nth-child(1) .cell {
  864. display: block;
  865. width: 30px;
  866. height: 30px;
  867. line-height: 30px;
  868. text-align: center;
  869. margin-left: 26px;
  870. border-radius: 50%;
  871. color: #FFFFFF !important;
  872. }
  873. ::v-deep .el-table__row:nth-child(1) td:nth-child(1) .cell {
  874. background-color: #f73131;
  875. box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.5);
  876. }
  877. ::v-deep .el-table__row:nth-child(2) td:nth-child(1) .cell {
  878. background-color: #f60 !important;
  879. box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.5);
  880. }
  881. ::v-deep .el-table__row:nth-child(3) td:nth-child(1) .cell {
  882. background-color: #ffc20d !important;
  883. box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.5);
  884. }
  885. ::v-deep .el-table__row:nth-child(4) td:nth-child(1) .cell {
  886. background-color: #c8c6c7 !important;
  887. box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.5);
  888. }
  889. ::v-deep .el-table__row:nth-child(5) td:nth-child(1) .cell {
  890. background-color: #c8c6c7 !important;
  891. box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.5);
  892. }
  893. }
  894. }
  895. }
  896. }
  897. }
  898. }
  899. }
  900. }
  901. </style>
  902. <style>
  903. .el-date-editor .el-range__icon,
  904. .el-date-editor .el-range__close-icon,
  905. .el-date-editor .el-range-separator {
  906. height: 28px;
  907. line-height: 28px;
  908. }
  909. .el-button-group .el-button.active {
  910. color: #fff;
  911. background-color: #8080FF;
  912. }
  913. </style>