Browse Source

대시보드(드론 현황) 작업 및 chart empty 처리

pull/2/head
김장현 10 months ago
parent
commit
e13120e08a
  1. 146
      src/components/dashboard/DashboardStcsArea.js
  2. 87
      src/components/dashboard/DashboardStcsDay.js
  3. 31
      src/containers/main/dash/MainDashContainer.js
  4. 5
      src/modules/main/dash/apis/mainDashApi.ts
  5. 13
      src/modules/main/dash/models/mainDashModel.ts
  6. 23
      src/modules/main/dash/sagas/mainDashSaga.ts

146
src/components/dashboard/DashboardStcsArea.js

@ -40,82 +40,75 @@ const options = {
}
};
const arrColors = [
successColorShade,
warningLightColor,
primaryColorShade,
yellowColor,
blueColor
];
const arrColorsClass = [
'successColorShade',
'warningLightColor',
'primaryColorShade',
'yellowColor',
'blueColor'
];
const titles = {
droneStatus: '드론 현황',
flightsRegion: 'TOP5 지역 별 비행횟수 통계'
};
export const DashboardStcsArea = props => {
export const DashboardStcsArea = ({ data, title, setStartDate, startDate }) => {
const [chartData, setChartData] = useState({});
const arrColors = [
successColorShade,
warningLightColor,
primaryColorShade,
yellowColor,
blueColor
];
const arrColorsClass = [
'successColorShade',
'warningLightColor',
'primaryColorShade',
'yellowColor',
'blueColor'
];
useEffect(() => {
chartDataInit();
}, [data]);
const chartDataInit = () => {
let arrArea = [];
let arrValue = [];
if (data.length > 0) {
let arrArea = [];
let arrValue = [];
props.data?.map(item => {
arrArea.push(item.typeCd);
arrValue.push(item.count);
});
data?.map(item => {
arrArea.push(item.typeCd);
arrValue.push(item.count);
});
setChartData({
labels: arrArea,
datasets: [
{
data: arrValue,
backgroundColor: arrColors,
borderWidth: 0,
pointStyle: 'rectRounded'
}
]
});
setChartData({
labels: arrArea,
datasets: [
{
data: arrValue,
backgroundColor: arrColors,
borderWidth: 0,
pointStyle: 'rectRounded'
}
]
});
} else {
setChartData({});
}
};
useEffect(() => {
chartDataInit();
}, [props.data]);
return (
<Card>
<CardHeader className=''>
<div className='w-100 d-flex justify-content-between'>
<CardTitle tag='h4'>{titles[`${props.title}`]}</CardTitle>
{/* <div className='d-flex align-items-center'>
<Calendar size={14} />
<Flatpickr
options={{
mode: 'single',
dateFormat: "Y-m-d",
defaultDate: ['today'],
}}
className='form-control flat-picker bg-transparent border-0 shadow-none'
/>
</div> */}
<CardTitle tag='h4'>{titles[`${title}`]}</CardTitle>
<div className='d-flex align-items-center'>
{props.title === 'flightsRegion' && (
{title === 'flightsRegion' && (
<>
<div className='datepicker-border-sm'>
<div className='datepicker-custom'>
<Calendar size={14} />
<DatePicker
locale={ko}
selected={props.startDate}
onChange={date => props.setStartDate(date)}
selected={startDate}
onChange={date => setStartDate(date)}
dateFormat='yyy / MMMM'
showMonthYearPicker
showFullMonthYearPicker
@ -134,32 +127,16 @@ export const DashboardStcsArea = props => {
</CardHeader>
<CardBody>
<div style={{ height: '275px' }}>
<Doughnut
data={chartData}
options={options}
height={275}
plugins={{
afterDraw: function (chart) {
let ctx = chart.chart.ctx;
let width = chart.chart.width;
let height = chart.chart.height;
chart.clear();
ctx.save();
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(
'표시할 데이터가 없습니다.',
width / 2,
height / 2
);
ctx.restore();
}
}}
/>
{Object.keys(chartData).length > 0 ? (
<Doughnut data={chartData} options={options} height={275} />
) : (
<div className='d-flex justify-content-center align-items-center h-100'>
<p>표시할 데이터가 없습니다.</p>
</div>
)}
</div>
<div className='doughnut-chart-list'>
{props.data?.map((item, index) => {
{data?.map((item, index) => {
return (
<div key={index}>
<div className='doughnut-chart-list-ti'>
@ -167,23 +144,6 @@ export const DashboardStcsArea = props => {
<span className='ti'>{item.typeCd}</span>
<span className='ti'>({item.count})</span>
</div>
{/* <div className='doughnut-chart-list-ti'>
<span className='dot-icon warningLightColor'></span>
<span className='ti'>인천광역시</span>
</div>
<div className='doughnut-chart-list-ti'>
<span className='dot-icon primaryColorShade'></span>
<span className='ti'>충청북도</span>
</div>
<div className='doughnut-chart-list-ti'>
<span className='dot-icon yellowColor'></span>
<span className='ti'>세종시</span>
</div>
<div className='doughnut-chart-list-ti'>
<span className='dot-icon blueColor'></span>
<span className='ti'>제주도</span>
</div> */}
</div>
);
})}

87
src/components/dashboard/DashboardStcsDay.js

@ -1,7 +1,7 @@
import 'react-datepicker/dist/react-datepicker.css';
import { ko } from 'date-fns/esm/locale';
import { Plus } from 'react-feather';
import { useEffect, useState } from 'react';
import { useEffect, useState, useRef } from 'react';
import { Bar } from 'react-chartjs-2';
import DatePicker from 'react-datepicker';
import { Calendar } from 'react-feather';
@ -61,7 +61,7 @@ const options = {
},
ticks: {
stepSize: 1,
// min: 0,
min: 0,
// max: 400,
fontColor: '#6e6b7bs'
}
@ -73,33 +73,36 @@ const options = {
export const DashboardStcsDay = ({ startDate, setStartDate, data }) => {
const [chartData, setChartData] = useState({});
const chartDataInit = () => {
let arrDay = [];
let arrValue = [];
useEffect(() => {
chartDataInit();
}, [data]);
data?.map(item => {
arrDay.push(item.typeCd);
arrValue.push(item.count);
});
const chartDataInit = () => {
if (data.length > 0) {
let arrDay = [];
let arrValue = [];
setChartData({
labels: arrDay,
data.map(item => {
arrDay.push(item.typeCd);
arrValue.push(item.count);
});
datasets: [
{
data: arrValue,
backgroundColor: successColorShade,
borderColor: 'transparent',
barThickness: 15
}
]
});
setChartData({
labels: [...arrDay],
datasets: [
{
data: [...arrValue],
backgroundColor: successColorShade,
borderColor: 'transparent',
barThickness: 15
}
]
});
} else {
setChartData({});
}
};
useEffect(() => {
chartDataInit();
}, [data]);
return (
<Card>
<CardHeader className='d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row flex-column'>
@ -112,7 +115,9 @@ export const DashboardStcsDay = ({ startDate, setStartDate, data }) => {
<DatePicker
locale={ko}
selected={startDate}
onChange={date => setStartDate(date)}
onChange={date => {
setStartDate(date);
}}
dateFormat='yyy / MMMM'
showMonthYearPicker
showFullMonthYearPicker
@ -129,31 +134,13 @@ export const DashboardStcsDay = ({ startDate, setStartDate, data }) => {
</CardHeader>
<CardBody>
<div style={{ height: '400px' }}>
<Bar
data={chartData}
options={options}
height={400}
plugins={{
afterDraw: function (chart) {
if (data.length <= 0) {
let ctx = chart.chart.ctx;
let width = chart.chart.width;
let height = chart.chart.height;
chart.clear();
ctx.save();
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(
'표시할 데이터가 없습니다.',
width / 2,
height / 2
);
ctx.restore();
}
}
}}
/>
{Object.keys(chartData).length > 0 ? (
<Bar data={chartData} options={options} height={400} />
) : (
<div className='d-flex justify-content-center align-items-center h-100'>
<p>표시할 데이터가 없습니다.</p>
</div>
)}
</div>
</CardBody>
</Card>

31
src/containers/main/dash/MainDashContainer.js

@ -23,6 +23,9 @@ export const MainDashContainer = () => {
state => [state.mainDashState.dashboardData],
shallowEqual
);
const { stcsDayList, stcsAreaList } = useSelector(
state => state.mainDashState
);
const { user } = useSelector(state => state.authState, shallowEqual);
const [dayStartDate, setDayStartDate] = useState(new Date());
const [areaStartDate, setAreaStartDate] = useState(new Date());
@ -60,13 +63,10 @@ export const MainDashContainer = () => {
);
};
const handlerStcsDayParam = useCallback(
date => {
setDayStartDate(date);
handlerStcsDaySearch(date);
},
[dayStartDate]
);
const handlerStcsDayParam = date => {
setDayStartDate(date);
handlerStcsDaySearch(date);
};
const handlerStcsAreaParam = date => {
setAreaStartDate(date);
@ -85,13 +85,9 @@ export const MainDashContainer = () => {
history.push(url);
};
useEffect(() => {
dispatch(
Actions.DASHBOARD_DATA.request({
stcsDay: moment(dayStartDate).format('YYYY-MM')
})
);
// handlerStcsDaySearch(dayStartDate);
// handlerStcsAreaSearch(areaStartDate);
dispatch(Actions.DASHBOARD_DATA.request());
handlerStcsDaySearch(dayStartDate);
handlerStcsAreaSearch(areaStartDate);
// handlerGroupSearch();
// handlerDronSearch();
}, []);
@ -136,7 +132,7 @@ export const MainDashContainer = () => {
<DashboardStcsArea
startDate={areaStartDate}
setStartDate={handlerStcsAreaParam}
// data={stcsAreaList}
data={dashboardData?.dronSituation || []}
title='droneStatus'
/>
</Col>
@ -148,10 +144,9 @@ export const MainDashContainer = () => {
<DashboardStcsDay
startDate={dayStartDate}
setStartDate={handlerStcsDayParam}
data={dashboardData?.stcsDayList || []}
data={stcsDayList || []}
/>
</Col>
<Col lg={4} md={12} className='dashboard-chart'>
{
// top5 지역 별 바행횟수
@ -159,7 +154,7 @@ export const MainDashContainer = () => {
<DashboardStcsArea
startDate={areaStartDate}
setStartDate={handlerStcsAreaParam}
// data={stcsAreaList}
data={stcsAreaList || []}
title='flightsRegion'
/>
</Col>

5
src/modules/main/dash/apis/mainDashApi.ts

@ -8,7 +8,7 @@ export const mainDashAPI = {
addQueryPrefix: true,
arrayFormat: 'repeat'
});
console.log(data);
return await axios.get(`api/main/dash/stcs/day${queryString}`);
},
stcsArea: async (data: string) => {
@ -42,5 +42,8 @@ export const mainDashAPI = {
},
dailyFlightCount: async () => {
return await axios.get('api/main/dash/stcs/dailyflight');
},
dronSituation: async () => {
return await axios.get('api/main/dash/stcs/dron-flight/');
}
};

13
src/modules/main/dash/models/mainDashModel.ts

@ -12,6 +12,17 @@ export enum EDateType {
tomorrow = '명일'
}
export enum EDronStatus {
inFlight = '비행 중',
flightComplete = '비행 완료',
flightWaiting = '비행 대기 중 '
}
export interface IDronSituation {
typeCd: string;
count: number;
}
export interface IDailyFlightPlan {
dateType: string;
plan: number;
@ -61,10 +72,10 @@ export interface DronListData {
}
export interface IDashBoardData {
stcsDayList: StcsDayData[];
dailyFlightWarn: IDailyFlightWarn[];
dailyFlightCount: IDailyFlightCount[];
dailyFlightPlan: IDailyFlightPlan[];
dronSituation: IDronSituation[];
}
export interface IDashBoardRq {

23
src/modules/main/dash/sagas/mainDashSaga.ts

@ -1,5 +1,6 @@
import { call, put, takeEvery, all } from '@redux-saga/core/effects';
import { ActionType } from 'typesafe-actions';
import { EDronStatus } from '../models/mainDashModel';
import * as MessageActions from '../../../comn/message/actions/comnMessageAction';
import * as Actions from '../actions/mainDashAction';
import * as Apis from '../apis/mainDashApi';
@ -121,20 +122,17 @@ function* dashboardData(
action: ActionType<typeof Actions.DASHBOARD_DATA.request>
) {
try {
const params = action.payload;
/*
stcsDayList:
dailyFlightPlan: 일일
dailyFlightCount: 일일
dailyFlighWarn: 일일
*/
const { stcsDayList, dailyFlighWarn, dailyFlightPlan, dailyFlightCount } =
const { dailyFlighWarn, dailyFlightPlan, dailyFlightCount, dronSituation } =
yield all({
stcsDayList: call(Apis.mainDashAPI.stcsDay, { yyyymm: params.stcsDay }),
dailyFlighWarn: call(Apis.mainDashAPI.dailyFlightWarn),
dailyFlightPlan: call(Apis.mainDashAPI.dailyFlightPlan),
dailyFlightCount: call(Apis.mainDashAPI.dailyFlightCount)
dailyFlightCount: call(Apis.mainDashAPI.dailyFlightCount),
dronSituation: call(Apis.mainDashAPI.dronSituation)
});
// if (errorCode) {
@ -150,15 +148,24 @@ function* dashboardData(
// return;
// }
let dronSituationArr: { typeCd: string; count: number }[] = [];
Object.keys(dronSituation.data).forEach(i => {
dronSituationArr.push({
typeCd: EDronStatus[`${i}`],
count: Number(dronSituation.data[i])
});
});
yield put(
Actions.DASHBOARD_DATA.success({
stcsDayList: stcsDayList.data,
dailyFlightWarn: dailyFlighWarn.data.slice(
0,
dailyFlightPlan.data.length - 1
),
dailyFlightCount: dailyFlightCount.data,
dailyFlightPlan: dailyFlightPlan.data
dailyFlightPlan: dailyFlightPlan.data,
dronSituation: dronSituationArr
})
);
} catch (error) {

Loading…
Cancel
Save