Browse Source

비행 시물레이션 슬라이드 기능 수정

master
박상현 9 months ago
parent
commit
5fb34289f3
  1. 90
      src/components/analysis/simulation/AnalysisSimulationDetail.js
  2. 22
      src/components/analysis/simulation/AnalysisSimulatorSlider.js
  3. 92
      src/containers/analysis/simulator/AnalysisSimulationContainer.js

90
src/components/analysis/simulation/AnalysisSimulationDetail.js

@ -1,18 +1,47 @@
import { useRTL } from '@hooks/useRTL';
import '@styles/react/libs/noui-slider/noui-slider.scss';
import moment from 'moment';
import React from 'react';
import React, { useRef, useEffect, useState } from 'react';
import { X } from 'react-feather';
import { AiFillCaretRight, AiOutlinePause } from 'react-icons/ai';
import { IoSettings } from 'react-icons/io5';
import ScrollContainer from 'react-indiana-drag-scroll';
import { Badge, Button } from 'reactstrap';
import {
Badge,
Button,
UncontrolledDropdown,
DropdownToggle,
DropdownMenu,
DropdownItem
} from 'reactstrap';
import drone_img from '../../../assets/images/drone.jpg';
import { ReactComponent as Simulation_icon } from '../../../assets/images/simulation_arrow.svg';
import { IMG_PATH } from '../../../configs/constants';
import AnalysisSimulatorSlider from './AnalysisSimulatorSlider';
export const AnalysisSimulationDetail = props => {
// 슬라이드 진행 방향
const [isRtl, setIsRtl] = useRTL();
// 슬라이드 Ref
const scrollContainerRef = useRef();
// 슬라이드 포커스
useEffect(() => {
const focusRes = document.querySelector('.date-num-focus');
const container = scrollContainerRef.current.getElement();
container.scrollTo({
left: focusRes?.offsetLeft - 120,
behavior: 'smooth'
});
}, [props.timeCd]);
// 소수점 6자리에서 반올림 하는 함수
const truncateToSixDecimalPlaces = number => {
const decimalPlaces = 6;
const multiplier = Math.pow(10, decimalPlaces);
return Math.round(number * multiplier) / multiplier;
};
return (
<div>
@ -56,7 +85,7 @@ export const AnalysisSimulationDetail = props => {
<Badge color='primary'>
시작일시
<span className='txt'>
{props.data?.cntrlStDtv
{props.data?.cntrlStDt
? moment(props.data?.cntrlStDt).format(
'MM월DD일 HH:mm:ss'
)
@ -125,9 +154,10 @@ export const AnalysisSimulationDetail = props => {
<div className='simulation-cont-box-list'>
<span className='ti'>좌표(위도/경도)</span>
<span className='txt'>
{props.info?.lon ? props.info?.lon + ' / ' : '-'}
{props.info?.lat}
{props.info?.lon
? truncateToSixDecimalPlaces(props.info?.lon) + ' / '
: '-'}
{truncateToSixDecimalPlaces(props.info?.lat)}
</span>
</div>
<div className='simulation-cont-box-list'>
@ -183,6 +213,48 @@ export const AnalysisSimulationDetail = props => {
<AiOutlinePause size={16} className='' />
)}
</Button.Ripple>
<UncontrolledDropdown direction='up' className='btn-icon'>
<DropdownToggle color='primary'>
<IoSettings size={16} />
</DropdownToggle>
<DropdownMenu
style={{
width: '30px',
display: 'flex',
flexDirection: 'column'
}}
>
<DropdownItem header>재생 속도</DropdownItem>
<DropdownItem
onClick={() => props.setSpeed(1000)}
style={{ cursor: 'pointer' }}
className={props.speed === 1000 ? 'date-num-focus' : ''}
>
보통
</DropdownItem>
<DropdownItem
onClick={() => props.setSpeed(1000 / 2)}
style={{ cursor: 'pointer' }}
className={props.speed === 500 ? 'date-num-focus' : ''}
>
2배속
</DropdownItem>
<DropdownItem
onClick={() => props.setSpeed(1000 / 4)}
style={{ cursor: 'pointer' }}
className={props.speed === 250 ? 'date-num-focus' : ''}
>
4배속
</DropdownItem>
<DropdownItem
onClick={() => props.setSpeed(1000 / 8)}
style={{ cursor: 'pointer' }}
className={props.speed === 125 ? 'date-num-focus' : ''}
>
8배속
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
<AnalysisSimulatorSlider
direction={isRtl === true ? 'rtl' : 'ltr'}
count={props.dronLength}
@ -192,7 +264,11 @@ export const AnalysisSimulationDetail = props => {
/>
</div>
<div className='simulation-date'>
<ScrollContainer className='scroll-container' hideScrollbars={false}>
<ScrollContainer
className='scroll-container'
ref={scrollContainerRef}
hideScrollbars={false}
>
<div className='simulation-date-cont'>
<div>
<div className='simulation-date-cont-ti'>

22
src/components/analysis/simulation/AnalysisSimulatorSlider.js

@ -8,21 +8,22 @@ const AnalysisSimulatorSlider = ({
setSliderCount,
countArray
}) => {
// hh:mm 형식으로 바꿔주는 코드
function convertToTimeFormat(number) {
// 시간과 분 계산
const hours = Math.floor(number / 60);
const minutes = Math.floor(number % 60);
const convertToTimeFormat = number => {
// 시간, 분, 초 계산
const hours = Math.floor(number / 3600);
const minutes = Math.floor((number % 3600) / 60);
const seconds = Math.floor(number % 60);
// 2자리 숫자로 포맷팅
const formattedHours = String(hours).padStart(2, '0');
const formattedMinutes = String(minutes).padStart(2, '0');
const formattedSeconds = String(seconds).padStart(2, '0');
// 시간 문자열 생성
const timeString = `${formattedHours}:${formattedMinutes}`;
const timeString = `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
return timeString;
}
};
// 슬라이더 값이 바뀔 때마다 실행되는 함수
const colorOptions = {
@ -55,9 +56,10 @@ const AnalysisSimulatorSlider = ({
},
onChange: e => {
function timeStringToMinutes(timeString) {
const [hours, minutes] = timeString.split(':').map(Number);
const totalMinutes = hours * 60 + minutes;
return totalMinutes.toString();
const [hours, minutes, seconds] = timeString.split(':').map(Number);
const totalSeconds = hours * 3600 + minutes * 60 + seconds;
return totalSeconds.toString();
}
setSliderCount(e.map(timeStringToMinutes));

92
src/containers/analysis/simulator/AnalysisSimulationContainer.js

@ -1,5 +1,5 @@
import moment from 'moment';
import { useEffect, useState, useCallback } from 'react';
import { useEffect, useState, useCallback, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { AnalysisSimulationDetail } from '../../../components/analysis/simulation/AnalysisSimulationDetail';
import { AnalysisSimulationMenu } from '../../../components/analysis/simulation/AnalysisSimulationMenu';
@ -61,6 +61,14 @@ export const AnalysisSimulationContainer = props => {
minVal: 0
});
// 재생 속도 배속
const [speed, setSpeed] = useState(1000);
const [currentSpeed, setCurrentSpeed] = useState(1000);
// 타이머 Ref 전역
const timerRef = useRef(null);
const dispatch = useDispatch();
// 드론 갯수
@ -82,38 +90,49 @@ export const AnalysisSimulationContainer = props => {
);
setCountArray(countCheck);
const timer = setInterval(() => {
if (playCount == log.length) {
playCount = 0;
clearInterval(timer);
setIsPlay(false);
}
setInfo({ ...log[playCount], playCount, playCounts });
if (log[playCount]?.srvrRcvDt) {
setTimeCd(moment(log[playCount]?.srvrRcvDt).format('HH:mm'));
}
timer(isPlay, log);
if (speed !== currentSpeed) {
clearInterval(timerRef.currnet);
setCurrentSpeed(speed);
}
return () => clearInterval(timerRef.current);
}
}, [isPlay, log, speed]);
// 타이머 로직 함수
const timer = (isPlay, log) => {
timerRef.current = setInterval(() => {
if (playCount == log.length) {
playCount = 0;
clearInterval(timerRef.current);
setIsPlay(false);
}
setInfo({ ...log[playCount], playCount, playCounts });
if (log[playCount]?.srvrRcvDt) {
setTimeCd(moment(log[playCount]?.srvrRcvDt).format('HH:mm'));
}
playCounts = moment(log[playCount]?.srvrRcvDt).diff(
moment(log[0]?.srvrRcvDt),
'seconds'
);
playCounts = moment(log[playCount]?.srvrRcvDt).diff(
setDronLength(
moment(log[log.length - 1]?.srvrRcvDt).diff(
moment(log[0]?.srvrRcvDt),
'seconds'
);
setDronLength(
moment(log[log.length - 1]?.srvrRcvDt).diff(
moment(log[0]?.srvrRcvDt),
'seconds'
)
);
playCount++;
}, 1000);
return () => clearInterval(timer);
}
}, [isPlay, log]);
)
);
playCount++;
}, speed);
};
//
// 새 리스트 선택시 초기화
useEffect(() => {
if (isPlay) {
setSpeed(1000);
setCurrentSpeed(1000);
setInfo({ ...log[playCount], playCount, playCounts });
setIsPlay(false);
}
@ -165,23 +184,6 @@ export const AnalysisSimulationContainer = props => {
if (log) {
setInfo({ ...log[playCount], playCount: 0 });
}
// let arrDate = log?.map(date => {
// const dateval = date.srvrRcvDt;
// if (dateval) {
// return Number(moment(dateval).format('DDHHmmss'));
// } else {
// return 0;
// }
// });
// setSliderVal({
// minVal: Math.min.apply(null, arrDate),
// maxVal: Math.max.apply(null, arrDate)
// });
// let maxDate = log.map(date => {
// return Math.max(date.srvrRcvDt);
// });
// let maxDate;
}, [log]);
// 검색 헨들러
@ -305,6 +307,8 @@ export const AnalysisSimulationContainer = props => {
setOpenReportList={handlerOpenReportList}
dronLength={dronLength}
countArray={countArray}
setSpeed={setSpeed}
speed={speed}
/>
<AnalysisSimulationPolyline
data={log}

Loading…
Cancel
Save