From f3be389a2b66345ea7b36a0569c4e5ba20a3469f Mon Sep 17 00:00:00 2001 From: hhjk00 Date: Wed, 15 Nov 2023 10:42:22 +0900 Subject: [PATCH] =?UTF-8?q?=ED=86=B5=EA=B3=84=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/statistics/StatisticsSearch.js | 368 ++++++++++++ src/components/statistics/StatisticsTotal.js | 69 +++ .../statistics/AbnormalSituationContainer.js | 536 +----------------- src/containers/statistics/FlightContainer.js | 473 +--------------- .../statistics/FlightResultContainer.js | 455 +-------------- 5 files changed, 519 insertions(+), 1382 deletions(-) create mode 100644 src/components/statistics/StatisticsSearch.js create mode 100644 src/components/statistics/StatisticsTotal.js diff --git a/src/components/statistics/StatisticsSearch.js b/src/components/statistics/StatisticsSearch.js new file mode 100644 index 0000000..4b5f338 --- /dev/null +++ b/src/components/statistics/StatisticsSearch.js @@ -0,0 +1,368 @@ +import { + Col, + Row, + Card, + CardHeader, + CardTitle, + CardBody, + CustomInput +} from 'reactstrap'; +import { Search } from 'react-feather'; +import { Bar, Doughnut } from 'react-chartjs-2'; + +export default function StatisticsSearch({ + tooltipShadow, + gridLineColor, + labelColor, + searchData, + searchType, + dateLists, + categoryTypeOptions, + handlerBarTicks, + handlerTitleName, + handleChangeSearchType +}) { + const options = { + elements: { + rectangle: { + borderWidth: 2, + borderSkipped: 'bottom' + } + }, + responsive: true, + maintainAspectRatio: false, + responsiveAnimationDuration: 500, + legend: { + display: false + }, + tooltips: { + // Updated default tooltip UI + shadowOffsetX: 1, + shadowOffsetY: 1, + shadowBlur: 8, + shadowColor: tooltipShadow, + backgroundColor: '#fff', + titleFontColor: '#000', + bodyFontColor: '#000' + }, + scales: { + xAxes: [ + { + display: true, + gridLines: { + display: true, + color: gridLineColor, + zeroLineColor: gridLineColor + }, + scaleLabel: { + display: false + }, + ticks: { + fontColor: labelColor + } + } + ], + yAxes: [ + { + display: true, + gridLines: { + color: gridLineColor, + zeroLineColor: gridLineColor + }, + ticks: { + ...handlerBarTicks(), + min: 0, + fontColor: labelColor + } + } + ] + } + }, + data = { + labels: searchData.graphData.map(i => i.name), + datasets: [ + { + data: searchData.graphData.map(i => i.value), + backgroundColor: '#00bcd4', + borderColor: '#00bcd4', + barThickness: 15 + } + ] + }; + + const options2 = { + responsive: true, + maintainAspectRatio: true, + responsiveAnimationDuration: 500, + cutoutPercentage: 60, + legend: { + position: 'bottom', + labels: { + usePointStyle: true, + padding: 18, + boxWidth: 8, + fontColor: labelColor, + fontSize: 14, + fontWeight: 500, + fontFamily: ['Rubik', 'Montserrat', 'NotoSansKR'] + } + }, + tooltips: { + callbacks: { + label(tooltipItem, data) { + const label = data.datasets[0].labels[tooltipItem.index] || '', + value = data.datasets[0].data[tooltipItem.index]; + const output = ` ${label} : ${value} %`; + return output; + } + }, + shadowOffsetX: 1, + shadowOffsetY: 1, + shadowBlur: 8, + shadowColor: tooltipShadow, + backgroundColor: '#fff', + titleFontColor: '#000', + bodyFontColor: '#000' + } + }, + data2 = { + labels: searchData.topData.map(i => i.name), + datasets: [ + { + labels: searchData.topData.map(i => i.name), + data: searchData.topData.map(i => i.value), + // 레드버전 + // backgroundColor: [ + // '#ffe8d1', + // '#ffb59e', + // '#f0826b', + // '#Bd4f38', + // '#8a1c05' + // ], + + backgroundColor: [ + '#ccffff', + '#99ffff', + '#66ffff', + '#33efff', + '#00bcd4' + ], + borderWidth: 0, + pointStyle: 'rectRounded' + } + ] + }; + + return ( + <> +
+ + +
+
+

검색조건

+
+ {/*
+ + + 검색 + +
*/} +
+ + +
+
+
+
+
검색조건
+
+
+ + + + handleChangeSearchType( + 'category', + e.target.value + ) + } + > + {Object.entries(categoryTypeOptions).map( + ([value, label]) => ( + + ) + )} + + + +
+
+
+
+
+
+
+
+ +
+
+
+ + + + + + {handlerTitleName(searchType.category)} 통계 + +
+ +
+ + handleChangeSearchType('dateType', e.target.value) + } + > + + + + + +
+ + {searchType.dateType === 'month' || + searchType.dateType === 'day' || + searchType.dateType === 'one-day' ? ( + <> +
+ + handleChangeSearchType('year', e.target.value) + } + > + + +
+ {searchType.dateType === 'day' || + searchType.dateType === 'one-day' ? ( +
+ + handleChangeSearchType('month', e.target.value) + } + > + {dateLists.month.map(i => ( + + ))} + +
+ ) : null} + {searchType.dateType === 'one-day' ? ( +
+ + handleChangeSearchType('day', e.target.value) + } + > + {dateLists.day.map(i => ( + + ))} + +
+ ) : null} + + ) : null} +
+ {/* + */} +
+
+ +
+ +
+
+
+ + + + + + {handlerTitleName(searchType.category)} TOP5 + + + +
+ +
+ {/*
+
+
*/} +
+
+ +
+
+ + ); +} diff --git a/src/components/statistics/StatisticsTotal.js b/src/components/statistics/StatisticsTotal.js new file mode 100644 index 0000000..832736d --- /dev/null +++ b/src/components/statistics/StatisticsTotal.js @@ -0,0 +1,69 @@ +import { Col, Row } from 'reactstrap'; +import { FcAlarmClock, FcWorkflow, FcBarChart } from 'react-icons/fc'; + +export default function StatisticsTotal({ + titleName, + totalData, + totalTitle, + parseTime, + addCommasToNumber +}) { + const renderIcon = idx => { + if (idx === 0) return ; + if (idx === 1) return ; + return ; + }; + + const renderData = (data, titleName, idx) => { + if (titleName === '비행 통계') { + if (idx === 0) return parseTime(data); + if (idx === 1) return <>{addCommasToNumber(data)}m; + return <>{addCommasToNumber(data)}건; + } else { + return <>{addCommasToNumber(data)}건; + } + }; + + return ( +
+ + {totalData.map((i, idx) => ( + +
+ + + + + + + + + + +
+ {renderIcon(idx)} + {totalTitle[idx]} + {i.name} + + + + {renderData(i.year, titleName, idx)} + +
+ + + {renderData(i.month, titleName, idx)} + + + + + {renderData(i.day, titleName, idx)} + +
+
+ + ))} +
+
+ ); +} diff --git a/src/containers/statistics/AbnormalSituationContainer.js b/src/containers/statistics/AbnormalSituationContainer.js index c2d4f80..bbe3334 100644 --- a/src/containers/statistics/AbnormalSituationContainer.js +++ b/src/containers/statistics/AbnormalSituationContainer.js @@ -1,26 +1,11 @@ import { CustomMainLayout } from '../../components/layout/CustomMainLayout'; -import { - Button, - Col, - Row, - Card, - CardHeader, - CardTitle, - CardBody, - CustomInput -} from 'reactstrap'; -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'; +import StatisticsSearch from '../../components/statistics/StatisticsSearch'; +import StatisticsTotal from '../../components/statistics/StatisticsTotal'; -export default function AbnormalSituationContainer({ - tooltipShadow, - gridLineColor, - labelColor -}) { +export default function AbnormalSituationContainer() { const dispatch = useDispatch(); const { abnormal, abnormalSearch } = useSelector( state => state.statisticsState @@ -39,6 +24,12 @@ export default function AbnormalSituationContainer({ }); const titleName = '비정상상황 통계'; + const totalTitle = ['비행경로이탈', '비정상고도', '충돌위험']; + const categoryTypeOptions = { + PLAN: '비행경로이탈', + ALTITUDE: '비정상고도', + CRASH: '충돌위험' + }; useEffect(() => { dispatch(StcsActions.ABNORMAL_STCS.request()); @@ -84,12 +75,7 @@ export default function AbnormalSituationContainer({ // 그래프 타이틀 handler const handlerTitleName = category => { - const categoryMappings = { - PLAN: '비행경로이탈', - ALTITUDE: '비정상고도', - CRASH: '충돌위험' - }; - return categoryMappings[category]; + return categoryTypeOptions[category]; }; // Bar Graph handler @@ -106,501 +92,29 @@ export default function AbnormalSituationContainer({ return 10 ** (exponent - 1); }; + // 123456789 -> 123,456,789 const addCommasToNumber = number => { if (number === 'noData') return 0; return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; - const options = { - elements: { - rectangle: { - borderWidth: 2, - borderSkipped: 'bottom' - } - }, - responsive: true, - maintainAspectRatio: false, - responsiveAnimationDuration: 500, - legend: { - display: false - }, - tooltips: { - // Updated default tooltip UI - shadowOffsetX: 1, - shadowOffsetY: 1, - shadowBlur: 8, - shadowColor: tooltipShadow, - backgroundColor: '#fff', - titleFontColor: '#000', - bodyFontColor: '#000' - }, - scales: { - xAxes: [ - { - display: true, - gridLines: { - display: true, - color: gridLineColor, - zeroLineColor: gridLineColor - }, - scaleLabel: { - display: false - }, - ticks: { - fontColor: labelColor - } - } - ], - yAxes: [ - { - display: true, - gridLines: { - color: gridLineColor, - zeroLineColor: gridLineColor - }, - ticks: { - ...handlerBarTicks(), - min: 0, - fontColor: labelColor - } - } - ] - } - }, - data = { - labels: abnormalSearch.graphData.map(i => i.name), - datasets: [ - { - data: abnormalSearch.graphData.map(i => i.value), - backgroundColor: '#00bcd4', - borderColor: '#00bcd4', - barThickness: 15 - } - ] - }; - - const options2 = { - responsive: true, - maintainAspectRatio: true, - responsiveAnimationDuration: 500, - cutoutPercentage: 60, - legend: { - position: 'bottom', - labels: { - usePointStyle: true, - padding: 18, - boxWidth: 8, - fontColor: labelColor, - fontSize: 14, - fontWeight: 500, - fontFamily: ['Rubik', 'Montserrat', 'NotoSansKR'] - } - }, - tooltips: { - callbacks: { - label(tooltipItem, data) { - const label = data.datasets[0].labels[tooltipItem.index] || '', - value = data.datasets[0].data[tooltipItem.index]; - const output = ` ${label} : ${value}건`; - return output; - } - }, - shadowOffsetX: 1, - shadowOffsetY: 1, - shadowBlur: 8, - shadowColor: tooltipShadow, - backgroundColor: '#fff', - titleFontColor: '#000', - bodyFontColor: '#000' - } - }, - data2 = { - labels: abnormalSearch.topData.map(i => i.name), - datasets: [ - { - labels: abnormalSearch.topData.map(i => i.name), - data: abnormalSearch.topData.map(i => i.value), - //레드버전 - // backgroundColor: [ - // '#ffe8d1', - // '#ffb59e', - // '#f0826b', - // '#Bd4f38', - // '#8a1c05' - // ], - - backgroundColor: [ - '#ccffff', - '#99ffff', - '#66ffff', - '#33efff', - '#00bcd4' - ], - borderWidth: 0, - pointStyle: 'rectRounded' - } - ] - }; - return (
-
- - {abnormal.map((i, idx) => ( - -
- - - - - - - - - -
- {idx === 0 ? ( - <> - - - - 비행경로이탈 - - ) : idx === 1 ? ( - <> - - - - 비정상고도 - - ) : ( - <> - - - - 충돌위험 - - )} - - {i.name} - - - - {addCommasToNumber(i.year)}건 - -
- - - {addCommasToNumber(i.month)}건 - - - - - {addCommasToNumber(i.day)}건 - -
-
- - ))} - {/* -
- - - - - - - - - -
- - - - 비행경로이탈 - PA0001 - - - 8일 10시간 35분 12초 -
- - 1일 35분 12초 - - - 35분 12초 -
-
- - -
- - - - - - - - - -
- - - - 비정상 고도 - PA0002 - - - 10,845m -
- - 1,201m - - - 53m -
-
- - -
- - - - - - - - - -
- - - - 충돌위험 - PA0002 - - - 1,024,845건 -
- - 111,201건 - - - 153건 -
-
- */} -
-
-
- - -
-
-

