index.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import React, { useEffect, useMemo, useRef, useState } from 'react'
  2. import Helmet from 'react-helmet'
  3. import Container from 'components/Container'
  4. import { init, EChartOption, ECharts } from 'echarts'
  5. import styles from './index.less'
  6. import api from 'utils/api'
  7. import request from 'utils/request'
  8. import ICON_BM from 'assets/images/icon_bm.png'
  9. import ICON_ML from 'assets/images/icon_mulu.png'
  10. import ICON_XT from 'assets/images/icon_xl.png'
  11. import ICON_ZY from 'assets/images/icon_zy.png'
  12. import IMG_BG_BM from 'assets/images/img_bg_bm.png'
  13. import IMG_BG_ML from 'assets/images/img_bg_mulu.png'
  14. import IMG_BG_XT from 'assets/images/img_bg_xl.png'
  15. import IMG_BG_ZY from 'assets/images/img_bg_zy.png'
  16. const DEFAULT_COLORS = [
  17. '#5470c6',
  18. '#91cc75',
  19. '#fac858',
  20. '#ee6666',
  21. '#73c0de',
  22. '#3ba272',
  23. '#fc8452',
  24. '#9a60b4',
  25. '#ea7ccc'
  26. ]
  27. // tslint:disable-next-line:interface-name
  28. interface DataOverviewState {
  29. originDept: number, // 来源部门数量
  30. countCatalogue: number, // 近一个月目录增长数量
  31. originSystem: number, // 来源系统数量
  32. dataSource: number, // 数据资源数量
  33. industryData: Array<{ name: string, value: number }>, // 行业分类饼图
  34. originDeptData: Array<{ name: string, value: number }>, // 来源部门柱状图
  35. }
  36. export default function DataOverview() {
  37. const pieElementRef = useRef<HTMLDivElement>(null)
  38. const barElementRef = useRef<HTMLDivElement>(null)
  39. const pieRef = useRef<ECharts>(null)
  40. const barRef = useRef<ECharts>(null)
  41. const [overview, setOverview] = useState<DataOverviewState>(
  42. {
  43. originDept: 0,
  44. countCatalogue: 0,
  45. originSystem: 0,
  46. dataSource: 0,
  47. industryData: [],
  48. originDeptData: []
  49. })
  50. const getDataScreening = async() => {
  51. try {
  52. const data = await request(api.dataScreening, { method: 'get' })
  53. setOverview((data as unknown as DataOverviewState))
  54. } catch (e) {
  55. console.log(e)
  56. }
  57. }
  58. const pieOption = useMemo<EChartOption>(() => ({
  59. tooltip: {
  60. trigger: 'item'
  61. },
  62. color: DEFAULT_COLORS,
  63. legend: {
  64. orient: 'vertical',
  65. right: 10,
  66. top: 'middle'
  67. },
  68. series: [
  69. {
  70. type: 'pie',
  71. radius: '50%',
  72. data: overview.industryData,
  73. emphasis: {
  74. itemStyle: {
  75. shadowBlur: 10,
  76. shadowOffsetX: 0,
  77. shadowColor: 'rgba(0, 0, 0, 0.5)'
  78. }
  79. }
  80. }
  81. ]
  82. }), [overview.industryData])
  83. const barOption = useMemo<EChartOption>(() => ({
  84. tooltip: {},
  85. dataset: {
  86. dimensions: ['name', 'value'],
  87. source: overview.originDeptData
  88. },
  89. xAxis: {},
  90. yAxis: {
  91. type: 'category',
  92. data: overview.originDeptData.map((o) => o.name)
  93. },
  94. series: [{
  95. type: 'bar',
  96. data: overview.originDeptData.map((o, idx) => ({
  97. value: o.value, itemStyle: {
  98. color: DEFAULT_COLORS[idx]
  99. }
  100. }))
  101. }]
  102. }), [overview.originDeptData])
  103. useEffect(() => {
  104. getDataScreening()
  105. }, [])
  106. useEffect(() => {
  107. barRef.current = init(barElementRef.current)
  108. barRef.current.setOption(barOption)
  109. }, [barOption])
  110. useEffect(() => {
  111. pieRef.current = init(pieElementRef.current)
  112. pieRef.current.setOption(pieOption)
  113. }, [pieOption])
  114. return (
  115. <Container>
  116. <Helmet title='数据总览' />
  117. <div className={styles['overview-container']}>
  118. <div className={styles['card-list']}>
  119. {[
  120. {
  121. title: '数据资源数量',
  122. num: overview.dataSource,
  123. icon: ICON_ZY,
  124. bg: IMG_BG_ZY
  125. },
  126. {
  127. title: '来源部门数量',
  128. num: overview.originDept,
  129. icon: ICON_BM,
  130. bg: IMG_BG_BM
  131. },
  132. {
  133. title: '来源系统数量',
  134. num: overview.originSystem,
  135. icon: ICON_XT,
  136. bg: IMG_BG_XT
  137. },
  138. {
  139. title: '近一月目录新增数量',
  140. num: overview.countCatalogue,
  141. icon: ICON_ML,
  142. bg: IMG_BG_ML
  143. }
  144. ].map((item) => (
  145. <div className={styles.item} key={item.title} style={{backgroundImage: `url("${item.bg}")` }}>
  146. <div className={styles.title}>{item.title}</div>
  147. <div>
  148. <span className={styles.num}>{item.num}</span> 个
  149. </div>
  150. <img src={item.icon} alt={item.title} />
  151. </div>
  152. ))}
  153. </div>
  154. <div className={styles.charts}>
  155. <div>
  156. <div className={styles['chart-title']}>行业分类</div>
  157. <div className={styles['chart-desc']}>资源目录各行业资源数量</div>
  158. <div ref={pieElementRef} />
  159. </div>
  160. <div>
  161. <div className={styles['chart-title']}>数据资源来源部门</div>
  162. <div className={styles['chart-desc']}>数据资源来源部门TOP10</div>
  163. <div ref={barElementRef} />
  164. </div>
  165. </div>
  166. </div>
  167. </Container>
  168. )
  169. }