Skip to content

Commit 4cd3e48

Browse files
author
Vincent van der Wal
committed
add scale
1 parent 7eb64ff commit 4cd3e48

File tree

3 files changed

+158
-89
lines changed

3 files changed

+158
-89
lines changed

src/lib/utils/color-scales.ts

Lines changed: 93 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -28,89 +28,97 @@ function interpolateColorScaleHSL(colors: Array<string>, steps: number) {
2828
}
2929

3030
export const colorScales = {
31-
cape: [
32-
...interpolateColorScaleHSL(
33-
[
34-
'#009392',
35-
'#39b185',
36-
'#9ccb86',
37-
'#e9e29c',
38-
'#eeb479',
39-
'#e88471',
40-
'#cf597e'
41-
],
42-
4000
43-
)
44-
],
45-
cloud: [
46-
...interpolateColorScaleHSL(['#FFF', '#c3c2c2'], 100) // 0 to 100%
47-
],
48-
precipitation: [
49-
...interpolateColorScaleHSL(['blue', 'green'], 5), // 0 to 5mm
50-
...interpolateColorScaleHSL(['green', 'orange'], 5), // 5 to 10mm
51-
...interpolateColorScaleHSL(['orange', 'red'], 10) // 10 to 20mm
52-
],
53-
pressure: [
54-
...interpolateColorScaleHSL(['#4444FF', '#FFFFFF'], 25), // 950 to 1000hPa
55-
...interpolateColorScaleHSL(['#FFFFFF', '#FF4444'], 25) // 1000hPa to 1050hPa
56-
],
57-
relative: [
58-
...interpolateColorScaleHSL(
59-
[
60-
'#009392',
61-
'#39b185',
62-
'#9ccb86',
63-
'#e9e29c',
64-
'#eeb479',
65-
'#e88471',
66-
'#cf597e'
67-
].reverse(),
68-
100
69-
)
70-
],
71-
shortwave: [
72-
...interpolateColorScaleHSL(
73-
[
74-
'#009392',
75-
'#39b185',
76-
'#9ccb86',
77-
'#e9e29c',
78-
'#eeb479',
79-
'#e88471',
80-
'#cf597e'
81-
],
82-
1000
83-
)
84-
],
85-
temperature: [
86-
...interpolateColorScaleHSL(['purple', 'blue'], 40), // -40° to 0°
87-
...interpolateColorScaleHSL(['blue', 'green'], 16), // 0° to 16°
88-
...interpolateColorScaleHSL(['green', 'orange'], 12), // 0° to 28°
89-
...interpolateColorScaleHSL(['orange', 'red'], 14), // 28° to 42°
90-
...interpolateColorScaleHSL(['red', 'purple'], 18) // 42° to 60°
91-
],
92-
thunderstorm: [
93-
...interpolateColorScaleHSL(['blue', 'green'], 33), //
94-
...interpolateColorScaleHSL(['green', 'orange'], 33), //
95-
...interpolateColorScaleHSL(['orange', 'red'], 33) //
96-
],
97-
uv: [
98-
...interpolateColorScaleHSL(
99-
[
100-
'#009392',
101-
'#39b185',
102-
'#9ccb86',
103-
'#e9e29c',
104-
'#eeb479',
105-
'#e88471',
106-
'#cf597e'
107-
],
108-
11
109-
)
110-
],
111-
wind: [
112-
...interpolateColorScaleHSL(['blue', 'green'], 10), // 0 to 10kn
113-
...interpolateColorScaleHSL(['green', 'orange'], 10), // 10 to 20kn
114-
...interpolateColorScaleHSL(['orange', 'red'], 20) // 20 to 40kn
115-
]
31+
cape: {
32+
min: 0,
33+
max: 4000,
34+
colors: [
35+
...interpolateColorScaleHSL(
36+
['#009392', '#39b185', '#9ccb86', '#e9e29c', '#eeb479', '#e88471', '#cf597e'],
37+
4000
38+
)
39+
]
40+
},
41+
cloud: {
42+
min: 0,
43+
max: 100,
44+
colors: [
45+
...interpolateColorScaleHSL(['#FFF', '#c3c2c2'], 100) // 0 to 100%
46+
]
47+
},
48+
precipitation: {
49+
min: 0,
50+
max: 20,
51+
colors: [
52+
...interpolateColorScaleHSL(['blue', 'green'], 5), // 0 to 5mm
53+
...interpolateColorScaleHSL(['green', 'orange'], 5), // 5 to 10mm
54+
...interpolateColorScaleHSL(['orange', 'red'], 10) // 10 to 20mm
55+
]
56+
},
57+
pressure: {
58+
min: 0,
59+
max: 50,
60+
colors: [
61+
...interpolateColorScaleHSL(['#4444FF', '#FFFFFF'], 25), // 950 to 1000hPa
62+
...interpolateColorScaleHSL(['#FFFFFF', '#FF4444'], 25) // 1000hPa to 1050hPa
63+
]
64+
},
65+
relative: {
66+
min: 0,
67+
max: 100,
68+
colors: [
69+
...interpolateColorScaleHSL(
70+
['#009392', '#39b185', '#9ccb86', '#e9e29c', '#eeb479', '#e88471', '#cf597e'].reverse(),
71+
100
72+
)
73+
]
74+
},
75+
shortwave: {
76+
min: 0,
77+
max: 1000,
78+
colors: [
79+
...interpolateColorScaleHSL(
80+
['#009392', '#39b185', '#9ccb86', '#e9e29c', '#eeb479', '#e88471', '#cf597e'],
81+
1000
82+
)
83+
]
84+
},
85+
temperature: {
86+
min: -40,
87+
max: 60,
88+
colors: [
89+
...interpolateColorScaleHSL(['purple', 'blue'], 40), // -40° to 0°
90+
...interpolateColorScaleHSL(['blue', 'green'], 16), // 0° to 16°
91+
...interpolateColorScaleHSL(['green', 'orange'], 12), // 0° to 28°
92+
...interpolateColorScaleHSL(['orange', 'red'], 14), // 28° to 42°
93+
...interpolateColorScaleHSL(['red', 'purple'], 18) // 42° to 60°
94+
]
95+
},
96+
thunderstorm: {
97+
min: 0,
98+
max: 100,
99+
colors: [
100+
...interpolateColorScaleHSL(['blue', 'green'], 33), //
101+
...interpolateColorScaleHSL(['green', 'orange'], 33), //
102+
...interpolateColorScaleHSL(['orange', 'red'], 34) //
103+
]
104+
},
105+
uv: {
106+
min: 0,
107+
max: 12,
108+
colors: [
109+
...interpolateColorScaleHSL(
110+
['#009392', '#39b185', '#9ccb86', '#e9e29c', '#eeb479', '#e88471', '#cf597e'],
111+
12
112+
)
113+
]
114+
},
115+
wind: {
116+
min: 0,
117+
max: 40,
118+
colors: [
119+
...interpolateColorScaleHSL(['blue', 'green'], 10), // 0 to 10kn
120+
...interpolateColorScaleHSL(['green', 'orange'], 10), // 10 to 20kn
121+
...interpolateColorScaleHSL(['orange', 'red'], 20) // 20 to 40kn
122+
]
123+
}
116124
};

