TypeScript library for zoomable visualization of two-dimensional scientific data maps, similar to deep zoom image formats but designed for NetCDF data.
npm install zoomdataimport { ZoomData, Palettes } from 'zoomdata';
const viewer = new ZoomData({
rootUrl: 'http://localhost:8000/data/',
colorPalette: Palettes.inferno(256),
minValue: 0.0,
maxValue: 1.0,
});
await viewer.start('canvasId');- Node.js 18+
- Python 3 (for the data server)
# Install dependencies
npm installThe demo requires two servers running simultaneously:
Terminal 1 - Data Server (serves NetCDF tile data with CORS headers):
npm run serve-data
# or directly: python cors_server.pyThis starts a Python HTTP server on port 8000 that serves the example data files.
Terminal 2 - Dev Server (Vite dev server with hot reload):
npm run devThis starts the Vite dev server on port 3000 and opens the demo in your browser.
# Type check
npm run typecheck
# Build for production
npm run buildThe built library will be in dist/.
The library expects a Deep Zoom Image (DZI) style directory structure:
data/
dzdata.json # Metadata file
dzdata_files/
0/ # Zoom level 0 (most zoomed out)
0_0.nc
1/ # Zoom level 1
0_0.nc
0_1.nc
1_0.nc
1_1.nc
...
{
"Image": {
"Size": {
"Width": 1024,
"Height": 1024
},
"TileSize": 256,
"Overlap": 0
}
}Each .nc file must contain:
- A
heightsvariable with the data values xandydimensions
Use the SurfaceTopography Python library:
from SurfaceTopography.Generation import fourier_synthesis
# Generate synthetic surface
t = fourier_synthesis((1024, 1024), (1.0, 1.0), 0.8, rms_slope=0.1, unit='mm')
# Export as DZI with NetCDF tiles
t.to_dzi('dzdata', 'output_dir', format='nc', meta_format='json')Main entry point for creating a zoomable viewer.
const viewer = new ZoomData(options: ZoomDataOptions);| Option | Type | Default | Description |
|---|---|---|---|
rootUrl |
string |
required | URL where dzdata.json is located |
colorPalette |
number[] |
Palettes.inferno(256) |
Color palette array |
minValue |
number |
0.0 |
Minimum data value |
maxValue |
number |
1.0 |
Maximum data value |
zoomLevelIncrement |
number |
0.1 |
Zoom change per scroll |
debug |
boolean |
false |
Show tile borders |
start(canvas: HTMLCanvasElement | string): Promise<void>- Start renderingstop(): void- Stop rendering and cleanupgetZoomLevel(): number- Get current zoom levelsetZoomLevel(level: number): void- Set zoom levelgetMaxZoomLevel(): number- Get maximum zoom levelresetView(): void- Reset to initial viewsetColorRange(min: number, max: number): void- Update color mapping
onZoomChange: (level: number) => void- Called when zoom level changesonError: (error: Error) => void- Called on errors
Built-in perceptually uniform colormaps (from matplotlib):
import { Palettes, inferno, viridis, magma, plasma, grayscale } from 'zoomdata';
// Using the Palettes namespace
const palette1 = Palettes.inferno(256);
const palette2 = Palettes.viridis(128);
// Or import functions directly
const palette3 = inferno(256);
const palette4 = grayscale(64);Available palettes:
inferno(n)- Black to yellow through red (good for heat/intensity)viridis(n)- Purple to yellow through green (colorblind-friendly)magma(n)- Black to white through pinkplasma(n)- Blue to yellow through pinkgrayscale(n)- Black to white
MIT