Files
MSE-PI-E2EEDA-Plein-de-eeee…/report/resources/measures/plot_measures.typ

149 lines
4.2 KiB
Typst

#import "@preview/lilaq:0.6.0" as lq
#let epoch = datetime(year: 1970, month: 01, day: 01, hour: 0, minute: 0, second: 0)
#let unix-to-datetime(stamp) = epoch + duration(seconds: int(stamp))
#let datetime-to-unix(dt) = int((dt - epoch).seconds())
#let parse-iso-datetime(s) = {
let parts = s.split("T")
let date-part = parts.at(0).split("-").map(int)
let time-part = parts.at(1).split(":").map(int)
datetime(
year: date-part.at(0),
month: date-part.at(1),
day: date-part.at(2),
hour: time-part.at(0),
minute: time-part.at(1),
second: time-part.at(2)
)
}
#let window-regions(filtered-windows, filtered-times-dt) = {
let regions = ()
let i = 0
while i < filtered-windows.len() {
let start-time = filtered-times-dt.at(i)
let status = filtered-windows.at(i)
let j = i
// Find end of consecutive region with same status
while j < filtered-windows.len() and filtered-windows.at(j) == status {
j += 1
}
let end-time = if j < filtered-times-dt.len() {
filtered-times-dt.at(j - 1)
} else {
filtered-times-dt.at(filtered-times-dt.len() - 1)
}
// Add small duration to end time to make rectangle visible
let end-time-dt = end-time + duration(seconds: 60)
let fill-color = if status == 0 { none } else { rgb("#e8e8e8") }
regions.push(lq.rect(
start-time,
0%,
width: end-time-dt - start-time,
height: 100%,
fill: fill-color,
stroke: none,
z-index: 1
))
i = j
}
regions
}
#let plot_co2(path, start-date, stop-date) = [
#let start-unix = datetime-to-unix(start-date)
#let stop-unix = datetime-to-unix(stop-date)
#let data = lq.load-txt(
read(path),
header: true,
converters: (time: parse-iso-datetime, rest: float)
)
#let times = data.at("time")
#let co2s = data.at("co2")
#let windows = data.at("windows")
// Filter data by date range
#let filtered-indices = range(times.len()).filter(i => {
let t = times.at(i)
t >= start-date and t <= stop-date
})
#let filtered-times-dt = filtered-indices.map(i => times.at(i))
#let filtered-co2s = filtered-indices.map(i => co2s.at(i))
#let filtered-windows = filtered-indices.map(i => windows.at(i))
#let regions = window-regions(filtered-windows, filtered-times-dt)
#lq.diagram(
width: 100%,
height: 7cm,
title: [CO2 Level over Time],
xlabel: [Time],
ylabel: [CO2 Level (ppm)],
yaxis: (lim: (400, 1500), exponent: 0),
xaxis: (format-ticks: lq.tick-format.datetime.with(
format-offset: (datetimes, period: none) => none,
)),
..regions,
lq.plot(filtered-times-dt, filtered-co2s, label: [CO2 Level], color: rgb("#388e3c"))
)
]
#let plot_temp_hum(path, start-date, stop-date) = [
#let start-unix = datetime-to-unix(start-date)
#let stop-unix = datetime-to-unix(stop-date)
#let data = lq.load-txt(
read(path),
header: true,
converters: (time: parse-iso-datetime, rest: float)
)
#let times = data.at("time")
#let temps = data.at("temperature")
#let hums = data.at("humidity")
#let windows = data.at("windows")
// Filter data by date range
#let filtered-indices = range(times.len()).filter(i => {
let t = times.at(i)
t >= start-date and t <= stop-date
})
#let filtered-times-dt = filtered-indices.map(i => times.at(i))
#let filtered-temps = filtered-indices.map(i => temps.at(i))
#let filtered-hums = filtered-indices.map(i => hums.at(i))
#let filtered-times-dt = filtered-indices.map(i => times.at(i))
#let filtered-windows = filtered-indices.map(i => windows.at(i))
#let regions = window-regions(filtered-windows, filtered-times-dt)
#lq.diagram(
width: 100%,
height: 7cm,
title: [Temperature and Humidity over Time],
xlabel: [Time],
ylabel: [Temperature (°C)],
yaxis: (lim: (20, 35)),
xaxis: (format-ticks: lq.tick-format.datetime.with(
format-offset: (datetimes, period: none) => none,
)),
..regions,
lq.plot(filtered-times-dt, filtered-temps, label: [Temperature], color: rgb("#d32f2f")),
lq.yaxis(
position: right,
label: [Humidity (%)],
lim: (30, 55),
lq.plot(filtered-times-dt, filtered-hums, label: [Humidity], color: rgb("#1976d2"))
)
)
]