index.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import { PageContainer } from '@ant-design/pro-layout';
  2. import { useEffect, useRef, useState } from 'react';
  3. import './index.less';
  4. import service from '../service';
  5. import DashBoard, { DashBoardTopCard } from '@/components/DashBoard';
  6. import type { EChartsOption } from 'echarts';
  7. type RefType = {
  8. getValues: Function;
  9. };
  10. const DeviceBoard = () => {
  11. const [channel, setChannel] = useState(0);
  12. const [errorChannel, setErrorChannel] = useState(0);
  13. const [collector, setCollector] = useState(0);
  14. const [errorCollector, setErrorCollector] = useState(0);
  15. const [point, setPoint] = useState(0);
  16. const [errorPoint, setErrorPoint] = useState(0);
  17. const ref = useRef<RefType>();
  18. const [options, setOptions] = useState<EChartsOption>({});
  19. const [timeToolOptions] = useState([
  20. { label: '最近1小时', value: 'hour' },
  21. { label: '今日', value: 'today' },
  22. { label: '近一周', value: 'week' },
  23. ]);
  24. //通道数量
  25. const channelStatus = async () => {
  26. const channelRes = await service.queryChannelCount({});
  27. if (channelRes.status === 200) {
  28. setChannel(channelRes.result);
  29. }
  30. const errorChannelRes = await service.queryChannelCount({
  31. terms: [
  32. {
  33. column: 'runningState',
  34. termType: 'not',
  35. value: 'running',
  36. },
  37. ],
  38. });
  39. if (errorChannelRes.status === 200) {
  40. setErrorChannel(errorChannelRes.result);
  41. }
  42. };
  43. //采集器数量
  44. const collectorStatus = async () => {
  45. const collectorRes = await service.queryCollectorCount({});
  46. if (collectorRes.status === 200) {
  47. setCollector(collectorRes.result);
  48. }
  49. const errorCollectorRes = await service.queryCollectorCount({
  50. terms: [
  51. {
  52. column: 'runningState',
  53. termType: 'not',
  54. value: 'running',
  55. },
  56. ],
  57. });
  58. if (errorCollectorRes.status === 200) {
  59. setErrorCollector(errorCollectorRes.result);
  60. }
  61. };
  62. // 点位
  63. const pointStatus = async () => {
  64. const pointRes = await service.queryPointCount({});
  65. if (pointRes.status === 200) {
  66. setPoint(pointRes.result);
  67. }
  68. const errorPointRes = await service.queryPointCount({
  69. terms: [
  70. {
  71. column: 'runningState',
  72. termType: 'not',
  73. value: 'running',
  74. },
  75. ],
  76. });
  77. if (errorPointRes.status === 200) {
  78. setErrorPoint(errorPointRes.result);
  79. }
  80. };
  81. const getParams = (dt: any) => {
  82. switch (dt.type) {
  83. case 'today':
  84. return {
  85. limit: 24,
  86. interval: '1h',
  87. format: 'HH:mm',
  88. };
  89. case 'week':
  90. return {
  91. limit: 7,
  92. interval: '1d',
  93. format: 'MM-dd',
  94. };
  95. case 'hour':
  96. return {
  97. limit: 60,
  98. interval: '1m',
  99. format: 'HH:mm',
  100. };
  101. default:
  102. const time = dt.end - dt.start;
  103. const hour = 60 * 60 * 1000;
  104. const days = hour * 24;
  105. if (time <= hour) {
  106. return {
  107. limit: Math.abs(Math.ceil(time / (60 * 60))),
  108. interval: '1m',
  109. format: 'HH:mm',
  110. };
  111. } else if (time > hour && time <= days) {
  112. return {
  113. limit: Math.abs(Math.ceil(time / hour)),
  114. interval: '1h',
  115. format: 'HH:mm',
  116. };
  117. } else {
  118. return {
  119. limit: Math.abs(Math.ceil(time / days)) + 1,
  120. interval: '1d',
  121. format: 'MM-dd',
  122. };
  123. }
  124. }
  125. };
  126. const getEcharts = async () => {
  127. const data = ref.current!.getValues();
  128. const res = await service.dashboard([
  129. {
  130. dashboard: 'collector',
  131. object: 'pointData',
  132. measurement: 'quantity',
  133. dimension: 'agg',
  134. params: {
  135. limit: getParams(data.time).limit,
  136. from: data.time.start,
  137. to: data.time.end,
  138. interval: getParams(data.time).interval,
  139. format: getParams(data.time).format,
  140. },
  141. },
  142. ]);
  143. if (res.status === 200) {
  144. const x = res.result.map((item: any) => item.data.timeString).reverse();
  145. const y = res.result.map((item: any) => item.data.value).reverse();
  146. setOptions({
  147. xAxis: {
  148. type: 'category',
  149. boundaryGap: false,
  150. data: x,
  151. },
  152. yAxis: {
  153. type: 'value',
  154. },
  155. tooltip: {
  156. trigger: 'axis',
  157. },
  158. grid: {
  159. top: '2%',
  160. bottom: '5%',
  161. left: '50px',
  162. right: '50px',
  163. },
  164. series: [
  165. {
  166. name: '消息量',
  167. data: y,
  168. type: 'line',
  169. smooth: true,
  170. color: '#60DFC7',
  171. areaStyle: {
  172. color: {
  173. type: 'linear',
  174. x: 0,
  175. y: 0,
  176. x2: 0,
  177. y2: 1,
  178. colorStops: [
  179. {
  180. offset: 0,
  181. color: '#60DFC7', // 100% 处的颜色
  182. },
  183. {
  184. offset: 1,
  185. color: '#FFFFFF', // 0% 处的颜色
  186. },
  187. ],
  188. global: false, // 缺省为 false
  189. },
  190. },
  191. },
  192. ],
  193. });
  194. }
  195. };
  196. useEffect(() => {
  197. channelStatus();
  198. collectorStatus();
  199. pointStatus();
  200. }, []);
  201. return (
  202. <PageContainer>
  203. <div className={'device-dash-board'}>
  204. <DashBoardTopCard>
  205. <DashBoardTopCard.Item
  206. title={'通道数量'}
  207. value={channel}
  208. footer={[
  209. {
  210. title: '异常通道',
  211. value: errorChannel,
  212. status: 'error',
  213. },
  214. ]}
  215. span={8}
  216. >
  217. <img src={require('/public/images/DataCollect/dashboard/channel.png')} />
  218. </DashBoardTopCard.Item>
  219. <DashBoardTopCard.Item
  220. title={'采集器数量'}
  221. value={collector}
  222. footer={[
  223. {
  224. title: '异常采集器',
  225. value: errorCollector,
  226. status: 'error',
  227. },
  228. ]}
  229. span={8}
  230. >
  231. <img src={require('/public/images/DataCollect/dashboard/collector.png')} />
  232. </DashBoardTopCard.Item>
  233. <DashBoardTopCard.Item
  234. title={'采集点位'}
  235. value={point}
  236. footer={[
  237. {
  238. title: '异常点位',
  239. value: errorPoint,
  240. status: 'error',
  241. },
  242. ]}
  243. span={8}
  244. >
  245. <img src={require('/public/images/DataCollect/dashboard/point.png')} />
  246. </DashBoardTopCard.Item>
  247. </DashBoardTopCard>
  248. <DashBoard
  249. title={'点位数据量'}
  250. options={options}
  251. ref={ref}
  252. height={500}
  253. defaultTime={'hour'}
  254. timeToolOptions={timeToolOptions}
  255. showTime={true}
  256. showTimeTool={true}
  257. onParamsChange={getEcharts}
  258. />
  259. </div>
  260. </PageContainer>
  261. );
  262. };
  263. export default DeviceBoard;