ServerMonitor.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. <script setup lang="ts">
  2. import { CountTo } from 'vue3-count-to'
  3. import type { EChartsOption } from 'echarts'
  4. import chinaJS from '@/components/echarts/china.json'
  5. const options: EChartsOption = reactive({
  6. tooltip: {},
  7. grid: {
  8. left: '1%',
  9. top: '1%',
  10. bottom: '1%',
  11. right: '1%'
  12. },
  13. xAxis: {
  14. type: 'category',
  15. boundaryGap: false,
  16. data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
  17. axisLine: { show: false },
  18. axisLabel: { show: false }
  19. },
  20. yAxis: {
  21. type: 'value',
  22. axisLine: { show: false },
  23. axisLabel: { show: false },
  24. splitLine: { show: false }
  25. },
  26. series: [
  27. {
  28. data: [820, 932, 901, 934, 1290, 1330, 1320],
  29. type: 'line',
  30. areaStyle: { color: '#b37feb' },
  31. smooth: true,
  32. lineStyle: {
  33. color: '#9254de'
  34. },
  35. symbol: 'none'
  36. }
  37. ]
  38. })
  39. const options1: EChartsOption = reactive({
  40. grid: {
  41. left: '1%',
  42. top: '1%',
  43. bottom: '1%',
  44. right: '1%'
  45. },
  46. xAxis: {
  47. type: 'category',
  48. data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
  49. axisLine: { show: false },
  50. axisLabel: { show: false }
  51. },
  52. yAxis: {
  53. type: 'value',
  54. axisLine: { show: false },
  55. axisLabel: { show: false },
  56. splitLine: { show: false }
  57. },
  58. series: [
  59. {
  60. data: [120, 200, 150, 80, 70, 110, 130],
  61. type: 'bar'
  62. }
  63. ]
  64. })
  65. const radio = ref('今天')
  66. const value = ref('')
  67. const options2: EChartsOption = reactive({
  68. tooltip: {},
  69. xAxis: {
  70. type: 'category',
  71. data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  72. },
  73. yAxis: {
  74. type: 'value'
  75. },
  76. series: [
  77. {
  78. data: [120, 200, 150, 80, 70, 110, 130],
  79. type: 'bar'
  80. }
  81. ]
  82. })
  83. const options3: EChartsOption = reactive({
  84. tooltip: {
  85. trigger: 'item',
  86. formatter: '{b}<br/>{c} 个'
  87. },
  88. toolbox: {
  89. show: true,
  90. orient: 'vertical',
  91. left: 'right',
  92. top: 'center',
  93. feature: {
  94. dataView: { readOnly: false },
  95. restore: {},
  96. saveAsImage: {}
  97. }
  98. },
  99. visualMap: {
  100. min: 800,
  101. max: 50000,
  102. text: ['High', 'Low'],
  103. realtime: false,
  104. calculable: true,
  105. inRange: {
  106. color: ['#e6f7ff', '#69c0ff', '#1890ff']
  107. }
  108. },
  109. series: [
  110. {
  111. type: 'map',
  112. map: 'china',
  113. layoutCenter: ['50%', '50%'],
  114. layoutSize: '100%',
  115. label: {
  116. show: true
  117. },
  118. data: [
  119. { name: '北京', value: 20057.34 },
  120. { name: '上海', value: 15477.48 },
  121. { name: '山西', value: 31686.1 },
  122. { name: '河南', value: 6992.6 },
  123. { name: '四川', value: 44045.49 },
  124. { name: '西藏', value: 40689.64 },
  125. { name: '新疆', value: 37659.78 },
  126. { name: '黑龙江', value: 45180.97 },
  127. { name: '内蒙古', value: 55204.26 },
  128. { name: '浙江', value: 21900.9 },
  129. { name: '云南', value: 4918.26 },
  130. { name: '海南', value: 5881.84 },
  131. { name: '青海', value: 4178.01 },
  132. { name: '辽宁', value: 2227.92 },
  133. { name: '湖南', value: 2180.98 },
  134. { name: '台湾', value: 9172.94 },
  135. { name: '福建', value: 3368 },
  136. { name: '湖北', value: 806.98 }
  137. ]
  138. }
  139. ]
  140. })
  141. const options4: any = reactive({
  142. title: {
  143. text: '关键词',
  144. show: false
  145. },
  146. tooltip: {},
  147. series: [
  148. {
  149. type: 'wordCloud',
  150. shape: 'circle',
  151. left: 'center',
  152. top: 'center',
  153. width: '75%',
  154. height: '60%',
  155. rotationRange: [-45, 45],
  156. rotationStep: 15, // 0 15 30 45 度倾斜
  157. gridSize: 12,
  158. drawOutOfBound: false,
  159. // 这是全局的文字样式,相对应的还可以对每个词设置字体样式
  160. textStyle: {
  161. fontFamily: 'sans-serif',
  162. fontWeight: 'bold',
  163. // 颜色可以用一个函数来返回字符串
  164. color: function () {
  165. // Random color
  166. return (
  167. 'rgb(' +
  168. [Math.round(Math.random() * 160), Math.round(Math.random() * 160), Math.round(Math.random() * 160)].join(
  169. ','
  170. ) +
  171. ')'
  172. )
  173. },
  174. emphasis: {
  175. shadowBlur: 2,
  176. shadowColor: '#333'
  177. }
  178. },
  179. data: [
  180. { name: 'Sam S Club', value: 1000 },
  181. { name: 'Macys', value: 6181 },
  182. { name: 'Amy Schumer', value: 4386 },
  183. { name: 'Jurassic World', value: 1001 }
  184. ]
  185. }
  186. ]
  187. })
  188. </script>
  189. <template>
  190. <div>
  191. <el-row :gutter="15">
  192. <el-col :span="6">
  193. <el-card>
  194. <div class="board-header text-secondary">
  195. <span>总销售额</span>
  196. <el-tooltip content="指标说明" placement="top">
  197. <el-icon size="16">
  198. <QuestionFilled />
  199. </el-icon>
  200. </el-tooltip>
  201. </div>
  202. <count-to class="count-num" :endVal="1234" :duration="1000" prefix="¥"></count-to>
  203. <div class="echarts-wrap">
  204. <div class="echarts-text">
  205. <span>周同比12%</span>
  206. <el-icon size="14" color="var(--el-color-danger)">
  207. <CaretTop />
  208. </el-icon>
  209. <span style="margin-left: 20px">日同比11%</span>
  210. <el-icon size="14" color="var(--el-color-success)">
  211. <CaretBottom />
  212. </el-icon>
  213. </div>
  214. </div>
  215. <el-divider />
  216. <div class="board-footer">
  217. 日销售额<count-to :startVal="1234" :endVal="1234" :duration="1" prefix="¥"></count-to>
  218. </div>
  219. </el-card>
  220. </el-col>
  221. <el-col :span="6">
  222. <el-card>
  223. <div class="board-header text-secondary">
  224. <span>访问量</span>
  225. <div>日</div>
  226. </div>
  227. <count-to class="count-num" :endVal="8864" :duration="1000" prefix="¥"></count-to>
  228. <div class="echarts-wrap">
  229. <Echarts :options="options" />
  230. </div>
  231. <el-divider />
  232. <div class="board-footer">
  233. 日访问量<count-to :startVal="1234" :endVal="1234" :duration="1" prefix="¥"></count-to>
  234. </div>
  235. </el-card>
  236. </el-col>
  237. <el-col :span="6">
  238. <el-card>
  239. <div class="board-header text-secondary">
  240. <span>支付笔数</span>
  241. <div>月</div>
  242. </div>
  243. <count-to class="count-num" :endVal="6560" :duration="1000" prefix="¥"></count-to>
  244. <div class="echarts-wrap">
  245. <Echarts :options="options1" />
  246. </div>
  247. <el-divider />
  248. <div class="board-footer">转化率60%</div>
  249. </el-card>
  250. </el-col>
  251. <el-col :span="6">
  252. <el-card>
  253. <div class="board-header text-secondary">
  254. <span>活动运营效果</span>
  255. <div>周</div>
  256. </div>
  257. <count-to class="count-num" :endVal="78" :duration="1000" suffix="%"></count-to>
  258. <div class="echarts-wrap">
  259. <el-progress
  260. class="board-progess"
  261. :text-inside="true"
  262. :stroke-width="8"
  263. :percentage="70"
  264. :show-text="false"
  265. />
  266. </div>
  267. <el-divider />
  268. <div class="board-footer">
  269. <div class="echarts-text">
  270. <span>周同比12%</span>
  271. <el-icon size="14" color="var(--el-color-danger)">
  272. <CaretTop />
  273. </el-icon>
  274. <span style="margin-left: 20px">日同比11%</span>
  275. <el-icon size="14" color="var(--el-color-success)">
  276. <CaretBottom />
  277. </el-icon>
  278. </div>
  279. </div>
  280. </el-card>
  281. </el-col>
  282. </el-row>
  283. <el-row class="mt-4" :gutter="15">
  284. <el-col :span="18">
  285. <el-card>
  286. <template #header>
  287. <div class="card-header">
  288. <span>用户分布</span>
  289. </div>
  290. </template>
  291. <div style="height: 469px">
  292. <Echarts :options="options3" :map="true" :data="chinaJS" />
  293. </div>
  294. </el-card>
  295. </el-col>
  296. <el-col :span="6">
  297. <el-row class="column-wrap" align="top">
  298. <el-col :span="24">
  299. <el-card>
  300. <template #header>
  301. <div class="card-header">
  302. <span>热门搜索</span>
  303. </div>
  304. </template>
  305. <div style="height: 176px">
  306. <Echarts :options="options4" />
  307. </div>
  308. </el-card>
  309. </el-col>
  310. <el-col :span="24">
  311. <el-card style="margin-top: 15px">
  312. <template #header>
  313. <div class="card-header">
  314. <span>用户活跃度</span>
  315. </div>
  316. </template>
  317. </el-card>
  318. </el-col>
  319. </el-row>
  320. </el-col>
  321. </el-row>
  322. <el-card class="mt-4">
  323. <div class="tab-header">
  324. <el-tabs class="demo-tabs">
  325. <el-tab-pane label="销售额" name="销售额"></el-tab-pane>
  326. <el-tab-pane label="访问量" name="访问量"></el-tab-pane>
  327. </el-tabs>
  328. <div class="flex">
  329. <el-radio-group v-model="radio" class="mr-3">
  330. <el-radio-button label="今天" />
  331. <el-radio-button label="本周" />
  332. <el-radio-button label="本月" />
  333. <el-radio-button label="本年" />
  334. </el-radio-group>
  335. <el-date-picker v-model="value" type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" />
  336. </div>
  337. </div>
  338. <el-row>
  339. <el-col :span="17">
  340. <div class="monitor-title">销售量趋势</div>
  341. <div style="height: 320px">
  342. <Echarts :options="options2" />
  343. </div>
  344. </el-col>
  345. <el-col :span="7">
  346. <div class="monitor-title">门店销售额排名</div>
  347. <div class="monitor-rank-item ele-cell">
  348. <div class="monitor-num">1</div>
  349. <div class="ele-cell-content ele-elip">工专路 1 号店</div>
  350. <count-to class="text-secondary" :startVal="323234" :endVal="323234" :duration="1"></count-to>
  351. </div>
  352. </el-col>
  353. </el-row>
  354. </el-card>
  355. </div>
  356. </template>
  357. <style lang="scss" scoped>
  358. .board-header {
  359. display: flex;
  360. justify-content: space-between;
  361. align-items: center;
  362. font-size: 14px;
  363. line-height: 1.5715;
  364. }
  365. .count-num {
  366. font-size: 30px;
  367. }
  368. .echarts-wrap {
  369. height: 40px;
  370. font-size: 14px;
  371. color: var(--text-color);
  372. .echarts-text {
  373. padding-top: 16px;
  374. display: flex;
  375. align-items: center;
  376. }
  377. .board-progess {
  378. padding-top: 16px;
  379. }
  380. }
  381. .echarts-text {
  382. white-space: nowrap;
  383. span {
  384. white-space: nowrap;
  385. }
  386. }
  387. .el-divider {
  388. margin: 12px 0;
  389. }
  390. .board-footer {
  391. color: var(--text-color);
  392. font-size: 14px;
  393. }
  394. .tab-header {
  395. display: flex;
  396. justify-content: space-between;
  397. align-items: center;
  398. }
  399. .monitor-title {
  400. padding: 6px 20px;
  401. }
  402. .monitor-rank-item {
  403. padding-left: 20px;
  404. margin-top: 18px;
  405. .monitor-num {
  406. display: flex;
  407. align-items: center;
  408. justify-content: center;
  409. background: #333;
  410. border-radius: 50%;
  411. color: #fff;
  412. width: 20px;
  413. height: 20px;
  414. }
  415. }
  416. .ele-cell:not(.ele-cell-align-top) {
  417. align-items: center;
  418. }
  419. .ele-cell {
  420. display: flex;
  421. }
  422. .ele-cell > * + .ele-cell-content {
  423. padding-left: 12px;
  424. }
  425. .ele-cell > .ele-cell-content {
  426. flex: 1;
  427. box-sizing: border-box;
  428. }
  429. .column-wrap {
  430. height: 50%;
  431. .el-col {
  432. height: calc(100% - 8px);
  433. .el-card {
  434. height: 100%;
  435. }
  436. }
  437. }
  438. </style>