diff --git a/src/App.tsx b/src/App.tsx index c5331b3..ab6a8d6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -36,6 +36,7 @@ import Info from './pages/Info'; import Hub from './pages/Hub'; import { FormRoles } from './pages/auth/Login'; +import 'uplot/dist/uPlot.min.css'; import 'react-perfect-scrollbar/dist/css/styles.css'; import './css/App.less'; diff --git a/src/components/Logs/LogCanvas.tsx b/src/components/Logs/LogCanvas.tsx index 5b7d355..66766b7 100644 --- a/src/components/Logs/LogCanvas.tsx +++ b/src/components/Logs/LogCanvas.tsx @@ -19,8 +19,6 @@ import { Colors } from '../../utils/colors'; import touchZoomPlugin from '../../utils/uPlot/touchZoomPlugin'; import { isNumber } from '../../utils/tune/expression'; -import 'uplot/dist/uPlot.min.css'; - const { useBreakpoint } = Grid; export interface SelectedField { diff --git a/src/components/TriggerLogs/CompositeCanvas.tsx b/src/components/TriggerLogs/CompositeCanvas.tsx index 8f0e731..a292cac 100644 --- a/src/components/TriggerLogs/CompositeCanvas.tsx +++ b/src/components/TriggerLogs/CompositeCanvas.tsx @@ -9,6 +9,7 @@ import touchZoomPlugin from '../../utils/uPlot/touchZoomPlugin'; import LandscapeNotice from '../Tune/Dialog/LandscapeNotice'; import { CompositeLogEntry } from '../../utils/logs/TriggerLogsParser'; import { Colors } from '../../utils/colors'; +import LogsPagination from './LogsPagination'; const { useBreakpoint } = Grid; @@ -16,6 +17,8 @@ const scale = 2; const secondaryTranslate = 2.6; const primaryTranslate = 1; +const PAGE_SIZE = 500; + interface Props { data: CompositeLogEntry[]; width: number; @@ -26,6 +29,8 @@ const CompositeCanvas = ({ data, width, height }: Props) => { const { sm } = useBreakpoint(); const [options, setOptions] = useState(); const [plotData, setPlotData] = useState(); + const [indexFrom, setIndexFrom] = useState(0); + const [indexTo, setIndexTo] = useState(PAGE_SIZE); useEffect(() => { const xData: number[] = []; @@ -33,30 +38,32 @@ const CompositeCanvas = ({ data, width, height }: Props) => { const primary: (number | null)[] = []; const sync: (number | null)[] = []; - data.forEach((entry, index) => { - const prevSecondary = data[index - 1] ? data[index - 1].secondaryLevel : 0; - const currentSecondary = (entry.secondaryLevel + secondaryTranslate) * scale; + data + .slice(indexFrom, indexTo) + .forEach((entry, index) => { + const prevSecondary = data[index - 1] ? data[index - 1].secondaryLevel : 0; + const currentSecondary = (entry.secondaryLevel + secondaryTranslate) * scale; - const prevPrimary = data[index - 1] ? data[index - 1].primaryLevel : 0; - const currentPrimary = (entry.primaryLevel + primaryTranslate) * scale; + const prevPrimary = data[index - 1] ? data[index - 1].primaryLevel : 0; + const currentPrimary = (entry.primaryLevel + primaryTranslate) * scale; - const prevSync = data[index - 1] ? data[index - 1].sync : 0; - const currentSync = entry.sync; + const prevSync = data[index - 1] ? data[index - 1].sync : 0; + const currentSync = entry.sync; - // base data - xData.push(index); - secondary.push(currentSecondary); - primary.push(currentPrimary); - sync.push(currentSync); - - // make it square - if (prevSecondary !== currentSecondary || prevPrimary !== currentPrimary || prevSync !== currentSync) { + // base data + xData.push(index); secondary.push(currentSecondary); primary.push(currentPrimary); sync.push(currentSync); - xData.push(index + 1); - } - }); + + // make it square + if (prevSecondary !== currentSecondary || prevPrimary !== currentPrimary || prevSync !== currentSync) { + secondary.push(currentSecondary); + primary.push(currentPrimary); + sync.push(currentSync); + xData.push(index + 1); + } + }); setPlotData([ xData, @@ -109,14 +116,23 @@ const CompositeCanvas = ({ data, width, height }: Props) => { }, plugins: [touchZoomPlugin()], }); - }, [data, width, height, sm]); + }, [data, width, height, sm, indexFrom, indexTo]); if (!sm) { return ; } return ( - + { + setIndexFrom(newIndexFrom); + setIndexTo(newIndexTo); + }} + pageSize={PAGE_SIZE} + total={data.length} + > + + ); }; diff --git a/src/components/TriggerLogs/LogsPagination.tsx b/src/components/TriggerLogs/LogsPagination.tsx new file mode 100644 index 0000000..ab526a1 --- /dev/null +++ b/src/components/TriggerLogs/LogsPagination.tsx @@ -0,0 +1,41 @@ +import { Pagination } from 'antd'; +import { + ReactNode, + useState, +} from 'react'; + +interface LogsPaginationProps { + children: ReactNode; + total: number; + pageSize: number; + onChange: (indexFrom: number, indexTo: number) => void; +} + +const LogsPagination = (props: LogsPaginationProps) => { + const [page, setPage] = useState(1); + const { children, total, pageSize, onChange } = props; + + const changePage = (newPage: number) => { + setPage(newPage); + const indexFrom = (newPage - 1) * pageSize; + const indexTo = indexFrom + pageSize; + onChange(indexFrom, indexTo); + }; + + return ( +
+
+ +
+ {children} +
+ ); +}; + +export default LogsPagination; diff --git a/src/components/TriggerLogs/ToothCanvas.tsx b/src/components/TriggerLogs/ToothCanvas.tsx index 4253c50..6d2a265 100644 --- a/src/components/TriggerLogs/ToothCanvas.tsx +++ b/src/components/TriggerLogs/ToothCanvas.tsx @@ -12,8 +12,7 @@ import { EntryType, } from '../../utils/logs/TriggerLogsParser'; import { Colors } from '../../utils/colors'; - -import 'uplot/dist/uPlot.min.css'; +import LogsPagination from './LogsPagination'; const { useBreakpoint } = Grid; const { bars } = uPlot.paths; @@ -24,23 +23,27 @@ interface Props { height: number; }; +const PAGE_SIZE = 500; + const ToothCanvas = ({ data, width, height }: Props) => { const { sm } = useBreakpoint(); const [options, setOptions] = useState(); const [plotData, setPlotData] = useState(); + const [indexFrom, setIndexFrom] = useState(0); + const [indexTo, setIndexTo] = useState(PAGE_SIZE); useEffect(() => { const xData: number[] = []; const yData: (number | null)[] = []; - // NOTE: temporary limit to 500 points - // TODO: add pagination - data.slice(0, 500).forEach((entry: ToothLogEntry, index) => { - if (entry.type === EntryType.TRIGGER) { - yData.push(entry.toothTime); - xData.push(index); - } - }); + data + .slice(indexFrom, indexTo) + .forEach((entry: ToothLogEntry, index) => { + if (entry.type === EntryType.TRIGGER) { + yData.push(entry.toothTime); + xData.push(index); + } + }); setPlotData([xData, yData]); @@ -80,14 +83,23 @@ const ToothCanvas = ({ data, width, height }: Props) => { }, plugins: [touchZoomPlugin()], }); - }, [data, width, height, sm]); + }, [data, width, height, sm, indexFrom, indexTo]); if (!sm) { return ; } return ( - + { + setIndexFrom(newIndexFrom); + setIndexTo(newIndexTo); + }} + pageSize={PAGE_SIZE} + total={data.length} + > + + ); };