src/routes/+page.svelte

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
import * as Select from '$lib/components/ui/select';
2424
import * as Drawer from '$lib/components/ui/drawer';
2525
26+
import { colorScales } from '$lib/utils/color-scales';
27+
2628
let partial = $state(false);
29+
let showScale = $state(true);
2730
let sheetOpen = $state(false);
2831
let drawerOpen = $state(false);
2932
@@ -111,7 +114,11 @@
111114
div.addEventListener('click', () => {
112115
partial = !partial;
113116
div.innerHTML = partial ? partialSVG : fullSVG;
114-
url.searchParams.set('partial', String(partial));
117+
if (partial) {
118+
url.searchParams.set('partial', String(partial));
119+
} else {
120+
url.searchParams.delete('partial');
121+
}
115122
pushState(url + map._hash.getHashString(), {});
116123
setTimeout(() => changeOMfileURL(), 500);
117124
});
@@ -436,10 +443,64 @@
436443
});
437444
438445
let selectedDomain = $derived(domain.value);
446+
447+
let colorScale = $derived.by(() => {
448+
for (let [cs, value] of Object.entries(colorScales)) {
449+
if (variable.value.startsWith(cs)) {
450+
return value;
451+
}
452+
}
453+
});
454+
455+
let colors = $derived(colorScale.colors.reverse());
439456
</script>
440457

