From ce8b767ec8e979e01d53623dca6da39cf519b881 Mon Sep 17 00:00:00 2001 From: hhjk00 Date: Tue, 14 Nov 2023 11:01:35 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B9=84=ED=96=89=20=ED=86=B5=EA=B3=84=20api?= =?UTF-8?q?=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/containers/statistics/FlightContainer.js | 297 +++++++++++------- .../statistics/FlightResultContainer.js | 7 +- 2 files changed, 179 insertions(+), 125 deletions(-) diff --git a/src/containers/statistics/FlightContainer.js b/src/containers/statistics/FlightContainer.js index 6ab1bc9..aa0892f 100644 --- a/src/containers/statistics/FlightContainer.js +++ b/src/containers/statistics/FlightContainer.js @@ -13,14 +13,19 @@ import { Search } from 'react-feather'; import { FcAlarmClock, FcWorkflow, FcBarChart } from 'react-icons/fc'; import { Bar, Doughnut } from 'react-chartjs-2'; import { useCallback, useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import * as StcsActions from '../../modules/statistics/actions'; export default function FlightContainer({ tooltipShadow, gridLineColor, labelColor }) { + const dispatch = useDispatch(); + const { flight, flightSearch } = useSelector(state => state.statisticsState); + const [searchType, setSearchType] = useState({ - flightType: '비행시간', + category: 'TIME', dateType: 'year', year: new Date().getFullYear(), month: new Date().getMonth() + 1, @@ -33,25 +38,97 @@ export default function FlightContainer({ const titleName = '비행 통계'; + useEffect(() => { + dispatch(StcsActions.FLIGHT_STCS.request()); + }, []); + + // 해당 월에 맞는 요일 표출 useEffect(() => { const { year, month } = searchType; - const lastDay = new Date(year, month, 0).getDate(); + const lastDay = new Date(year, Number(month), 0).getDate(); const dayList = Array.from({ length: lastDay }, (_, index) => index + 1); setDateLists({ ...dateLists, day: dayList }); }, [searchType.month]); + useEffect(() => { + const { category, dateType, year, month, day } = searchType; + + const dateMapping = { + month: year, + day: `${year}-${month}`, + 'one-day': `${year}-${month}-${day}` + }; + const date = dateMapping[dateType] || ''; + + dispatch( + StcsActions.FLIGHT_STCS_SEARCH.request({ + cate: category, + date, + type: dateType + }) + ); + }, [searchType]); + // 검색조건 handler const handleChangeSearchType = useCallback( (type, val) => { setSearchType({ ...searchType, - [type]: type === 'dateType' || type === 'flightType' ? val : Number(val) + [type]: val }); }, [searchType] ); + // 그래프 타이틀 handler + const handlerTitleName = category => { + const categoryMappings = { + TIME: '비행 시간', + DISTANCE: '비행 거리', + FLT_COUNT: '비행 횟수' + }; + return categoryMappings[category]; + }; + + // Bar Graph handler + const handlerBarTicks = () => { + const data = flightSearch.topData.map(i => i.value); + const max = Math.ceil(Math.max(...data) / 10) * 10; + const stepSize = handlerStepSize(max); + + return { max, stepSize }; + }; + + const handlerStepSize = max => { + const exponent = Math.ceil(Math.log10(max)); + return 10 ** (exponent - 1); + }; + + const addCommasToNumber = number => { + if (number === 'noData') return 0; + return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); + }; + + const parseTime = time => { + if (time === 'noData') { + return '0초'; + } + + const [hour, minute, second] = time.split(':').map(Number); + + const formatPart = (value, unit) => (value > 0 ? `${value}${unit}` : ''); + + const parts = [ + formatPart(Math.floor(hour / 24), '일'), + formatPart(hour % 24, '시간'), + formatPart(minute, '분'), + formatPart(second, '초') + ].filter(Boolean); + + return parts.join(' '); + }; + const options = { elements: { rectangle: { @@ -100,9 +177,8 @@ export default function FlightContainer({ zeroLineColor: gridLineColor }, ticks: { - stepSize: 100, + ...handlerBarTicks(), min: 0, - max: 400, fontColor: labelColor } } @@ -110,22 +186,10 @@ export default function FlightContainer({ } }, data = { - labels: [ - '7/12', - '8/12', - '9/12', - '10/12', - '11/12', - '12/12', - '13/12', - '14/12', - '15/12', - '16/12', - '17/12' - ], + labels: flightSearch.graphData.map(i => i.name), datasets: [ { - data: [275, 90, 190, 205, 125, 85, 55, 87, 127, 150, 230, 280, 190], + data: flightSearch.graphData.map(i => i.value), backgroundColor: '#00bcd4', borderColor: '#00bcd4', barThickness: 15 @@ -169,12 +233,12 @@ export default function FlightContainer({ } }, data2 = { - labels: ['PA0001', 'PA0002', 'PA0003', 'PA0004', 'PA0005'], + labels: flightSearch.topData.map(i => i.name), datasets: [ { - labels: ['PA0001', 'PA0002', 'PA0003', 'PA0004', 'PA0005'], - data: [10, 20, 30, 40, 80], - //레드버전 + labels: flightSearch.topData.map(i => i.name), + data: flightSearch.topData.map(i => i.value), + // 레드버전 // backgroundColor: [ // '#ffe8d1', // '#ffb59e', @@ -201,93 +265,74 @@ export default function FlightContainer({
- -
- - - - - - - - - -
- - - - 총 비행시간 - PA0001 - - - 8일 10시간 35분 12초 -
- - 1일 35분 12초 - - - 35분 12초 -
-
- - -
- - - - - - - - - -
- - - - 총 비행거리 - PA0002 - - - 10,845m -
- - 1,201m - - - 53m -
-
- - -
- - - - - - - - - -
- - - - 총 비행횟수 - PA0002 - - - 1,024,845건 -
- - 111,201건 - - - 153건 -
-
- + {flight.map((i, idx) => ( + +
+ + + + + + + + + + +
+ + {idx === 0 ? ( + + ) : idx === 1 ? ( + + ) : ( + + )} + + + {idx === 0 + ? '총 비행시간' + : idx === 1 + ? '총 비행거리' + : '총 비행횟수'} + + {i.name} + + + + {idx === 0 ? ( + <>{parseTime(i.year)} + ) : idx === 1 ? ( + <>{addCommasToNumber(i.year)}m + ) : ( + <>{addCommasToNumber(i.year)}건 + )} + +
+ + + {idx === 0 ? ( + <>{parseTime(i.month)} + ) : idx === 1 ? ( + <>{addCommasToNumber(i.month)}m + ) : ( + <>{addCommasToNumber(i.month)}건 + )} + + + + + {idx === 0 ? ( + <>{parseTime(i.day)} + ) : idx === 1 ? ( + <>{addCommasToNumber(i.day)}m + ) : ( + <>{addCommasToNumber(i.day)}건 + )} + +
+
+ + ))}
@@ -297,12 +342,12 @@ export default function FlightContainer({

검색조건

-
+ {/*
검색 -
+
*/}
@@ -322,14 +367,18 @@ export default function FlightContainer({ bsSize='sm' onChange={e => handleChangeSearchType( - 'flightType', + 'category', e.target.value ) } > - - - + + + @@ -349,7 +398,9 @@ export default function FlightContainer({ - {searchType.flightType} 통계 + + {handlerTitleName(searchType.category)} 통계 +
@@ -366,13 +417,13 @@ export default function FlightContainer({ - +
{searchType.dateType === 'month' || searchType.dateType === 'day' || - searchType.dateType === 'time' ? ( + searchType.dateType === 'one-day' ? ( <>
{searchType.dateType === 'day' || - searchType.dateType === 'time' ? ( + searchType.dateType === 'one-day' ? (
) : null} - {searchType.dateType === 'time' ? ( + {searchType.dateType === 'one-day' ? (
- {searchType.flightType} TOP5 + + {handlerTitleName(searchType.category)} TOP5 +
diff --git a/src/containers/statistics/FlightResultContainer.js b/src/containers/statistics/FlightResultContainer.js index 2647d62..8ba63e9 100644 --- a/src/containers/statistics/FlightResultContainer.js +++ b/src/containers/statistics/FlightResultContainer.js @@ -106,6 +106,7 @@ export default function ResultContainer({ }; const addCommasToNumber = number => { + if (number === 'NoData') return 0; return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; @@ -213,11 +214,11 @@ export default function ResultContainer({ } }, data2 = { - labels: resultSearch?.topData.map(i => i.name), + labels: resultSearch.topData.map(i => i.name), datasets: [ { - labels: resultSearch?.topData.map(i => i.name), - data: resultSearch?.topData.map(i => i.value), + labels: resultSearch.topData.map(i => i.name), + data: resultSearch.topData.map(i => i.value), // 레드버전 // backgroundColor: [ // '#ffe8d1',