검색조건

-
- {/*
- - - 검색 - -
*/} -
- - -
-
-
-
-
검색조건
-
-
- - - - handleChangeSearchType( - 'category', - e.target.value - ) - } - > - - - - - - -
-
-
-
-
-
-
-
- -
-
-
- - - - - - {handlerTitleName(searchType.category)} 통계 - -
- -
- - handleChangeSearchType('dateType', e.target.value) - } - > - - - - - -
- - {searchType.dateType === 'month' || - searchType.dateType === 'day' || - searchType.dateType === 'one-day' ? ( - <> -
- - handleChangeSearchType('year', e.target.value) - } - > - - -
- {searchType.dateType === 'day' || - searchType.dateType === 'one-day' ? ( -
- - handleChangeSearchType( - 'month', - e.target.value - ) - } - > - {dateLists.month.map(i => ( - - ))} - -
- ) : null} - {searchType.dateType === 'one-day' ? ( -
- - handleChangeSearchType('day', e.target.value) - } - > - {dateLists.day.map(i => ( - - ))} - -
- ) : null} - - ) : null} -
- {/* - */} -
-
- -
- -
-
-
- - - - - - {handlerTitleName(searchType.category)} TOP5 - - - -
- -
- {/*
-
-
*/} -
-
- -
-
+ +
); diff --git a/src/containers/statistics/FlightContainer.js b/src/containers/statistics/FlightContainer.js index 33de57b..744db43 100644 --- a/src/containers/statistics/FlightContainer.js +++ b/src/containers/statistics/FlightContainer.js @@ -1,26 +1,11 @@ import { CustomMainLayout } from '../../components/layout/CustomMainLayout'; -import { - Button, - Col, - Row, - Card, - CardHeader, - CardTitle, - CardBody, - CustomInput -} from 'reactstrap'; -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'; +import StatisticsTotal from '../../components/statistics/StatisticsTotal'; +import StatisticsSearch from '../../components/statistics/StatisticsSearch'; -export default function FlightContainer({ - tooltipShadow, - gridLineColor, - labelColor -}) { +export default function FlightContainer() { const dispatch = useDispatch(); const { flight, flightSearch } = useSelector(state => state.statisticsState); @@ -37,6 +22,12 @@ export default function FlightContainer({ }); const titleName = '비행 통계'; + const totalTitle = ['총 비행시간', '총 비행거리', '총 비행횟수']; + const categoryTypeOptions = { + TIME: '비행 시간', + DISTANCE: '비행 거리', + FLT_COUNT: '비행 횟수' + }; useEffect(() => { dispatch(StcsActions.FLIGHT_STCS.request()); @@ -83,17 +74,12 @@ export default function FlightContainer({ // 그래프 타이틀 handler const handlerTitleName = category => { - const categoryMappings = { - TIME: '비행 시간', - DISTANCE: '비행 거리', - FLT_COUNT: '비행 횟수' - }; - return categoryMappings[category]; + return categoryTypeOptions[category]; }; // Bar Graph handler const handlerBarTicks = () => { - const data = flightSearch.topData.map(i => i.value); + const data = flightSearch.graphData.map(i => i.value); const max = Math.ceil(Math.max(...data) / 10) * 10; const stepSize = handlerStepSize(max); @@ -105,15 +91,16 @@ export default function FlightContainer({ return 10 ** (exponent - 1); }; + // 123456789 -> 123,456,789 const addCommasToNumber = number => { if (number === 'noData') return 0; + return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; + // '24:35:12' -> 1일 35분 12초 const parseTime = time => { - if (time === 'noData') { - return '0초'; - } + if (time === 'noData') return '0초'; const [hour, minute, second] = time.split(':').map(Number); @@ -129,423 +116,25 @@ export default function FlightContainer({ return parts.join(' '); }; - const options = { - elements: { - rectangle: { - borderWidth: 2, - borderSkipped: 'bottom' - } - }, - responsive: true, - maintainAspectRatio: false, - responsiveAnimationDuration: 500, - legend: { - display: false - }, - tooltips: { - // Updated default tooltip UI - shadowOffsetX: 1, - shadowOffsetY: 1, - shadowBlur: 8, - shadowColor: tooltipShadow, - backgroundColor: '#fff', - titleFontColor: '#000', - bodyFontColor: '#000' - }, - scales: { - xAxes: [ - { - display: true, - gridLines: { - display: true, - color: gridLineColor, - zeroLineColor: gridLineColor - }, - scaleLabel: { - display: false - }, - ticks: { - fontColor: labelColor - } - } - ], - yAxes: [ - { - display: true, - gridLines: { - color: gridLineColor, - zeroLineColor: gridLineColor - }, - ticks: { - ...handlerBarTicks(), - min: 0, - fontColor: labelColor - } - } - ] - } - }, - data = { - labels: flightSearch.graphData.map(i => i.name), - datasets: [ - { - data: flightSearch.graphData.map(i => i.value), - backgroundColor: '#00bcd4', - borderColor: '#00bcd4', - barThickness: 15 - } - ] - }; - - const options2 = { - responsive: true, - maintainAspectRatio: true, - responsiveAnimationDuration: 500, - cutoutPercentage: 60, - legend: { - position: 'bottom', - labels: { - usePointStyle: true, - padding: 18, - boxWidth: 8, - fontColor: labelColor, - fontSize: 14, - fontWeight: 500, - fontFamily: ['Rubik', 'Montserrat', 'NotoSansKR'] - } - }, - tooltips: { - callbacks: { - label(tooltipItem, data) { - const label = data.datasets[0].labels[tooltipItem.index] || '', - value = data.datasets[0].data[tooltipItem.index]; - const output = ` ${label} : ${value} %`; - return output; - } - }, - shadowOffsetX: 1, - shadowOffsetY: 1, - shadowBlur: 8, - shadowColor: tooltipShadow, - backgroundColor: '#fff', - titleFontColor: '#000', - bodyFontColor: '#000' - } - }, - data2 = { - labels: flightSearch.topData.map(i => i.name), - datasets: [ - { - labels: flightSearch.topData.map(i => i.name), - data: flightSearch.topData.map(i => i.value), - // 레드버전 - // backgroundColor: [ - // '#ffe8d1', - // '#ffb59e', - // '#f0826b', - // '#Bd4f38', - // '#8a1c05' - // ], - - backgroundColor: [ - '#ccffff', - '#99ffff', - '#66ffff', - '#33efff', - '#00bcd4' - ], - borderWidth: 0, - pointStyle: 'rectRounded' - } - ] - }; - return (
-
- - {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)}건 - )} - -
-
- - ))} -
-
-
- - -
-
-

