Fix double drawing by taking out canvas from gribfile.tsx
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { Component, createEffect, createSignal, Signal } from 'solid-js'
|
||||
|
||||
import { LoadingSpinner } from '../components/LoadingSpinner'
|
||||
import { DrawOptions, GribMessage } from './interfaces'
|
||||
import { drawGrib } from './draw/drawGrib'
|
||||
|
||||
const CROP_BOUNDS = { x: 1906-1-440, y: 895, width: 440, height: 380 }
|
||||
|
||||
export const DrawView: Component<{
|
||||
isLoadingSignal: Signal<boolean>,
|
||||
options: DrawOptions;
|
||||
cachedMessagesSignal: Signal<GribMessage[]>,
|
||||
cachedBuffersSignal: Signal<Uint8Array[]>,
|
||||
cachedBitmasksSignal: Signal<Uint8Array[]>,
|
||||
}> = ({
|
||||
isLoadingSignal: [getIsLoading, setIsLoading],
|
||||
options,
|
||||
cachedMessagesSignal: [getCachedMessages],
|
||||
cachedBuffersSignal: [getCachedBuffers],
|
||||
cachedBitmasksSignal: [getCachedBitmasks],
|
||||
}) => {
|
||||
const [getCanvas, setCanvas] = createSignal<HTMLCanvasElement>()
|
||||
|
||||
createEffect(async () => {
|
||||
setIsLoading(true)
|
||||
const canvas = getCanvas()!
|
||||
const ctx = canvas.getContext('2d')!
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||
const cropBounds = options.getIsCrop() ? CROP_BOUNDS : undefined
|
||||
const contour = options.getIsContour()
|
||||
const isInterpolated = options.getIsInterpolated()
|
||||
if (getCachedMessages().length === 0) return;
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
// hack to show loading spinner
|
||||
drawGrib(canvas, getCachedMessages(), getCachedBuffers(), getCachedBitmasks(), cropBounds, contour, isInterpolated)
|
||||
setIsLoading(false)
|
||||
})
|
||||
|
||||
return <>
|
||||
{ getIsLoading() && <LoadingSpinner text='' />}
|
||||
<canvas ref={setCanvas} style={{ display: getIsLoading() ? 'none' : 'block' }} />
|
||||
</>
|
||||
}
|
||||
@@ -1,50 +1,34 @@
|
||||
import { Accessor, Component, createEffect, createSignal, Setter } from 'solid-js'
|
||||
import { Accessor, batch, Component, createSignal, Setter, Signal } from 'solid-js'
|
||||
|
||||
import styles from './harmonie.module.css'
|
||||
import { apiHost } from '../consts'
|
||||
import { DrawOptions, GribMessage } from './interfaces'
|
||||
import { GribMessage } from './interfaces'
|
||||
import { fetchBuffer } from '../helpers/fetch'
|
||||
import { drawGrib } from './draw/drawGrib'
|
||||
import { fetchWindData, isCalculatedWindDirection } from './draw/windDirection'
|
||||
import { fetchHourPrecipitationData, isCalculatedHourPrecipitation } from './draw/precipitation'
|
||||
|
||||
const CROP_BOUNDS = { x: 1906-1-440, y: 895, width: 440, height: 380 }
|
||||
|
||||
export const GribFile: Component<{
|
||||
name: string,
|
||||
getCanvas: Accessor<HTMLCanvasElement | undefined>,
|
||||
setIsLoading: Setter<boolean>,
|
||||
getFileGribList: Accessor<GribMessage[]> // specific reference and forecast time (in one file)
|
||||
getAllGribLists: Accessor<GribMessage[]>
|
||||
options: DrawOptions;
|
||||
getFileGribList: Accessor<GribMessage[]>, // specific reference and forecast time (in one file)
|
||||
getAllGribLists: Accessor<GribMessage[]>,
|
||||
onClick: (name: string) => void,
|
||||
cachedMessagesSignal: Signal<GribMessage[]>,
|
||||
cachedBuffersSignal: Signal<Uint8Array[]>,
|
||||
cachedBitmasksSignal: Signal<Uint8Array[]>,
|
||||
}> = ({
|
||||
name,
|
||||
getCanvas,
|
||||
setIsLoading,
|
||||
getFileGribList,
|
||||
getAllGribLists,
|
||||
options,
|
||||
onClick,
|
||||
cachedMessagesSignal: [, setCachedMessages],
|
||||
cachedBuffersSignal: [, setCachedBuffers],
|
||||
cachedBitmasksSignal: [, setCachedBitmasks],
|
||||
}) => {
|
||||
let cachedMessages: GribMessage[] = []
|
||||
let cachedBuffers: Uint8Array[] = []
|
||||
let cachedBitmasks: Uint8Array[] = []
|
||||
|
||||
const [getIsActive, setIsActive] = createSignal(false)
|
||||
|
||||
createEffect(async () => {
|
||||
setIsLoading(true)
|
||||
const cropBounds = options.getIsCrop() ? CROP_BOUNDS : undefined
|
||||
const contour = options.getIsContour()
|
||||
const isInterpolated = options.getIsInterpolated()
|
||||
// hack to show loading spinner
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
if (cachedMessages.length === 0) return;
|
||||
drawGrib(getCanvas()!, cachedMessages, cachedBuffers, cachedBitmasks, cropBounds, contour, isInterpolated)
|
||||
setIsLoading(false)
|
||||
})
|
||||
|
||||
function onParamClick(paramId: number) {
|
||||
setIsLoading(true);
|
||||
const grib = getFileGribList()[paramId]
|
||||
@@ -70,11 +54,11 @@ export const GribFile: Component<{
|
||||
if(isCalculatedHourPrecipitation(grib)) fetchPromise = fetchHourPrecipitationData(grib, getAllGribLists())
|
||||
|
||||
fetchPromise.then(([messages, binaryBuffers, bitmasks]) => {
|
||||
cachedMessages = messages
|
||||
cachedBuffers = binaryBuffers.map(b => new Uint8Array(b))
|
||||
cachedBitmasks = bitmasks.map(b => new Uint8Array(b))
|
||||
const cropBounds = options.getIsCrop() ? CROP_BOUNDS : undefined
|
||||
drawGrib(getCanvas()!, cachedMessages, cachedBuffers, cachedBitmasks, cropBounds, options.getIsContour(), options.getIsInterpolated())
|
||||
batch(() => {
|
||||
setCachedMessages(messages)
|
||||
setCachedBuffers(binaryBuffers.map(b => new Uint8Array(b)))
|
||||
setCachedBitmasks(bitmasks.map(b => new Uint8Array(b)))
|
||||
})
|
||||
})
|
||||
.catch(err => console.warn(err.message))
|
||||
.finally(() => setIsLoading(false))
|
||||
|
||||
@@ -3,11 +3,11 @@ import { Component, createSignal } from 'solid-js'
|
||||
import { apiHost } from '../consts'
|
||||
import styles from './harmonie.module.css'
|
||||
import { GribFile } from './GribFile'
|
||||
import { LoadingSpinner } from '../components/LoadingSpinner'
|
||||
import { GribMessage } from './interfaces'
|
||||
import { fetchJson } from '../helpers/fetch'
|
||||
import { getFakeWindDirection, isWindSpeed } from './draw/windDirection'
|
||||
import { getFakeHourPrecipitation, isPrecipitation } from './draw/precipitation'
|
||||
import { DrawView } from './DrawView'
|
||||
|
||||
export const Harmonie: Component<{}> = () => {
|
||||
const [getFileList, setFileList] = createSignal<string[]>([])
|
||||
@@ -18,6 +18,10 @@ export const Harmonie: Component<{}> = () => {
|
||||
const [getIsInterpolated, setIsInterpolated] = createSignal(true)
|
||||
const [getGribList, setGribList] = createSignal<GribMessage[]>([])
|
||||
|
||||
const cachedMessagesSignal = createSignal<GribMessage[]>([])
|
||||
const cachedBuffersSignal = createSignal<Uint8Array[]>([])
|
||||
const cachedBitmasksSignal = createSignal<Uint8Array[]>([])
|
||||
|
||||
fetchJson(`${apiHost}/api/show/grib-list`)
|
||||
.then(fileList => {
|
||||
fileList.sort((a: string, b: string) => a < b ? 1 : -1)
|
||||
@@ -79,15 +83,22 @@ export const Harmonie: Component<{}> = () => {
|
||||
setIsLoading={setIsLoading}
|
||||
getFileGribList={() => getCurrentGribList(fileName)}
|
||||
getAllGribLists={getGribList}
|
||||
options={{ getIsCrop: getIsCrop, getIsContour: getIsContour, getIsInterpolated: getIsInterpolated }}
|
||||
onClick={() => onGribMessageClick(fileName)}
|
||||
cachedMessagesSignal={cachedMessagesSignal}
|
||||
cachedBuffersSignal={cachedBuffersSignal}
|
||||
cachedBitmasksSignal={cachedBitmasksSignal}
|
||||
/>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div class={styles.column}>
|
||||
{ getIsLoading() && <LoadingSpinner text='' />}
|
||||
<canvas ref={setCanvas} style={{ display: getIsLoading() ? 'none' : 'block' }} />
|
||||
<DrawView
|
||||
isLoadingSignal={[getIsLoading, setIsLoading]}
|
||||
options={{ getIsCrop: getIsCrop, getIsContour: getIsContour, getIsInterpolated: getIsInterpolated }}
|
||||
cachedMessagesSignal={cachedMessagesSignal}
|
||||
cachedBuffersSignal={cachedBuffersSignal}
|
||||
cachedBitmasksSignal={cachedBitmasksSignal}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user