autumnplot-gl 3.1.0 → 4.0.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +6 -11
  2. package/dist/110.autumnplot-gl.js +1 -1
  3. package/dist/110.autumnplot-gl.js.map +1 -1
  4. package/dist/autumnplot-gl.js +1 -1
  5. package/dist/autumnplot-gl.js.map +1 -1
  6. package/dist/marchingsquares.wasm +0 -0
  7. package/lib/AutumnTypes.d.ts +53 -5
  8. package/lib/AutumnTypes.js +25 -1
  9. package/lib/Barbs.d.ts +23 -6
  10. package/lib/Barbs.js +20 -18
  11. package/lib/BillboardCollection.d.ts +16 -8
  12. package/lib/BillboardCollection.js +107 -59
  13. package/lib/Color.d.ts +57 -0
  14. package/lib/Color.js +163 -0
  15. package/lib/ColorBar.d.ts +12 -1
  16. package/lib/ColorBar.js +9 -7
  17. package/lib/Colormap.d.ts +19 -18
  18. package/lib/Colormap.js +84 -23
  19. package/lib/Contour.d.ts +42 -11
  20. package/lib/Contour.js +67 -58
  21. package/lib/ContourCreator.d.ts +4 -0
  22. package/lib/ContourCreator.js +2 -1
  23. package/lib/Fill.d.ts +27 -16
  24. package/lib/Fill.js +105 -83
  25. package/lib/Grid.d.ts +125 -29
  26. package/lib/Grid.js +303 -95
  27. package/lib/Hodographs.d.ts +24 -6
  28. package/lib/Hodographs.js +28 -24
  29. package/lib/Map.js +1 -1
  30. package/lib/Paintball.d.ts +6 -5
  31. package/lib/Paintball.js +38 -32
  32. package/lib/ParticleTracer.d.ts +19 -0
  33. package/lib/ParticleTracer.js +37 -0
  34. package/lib/PlotComponent.d.ts +6 -7
  35. package/lib/PlotComponent.js +17 -7
  36. package/lib/PlotLayer.d.ts +4 -4
  37. package/lib/PlotLayer.worker.d.ts +1 -2
  38. package/lib/PlotLayer.worker.js +22 -57
  39. package/lib/PolylineCollection.d.ts +18 -9
  40. package/lib/PolylineCollection.js +124 -89
  41. package/lib/RawField.d.ts +76 -23
  42. package/lib/RawField.js +138 -29
  43. package/lib/ShaderManager.d.ts +12 -0
  44. package/lib/ShaderManager.js +58 -0
  45. package/lib/StationPlot.d.ts +145 -0
  46. package/lib/StationPlot.js +205 -0
  47. package/lib/TextCollection.d.ts +12 -8
  48. package/lib/TextCollection.js +113 -71
  49. package/lib/cpp/marchingsquares.js +483 -585
  50. package/lib/cpp/marchingsquares.wasm +0 -0
  51. package/lib/cpp/marchingsquares_embind.d.ts +23 -3
  52. package/lib/index.d.ts +7 -4
  53. package/lib/index.js +5 -3
  54. package/lib/utils.d.ts +5 -8
  55. package/lib/utils.js +12 -83
  56. package/package.json +2 -2
