Statistic.tsx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. 'use client'
  2. import { useState } from 'react'
  3. import cn from '@/utils/classnames'
  4. import ReactECharts from 'echarts-for-react'
  5. import * as echarts from 'echarts'
  6. const cardClass = 'bg-[#FCFCFC] border rounded-[10px] border-[#E6E7EB] p-6 flex'
  7. const Statistic = () => {
  8. const [knowledges, setKnowledges] = useState(0)
  9. const [depts, setDepts] = useState(0)
  10. const [tags, setTags] = useState(0)
  11. const [typeData, setTypeData] = useState([])
  12. const [updateData, setUpdateData] = useState([])
  13. const [tagData, setTagData] = useState([
  14. { name: '标签1', value: 100 },
  15. { name: '标签2', value: 90 },
  16. { name: '标签3', value: 80 },
  17. { name: '标签4', value: 70 },
  18. { name: '标签5', value: 60 },
  19. { name: '标签6', value: 50 },
  20. { name: '标签7', value: 40 },
  21. { name: '标签8', value: 30 },
  22. { name: '标签9', value: 20 },
  23. { name: '标签10', value: 10 },
  24. { name: '标签11', value: 9 },
  25. { name: '标签12', value: 8 },
  26. { name: '标签13', value: 7 },
  27. { name: '标签14', value: 6 },
  28. { name: '标签15', value: 5 },
  29. ])
  30. const typeOptions = {
  31. grid: {
  32. top: 0,
  33. bottom: 0,
  34. left: 0,
  35. right: 0,
  36. },
  37. tooltip: {
  38. trigger: 'item',
  39. },
  40. legend: {
  41. orient: 'horizontal',
  42. top: 0,
  43. itemWidth: 8,
  44. itemHeight: 8,
  45. },
  46. series: [
  47. {
  48. type: 'pie',
  49. radius: ['26%', '50%'],
  50. data: [
  51. { value: 1048, name: 'Search Engine' },
  52. { value: 735, name: 'Direct' },
  53. { value: 580, name: 'Email' },
  54. { value: 484, name: 'Union Ads' },
  55. { value: 300, name: 'Video Ads' },
  56. ],
  57. label: {
  58. formatter: '{b} {d}%',
  59. },
  60. emphasis: {
  61. disabled: true,
  62. },
  63. },
  64. ],
  65. }
  66. const updateOptions = {
  67. grid: {
  68. top: 40,
  69. bottom: 20,
  70. left: 40,
  71. right: 0,
  72. },
  73. tooltip: {
  74. trigger: 'axis',
  75. },
  76. xAxis: {
  77. type: 'category',
  78. data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
  79. axisLine: { show: false },
  80. axisTick: { show: false },
  81. splitLine: { show: false },
  82. axisLabel: {
  83. fontSize: 10,
  84. interval: 0,
  85. color: 'rgba(87, 98, 117, 1)',
  86. },
  87. },
  88. yAxis: {
  89. type: 'value',
  90. axisLine: { show: false },
  91. axisTick: { show: false },
  92. splitNumber: 3,
  93. splitLine: {
  94. lineStyle: {
  95. type: 'dashed',
  96. color: 'rgba(239, 241, 248, 1)',
  97. },
  98. },
  99. axisLabel: {
  100. fontSize: 10,
  101. },
  102. },
  103. series: [
  104. {
  105. type: 'bar',
  106. data: [120, 200, 150, 80, 70, 110, 130],
  107. itemStyle: {
  108. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  109. { offset: 0, color: '#2078FC' },
  110. { offset: 1, color: '#5DC9F9' },
  111. ]),
  112. },
  113. },
  114. ],
  115. }
  116. const tagColors = ['#7185fb', '#4bc97d', '#2079fe', '#dba53c', '#4ec5f9']
  117. const tagOptions = {
  118. tooltip: {
  119. trigger: 'item',
  120. },
  121. series: [
  122. {
  123. type: 'graph',
  124. layout: 'force',
  125. data: tagData.sort((a, b) => b.value - a.value).map((v, i) => {
  126. if (i < Math.floor(tagData.length / 4)) {
  127. v.symbolSize = 100
  128. v.label = {
  129. fontSize: 30,
  130. }
  131. }
  132. else if (i < Math.floor(tagData.length / 2)) {
  133. v.symbolSize = 90
  134. v.label = {
  135. fontSize: 24,
  136. }
  137. }
  138. else if (i < Math.floor(tagData.length * 3 / 4)) {
  139. v.symbolSize = 80
  140. v.label = {
  141. fontSize: 20,
  142. }
  143. }
  144. else {
  145. v.symbolSize = 70
  146. v.label = {
  147. fontSize: 16,
  148. }
  149. }
  150. v.itemStyle = {
  151. color: tagColors[i % tagColors.length],
  152. }
  153. return v
  154. }),
  155. links: [],
  156. roam: true,
  157. force: {
  158. repulsion: 110,
  159. edgeLength: [10, 50],
  160. },
  161. symbolSize: 60,
  162. label: {
  163. show: true,
  164. color: '#ffffff',
  165. },
  166. emphasis: {
  167. disabled: true,
  168. },
  169. },
  170. ],
  171. }
  172. return (
  173. <div className="w-full px-12">
  174. <div className={cn('w-full gap-6', cardClass)}>
  175. <div className="flex h-[120px] grow items-center bg-[url('/imgs/statistic-bg.png')] bg-[length:100%_100%] bg-no-repeat pl-6">
  176. <img src="/imgs/statistic-icon-1.png" className="mr-6 h-16 w-16"/>
  177. <div>
  178. <div className="text-[36px] text-[#111111]">{knowledges}</div>
  179. <div className="text-[#111111]">知识库总量</div>
  180. </div>
  181. </div>
  182. <div className="flex h-[120px] grow items-center bg-[url('/imgs/statistic-bg.png')] bg-[length:100%_100%] bg-no-repeat pl-6">
  183. <img src="/imgs/statistic-icon-2.png" className="mr-6 h-16 w-16"/>
  184. <div>
  185. <div className="text-[36px] text-[#111111]">{depts}</div>
  186. <div className="text-[#111111]">部门总量</div>
  187. </div>
  188. </div>
  189. <div className="flex h-[120px] grow items-center bg-[url('/imgs/statistic-bg.png')] bg-[length:100%_100%] bg-no-repeat pl-6">
  190. <img src="/imgs/statistic-icon-3.png" className="mr-6 h-16 w-16"/>
  191. <div>
  192. <div className="text-[36px] text-[#111111]">{tags}</div>
  193. <div className="text-[#111111]">标签总量</div>
  194. </div>
  195. </div>
  196. </div>
  197. <div className='mt-6 flex w-full gap-8'>
  198. <div className={cn(cardClass, 'h-[360px] flex-1 flex-col overflow-hidden')}>
  199. <div className="text-2xl font-bold text-[#333333]">知识库类别统计</div>
  200. <div className="relative mt-3 flex flex-1 items-center justify-center">
  201. <img src="/imgs/statistic-icon-4.png" className="absolute"/>
  202. <ReactECharts option={typeOptions} className="flex-1" />
  203. </div>
  204. </div>
  205. <div className={cn(cardClass, 'h-[360px] flex-1 flex-col overflow-hidden')}>
  206. <div className="text-2xl font-bold text-[#333333]">知识库更新情况统计</div>
  207. <ReactECharts option={updateOptions} className="flex-1" />
  208. </div>
  209. <div className={cn(cardClass, 'h-[360px] flex-1 flex-col overflow-hidden bg-[url("/imgs/statistic-icon-5.png")] bg-[length:100%_100%] bg-no-repeat')}>
  210. <div className="text-2xl font-bold text-[#333333]">标签云图</div>
  211. <ReactECharts option={tagOptions} className="flex-1" />
  212. </div>
  213. </div>
  214. </div>
  215. )
  216. }
  217. export default Statistic