441458
<div class="map" id="#map_container" bind:this={mapContainer}></div>
442-
459+
<div class="absolute bottom-1 left-1 max-h-[300px]">
460+
{#if showScale}
461+
{#each colors as cs, i (i)}
462+
<div
463+
style={'background: rgba(' +
464+
cs.join(',') +
465+
`); width: 25px; height:${300 / (colorScale.max - colorScale.min)}px;`}
466+
></div>
467+
{/each}
468+
469+
{#each [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100] as step, i (i)}
470+
<div
471+
class="absolute w-[25px] text-center text-xs"
472+
style={'bottom: ' + (2 + 298 * step * 0.0093) + 'px;'}
473+
>
474+
{(colorScale.min + step * 0.01 * (colorScale.max - colorScale.min)).toFixed(0)}
475+
</div>
476+
{/each}
477+
{#if variable.value.startsWith('temperature')}
478+
<div class="bg-background absolute top-[-20px] w-[25px] py-1 text-center text-xs">C°</div>
479+
{/if}
480+
{#if variable.value.startsWith('precipitation')}
481+
<div class="bg-background absolute top-[-20px] w-[25px] py-1 text-center text-xs">mm</div>
482+
{/if}
483+
{/if}
484+
<div
485+
class=" bg-background/35 absolute bottom-0 left-8 w-[190px] rounded px-3 py-2 text-xs overflow-ellipsis"
486+
>
487+
<div>Domain: <span class="ml-auto text-end">{domain.label}</span></div>
488+
<div>
489+
Local time: <span class="ml-auto text-end"
490+
>{timeSelected.getFullYear() +
491+
'-' +
492+
pad(timeSelected.getMonth() + 1) +
493+
'-' +
494+
timeSelected.getDate() +
495+
' ' +
496+
timeSelected.getHours() +
497+
':' +
498+
pad(timeSelected.getMinutes())}</span
499+
>
500+
</div>
501+
<div>Variable: <span class="ml-auto text-end">{variable.label}</span></div>
502+
</div>
503+
</div>
443504
<div class="absolute">
444505
<Sheet.Root bind:open={sheetOpen}>
445506
<Sheet.Content><div class="px-6 pt-12">Units</div></Sheet.Content>

src/worker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ self.onmessage = async (message) => {
146146
const z = message.data.z;
147147
const values = message.data.data.values;
148148
const ranges = message.data.ranges;
149-
const mapBounds = message.data.mapBounds;
150149

151150
const domain = message.data.domain;
152151
const variable = message.data.variable;
@@ -155,7 +154,8 @@ self.onmessage = async (message) => {
155154
const rgba = new Uint8ClampedArray(pixels * 4);
156155
const dark = message.data.dark;
157156

158-
colors = colorScales[variable.value.split('_')[0]] ?? colors['temperature'];
157+
const colorsObject = colorScales[variable.value.split('_')[0]] ?? colors['temperature'];
158+
colors = colorsObject.colors;
159159

160160
let projectionGrid = null;
161161
if (domain.grid.projection) {

0 commit comments

Comments
 (0)