Skip to content

Commit

Permalink
Merge pull request #11 from renanrms/time-window-control
Browse files Browse the repository at this point in the history
Time window control
  • Loading branch information
renanrms authored Oct 24, 2023
2 parents c003bde + 930af0c commit caef618
Show file tree
Hide file tree
Showing 14 changed files with 109 additions and 19 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ Todas as alterações notáveis neste projeto serão documentadas neste arquivo.
O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.0/),
e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR/spec/v2.0.0.html).

## [0.9.0] - 2023-10-24

### Adicionado

- Controle da janela de tempo para o experimento. Agora são exportadas apenas as medidas mais recentes, na janela de tempo definida. O intervalo de medidas exibidas segue o tamanho da janela até um limite máximo para evitar lentidão na renderização.

## [0.8.1] - 2023-10-03

### Alterado
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ftrlab",
"productName": "FTRLab",
"version": "0.8.1",
"version": "0.9.0",
"description": "Uma aplicação desktop para um sistema de aquisição de dados em física experimental",
"main": "./out/main/index.js",
"author": {
Expand Down
19 changes: 13 additions & 6 deletions src/main/ipc/handlers/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,23 +161,30 @@ export function configureIpcHandlers(devicesController: DevicesController) {
const sensor: Sensor = (await SensorModel.findByPk(request.sensorId))
?.dataValues

const maxTimestamp: number = await MeasurementModel.max('timestamp', {
where: {
sensorId: sensor.id,
},
})

const measurements: Measurement[] = (
await MeasurementModel.findAll({
where: {
sensorId: request.sensorId,
sensorId: sensor.id,
timestamp: {
[Op.gte]: maxTimestamp - request.timeRange,
},
},
order: [['timestamp', 'ASC']],
})
).map((model) => model.dataValues)
).map((measurementM) => transformToRelativeTime(measurementM.dataValues))

const fileHeader = `t, ${sensor.quantity}`

const fileBody = measurements
.sort((a, b) => a.timestamp - b.timestamp)
.map(
(measurement) =>
`${(measurement.timestamp - startTime).toFixed(6)}, ${
measurement.value
}`,
`${measurement.timestamp.toFixed(6)}, ${measurement.value}`,
)
.join('\n')

Expand Down
13 changes: 11 additions & 2 deletions src/renderer/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import './styles/global.css'

import { useState } from 'react'

import { Header } from './components/Header'
import { ReactQueryProvider } from './components/providers/ReactQueryProvider'
import { ThemeProvider } from './components/providers/ThemeProvider'
import { Sidebar } from './components/Sidebar'
import { useDevices } from './features/devices/hooks/useDevices'
import { ChartsArea } from './features/measurements/components/ChartsArea'
import { maxDisplayedTimeRange } from './features/measurements/constants/maxDisplayedTimeRange'
import { useMeasurements } from './features/measurements/hooks/useMeasurements'

export function App() {
const [timeRange, setTimeRange] = useState<number>(maxDisplayedTimeRange)
const devices = useDevices()
const { sensorMeasurements, clearMeasurements } = useMeasurements()
const { sensorMeasurements, clearMeasurements } = useMeasurements(timeRange)

return (
<ReactQueryProvider>
Expand All @@ -24,10 +28,15 @@ export function App() {
}}
>
<Header clearMeasurements={clearMeasurements}></Header>
<Sidebar devices={devices}></Sidebar>
<Sidebar
devices={devices}
timeRange={timeRange}
setTimeRange={setTimeRange}
></Sidebar>
<ChartsArea
devices={devices}
sensorMeasurements={sensorMeasurements}
timeRange={timeRange}
></ChartsArea>
</div>
</ThemeProvider>
Expand Down
17 changes: 13 additions & 4 deletions src/renderer/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Dispatch, SetStateAction } from 'react'

import { DeviceCard } from '@renderer/features/devices/components/DeviceCard'
import { devicePriorityCompare } from '@renderer/features/devices/utils/deviceOrderingPriority'
import { ControlCard } from '@renderer/features/measurements/components/ControlCard'
import { Device } from '@shared/types/Device'

import { DeviceCard } from '../features/devices/components/DeviceCard'

interface SidebarProps {
devices: Array<Device>
timeRange: number
setTimeRange: Dispatch<SetStateAction<number>>
}

export function Sidebar(props: SidebarProps) {
Expand All @@ -15,8 +19,13 @@ export function Sidebar(props: SidebarProps) {
gridArea: 'aside',
}}
>
{props.devices.sort(devicePriorityCompare).map((device, index) => (
<DeviceCard device={device} key={index}></DeviceCard>
<ControlCard
timeRange={props.timeRange}
setTimeRange={props.setTimeRange}
/>

{props.devices.sort(devicePriorityCompare).map((device) => (
<DeviceCard device={device} key={device.id}></DeviceCard>
))}
</aside>
)
Expand Down
2 changes: 2 additions & 0 deletions src/renderer/src/features/measurements/components/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface ChartProps {
YAxis: { key: string; name: string }
data: Object[]
sensor: Sensor
timeRange: number
}

export function Chart(props: ChartProps) {
Expand Down Expand Up @@ -116,6 +117,7 @@ export function Chart(props: ChartProps) {
onClick={() => {
window.api.measurements.export({
sensorId: props.sensor.id,
timeRange: props.timeRange,
})
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Chart } from './Chart'
interface ChartContainerProps {
sensor: Sensor
measurements: Measurement[]
timeRange: number
}

export function ChartContainer(props: ChartContainerProps) {
Expand All @@ -32,6 +33,7 @@ export function ChartContainer(props: ChartContainerProps) {
YAxis={serie.YAxis}
data={serie.data}
sensor={props.sensor}
timeRange={props.timeRange}
></Chart>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ChartContainer } from './ChartContainer'
interface ChartsAreaProps {
devices: Device[]
sensorMeasurements: MeasurementsBySensor
timeRange: number
}

export function ChartsArea(props: ChartsAreaProps) {
Expand All @@ -28,6 +29,7 @@ export function ChartsArea(props: ChartsAreaProps) {
sensor={sensor}
measurements={props.sensorMeasurements[sensor.id]!}
key={sensor.id}
timeRange={props.timeRange}
></ChartContainer>
))}
</main>
Expand Down
35 changes: 35 additions & 0 deletions src/renderer/src/features/measurements/components/ControlCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Dispatch, SetStateAction } from 'react'

import { Slider } from '@mui/material'

import { maxDisplayedTimeRange } from '../constants/maxDisplayedTimeRange'
import { formatTime } from '../utils/formatTime'

interface ControlCardProps {
timeRange: number
setTimeRange: Dispatch<SetStateAction<number>>
}

export function ControlCard(props: ControlCardProps) {
return (
<div className="w-full p-4 mb-4 border border-neutral-90 dark:border-neutral-30 rounded-md flex flex-col items-start justify-between bg-neutral-100 dark:bg-background text-on-background">
<p className="mb-1">
Janela de tempo:{' '}
<span className="text-sm">{formatTime(props.timeRange)}</span>
</p>
<Slider
defaultValue={maxDisplayedTimeRange}
step={0.1}
min={1}
max={Math.log2(24 * 60 * 60)}
valueLabelFormat={(value) => `${value} s`}
valueLabelDisplay="auto"
scale={(value) => Math.floor(2 ** value)}
value={Math.log2(props.timeRange)}
onChange={(event, value) => {
props.setTimeRange(2 ** (value as number))
}}
/>
</div>
)
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const maxDisplayedTimeRange = 8
14 changes: 9 additions & 5 deletions src/renderer/src/features/measurements/hooks/useMeasurements.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { useEffect, useState } from 'react'

import { defaultDisplayedTimeRange } from '@renderer/features/measurements/constants/defaultDisplayedTimeRange'
import { maxDisplayedTimeRange } from '@renderer/features/measurements/constants/maxDisplayedTimeRange'
import { Measurement, MeasurementsBySensor } from '@shared/types/Measurement'

import { transformToRelativeTime } from '../../devices/utils/transformToRelativeTime'

export function useMeasurements() {
export function useMeasurements(timeRange: number) {
const [sensorMeasurements, setSensorMeasurements] =
useState<MeasurementsBySensor>({})

useEffect(() => {
const displayedTimeRange =
timeRange <= maxDisplayedTimeRange ? timeRange : maxDisplayedTimeRange
window.api.measurements
.findLastByDevice({ timeRange: defaultDisplayedTimeRange })
.findLastByDevice({
timeRange: displayedTimeRange,
})
.then(({ measurementsBySensor }) => {
setSensorMeasurements(measurementsBySensor)
})
Expand Down Expand Up @@ -40,7 +44,7 @@ export function useMeasurements() {

// Filtra para manter apenas as medições mais recentes
const thresholdTimestamp = Math.floor(
newSensorState.at(-1)!.timestamp - defaultDisplayedTimeRange,
newSensorState.at(-1)!.timestamp - displayedTimeRange,
)
const startIndex = newSensorState.findIndex(
(measurement) => measurement.timestamp > thresholdTimestamp,
Expand All @@ -57,7 +61,7 @@ export function useMeasurements() {
)

return removeListener
}, [])
}, [timeRange])

const clearMeasurements = async () => {
await window.api.measurements.deleteAll()
Expand Down
13 changes: 13 additions & 0 deletions src/renderer/src/features/measurements/utils/formatTime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function formatTime(t: number) {
const hours = Math.floor(t / 3600)
const minutes = Math.floor((t - 3600 * hours) / 60)
const seconds = Math.floor((t - 3600 * hours - 60 * minutes) % 60)

if (hours > 0) {
return `${hours}h ${minutes}min`
} else if (minutes > 0) {
return `${minutes}min ${seconds}s`
} else {
return `${seconds}s`
}
}
1 change: 1 addition & 0 deletions src/shared/types/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ export interface UpdateDeviceSettingsRequest {

export interface ExportMeasurementsRequest {
sensorId: SensorId
timeRange: number
}

0 comments on commit caef618

Please sign in to comment.