Browse Source

비행 통계 api 연결

pull/2/head
hhjk00 10 months ago
parent
commit
ce8b767ec8
  1. 297
      src/containers/statistics/FlightContainer.js
  2. 7
      src/containers/statistics/FlightResultContainer.js

297
src/containers/statistics/FlightContainer.js

@ -13,14 +13,19 @@ import { Search } from 'react-feather';
import { FcAlarmClock, FcWorkflow, FcBarChart } from 'react-icons/fc'; import { FcAlarmClock, FcWorkflow, FcBarChart } from 'react-icons/fc';
import { Bar, Doughnut } from 'react-chartjs-2'; import { Bar, Doughnut } from 'react-chartjs-2';
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import * as StcsActions from '../../modules/statistics/actions';
export default function FlightContainer({ export default function FlightContainer({
tooltipShadow, tooltipShadow,
gridLineColor, gridLineColor,
labelColor labelColor
}) { }) {
const dispatch = useDispatch();
const { flight, flightSearch } = useSelector(state => state.statisticsState);
const [searchType, setSearchType] = useState({ const [searchType, setSearchType] = useState({
flightType: '비행시간', category: 'TIME',
dateType: 'year', dateType: 'year',
year: new Date().getFullYear(), year: new Date().getFullYear(),
month: new Date().getMonth() + 1, month: new Date().getMonth() + 1,
@ -33,25 +38,97 @@ export default function FlightContainer({
const titleName = '비행 통계'; const titleName = '비행 통계';
useEffect(() => {
dispatch(StcsActions.FLIGHT_STCS.request());
}, []);
// 해당 월에 맞는 요일 표출
useEffect(() => { useEffect(() => {
const { year, month } = searchType; 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); const dayList = Array.from({ length: lastDay }, (_, index) => index + 1);
setDateLists({ ...dateLists, day: dayList }); setDateLists({ ...dateLists, day: dayList });
}, [searchType.month]); }, [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 // 검색조건 handler
const handleChangeSearchType = useCallback( const handleChangeSearchType = useCallback(
(type, val) => { (type, val) => {
setSearchType({ setSearchType({
...searchType, ...searchType,
[type]: type === 'dateType' || type === 'flightType' ? val : Number(val) [type]: val
}); });
}, },
[searchType] [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 = { const options = {
elements: { elements: {
rectangle: { rectangle: {
@ -100,9 +177,8 @@ export default function FlightContainer({
zeroLineColor: gridLineColor zeroLineColor: gridLineColor
}, },
ticks: { ticks: {
stepSize: 100, ...handlerBarTicks(),
min: 0, min: 0,
max: 400,
fontColor: labelColor fontColor: labelColor
} }
} }
@ -110,22 +186,10 @@ export default function FlightContainer({
} }
}, },
data = { data = {
labels: [ labels: flightSearch.graphData.map(i => i.name),
'7/12',
'8/12',
'9/12',
'10/12',
'11/12',
'12/12',
'13/12',
'14/12',
'15/12',
'16/12',
'17/12'
],
datasets: [ datasets: [
{ {
data: [275, 90, 190, 205, 125, 85, 55, 87, 127, 150, 230, 280, 190], data: flightSearch.graphData.map(i => i.value),
backgroundColor: '#00bcd4', backgroundColor: '#00bcd4',
borderColor: '#00bcd4', borderColor: '#00bcd4',
barThickness: 15 barThickness: 15
@ -169,12 +233,12 @@ export default function FlightContainer({
} }
}, },
data2 = { data2 = {
labels: ['PA0001', 'PA0002', 'PA0003', 'PA0004', 'PA0005'], labels: flightSearch.topData.map(i => i.name),
datasets: [ datasets: [
{ {
labels: ['PA0001', 'PA0002', 'PA0003', 'PA0004', 'PA0005'], labels: flightSearch.topData.map(i => i.name),
data: [10, 20, 30, 40, 80], data: flightSearch.topData.map(i => i.value),
//레드버전 // 레드버전
// backgroundColor: [ // backgroundColor: [
// '#ffe8d1', // '#ffe8d1',
// '#ffb59e', // '#ffb59e',
@ -201,93 +265,74 @@ export default function FlightContainer({
<div className='pal-card-box statistics'> <div className='pal-card-box statistics'>
<div> <div>
<Row> <Row>
<Col md='4'> {flight.map((i, idx) => (
<div> <Col md='4' key={idx}>
<table className='statistics-table'> <div>
<tr> <table className='statistics-table'>
<th rowSpan='2'> <tr>
<span> <th rowSpan='2'>
<FcAlarmClock /> <span>
</span> {idx === 0 ? (
<span> 비행시간</span> <FcAlarmClock />
<span>PA0001</span> ) : idx === 1 ? (
</th> <FcWorkflow />
<td colSpan='3'> ) : (
<span className='date'></span> <FcBarChart />
<span className='date-data'>8 10시간 35 12</span> )}
</td> </span>
</tr> <span>
<tr> {idx === 0
<td> ? '총 비행시간'
<span className='date'></span> : idx === 1
<span className='date-data'>1 35 12</span> ? '총 비행거리'
</td> : '총 비행횟수'}
<td> </span>
<span className='date'></span> <span>{i.name}</span>
<span className='date-data'>35 12</span> </th>
</td>
</tr> <td colSpan='3'>
</table> <span className='date'></span>
</div> <span className='date-data'>
</Col> {idx === 0 ? (
<Col md='4'> <>{parseTime(i.year)}</>
<div> ) : idx === 1 ? (
<table className='statistics-table'> <>{addCommasToNumber(i.year)}m</>
<tr> ) : (
<th rowSpan='2'> <>{addCommasToNumber(i.year)}</>
<span> )}
<FcWorkflow /> </span>
</span> </td>
<span> 비행거리</span> </tr>
<span>PA0002</span> <tr>
</th> <td>
<td colSpan='3'> <span className='date'></span>
<span className='date'></span> <span className='date-data'>
<span className='date-data'>10,845m</span> {idx === 0 ? (
</td> <>{parseTime(i.month)}</>
</tr> ) : idx === 1 ? (
<tr> <>{addCommasToNumber(i.month)}m</>
<td> ) : (
<span className='date'></span> <>{addCommasToNumber(i.month)}</>
<span className='date-data'>1,201m</span> )}
</td> </span>
<td> </td>
<span className='date'></span> <td>
<span className='date-data'>53m</span> <span className='date'></span>
</td> <span className='date-data'>
</tr> {idx === 0 ? (
</table> <>{parseTime(i.day)}</>
</div> ) : idx === 1 ? (
</Col> <>{addCommasToNumber(i.day)}m</>
<Col md='4'> ) : (
<div> <>{addCommasToNumber(i.day)}</>
<table className='statistics-table'> )}
<tr> </span>
<th rowSpan='2'> </td>
<span> </tr>
<FcBarChart /> </table>
</span> </div>
<span> 비행횟수</span> </Col>
<span>PA0002</span> ))}
</th>
<td colSpan='3'>
<span className='date'></span>
<span className='date-data'>1,024,845</span>
</td>
</tr>
<tr>
<td>
<span className='date'></span>
<span className='date-data'>111,201</span>
</td>
<td>
<span className='date'></span>
<span className='date-data'>153</span>
</td>
</tr>
</table>
</div>
</Col>
</Row> </Row>
</div> </div>
<div> <div>
@ -297,12 +342,12 @@ export default function FlightContainer({
<div> <div>
<h4>검색조건</h4> <h4>검색조건</h4>
</div> </div>
<div className='d-flex align-items-center'> {/* <div className='d-flex align-items-center'>
<Button.Ripple color='primary' size='sm'> <Button.Ripple color='primary' size='sm'>
<Search size={16} /> <Search size={16} />
검색 검색
</Button.Ripple> </Button.Ripple>
</div> </div> */}
</div> </div>
<Card> <Card>
<CardBody className='pal-card-body'> <CardBody className='pal-card-body'>
@ -322,14 +367,18 @@ export default function FlightContainer({
bsSize='sm' bsSize='sm'
onChange={e => onChange={e =>
handleChangeSearchType( handleChangeSearchType(
'flightType', 'category',
e.target.value e.target.value
) )
} }
> >
<option value={'비행시간'}>비행시간</option> <option value={'TIME'}>비행 시간</option>
<option value={'비행거리'}>비행거리</option> <option value={'DISTANCE'}>
<option value={'비행횟수'}>비행횟수</option> 비행 거리
</option>
<option value={'FLT_COUNT'}>
비행 횟수
</option>
</CustomInput> </CustomInput>
</Col> </Col>
</Row> </Row>
@ -349,7 +398,9 @@ export default function FlightContainer({
<Col md='8' className='chart-wrap'> <Col md='8' className='chart-wrap'>
<Card> <Card>
<CardHeader className='d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row flex-column'> <CardHeader className='d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row flex-column'>
<CardTitle tag='h4'>{searchType.flightType} 통계</CardTitle> <CardTitle tag='h4'>
{handlerTitleName(searchType.category)} 통계
</CardTitle>
<div className='select-date-wrap'> <div className='select-date-wrap'>
<Row> <Row>
<div className='select-date'> <div className='select-date'>
@ -366,13 +417,13 @@ export default function FlightContainer({
<option value='year'></option> <option value='year'></option>
<option value='month'></option> <option value='month'></option>
<option value='day'></option> <option value='day'></option>
<option value='time'>시간</option> <option value='one-day'>시간</option>
</CustomInput> </CustomInput>
</div> </div>
{searchType.dateType === 'month' || {searchType.dateType === 'month' ||
searchType.dateType === 'day' || searchType.dateType === 'day' ||
searchType.dateType === 'time' ? ( searchType.dateType === 'one-day' ? (
<> <>
<div className='select-date'> <div className='select-date'>
<CustomInput <CustomInput
@ -389,7 +440,7 @@ export default function FlightContainer({
</CustomInput> </CustomInput>
</div> </div>
{searchType.dateType === 'day' || {searchType.dateType === 'day' ||
searchType.dateType === 'time' ? ( searchType.dateType === 'one-day' ? (
<div className='select-date'> <div className='select-date'>
<CustomInput <CustomInput
inline inline
@ -412,7 +463,7 @@ export default function FlightContainer({
</CustomInput> </CustomInput>
</div> </div>
) : null} ) : null}
{searchType.dateType === 'time' ? ( {searchType.dateType === 'one-day' ? (
<div className='select-date'> <div className='select-date'>
<CustomInput <CustomInput
inline inline
@ -455,7 +506,9 @@ export default function FlightContainer({
<Col md='4' className='chart-wrap'> <Col md='4' className='chart-wrap'>
<Card> <Card>
<CardHeader className='d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row flex-column'> <CardHeader className='d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row flex-column'>
<CardTitle tag='h4'>{searchType.flightType} TOP5</CardTitle> <CardTitle tag='h4'>
{handlerTitleName(searchType.category)} TOP5
</CardTitle>
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<div style={{ height: '275px' }}> <div style={{ height: '275px' }}>

7
src/containers/statistics/FlightResultContainer.js

@ -106,6 +106,7 @@ export default function ResultContainer({
}; };
const addCommasToNumber = number => { const addCommasToNumber = number => {
if (number === 'NoData') return 0;
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}; };
@ -213,11 +214,11 @@ export default function ResultContainer({
} }
}, },
data2 = { data2 = {
labels: resultSearch?.topData.map(i => i.name), labels: resultSearch.topData.map(i => i.name),
datasets: [ datasets: [
{ {
labels: resultSearch?.topData.map(i => i.name), labels: resultSearch.topData.map(i => i.name),
data: resultSearch?.topData.map(i => i.value), data: resultSearch.topData.map(i => i.value),
// 레드버전 // 레드버전
// backgroundColor: [ // backgroundColor: [
// '#ffe8d1', // '#ffe8d1',

Loading…
Cancel
Save