검색조건

-
- {/*
- - - 검색 - -
*/} -
- - -
-
-
-
-
검색조건
-
-
- - - - handleChangeSearchType( - 'category', - e.target.value - ) - } - > - - - - - - -
-
-
-
-
-
-
-
- -
-
-
- - - - - - {handlerTitleName(searchType.category)} 통계 - -
- -
- - handleChangeSearchType('dateType', e.target.value) - } - > - - - - - -
- - {searchType.dateType === 'month' || - searchType.dateType === 'day' || - searchType.dateType === 'one-day' ? ( - <> -
- - handleChangeSearchType('year', e.target.value) - } - > - - -
- {searchType.dateType === 'day' || - searchType.dateType === 'one-day' ? ( -
- - handleChangeSearchType( - 'month', - e.target.value - ) - } - > - {dateLists.month.map(i => ( - - ))} - -
- ) : null} - {searchType.dateType === 'one-day' ? ( -
- - handleChangeSearchType('day', e.target.value) - } - > - {dateLists.day.map(i => ( - - ))} - -
- ) : null} - - ) : null} -
- {/* - */} -
-
- -
- -
-
-
- - - - - - {handlerTitleName(searchType.category)} TOP5 - - - -
- -
- {/*
-
-
*/} -
-
- -
-
+ +
); diff --git a/src/containers/statistics/FlightResultContainer.js b/src/containers/statistics/FlightResultContainer.js index 990332e..3236b90 100644 --- a/src/containers/statistics/FlightResultContainer.js +++ b/src/containers/statistics/FlightResultContainer.js @@ -1,26 +1,11 @@ import { CustomMainLayout } from '../../components/layout/CustomMainLayout'; -import { - Button, - Col, - Row, - Card, - CardHeader, - CardTitle, - CardBody, - CustomInput -} from 'reactstrap'; -import { Search } from 'react-feather'; -import { FcAlarmClock, FcWorkflow, FcBarChart } from 'react-icons/fc'; -import { Bar, Doughnut } from 'react-chartjs-2'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import * as StcsActions from '../../modules/statistics/actions'; +import StatisticsTotal from '../../components/statistics/StatisticsTotal'; +import StatisticsSearch from '../../components/statistics/StatisticsSearch'; -export default function ResultContainer({ - tooltipShadow, - gridLineColor, - labelColor -}) { +export default function ResultContainer() { const dispatch = useDispatch(); const { result, resultSearch } = useSelector(state => state.statisticsState); @@ -37,6 +22,12 @@ export default function ResultContainer({ }); const titleName = '비행 실적 통계'; + const totalTitle = ['비행 실적', '비행 계획', '비행 승인']; + const categoryTypeOptions = { + FLT_RESULT: '비행 실적', + FLT_PLAN: '비행 계획', + FLT_PLAN_APRVN: '비행 승인' + }; useEffect(() => { dispatch(StcsActions.RESULT_STCS.request()); @@ -83,12 +74,7 @@ export default function ResultContainer({ // 그래프 타이틀 handler const handlerTitleName = category => { - const categoryMappings = { - FLT_RESULT: '비행 실적', - FLT_PLAN: '비행 계획', - FLT_PLAN_APRVN: '비행 승인' - }; - return categoryMappings[category]; + return categoryTypeOptions[category]; }; // Bar Graph handler @@ -105,418 +91,29 @@ export default function ResultContainer({ return 10 ** (exponent - 1); }; + // 123456789 -> 123,456,789 const addCommasToNumber = number => { if (number === 'NoData') return 0; return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; - const options = { - elements: { - rectangle: { - borderWidth: 2, - borderSkipped: 'bottom' - } - }, - responsive: true, - maintainAspectRatio: false, - responsiveAnimationDuration: 500, - legend: { - display: false - }, - tooltips: { - // Updated default tooltip UI - shadowOffsetX: 1, - shadowOffsetY: 1, - shadowBlur: 8, - shadowColor: tooltipShadow, - backgroundColor: '#fff', - titleFontColor: '#000', - bodyFontColor: '#000' - }, - scales: { - xAxes: [ - { - display: true, - gridLines: { - display: true, - color: gridLineColor, - zeroLineColor: gridLineColor - }, - scaleLabel: { - display: false - }, - ticks: { - fontColor: labelColor - } - } - ], - yAxes: [ - { - display: true, - gridLines: { - color: gridLineColor, - zeroLineColor: gridLineColor - }, - ticks: { - ...handlerBarTicks(), - min: 0, - fontColor: labelColor - } - } - ] - } - }, - data = { - labels: resultSearch.graphData.map(i => i.name), - datasets: [ - { - data: resultSearch.graphData.map(i => i.value), - backgroundColor: '#00bcd4', - borderColor: '#00bcd4', - barThickness: 15 - } - ] - }; - - const options2 = { - responsive: true, - maintainAspectRatio: true, - responsiveAnimationDuration: 500, - cutoutPercentage: 60, - legend: { - position: 'bottom', - labels: { - usePointStyle: true, - padding: 18, - boxWidth: 8, - fontColor: labelColor, - fontSize: 14, - fontWeight: 500, - fontFamily: ['Rubik', 'Montserrat', 'NotoSansKR'] - } - }, - tooltips: { - callbacks: { - label(tooltipItem, data) { - const label = data.datasets[0].labels[tooltipItem.index] || '', - value = data.datasets[0].data[tooltipItem.index]; - const output = ` ${label} : ${value}건`; - return output; - } - }, - shadowOffsetX: 1, - shadowOffsetY: 1, - shadowBlur: 8, - shadowColor: tooltipShadow, - backgroundColor: '#fff', - titleFontColor: '#000', - bodyFontColor: '#000' - } - }, - data2 = { - labels: resultSearch.topData.map(i => i.name), - datasets: [ - { - labels: resultSearch.topData.map(i => i.name), - data: resultSearch.topData.map(i => i.value), - // 레드버전 - // backgroundColor: [ - // '#ffe8d1', - // '#ffb59e', - // '#f0826b', - // '#Bd4f38', - // '#8a1c05' - // ], - - backgroundColor: [ - '#ccffff', - '#99ffff', - '#66ffff', - '#33efff', - '#00bcd4' - ], - borderWidth: 0, - pointStyle: 'rectRounded' - } - ] - }; - return (
-
- - {result.map((i, idx) => ( - -
- - - - - - - - - -
- {idx === 0 ? ( - <> - - - - 비행 실적 - - ) : idx === 1 ? ( - <> - - - - 비행 계획 - - ) : ( - <> - - - - 비행 승인 - - )} - - {i.name} - - - - {addCommasToNumber(i.year)}건 - -
- - - {addCommasToNumber(i.month)}건 - - - - - {addCommasToNumber(i.day)}건 - -
-
- - ))} -
-
-
- - -
-
-

검색조건

-
- {/*
- - - 검색 - -
*/} -
- - -
-
-
-
-
검색조건
-
-
- - - - handleChangeSearchType( - 'category', - e.target.value - ) - } - > - - - - - - -
-
-
-
-
-
-
-
- -
-
-
- - - - - - {handlerTitleName(searchType.category)} 통계 - -
- -
- - handleChangeSearchType('dateType', e.target.value) - } - > - - - - - -
- - {searchType.dateType === 'month' || - searchType.dateType === 'day' || - searchType.dateType === 'one-day' ? ( - <> -
- - handleChangeSearchType('year', e.target.value) - } - > - - -
- {searchType.dateType === 'day' || - searchType.dateType === 'one-day' ? ( -
- - handleChangeSearchType( - 'month', - e.target.value - ) - } - > - {dateLists.month.map(i => ( - - ))} - -
- ) : null} - {searchType.dateType === 'one-day' ? ( -
- - handleChangeSearchType('day', e.target.value) - } - > - {dateLists.day.map(i => ( - - ))} - -
- ) : null} - - ) : null} -
- {/* - */} -
-
- -
- -
-
-
- - - - - - {handlerTitleName(searchType.category)} TOP5 - - - -
- -
- {/*
-
-
*/} -
-
- -
-
+ +
);