This commit is contained in:
David Fencl
2026-06-09 20:45:08 +02:00
parent c4cad149ea
commit c8fe97078d
56 changed files with 50749 additions and 48947 deletions
+38 -18
View File
@@ -200,15 +200,27 @@ const LakeDetail = ({ language, lakeId, windUnit = 'kmh' }: Props) => {
// Outlier/sensor glitch detection
if (level > 0) {
let isGlitch = false;
if (staticConfig && staticConfig.minLevel && staticConfig.maxLevel) {
const minAllowed = staticConfig.minLevel - 5;
const maxAllowed = staticConfig.maxLevel + 5;
if (level < minAllowed || level > maxAllowed) {
// Glitch detected, fallback to last known valid level
level = lastValidLevel !== null ? lastValidLevel : (staticConfig.minLevel + staticConfig.maxLevel) / 2;
} else {
lastValidLevel = level;
isGlitch = true;
}
}
// Check rate of change: sudden spikes/drops
if (!isGlitch && lastValidLevel !== null) {
const isRiver = staticConfig?.type === 'river';
const maxAllowedDelta = isRiver ? 50 : 0.5; // 50 cm for rivers, 0.5 m for reservoirs
if (Math.abs(level - lastValidLevel) > maxAllowedDelta) {
isGlitch = true;
}
}
if (isGlitch) {
// Glitch detected, fallback to last known valid level
level = lastValidLevel !== null ? lastValidLevel : (staticConfig && staticConfig.minLevel && staticConfig.maxLevel ? (staticConfig.minLevel + staticConfig.maxLevel) / 2 : level);
} else {
lastValidLevel = level;
}
@@ -394,15 +406,29 @@ const LakeDetail = ({ language, lakeId, windUnit = 'kmh' }: Props) => {
e.preventDefault();
const isTouchEvent = 'touches' in e;
const currentDomain = axis === 'left'
? (leftCustomDomain || getDefaultLeftDomain())
: (rightCustomDomain || getDefaultRightDomain());
// Calculate the center based on the middle of the actual data values to keep the graph line centered
let dataCenter = (currentDomain[1] + currentDomain[0]) / 2;
if (axis === 'left') {
const levels = chartData.map(d => d.level).filter(v => v !== null && v !== undefined && !isNaN(v));
if (levels.length > 0) {
dataCenter = (Math.min(...levels) + Math.max(...levels)) / 2;
}
} else {
const flows = chartData.flatMap(d => [d.outflow, d.inflow]).filter(v => v !== null && v !== undefined && !isNaN(v));
if (flows.length > 0) {
dataCenter = (Math.min(...flows) + Math.max(...flows)) / 2;
}
}
if (isTouchEvent && e.touches.length === 2) {
const touch1 = e.touches[0];
const touch2 = e.touches[1];
const dist = Math.abs(touch1.clientY - touch2.clientY);
const currentDomain = axis === 'left'
? (leftCustomDomain || getDefaultLeftDomain())
: (rightCustomDomain || getDefaultRightDomain());
const onTouchMove = (moveEvent: TouchEvent) => {
if (moveEvent.touches.length === 2) {
moveEvent.preventDefault(); // Stop native page zooming
@@ -411,10 +437,9 @@ const LakeDetail = ({ language, lakeId, windUnit = 'kmh' }: Props) => {
const currentDist = Math.abs(mTouch1.clientY - mTouch2.clientY);
if (currentDist > 5) {
const factor = dist / currentDist;
const center = (currentDomain[0] + currentDomain[1]) / 2;
const range = currentDomain[1] - currentDomain[0];
const newMin = center - (range * factor) / 2;
const newMax = center + (range * factor) / 2;
const newMin = dataCenter - (range * factor) / 2;
const newMax = dataCenter + (range * factor) / 2;
if (axis === 'left') {
setLeftCustomDomain([newMin, newMax]);
@@ -436,12 +461,7 @@ const LakeDetail = ({ language, lakeId, windUnit = 'kmh' }: Props) => {
}
const startY = isTouchEvent ? e.touches[0].clientY : e.clientY;
const currentDomain = axis === 'left'
? (leftCustomDomain || getDefaultLeftDomain())
: (rightCustomDomain || getDefaultRightDomain());
const initialRange = currentDomain[1] - currentDomain[0];
const center = (currentDomain[1] + currentDomain[0]) / 2;
const onMove = (moveEvent: MouseEvent | TouchEvent) => {
if ('touches' in moveEvent) {
@@ -451,8 +471,8 @@ const LakeDetail = ({ language, lakeId, windUnit = 'kmh' }: Props) => {
const deltaY = clientY - startY;
const factor = Math.pow(2.5, deltaY / 150);
const newMin = center - (initialRange * factor) / 2;
const newMax = center + (initialRange * factor) / 2;
const newMin = dataCenter - (initialRange * factor) / 2;
const newMax = dataCenter + (initialRange * factor) / 2;
if (axis === 'left') {
setLeftCustomDomain([newMin, newMax]);