package/lib/Color.js ADDED
@@ -0,0 +1,163 @@
1
+ const hex2rgba = (hexstr, out_type) => {
2
+ out_type = out_type === undefined ? 'float' : out_type;
3
+ const match = hexstr.match(/#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?/i);
4
+ if (match === null) {
5
+ throw `Got '${hexstr}' in hex2rgba, which does not look like a hex color`;
6
+ }
7
+ let rgba = match.slice(1).filter(c => c !== undefined).map(c => parseInt(c, 16));
8
+ if (out_type == 'float') {
9
+ rgba = rgba.map(c => c / 255);
10
+ }
11
+ return rgba[3] === undefined ? [rgba[0], rgba[1], rgba[2], 1] : [rgba[0], rgba[1], rgba[2], rgba[3]];
12
+ };
13
+ const rgba2hex = (rgba, in_type) => {
14
+ in_type = in_type === undefined ? 'float' : in_type;
15
+ let rgba_ = rgba;
16
+ if (in_type == 'float') {
17
+ rgba_ = rgba_.map(c => Math.round(c * 255));
18
+ }
19
+ return '#' + rgba_.map(c => c.toString(16).padStart(2, '0').toUpperCase()).join('');
20
+ };
21
+ const rgb2hsv = (rgb) => {
22
+ const [r, g, b] = rgb;
23
+ const Cmax = Math.max(r, g, b);
24
+ const Cmin = Math.min(r, g, b);
25
+ const Delta = Cmax - Cmin;
26
+ let H;
27
+ if (Delta == 0) {
28
+ H = 0;
29
+ }
30
+ else if (Cmax == r) {
31
+ H = 60 * ((g - b) / Delta) % 6;
32
+ }
33
+ else if (Cmax == g) {
34
+ H = 60 * ((b - r) / Delta + 2);
35
+ }
36
+ else if (Cmax == b) {
37
+ H = 60 * ((r - g) / Delta + 4);
38
+ }
39
+ else {
40
+ throw "You've messed something up in rgb2hsv()";
41
+ }
42
+ let S = Cmax == 0 ? 0 : Delta / Cmax;
43
+ let V = Cmax;
44
+ return [H, S, V];
45
+ };
46
+ const hsv2rgb = (hsv) => {
47
+ const [H, S, V] = hsv;
48
+ const C = V * S;
49
+ const X = C * (1 - Math.abs(H / 60 % 2 - 1));
50
+ const m = V - C;
51
+ let r_prime, g_prime, b_prime;
52
+ if (0 <= H && H < 60) {
53
+ r_prime = C;
54
+ g_prime = X, b_prime = 0;
55
+ }
56
+ else if (60 <= H && H < 120) {
57
+ r_prime = X;
58
+ g_prime = C, b_prime = 0;
59
+ }
60
+ else if (120 <= H && H < 180) {
61
+ r_prime = 0;
62
+ g_prime = C, b_prime = X;
63
+ }
64
+ else if (180 <= H && H < 240) {
65
+ r_prime = 0;
66
+ g_prime = X, b_prime = C;
67
+ }
68
+ else if (240 <= H && H < 300) {
69
+ r_prime = X;
70
+ g_prime = 0, b_prime = C;
71
+ }
72
+ else if (300 <= H && H < 360) {
73
+ r_prime = C;
74
+ g_prime = 0, b_prime = X;
75
+ }
76
+ else {
77
+ throw "H is out of bounds in hsv2rgb";
78
+ }
79
+ return [r_prime + m, g_prime + m, b_prime + m];
80
+ };
81
+ class Color {
82
+ /**
83
+ * Create a new color object
84
+ * @param rgba - An RGBA tuple of floats between 0 and 1
85
+ */
86
+ constructor(rgba) {
87
+ this.rgba = rgba;
88
+ }
89
+ /**
90
+ * The red component of the color as a float value between 0 and 1
91
+ */
92
+ get r() {
93
+ return this.rgba[0];
94
+ }
95
+ /**
96
+ * The green component of the color as a float value between 0 and 1
97
+ */
98
+ get g() {
99
+ return this.rgba[1];
100
+ }
101
+ /**
102
+ * The blue component of the color as a float value between 0 and 1
103
+ */
104
+ get b() {
105
+ return this.rgba[2];
106
+ }
107
+ /**
108
+ * The alpha component (opacity) of the color as a float value between 0 and 1
109
+ */
110
+ get a() {
111
+ return this.rgba[3];
112
+ }
113
+ /**
114
+ * @param opacity - The new alpha component (opacity)
115
+ * @returns A new color with the alpha component set to opacity.
116
+ */
117
+ withOpacity(opacity) {
118
+ return new Color([this.r, this.g, this.b, opacity]);
119
+ }
120
+ /**
121
+ * @returns The color as an RGB hex string (e.g., '#dedbef')
122
+ */
123
+ toRGBHex() {
124
+ return this.toRGBAHex().slice(0, -2);
125
+ }
126
+ /**
127
+ * @returns The color as an RGBA hex string (e.g., '#dedbefff')
128
+ */
129
+ toRGBAHex() {
130
+ return rgba2hex(this.rgba);
131
+ }
132
+ /**
133
+ * @returns The color as an RGBA float tuple
134
+ */
135
+ toRGBATuple() {
136
+ return this.rgba;
137
+ }
138
+ /**
139
+ * @returns The color as a tuple of HSV values
140
+ */
141
+ toHSVTuple() {
142
+ return rgb2hsv([this.r, this.g, this.b]);
143
+ }
144
+ /**
145
+ * @param hex - An RGB or RGBA hex string to parse
146
+ * @returns a new Color object
147
+ */
148
+ static fromHex(hex) {
149
+ return new Color(hex2rgba(hex));
150
+ }
151
+ /**
152
+ * @param hsv - A tuple of HSV values
153
+ * @returns a new Color object
154
+ */
155
+ static fromHSVTuple(hsv) {
156
+ const rgb = hsv2rgb(hsv);
157
+ return new Color([rgb[0], rgb[1], rgb[2], 1]);
158
+ }
159
+ static normalizeColor(color) {
160
+ return color instanceof Color ? color : Color.fromHex(color);
161
+ }
162
+ }
163
+ export { Color };
package/lib/ColorBar.d.ts CHANGED
@@ -1,9 +1,20 @@
1
- import { Color, ColorMap } from "./Colormap";
1
+ import { ColorMap } from "./Colormap";
2
+ import { Color } from "./Color";
2
3
  type ColorbarOrientation = 'horizontal' | 'vertical';
3
4
  type ColorbarTickDirection = 'top' | 'bottom' | 'left' | 'right';
4
5
  interface ColorBarOptions {
5
6
  /** The label to place along the color bar */
6
7
  label?: string;
8
+ /**
9
+ * The size in pixels along the long axis of the colorbar
10
+ * @default 600
11
+ */
12
+ size_long?: number;
13
+ /**
14
+ * The size in pixels along the short axis of the colorbar
15
+ * @default size_long / 9
16
+ */
17
+ size_short?: number;
7
18
  /**
8
19
  * An array of numbers to use as the tick locations.
9
20
  * @default Use all the levels in the color map provided to {@link makeColorBar}.
package/lib/ColorBar.js CHANGED
@@ -30,6 +30,8 @@ function makeColorBar(colormap, opts) {
30
30
  const orientation = opts.orientation || 'vertical';
31
31
  const fontface = opts.fontface || 'sans-serif';
32
32
  const tickfontsize = opts.ticklabelsize || 12;
33
+ const size_long = opts.size_long || 600;
34
+ const size_short = opts.size_short || size_long / 9;
33
35
  const tick_dir = opts.tick_direction || (orientation == 'vertical' ? 'left' : 'bottom');
34
36
  if (orientation == 'vertical' && (tick_dir == 'top' || tick_dir == 'bottom') ||
35
37
  orientation == 'horizontal' && (tick_dir == 'left' || tick_dir == 'right')) {
@@ -41,8 +43,8 @@ function makeColorBar(colormap, opts) {
41
43
  const chars_left = getNChar(ticks[0]);
42
44
  const chars_right = getNChar(ticks[ticks.length - 1]);
43
45
  const need_overflow = colormap.underflow_color !== null || colormap.overflow_color !== null;
44
- const bar_long_size = 600;
45
- const bar_cross_size = bar_long_size / 9;
46
+ const bar_long_size = size_long;
47
+ const bar_cross_size = size_short;
46
48
  const bar_long_pad = Math.max(orientation == 'horizontal' ? Math.max(chars_left, chars_right) * 6 : 8, need_overflow ? bar_cross_size / (2 * Math.sqrt(3)) : 0);
47
49
  const bar_cross_pad = 3;
48
50
  const bar_thickness = 10;
@@ -97,7 +99,7 @@ function makeColorBar(colormap, opts) {
97
99
  else {
98
100
  attrs = { x: bar_left + bar_width * icolor / n_colors, y: bar_top, width: bar_width / n_colors, height: bar_height };
99
101
  }
100
- createElement('rect', { ...attrs, fill: color.color, opacity: color.opacity }, gbar);
102
+ createElement('rect', { ...attrs, fill: color.toRGBHex(), opacity: color.a }, gbar);
101
103
  });
102
104
  // Make the overflow and underflow triangles
103
105
  if (colormap.underflow_color !== null) {
@@ -108,7 +110,7 @@ function makeColorBar(colormap, opts) {
108
110
  else {
109
111
  point_list = `${bar_left} ${bar_bottom}, ${bar_low_arrow} ${bar_middle}, ${bar_left} ${bar_top}, ${bar_left} ${bar_bottom}`;
110
112
  }
111
- const underflow_attrs = { points: point_list, fill: colormap.underflow_color.color, opacity: colormap.underflow_color.opacity };
113
+ const underflow_attrs = { points: point_list, fill: colormap.underflow_color.toRGBHex(), opacity: colormap.underflow_color.a };
112
114
  createElement('polygon', underflow_attrs, gbar);
113
115
  }
114
116
  if (colormap.overflow_color !== null) {
@@ -119,7 +121,7 @@ function makeColorBar(colormap, opts) {
119
121
  else {
120
122
  point_list = `${bar_right} ${bar_top}, ${bar_high_arrow} ${bar_middle}, ${bar_right} ${bar_bottom}, ${bar_right} ${bar_top}`;
121
123
  }
122
- const overflow_attrs = { points: point_list, fill: colormap.overflow_color.color, opacity: colormap.overflow_color.opacity };
124
+ const overflow_attrs = { points: point_list, fill: colormap.overflow_color.toRGBHex(), opacity: colormap.overflow_color.a };
123
125
  createElement('polygon', overflow_attrs, gbar);
124
126
  }
125
127
  // Make the ticks marks and labels
@@ -219,8 +221,8 @@ function makePaintballKey(colors, labels, opts) {
219
221
  const icol = Math.floor(icolor / n_rows);
220
222
  let opacity = 1.;
221
223
  if (typeof color != 'string') {
222
- opacity = color.opacity;
223
- color = color.color;
224
+ opacity = color.a;
225
+ color = color.toRGBHex();
224
226
  }
225
227
  const x = swatch_width_pad + icol * (swatch_width + swatch_text_pad + swatch_text_space + swatch_width_pad);
226
228
  const y = swatch_height_pad + irow * (swatch_height + swatch_height_pad);
package/lib/Colormap.d.ts CHANGED
@@ -1,14 +1,10 @@
1
- import { Float16Array } from "@petamoriken/float16";
2
- interface Color {
3
- /** The color as a hex color string */
4
- color: string;
5
- /** The opacity as a number from 0 to 1 */
6
- opacity: number;
7
- }
1
+ import { WGLProgram, WGLTexture } from "autumn-wgl";
2
+ import { WebGLAnyRenderingContext } from "./AutumnTypes";
3
+ import { Color } from "./Color";
8
4
  interface ColorMapOptions {
9
- /** The color to use for areas where the value is below the lowest value in the color map */
10
- overflow_color?: Color | string;
11
5
  /** The color to use for areas where the value is above the highest value in the color map */
6
+ overflow_color?: Color | string;
7
+ /** The color to use for areas where the value is below the lowest value in the color map */
12
8
  underflow_color?: Color | string;
13
9
  }
14
10
  /** A mapping from values to colors */
@@ -71,12 +67,17 @@ declare const redblue: (level_min: number, level_max: number, n_colors: number)
71
67
  * @returns a Colormap object
72
68
  */
73
69
  declare const bluered: (level_min: number, level_max: number, n_colors: number) => ColorMap;
74
- /**
75
- * Make a canvas image corresponding to a color map
76
- * @param colormap - The color map to use
77
- * @returns A canvas element containing each color of the color map
78
- */
79
- declare function makeTextureImage(colormap: ColorMap): HTMLCanvasElement;
80
- declare function makeIndexMap(colormap: ColorMap): Float16Array;
81
- export { ColorMap, bluered, redblue, pw_speed500mb, pw_speed850mb, pw_cape, pw_t2m, pw_td2m, nws_storm_clear_refl, makeTextureImage, makeIndexMap };
82
- export type { Color, ColorMapOptions };
70
+ interface ColorMapGLElems {
71
+ cmap_texture: WGLTexture;
72
+ cmap_nonlin_texture: WGLTexture;
73
+ }
74
+ declare class ColorMapGPUInterface {
75
+ readonly colormap: ColorMap;
76
+ gl_elems: ColorMapGLElems | null;
77
+ constructor(colormap: ColorMap);
78
+ static applyShader(shader_src: string): string;
79
+ setupShaderVariables(gl: WebGLAnyRenderingContext, mag_filter: number): void;
80
+ bindShaderVariables(program: WGLProgram): void;
81
+ }
82
+ export { ColorMap, ColorMapGPUInterface, bluered, redblue, pw_speed500mb, pw_speed850mb, pw_cape, pw_t2m, pw_td2m, nws_storm_clear_refl };
83
+ export type { ColorMapOptions };
package/lib/Colormap.js CHANGED
@@ -1,4 +1,3 @@
1
- import { hex2rgb, hsv2rgb, rgb2hex, rgb2hsv } from "./utils";
2
1
  const spd500_colormap_data = { "levels": [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140], "colors": [ "#e6f4ff", "#dbf0fe", "#d1ebfe", "#c6e7fd", "#bce3fd", "#b1dffc", "#a7dbfc", "#9cd6fb", "#92d2fb", "#87cefa", "#84c2f6", "#81b7f1", "#7eabed", "#7ba0e8", "#7994e4", "#7688df", "#737ddb", "#7071d6", "#6d66d2", "#6a5acd", "#7660cf", "#8366d0", "#8f6cd2", "#9c72d3", "#a878d5", "#b47ed6", "#c184d8", "#cd8ad9", "#da90db", "#e696dc", "#e390d9", "#e08ad6", "#dd84d3", "#da7ed0", "#d778cd", "#d472ca", "#d16cc7", "#ce66c4", "#cb60c1", "#c85abe", "#c453ba", "#c04cb6", "#bc45b2", "#b83eae", "#b437aa", "#b030a6", "#ac29a2", "#a8229e", "#a41b9a", "#a01496", "#a41080", "#a80e75", "#ac0e75", "#b00c6a", "#b4085f", "#b80649", "#bc043e", "#c00233", "#c80028", "#c80028", "#ca042a", "#cc082c", "#d00c2c", "#d21432", "#d41834", "#d41834", "#d61c36", "#da243a", "#dc283c", "#de2c3e", "#e03040", "#e23442", "#e43844", "#e63c46", "#e84048", "#ea444a", "#ec484c", "#ee4c4e", "#f05050", "#f16052", "#f27054", "#f38056", "#f49058", "#f5a05a", "#f6b05c", "#f7c05e", "#f8d060", "#f9e062", "#faf064", "#f7eb61", "#f4e65e", "#f1e15b", "#eedc58", "#ebd755", "#e8d252", "#e5cd4f", "#e2c84c", "#dfc349", "#dcbe46", "#d9b943", "#d6b440", "#d3af3d", "#d0aa3a", "#cda537", "#caa034", "#c79b31", "#c4962e", "#c1912b", "#be8c28", "#bb8725", "#b88222", "#b57d1f", "#b2781c", "#af7319", "#ac6e16", "#a96913", "#a66410", "#a35f0d", "#a05a0a", "#a05a0a" ] }
3
2
  const spd850_colormap_data = { "levels": [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80], "colors": [ "#f0f8ff", "#dbf0fe", "#c6e7fd", "#b1dffc", "#9cd6fb", "#87cefa", "#81b7f1", "#7ba0e8", "#7688df", "#7071d6", "#6a5acd", "#8366d0", "#9c72d3", "#b47ed6", "#cd8ad9", "#e696dc", "#e08ad6", "#da7ed0", "#d472ca", "#ce66c4", "#c85abe", "#c04cb6", "#b83eae", "#b030a6", "#a8229e", "#a01496", "#a81080", "#b00c6a", "#b8043e", "#c80028", "#c80028", "#d01030", "#d41834", "#d82038", "#dc283c", "#e03040", "#e43844", "#e84048", "#ec484c", "#f05050", "#f27054", "#f49058", "#f6b05c", "#f8d060", "#faf064", "#f4e65e", "#eedc58", "#e8d252", "#e2c84c", "#dcbe46", "#d6b440", "#d0aa3a", "#caa034", "#c4962e", "#be8c28", "#b88222", "#b2781c", "#ac6e16", "#a66410", "#a05a0a" ] }
4
3
  const cape_colormap_data = { "levels": [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000, 4100, 4200, 4300, 4400, 4500, 4600, 4700, 4800, 4900, 5000, 5100, 5200, 5300, 5400, 5500, 5600, 5700, 5800, 5900, 6000, 6500, 7000, 7500, 8000, 8500, 9000, 9500, 10000], "colors": [ "#ffffff", "#f0f0f0", "#e1e1e1", "#d2d2d2", "#c3c3c3", "#a5a5a5", "#969696", "#878787", "#787878", "#696969", "#37536a", "#436075", "#506d80", "#5c7a8b", "#698796", "#7594a2", "#82a1ad", "#8eaeb8", "#9bbbc3", "#a7c8ce", "#e9dd96", "#e8d186", "#e7c575", "#e6b865", "#e5ac54", "#e5a044", "#e49433", "#e38723", "#e27b12", "#e16f02", "#dc4110", "#d33b17", "#ca351e", "#c12e25", "#b8282c", "#af2234", "#a61c3b", "#9d1542", "#940f49", "#8b0950", "#73088a", "#7e1894", "#8a289f", "#9538a9", "#a148b3", "#ac59be", "#b869c8", "#c379d2", "#cf89dd", "#da99e7", "#e9bec3", "#e3b0b7", "#dda3ac", "#d795a0", "#d18894", "#ca7a89", "#c46d7d", "#be5f71", "#b85266", "#b2445a", "#893d48", "#8f4752", "#96525b", "#9c5c65", "#a2676f", "#a97178", "#af7c82", "#b6868b" ] }
@@ -6,9 +5,38 @@ const t2m_colormap_data = { "levels": [-60, -59, -58, -57, -56, -55, -54, -5
6
5
  const td2m_colormap_data = { "levels": [-40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "colors": [ "#986d4d", "#966c4c", "#946b4c", "#926a4b", "#90694b", "#8e684a", "#8c664a", "#8a6549", "#886448", "#866348", "#846247", "#826147", "#806046", "#7e5f46", "#7c5e45", "#7a5d44", "#785b44", "#765a43", "#745943", "#725842", "#715742", "#6f5641", "#6d5540", "#6b5440", "#69533f", "#67523f", "#65503e", "#634f3d", "#614e3d", "#5f4d3c", "#5d4c3c", "#5b4b3b", "#594a3b", "#57493a", "#554839", "#534739", "#514538", "#4f4438", "#4d4337", "#4b4237", "#494136", "#4d4334", "#514738", "#564c3c", "#5a5041", "#5e5545", "#625949", "#675e4d", "#6b6251", "#6f6755", "#746b5a", "#78705e", "#7c7462", "#807966", "#857d6a", "#89826f", "#8d8673", "#928b77", "#968f7b", "#9a947f", "#9e9883", "#a39d88", "#a7a18c", "#aba690", "#afaa94", "#b8b39c", "#b8b39c", "#bcb8a1", "#c1bca5", "#c9c5ad", "#c9cab1", "#d2ceb6", "#d2ceb6", "#d6d3ba", "#dfdcc2", "#e3e0c6", "#e7e5ca", "#ebe9cf", "#f0eed3", "#f4f2d7", "#e6f5e6", "#d7f0d7", "#c8eac8", "#b9e5b9", "#aadfaa", "#9bda9b", "#8cd48c", "#7dcf7d", "#6ec96e", "#5fc45f", "#30ae30", "#2ca32c", "#279927", "#238e23", "#1e831e", "#1a791a", "#156e15", "#116311", "#0c590c", "#084e08", "#61a3af", "#5896a0", "#508992", "#477b83", "#3e6e74", "#366166", "#2d5457", "#244648", "#1c393a", "#132c2b", "#66669a", "#605e94", "#59568e", "#534e88", "#4d4682", "#463e7c", "#403676", "#3a2e70", "#33266a", "#2d1e64", "#724071", "#784573", "#7d4b75", "#835076", "#885678", "#8e5b7a", "#93617c", "#99667d", "#9e6c7f", "#a47181" ] }
7
6
  const nws_storm_clear_refl_colormap_data = { "levels": [ -15, -14.53608247, -14.07216495, -13.60824742, -13.1443299, -12.68041237, -12.21649485, -11.75257732, -11.28865979, -10.82474227, -10.36082474, -9.89690722, -9.43298969, -8.96907216, -8.50515464, -8.04123711, -7.57731959, -7.11340206, -6.64948454, -6.18556701, -5.72164948, -5.25773196, -4.79381443, -4.32989691, -3.86597938, -3.40206186, -2.93814433, -2.4742268, -2.01030928, -1.54639175, -1.08247423, -0.6185567, -0.15463918, 0.30927835, 0.77319588, 1.2371134, 1.70103093, 2.16494845, 2.62886598, 3.09278351, 3.55670103, 4.02061856, 4.48453608, 4.94845361, 5.41237113, 5.87628866, 6.34020619, 6.80412371, 7.26804124, 7.73195876, 8.19587629, 8.65979381, 9.12371134, 9.58762887, 10.05154639, 10.51546392, 10.97938144, 11.44329897, 11.90721649, 12.37113402, 12.83505155, 13.29896907, 13.7628866, 14.22680412, 14.69072165, 15.15463918, 15.6185567, 16.08247423, 16.54639175, 17.01030928, 17.4742268, 17.93814433, 18.40206186, 18.86597938, 19.32989691, 19.79381443, 20.25773196, 20.72164948, 21.18556701, 21.64948454, 22.11340206, 22.57731959, 23.04123711, 23.50515464, 23.96907216, 24.43298969, 24.89690722, 25.36082474, 25.82474227, 26.28865979, 26.75257732, 27.21649485, 27.68041237, 28.1443299, 28.60824742, 29.07216495, 29.53608247, 30, 30.46391753, 30.92783505, 31.39175258, 31.8556701, 32.31958763, 32.78350515, 33.24742268, 33.71134021, 34.17525773, 34.63917526, 35.10309278, 35.56701031, 36.03092784, 36.49484536, 36.95876289, 37.42268041, 37.88659794, 38.35051546, 38.81443299, 39.27835052, 39.74226804, 40.20618557, 40.67010309, 41.13402062, 41.59793814, 42.06185567, 42.5257732, 42.98969072, 43.45360825, 43.91752577, 44.3814433, 44.84536082, 45.30927835, 45.77319588, 46.2371134, 46.70103093, 47.16494845, 47.62886598, 48.09278351, 48.55670103, 49.02061856, 49.48453608, 49.94845361, 50.41237113, 50.87628866, 51.34020619, 51.80412371, 52.26804124, 52.73195876, 53.19587629, 53.65979381, 54.12371134, 54.58762887, 55.05154639, 55.51546392, 55.97938144, 56.44329897, 56.90721649, 57.37113402, 57.83505155, 58.29896907, 58.7628866, 59.22680412, 59.69072165, 60.15463918, 60.6185567, 61.08247423, 61.54639175, 62.01030928, 62.4742268, 62.93814433, 63.40206186, 63.86597938, 64.32989691, 64.79381443, 65.25773196, 65.72164948, 66.18556701, 66.64948454, 67.11340206, 67.57731959, 68.04123711, 68.50515464, 68.96907216, 69.43298969, 69.89690722, 70.36082474, 70.82474227, 71.28865979, 71.75257732, 72.21649485, 72.68041237, 73.1443299, 73.60824742, 74.07216495, 74.53608247, 75 ], "colors": [ "#959052", "#979356", "#9c9a60", "#a09c64", "#a3a067", "#a8a570", "#aaa875", "#acac79", "#b1b182", "#b5b587", "#b6b88c", "#bcbd93", "#bfc199", "#c1c39c", "#c1c39c", "#c6caa5", "#cacdaa", "#cccfaf", "#cfd1b3", "#cccfb3", "#c8ccb3", "#c6c8b3", "#bfc3b3", "#bfc3b3", "#bcc1b3", "#b8bdb3", "#b5bab3", "#afb5b3", "#acb3b3", "#aaafb3", "#a7aeb3", "#a3aab3", "#a0a8b3", "#9ca5b3", "#9aa1b3", "#97a0b3", "#939cb3", "#909ab3", "#939ab5", "#8c95b3", "#8791b1", "#838eb1", "#808caf", "#7c89af", "#7785ae", "#7482ac", "#7080aa", "#6b7caa", "#6275a8", "#5e72a7", "#5e72a7", "#5b70a5", "#566da3", "#5269a3", "#4f67a1", "#4b64a1", "#4660a0", "#425d9e", "#4260a1", "#4467a5", "#486eaa", "#4975ae", "#4d7cb1", "#4f83b5", "#508aba", "#5491bf", "#5699c3", "#599ec6", "#5ba5ca", "#5daccf", "#60b3d4", "#62bad8", "#64c1db", "#67c8df", "#69cfe4", "#6ed6e8", "#67d6d6", "#60d6c4", "#59d6b3", "#52d6a1", "#4bd690", "#42d67e", "#3bd66d", "#34d65b", "#11d418", "#11d116", "#0fcd16", "#0fc816", "#0fc316", "#0fbf15", "#0fbc15", "#0fb613", "#0eb313", "#0eaf13", "#0eaa13", "#0ca511", "#0ca111", "#0c9e11", "#0c9911", "#0c950f", "#0c900f", "#0a8c0f", "#0a870f", "#0a830e", "#0a800e", "#0a7c0c", "#0a770c", "#08720c", "#086e0c", "#086b0a", "#08660a", "#08620a", "#085d08", "#1c6708", "#317208", "#467c08", "#5b8707", "#6e9107", "#839c05", "#97a805", "#acb105", "#c1bc05", "#d6c603", "#e9d103", "#ffe200", "#ffd800", "#ffd300", "#ffc800", "#ffc300", "#ffba00", "#ffb500", "#ffb000", "#ffac00", "#ffa700", "#ff9e00", "#ff9900", "#ff9300", "#ff8900", "#ff8500", "#ff7f00", "#ff0000", "#f70000", "#f00000", "#e90000", "#e20000", "#db0000", "#d40000", "#cd0000", "#c60000", "#bf0000", "#b80000", "#b10000", "#aa0000", "#a30000", "#9a0000", "#930000", "#8c0000", "#850000", "#7e0000", "#770000", "#700000", "#ffffff", "#fff4ff", "#ffe9ff", "#ffdfff", "#ffd4ff", "#ffc8ff", "#ffbdff", "#ffb3ff", "#ffa8ff", "#ff9cff", "#ff91ff", "#ff75ff", "#fb6bfd", "#f960f9", "#f656f6", "#f24bf4", "#ef3ff0", "#ed36ef", "#e92aeb", "#e61fe8", "#e416e6", "#e10ae2", "#b100ff", "#ac00fb", "#a300f6", "#9a00f4", "#9300ef", "#8700e9", "#8200e8", "#7900e2", "#7200dd", "#6900db", "#6200d6" ] }
8
7
  import { Float16Array } from "@petamoriken/float16";
9
- function isColor(obj) {
10
- return (typeof obj == 'object') && 'color' in obj && 'opacity' in obj;
11
- }
8
+ import { WGLTexture } from "autumn-wgl";
9
+ import { getGLFormatTypeAlignment } from "./PlotComponent";
10
+ import { Color } from "./Color";
11
+ import { mergeShaderCode } from "./utils";
12
+ const colormap_shader_src = `
13
+ uniform sampler2D u_cmap_sampler;
14
+ uniform sampler2D u_cmap_nonlin_sampler;
15
+ uniform highp float u_cmap_min;
16
+ uniform highp float u_cmap_max;
17
+ uniform highp vec4 u_underflow_color;
18
+ uniform highp vec4 u_overflow_color;
19
+ uniform int u_n_index;
20
+
21
+ lowp vec4 apply_colormap(highp float value) {
22
+ lowp float normed_val = (value - u_cmap_min) / (u_cmap_max - u_cmap_min);
23
+
24
+ lowp vec4 color;
25
+ if (normed_val < 0.0) {
26
+ color = u_underflow_color;
27
+ }
28
+ else if (normed_val > 1.0) {
29
+ color = u_overflow_color;
30
+ }
31
+ else {
32
+ lowp float index_buffer = 1. / (2. * float(u_n_index));
33
+ normed_val = index_buffer + normed_val * (1. - 2. * index_buffer);
34
+ highp float nonlin_val = texture(u_cmap_nonlin_sampler, vec2(normed_val, 0.5)).r;
35
+ color = texture(u_cmap_sampler, vec2(nonlin_val, 0.5));
36
+ }
37
+
38
+ return color;
39
+ }`
12
40
  /** A mapping from values to colors */
13
41
  class ColorMap {
14
42
  /**
@@ -21,24 +49,23 @@ class ColorMap {
21
49
  if (levels.length != colors.length + 1) {
22
50
  throw `Mismatch between number of levels (${levels.length}) and number of colors (${colors.length}; expected ${levels.length - 1})`;
23
51
  }
24
- const normalizeColor = (c) => isColor(c) ? c : { 'color': c, 'opacity': 1. };
25
52
  this.levels = levels;
26
- this.colors = colors.map(c => normalizeColor(c));
53
+ this.colors = colors.map(c => Color.normalizeColor(c));
27
54
  opts = opts === undefined ? {} : opts;
28
- this.overflow_color = opts.overflow_color === undefined ? null : normalizeColor(opts.overflow_color);
29
- this.underflow_color = opts.underflow_color === undefined ? null : normalizeColor(opts.underflow_color);
55
+ this.overflow_color = opts.overflow_color === undefined ? null : Color.normalizeColor(opts.overflow_color);
56
+ this.underflow_color = opts.underflow_color === undefined ? null : Color.normalizeColor(opts.underflow_color);
30
57
  }
31
58
  /**
32
59
  * @returns an array of hex color strings
33
60
  */
34
61
  getColors() {
35
- return this.colors.map(s => s['color']);
62
+ return this.colors.map(s => s.toRGBHex());
36
63
  }
37
64
  /**
38
65
  * @returns an array of opacities, one for each color in the color map
39
66
  */
40
67
  getOpacities() {
41
- return this.colors.map(s => s['opacity']);
68
+ return this.colors.map(s => s.a);
42
69
  }
43
70
  /**
44
71
  * Make a new color map with different opacities. The opacities are set by func.
@@ -54,7 +81,7 @@ class ColorMap {
54
81
  const level_lower = this.levels[ic];
55
82
  const level_upper = this.levels[ic + 1];
56
83
  const new_opacity = func(level_lower, level_upper);
57
- const new_color = { color: color.color, opacity: new_opacity };
84
+ const new_color = color.withOpacity(new_opacity);
58
85
  if (new_opacity > 0) {
59
86
  if (new_levels[new_levels.length - 1] != level_lower)
60
87
  new_levels.push(level_lower);
@@ -65,13 +92,13 @@ class ColorMap {
65
92
  if (this.underflow_color !== null) {
66
93
  const underflow_opacity = func(this.levels[0], this.levels[0]);
67
94
  if (underflow_opacity > 0) {
68
- opts.underflow_color = { color: this.underflow_color.color, opacity: underflow_opacity };
95
+ opts.underflow_color = this.underflow_color.withOpacity(underflow_opacity);
69
96
  }
70
97
  }
71
98
  if (this.overflow_color !== null) {
72
99
  const overflow_opacity = func(this.levels[this.levels.length - 1], this.levels[this.levels.length - 1]);
73
100
  if (overflow_opacity > 0) {
74
- opts.overflow_color = { color: this.overflow_color.color, opacity: overflow_opacity };
101
+ opts.overflow_color = this.overflow_color.withOpacity(overflow_opacity);
75
102
  }
76
103
  }
77
104
  return new ColorMap(new_levels, new_colors, opts);
@@ -91,30 +118,30 @@ class ColorMap {
91
118
  const level_step = (level_max - level_min) / (n_colors - 1);
92
119
  const crossover = (level_max + level_min) / 2;
93
120
  const crossover_hsv = [0, 0, 0.9];
94
- const color1_hsv = rgb2hsv(hex2rgb(color1));
95
- const color2_hsv = rgb2hsv(hex2rgb(color2));
121
+ const color1_hsv = Color.fromHex(color1).toHSVTuple();
122
+ const color2_hsv = Color.fromHex(color2).toHSVTuple();
123
+ const interp_fac_power = 1.5;
96
124
  for (let istop = 0; istop < n_colors; istop++) {
97
125
  const level = level_min + istop * level_step;
98
126
  let h, s, v;
99
127
  let interp_fac;
100
128
  if (level < crossover) {
101
- interp_fac = (crossover - level) / (crossover - level_min);
129
+ interp_fac = Math.pow((crossover - level) / (crossover - level_min), interp_fac_power);
102
130
  [h, s, v] = [
103
131
  color1_hsv[0],
104
132
  crossover_hsv[1] + (color1_hsv[1] - crossover_hsv[1]) * interp_fac,
105
133
  crossover_hsv[2] + (color1_hsv[2] - crossover_hsv[2]) * interp_fac
106
134
  ];
107
135
  }
108
- else if (level >= crossover) {
109
- interp_fac = (level - crossover) / (level_max - crossover);
136
+ else {
137
+ interp_fac = Math.pow((level - crossover) / (level_max - crossover), interp_fac_power);
110
138
  [h, s, v] = [
111
139
  color2_hsv[0],
112
140
  crossover_hsv[1] + (color2_hsv[1] - crossover_hsv[1]) * interp_fac,
113
141
  crossover_hsv[2] + (color2_hsv[2] - crossover_hsv[2]) * interp_fac
114
142
  ];
115
143
  }
116
- const color = rgb2hex(hsv2rgb([h, s, v]));
117
- stops.push({ 'color': color, 'opacity': Math.min(2 * interp_fac, 1) });
144
+ stops.push(Color.fromHSVTuple([h, s, v]).withOpacity(Math.min(2 * interp_fac, 1)));
118
145
  }
119
146
  for (let ilev = 0; ilev <= n_colors; ilev++) {
120
147
  const level_step = (level_max - level_min) / n_colors;
@@ -161,6 +188,40 @@ const redblue = (level_min, level_max, n_colors) => {
161
188
  const bluered = (level_min, level_max, n_colors) => {
162
189
  return ColorMap.diverging('#0000ff', '#ff0000', level_min, level_max, n_colors);
163
190
  };
191
+ const N_INDEX_MAP = 101;
192
+ class ColorMapGPUInterface {
193
+ constructor(colormap) {
194
+ this.colormap = colormap;
195
+ this.gl_elems = null;
196
+ }
197
+ static applyShader(shader_src) {
198
+ return mergeShaderCode(colormap_shader_src, shader_src);
199
+ }
200
+ setupShaderVariables(gl, mag_filter) {
201
+ const index_map = makeIndexMap(this.colormap);
202
+ const cmap_image = makeTextureImage(this.colormap);
203
+ const { format: format_nonlin, type: type_nonlin, row_alignment: row_alignment_nonlin } = getGLFormatTypeAlignment(gl, 'float16');
204
+ const cmap_image_spec = { 'format': gl.RGBA, 'type': gl.UNSIGNED_BYTE, 'image': cmap_image, 'mag_filter': mag_filter };
205
+ const cmap_texture = new WGLTexture(gl, cmap_image_spec);
206
+ const cmap_nonlin_image = { 'format': format_nonlin, 'type': type_nonlin,
207
+ 'width': index_map.length, 'height': 1,
208
+ 'image': new Uint16Array(index_map.buffer),
209
+ 'mag_filter': gl.LINEAR, 'row_alignment': row_alignment_nonlin,
210
+ };
211
+ const cmap_nonlin_texture = new WGLTexture(gl, cmap_nonlin_image);
212
+ this.gl_elems = { cmap_texture: cmap_texture, cmap_nonlin_texture: cmap_nonlin_texture };
213
+ }
214
+ bindShaderVariables(program) {
215
+ if (this.gl_elems === null)
216
+ return;
217
+ const cmap = this.colormap;
218
+ const underflow_color = cmap.underflow_color === null ? [0, 0, 0, 0] : cmap.underflow_color.toRGBATuple();
219
+ const overflow_color = cmap.overflow_color === null ? [0, 0, 0, 0] : cmap.overflow_color.toRGBATuple();
220
+ program.setUniforms({ 'u_cmap_min': cmap.levels[0], 'u_cmap_max': cmap.levels[cmap.levels.length - 1],
221
+ 'u_n_index': N_INDEX_MAP, 'u_underflow_color': underflow_color, 'u_overflow_color': overflow_color });
222
+ program.bindTextures({ 'u_cmap_sampler': this.gl_elems.cmap_texture, 'u_cmap_nonlin_sampler': this.gl_elems.cmap_nonlin_texture });
223
+ }
224
+ }
164
225
  /**
165
226
  * Make a canvas image corresponding to a color map
166
227
  * @param colormap - The color map to use
@@ -175,7 +236,7 @@ function makeTextureImage(colormap) {
175
236
  if (ctx === null) {
176
237
  throw "Could not get rendering context for colormap image canvas";
177
238
  }
178
- ctx.fillStyle = stop['color'] + Math.round(stop['opacity'] * 255).toString(16);
239
+ ctx.fillStyle = stop.toRGBAHex();
179
240
  ctx.fillRect(istop, 0, 1, 1);
180
241
  });
181
242
  return cmap_image;
@@ -183,7 +244,7 @@ function makeTextureImage(colormap) {
183
244
  function makeIndexMap(colormap) {
184
245
  // Build a texture to account for nonlinear colormaps (basically inverts the relationship between
185
246
  // the normalized index and the normalized level)
186
- const n_nonlin = 101;
247
+ const n_nonlin = N_INDEX_MAP;
187
248
  const map_norm = [];
188
249
  for (let i = 0; i < n_nonlin; i++) {
189
250
  map_norm.push(i / (n_nonlin - 1));
@@ -200,4 +261,4 @@ function makeIndexMap(colormap) {
200
261
  });
201
262
  return new Float16Array(inv_cmap_norm);
202
263
  }
203
- export { ColorMap, bluered, redblue, pw_speed500mb, pw_speed850mb, pw_cape, pw_t2m, pw_td2m, nws_storm_clear_refl, makeTextureImage, makeIndexMap };
264
+ export { ColorMap, ColorMapGPUInterface, bluered, redblue, pw_speed500mb, pw_speed850mb, pw_cape, pw_t2m, pw_td2m, nws_storm_clear_refl };
package/lib/Contour.d.ts CHANGED
@@ -1,23 +1,49 @@
1
- import { TypedArray, WebGLAnyRenderingContext } from './AutumnTypes';
1
+ import { RenderMethodArg, TypedArray, WebGLAnyRenderingContext } from './AutumnTypes';
2
2
  import { MapLikeType } from './Map';
3
3
  import { PlotComponent } from './PlotComponent';
4
4
  import { RawScalarField } from './RawField';
5
+ import { LineStyle } from './PolylineCollection';
6
+ import { ColorMap } from './Colormap';
7
+ import { StructuredGrid } from './Grid';
5
8
  interface ContourOptions {
6
9
  /**
7
10
  * The color of the contours as a hex color string
8
11
  * @default '#000000'
9
12
  */
10
13
  color?: string;
14
+ /**
15
+ * A color map to use to color the contours. Specifying a colormap overrides the color option.
16
+ * @default null
17
+ */
18
+ cmap?: ColorMap | null;
11
19
  /**
12
20
  * The contour interval for drawing contours at regular intervals
13
21
  * @default 1
14
22
  */
15
23
  interval?: number;
16
24
  /**
17
- * A list of arbitrary levels (up to 40) to contour. This overrides the `interval` option.
18
- * @default Draw contours at regular intervals given by the `interval` option.
25
+ * A list of arbitrary levels to contour. This overrides the `interval` option.
26
+ * @default null
27
+ */
28
+ levels?: number[] | null;
29
+ /**
30
+ * The width of the line in pixels. This could be either a number or a function that takes a contour level as a number and returns a line width. This
31
+ * can be used to vary the width of the contours by value.
32
+ * @example level => level >= 100 ? 3 : 1.5
33
+ * @default 2
34
+ */
35
+ line_width?: number | ((level: number) => number);
36
+ /**
37
+ * The style to use for the line. This can be either a LineStyle or a function that takes a contour level as a number and returns a LineStyle. This
38
+ * can be used to vary the contours by value.
39
+ * @example level => level < 0 ? '--' : '-'
40
+ * @default '-'
19
41
  */
20
- levels?: number[];
42
+ line_style?: LineStyle | ((level: number) => LineStyle);
43
+ /**
44
+ *
45
+ */
46
+ quad_as_tri?: boolean;
21
47
  }
22
48
  /**
23
49
  * A field of contoured data.
@@ -26,7 +52,7 @@ interface ContourOptions {
26
52
  * // meters).
27
53
  * const contours = new Contour(height_field, {color: '#000000', interval: 30});
28
54
  */
29
- declare class Contour<ArrayType extends TypedArray, MapType extends MapLikeType> extends PlotComponent<MapType> {
55
+ declare class Contour<ArrayType extends TypedArray, GridType extends StructuredGrid, MapType extends MapLikeType> extends PlotComponent<MapType> {
30
56
  private field;
31
57
  readonly opts: Required<ContourOptions>;
32
58
  private gl_elems;
@@ -36,12 +62,12 @@ declare class Contour<ArrayType extends TypedArray, MapType extends MapLikeType>
36
62
  * @param field - The field to contour
37
63
  * @param opts - Options for creating the contours
38
64
  */
39
- constructor(field: RawScalarField<ArrayType>, opts: ContourOptions);
65
+ constructor(field: RawScalarField<ArrayType, GridType>, opts: ContourOptions);
40
66
  /**
41
67
  * Update the data displayed as contours
42
68
  * @param field - The new field to contour
43
69
  */
44
- updateField(field: RawScalarField<ArrayType>): Promise<void>;
70
+ updateField(field: RawScalarField<ArrayType, GridType>): Promise<void>;
45
71
  getContours(): Promise<import("./AutumnTypes").ContourData>;
46
72
  /**
47
73
  * @internal
@@ -52,7 +78,7 @@ declare class Contour<ArrayType extends TypedArray, MapType extends MapLikeType>
52
78
  * @internal
53
79
  * Render the contours
54
80
  */
55
- render(gl: WebGLAnyRenderingContext, matrix: number[] | Float32Array): void;
81
+ render(gl: WebGLAnyRenderingContext, arg: RenderMethodArg): void;
56
82
  }
57
83
  interface ContourLabelOptions {
58
84
  /**
@@ -89,13 +115,18 @@ interface ContourLabelOptions {
89
115
  * @default false
90
116
  */
91
117
  halo?: boolean;
118
+ /**
119
+ * Label density. 2 makes the labels twice as dense, 0.5 makes them half as dense.
120
+ * @default 1
121
+ */
122
+ density?: number;
92
123
  }
93
- declare class ContourLabels<ArrayType extends TypedArray, MapType extends MapLikeType> extends PlotComponent<MapType> {
124
+ declare class ContourLabels<ArrayType extends TypedArray, GridType extends StructuredGrid, MapType extends MapLikeType> extends PlotComponent<MapType> {
94
125
  private readonly contours;
95
126
  private gl_elems;
96
127
  private text_collection;
97
128
  private readonly opts;
98
- constructor(contours: Contour<ArrayType, MapType>, opts?: ContourLabelOptions);
129
+ constructor(contours: Contour<ArrayType, GridType, MapType>, opts?: ContourLabelOptions);
99
130
  /**
100
131
  * Update contour labels when the field for the associated Contour object has been changed.
101
132
  */
@@ -109,7 +140,7 @@ declare class ContourLabels<ArrayType extends TypedArray, MapType extends MapLik
109
140
  * @internal
110
141
  * Render the contour labels
111
142
  */
112
- render(gl: WebGLAnyRenderingContext, matrix: number[]): void;
143
+ render(gl: WebGLAnyRenderingContext, arg: RenderMethodArg): void;
113
144
  }
114
145
  export default Contour;
115
146
  export { ContourLabels };