Skip to content

Commit 3c0e448

Browse files
committed
Fix multiple bugs surrounding parameter ranges. (-> Fixes every dimension maximum being off-by-1 in the visualization.) Fix multiple rendering bugs. (-> Fixes grey pixel artifacts at cube edges in multiple scenarios.) Fix animation settings window not disappearing on touch/mouse hybrid devices. Bump to v0.4.23.
1 parent e837ee6 commit 3c0e448

File tree

14 files changed

+313
-137
lines changed

14 files changed

+313
-137
lines changed

lexcube/_frontend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@
2222
"""
2323

2424
module_name = "lexcube"
25-
module_version = "^0.4.21"
25+
module_version = "^0.4.23"

lexcube/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717
# You should have received a copy of the GNU General Public License
1818
# along with this program. If not, see <https://www.gnu.org/licenses/>.
1919

20-
__version__ = "0.4.21"
20+
__version__ = "0.4.23"

lexcube/cube3d.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ def validate_boundary(self, proposal, axis):
117117
if (axis == 0 and self.zwrap) or (axis == 1 and self.ywrap) or (axis == 2 and self.xwrap):
118118
max_value = 2 * max_value
119119
wrapping = True
120-
if proposal < 0 or proposal >= max_value:
120+
if proposal < 0 or proposal > max_value:
121121
if wrapping:
122122
raise TraitError(f"Boundary of axis {axis} needs to be within double the range of the data source (considering this dimension wraps around the cube): 0 <= value < {max_value}")
123-
raise TraitError(f"Boundary of axis {axis} needs to be within the range of the data source: 0 <= value < {max_value}")
123+
raise TraitError(f"Boundary of axis {axis} needs to be within the range of the data source: 0 <= value <= {max_value}")
124124
return proposal
125125

126126

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lexcube",
3-
"version": "0.4.21",
3+
"version": "0.4.23",
44
"description": "Lexcube: 3D Data Cube Visualization in Jupyter Notebooks",
55
"keywords": [
66
"jupyter",

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ dependencies = [
4444
"xarray>=v2022.12.0",
4545
"zarr>=2.14.2",
4646
]
47-
version = "0.4.21"
47+
version = "0.4.23"
4848

4949
[project.optional-dependencies]
5050
docs = [
@@ -108,7 +108,7 @@ build_cmd = "build:prod"
108108
github_url = "https://github.com/msoechting/lexcube/"
109109

110110
[tool.tbump.version]
111-
current = "0.4.21"
111+
current = "0.4.23"
112112

113113
# Example of a semver regexp.
114114
# Make sure this matches current_version before

src/lexcube-client/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lexcube-client/src/client/client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class CubeClientContext {
4040
orchestrationMasterMode: boolean = (document.URL.indexOf("orchestrationMaster") > 0);
4141
noUiMode: boolean = (document.URL.indexOf("noUi") > 0);
4242
scriptedMultiViewMode: boolean = (document.URL.indexOf("scriptedMultiView") > 0);
43+
linearTextureFilteringEnabled: boolean = (document.URL.indexOf("linearTextureFiltering") > 0);
4344

4445
screenOrientation: DeviceOrientation = (screen.orientation ? (screen.orientation.type.indexOf("landscape") > -1 ? DeviceOrientation.Landscape : DeviceOrientation.Portrait) : (window.innerHeight > window.innerWidth ? DeviceOrientation.Portrait : DeviceOrientation.Landscape));
4546
screenAspectRatio: number = window.screen.width / window.screen.height;

src/lexcube-client/src/client/constants.ts

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,52 @@ function range(start: number, end: number) {
5757
}
5858

5959

60+
function saveFloatArrayAsPNG(data: Float32Array | Float64Array, width: number, height: number, colormapMinimumValue: number, colormapMaximumValue: number, filename: string): void {
61+
// Create a canvas element
62+
const canvas = document.createElement('canvas');
63+
canvas.width = width;
64+
canvas.height = height;
65+
const ctx = canvas.getContext('2d')!;
66+
67+
// Create an ImageData object from the Float32Array
68+
const imageData = ctx.createImageData(width, height);
69+
const uint8Data = new Uint8ClampedArray(data.length * 4);
70+
71+
// Convert Float32Array values to RGBA format
72+
for (let i = 0; i < data.length; i++) {
73+
const value = Math.floor((data[i] - colormapMinimumValue) / (colormapMaximumValue - colormapMinimumValue) * 255);
74+
const index = i * 4;
75+
let r = value;
76+
let g = value;
77+
let b = value;
78+
if (data[i] == NAN_REPLACEMENT_VALUE) {
79+
r = 0;
80+
g = 0;
81+
b = 255;
82+
}
83+
uint8Data[index] = r; // R
84+
uint8Data[index + 1] = g; // G
85+
uint8Data[index + 2] = b; // B
86+
uint8Data[index + 3] = 255; // A (fully opaque)
87+
}
88+
89+
imageData.data.set(uint8Data);
90+
91+
// Put the image data on the canvas
92+
ctx.putImageData(imageData, 0, 0);
93+
94+
// Convert the canvas to a data URL
95+
const dataURL = canvas.toDataURL('image/png');
96+
97+
// Create a download link and trigger the download
98+
const link = document.createElement('a');
99+
link.href = dataURL;
100+
link.download = filename;
101+
link.click();
102+
}
103+
104+
105+
60106
function capitalizeString(s: string) {
61107
return s[0].toUpperCase() + s.slice(1);
62108
}
@@ -79,8 +125,8 @@ const TILE_FORMAT_MAGIC_BYTES = "lexc";
79125
const ANOMALY_PARAMETER_ID_SUFFIX= "_lxc_anomaly";
80126
const NAN_TILE_MAGIC_NUMBER = -1;
81127
const LOSSLESS_TILE_MAGIC_NUMBER = -2;
82-
const NAN_REPLACEMENT_VALUE = -9999.0; // hardcoded in shader, change there as well
83-
const NOT_LOADED_REPLACEMENT_VALUE = -99999.0; // hardcoded in shader, change there as well
128+
const NAN_REPLACEMENT_VALUE = -9999.0;
129+
const NOT_LOADED_REPLACEMENT_VALUE = -99999.0;
84130
const COLORMAP_STEPS = 1024;
85131
const DEFAULT_COLORMAP = "viridis";
86132

@@ -90,6 +136,6 @@ const DEFAULT_WIDGET_HEIGHT = 768;
90136
const API_VERSION = 5;
91137
const TILE_VERSION = 2;
92138

93-
const PACKAGE_VERSION = "0.4.21";
139+
const PACKAGE_VERSION = "0.4.23";
94140

95-
export { DeviceOrientation, PACKAGE_VERSION, roundDownToSparsity, roundUpToSparsity, roundToSparsity, positiveModulo, range, getIndexDimensionOfFace, getAddressedFacesOfDimension, getFacesOfIndexDimension, capitalizeString, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT, DEFAULT_COLORMAP, ANOMALY_PARAMETER_ID_SUFFIX, TILE_FORMAT_MAGIC_BYTES, TILE_VERSION, TILE_SIZE, MAX_ZOOM_FACTOR, NAN_TILE_MAGIC_NUMBER, LOSSLESS_TILE_MAGIC_NUMBER, NAN_REPLACEMENT_VALUE, COLORMAP_STEPS, NOT_LOADED_REPLACEMENT_VALUE, API_VERSION, Dimension, CubeFace }
141+
export { saveFloatArrayAsPNG, DeviceOrientation, PACKAGE_VERSION, roundDownToSparsity, roundUpToSparsity, roundToSparsity, positiveModulo, range, getIndexDimensionOfFace, getAddressedFacesOfDimension, getFacesOfIndexDimension, capitalizeString, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT, DEFAULT_COLORMAP, ANOMALY_PARAMETER_ID_SUFFIX, TILE_FORMAT_MAGIC_BYTES, TILE_VERSION, TILE_SIZE, MAX_ZOOM_FACTOR, NAN_TILE_MAGIC_NUMBER, LOSSLESS_TILE_MAGIC_NUMBER, NAN_REPLACEMENT_VALUE, COLORMAP_STEPS, NOT_LOADED_REPLACEMENT_VALUE, API_VERSION, Dimension, CubeFace }

0 commit comments

Comments
 (0)