From fae1f17ba00f54a1eba3a103c28e949a72bba0ad Mon Sep 17 00:00:00 2001 From: acheronfail Date: Mon, 16 Sep 2024 21:47:40 +0930 Subject: [PATCH] noUncheckedIndexedAccess --- src/components/App.svelte | 10 +++--- src/components/Chart.svelte | 71 +++++++++++++++++++------------------ src/components/Map.svelte | 4 +-- tsconfig.json | 3 +- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/components/App.svelte b/src/components/App.svelte index 568f96f..408ae36 100644 --- a/src/components/App.svelte +++ b/src/components/App.svelte @@ -28,7 +28,7 @@ const gpsGaps: number[] = [0]; for (let i = 0; i < rows.length; ++i) { const prev = rows[i - 1]; - const curr = rows[i]; + const curr = rows[i]!; gpsPoints.push([curr.gps_latitude, curr.gps_longitude]); if (prev && curr.time - prev.time > 60) { @@ -42,9 +42,9 @@ // Either way, here we attempt to find the first "good" point and use that instead. // TODO: verify if we need to do this for Floaty-recorded rides for (let i = 0; i < gpsGaps.length; ++i) { - const start = gpsGaps[i]; + const start = gpsGaps[i]!; const end = gpsGaps[i + 1]; - const curr = rows[start]; + const curr = rows[start]!; const guessedGoodValue = rows.slice(start, end).find((row) => { const samePoint = curr.gps_latitude === row.gps_latitude && curr.gps_longitude === row.gps_longitude; return row.gps_accuracy > 0 && !samePoint; @@ -63,7 +63,7 @@ let faultPoints = $derived.by(() => { const points: FaultPoint[] = []; for (let i = 0; i < rows.length; i++) { - const row = rows[i]; + const row = rows[i]!; let fault: string | undefined; if (row.state !== 'riding') { @@ -96,7 +96,7 @@ let gaps: number[] = []; let prev = visibleRows[0]?.index ?? 0; for (let i = 1; i < visibleRows.length; i++) { - const { index } = visibleRows[i]; + const { index } = visibleRows[i]!; if (prev < index - 1) { gaps.push(i); } diff --git a/src/components/Chart.svelte b/src/components/Chart.svelte index 86cf8bf..3e87a49 100644 --- a/src/components/Chart.svelte +++ b/src/components/Chart.svelte @@ -52,7 +52,7 @@ const aggMaxAbs = (acc: number, n: number) => (Math.abs(acc) > Math.abs(n) ? acc : n); let { data, selectedIndex, setSelectedIdx, gapIndices, unit = '', title = '', precision, yAxis }: Props = $props(); - let dataLen = $derived(data[0].values.length); + let dataLen = $derived(data[0]?.values.length ?? 0); assert( data.every(({ values }) => values.length === dataLen), 'All input data lists must be the same length', @@ -65,7 +65,7 @@ let chunkSize = $state(1); /** scaled points representing the data */ let dataPoints = $state(data.map(() => [])); - let dataPointsLen = $derived(dataPoints[0].length); + let dataPointsLen = $derived(dataPoints[0]?.length ?? 0); /** start and end coordinates of where 0 is on the x axis */ let zeroPath = $state<[[number, number], [number, number]] | undefined>(); /** x coordinate of where the vertical line indicator should be */ @@ -143,16 +143,18 @@ const touchXThreshold = 15; let touchStartX = Infinity; - const ontouchstart: TouchEventHandler = (e) => (touchStartX = e.touches[0].clientX); + const ontouchstart: TouchEventHandler = (e) => e.touches[0] && (touchStartX = e.touches[0].clientX); const ontouchmove: TouchEventHandler = (e) => { - const { clientX } = e.touches[0]; - if (touchStartX === Infinity || Math.abs(touchStartX - clientX) > touchXThreshold) { - selectPoint(clientX); - touchStartX = Infinity; + if (e.touches[0]) { + const { clientX } = e.touches[0]; + if (touchStartX === Infinity || Math.abs(touchStartX - clientX) > touchXThreshold) { + selectPoint(clientX); + touchStartX = Infinity; + } } }; - const formatValue = (value: number): string => { + const formatValue = (value: number | undefined): string => { if (typeof value !== 'number' || Number.isNaN(value)) { return ''; } @@ -161,34 +163,33 @@ return `${n}${unit}`; }; - let chartDiv: HTMLDivElement | undefined; - const nodes: HTMLDivElement[] = []; + let chartEl: HTMLDivElement | undefined; + let tooltipEl: HTMLDivElement | undefined; const onCreateTooltip = (el: HTMLDivElement) => { - nodes.push(el); + tooltipEl = el; }; const onCreateContainer = (el: HTMLDivElement) => { - chartDiv = el; + chartEl = el; }; - $effect(() => { - if (selectedDataPointIndex > -1) { - const tooltipEl = nodes[0]; - const container = chartDiv!.parentElement!; - const halfWidth = tooltipEl.offsetWidth / 2; - - const containerRect = container.getBoundingClientRect(); - const chartRect = chartDiv!.getBoundingClientRect(); - const tooltipRect = tooltipEl.getBoundingClientRect(); - - const leftGap = chartRect.left - containerRect.left; - if (tooltipRect.left < containerRect.left) { - tooltipEl.style.left = `${halfWidth - leftGap}px`; - } + if (!chartEl || !tooltipEl) return; + if (selectedDataPointIndex == -1) return; - const rightGap = containerRect.right - chartRect.right; - if (tooltipRect.right > containerRect.right) { - tooltipEl.style.left = `${chartRect.width + rightGap - halfWidth}px`; - } + const container = chartEl!.parentElement!; + const halfWidth = tooltipEl.offsetWidth / 2; + + const containerRect = container.getBoundingClientRect(); + const chartRect = chartEl!.getBoundingClientRect(); + const tooltipRect = tooltipEl.getBoundingClientRect(); + + const leftGap = chartRect.left - containerRect.left; + if (tooltipRect.left < containerRect.left) { + tooltipEl.style.left = `${halfWidth - leftGap}px`; + } + + const rightGap = containerRect.right - chartRect.right; + if (tooltipRect.right > containerRect.right) { + tooltipEl.style.left = `${chartRect.width + rightGap - halfWidth}px`; } }); @@ -274,7 +275,7 @@ {#each dataPoints as values, i} - {#if data[i].label} - {data[i].label + ':'} + {#if data[i]?.label} + {data[i]?.label + ':'} {/if} - {formatValue(data[i].values[selectedIndex])} + {formatValue(data[i]?.values[selectedIndex])} {/each} {/if} diff --git a/src/components/Map.svelte b/src/components/Map.svelte index ab1b312..dc4f20f 100644 --- a/src/components/Map.svelte +++ b/src/components/Map.svelte @@ -101,7 +101,7 @@ // add fault markers for (const { index, fault } of faultPoints) { const { icon, className } = getIcon(fault); - const marker = Leaflet.marker(gpsPoints[index], { + const marker = Leaflet.marker(gpsPoints[index]!, { icon, title: fault, }); @@ -117,7 +117,7 @@ // find the point in `visibleRows`, if it was clicked it was visible, so it must // be in this list for (let i = 0; i < visibleRows.length; i++) { - if (visibleRows[i].index === index) { + if (visibleRows[i]!.index === index) { setSelectedIdx(i); break; } diff --git a/tsconfig.json b/tsconfig.json index aca9bdc..e70d115 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,8 +16,7 @@ "isolatedModules": true, "strict": true, "noUnusedLocals": true, - // TODO: enable, and also add svelte-check to `types` script - "noUncheckedIndexedAccess": false, + "noUncheckedIndexedAccess": true, "moduleDetection": "force" }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],