matterviz 0.3.1 → 0.3.2
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.
- package/dist/FilePicker.svelte +37 -20
- package/dist/Icon.svelte +2 -2
- package/dist/app.css +29 -0
- package/dist/brillouin/BrillouinZone.svelte +19 -61
- package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneExportPane.svelte +12 -20
- package/dist/brillouin/BrillouinZoneScene.svelte +2 -2
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram.svelte +192 -0
- package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +677 -0
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2688 -0
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
- package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -0
- package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
- package/dist/chempot-diagram/color.d.ts +10 -0
- package/dist/chempot-diagram/color.js +33 -0
- package/dist/chempot-diagram/compute.d.ts +38 -0
- package/dist/chempot-diagram/compute.js +650 -0
- package/dist/chempot-diagram/index.d.ts +5 -0
- package/dist/chempot-diagram/index.js +5 -0
- package/dist/chempot-diagram/pointer.d.ts +16 -0
- package/dist/chempot-diagram/pointer.js +40 -0
- package/dist/chempot-diagram/temperature.d.ts +15 -0
- package/dist/chempot-diagram/temperature.js +37 -0
- package/dist/chempot-diagram/types.d.ts +83 -0
- package/dist/chempot-diagram/types.js +27 -0
- package/dist/colors/index.d.ts +3 -1
- package/dist/colors/index.js +4 -0
- package/dist/composition/BarChart.svelte +13 -22
- package/dist/composition/BubbleChart.svelte +5 -3
- package/dist/composition/FormulaFilter.svelte +586 -94
- package/dist/composition/FormulaFilter.svelte.d.ts +35 -1
- package/dist/composition/PieChart.svelte +43 -18
- package/dist/composition/PieChart.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull.svelte +4 -2
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull2D.svelte +13 -44
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +16 -7
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +17 -7
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullStats.svelte +701 -226
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +6 -1
- package/dist/convex-hull/ConvexHullTooltip.svelte +1 -0
- package/dist/convex-hull/demo-temperature.d.ts +6 -0
- package/dist/convex-hull/demo-temperature.js +36 -0
- package/dist/convex-hull/helpers.d.ts +1 -1
- package/dist/convex-hull/helpers.js +2 -4
- package/dist/convex-hull/index.d.ts +1 -0
- package/dist/convex-hull/index.js +1 -0
- package/dist/convex-hull/thermodynamics.d.ts +8 -21
- package/dist/convex-hull/thermodynamics.js +106 -17
- package/dist/convex-hull/types.d.ts +5 -0
- package/dist/convex-hull/types.js +5 -0
- package/dist/coordination/CoordinationBarPlot.svelte +29 -46
- package/dist/element/BohrAtom.svelte +1 -1
- package/dist/element/data.js +2 -14
- package/dist/element/data.json.gz +0 -0
- package/dist/element/types.d.ts +1 -0
- package/dist/fermi-surface/FermiSurface.svelte +20 -64
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
- package/dist/fermi-surface/parse.js +16 -22
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +1273 -0
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +171 -0
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +31 -0
- package/dist/heatmap-matrix/index.d.ts +53 -0
- package/dist/heatmap-matrix/index.js +100 -0
- package/dist/heatmap-matrix/shared.d.ts +2 -0
- package/dist/heatmap-matrix/shared.js +4 -0
- package/dist/icons.d.ts +111 -0
- package/dist/icons.js +111 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/io/export.js +15 -3
- package/dist/io/file-drop.d.ts +7 -0
- package/dist/io/file-drop.js +43 -0
- package/dist/io/index.d.ts +2 -2
- package/dist/io/index.js +2 -112
- package/dist/io/types.d.ts +1 -0
- package/dist/io/url-drop.d.ts +2 -0
- package/dist/io/url-drop.js +118 -0
- package/dist/isosurface/Isosurface.svelte +101 -45
- package/dist/isosurface/IsosurfaceControls.svelte +19 -0
- package/dist/isosurface/parse.js +73 -30
- package/dist/isosurface/slice.d.ts +2 -1
- package/dist/isosurface/slice.js +3 -3
- package/dist/isosurface/types.d.ts +13 -1
- package/dist/isosurface/types.js +98 -0
- package/dist/labels.d.ts +2 -1
- package/dist/labels.js +1 -0
- package/dist/layout/InfoTag.svelte +62 -62
- package/dist/layout/SubpageGrid.svelte +74 -0
- package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.js +1 -0
- package/dist/layout/json-tree/JsonNode.svelte +83 -85
- package/dist/layout/json-tree/JsonTree.svelte +20 -19
- package/dist/layout/json-tree/JsonTree.svelte.d.ts +1 -1
- package/dist/layout/json-tree/JsonValue.svelte +196 -116
- package/dist/layout/json-tree/types.d.ts +10 -2
- package/dist/layout/json-tree/utils.d.ts +2 -0
- package/dist/layout/json-tree/utils.js +33 -0
- package/dist/math.d.ts +7 -0
- package/dist/math.js +358 -7
- package/dist/overlays/ContextMenu.svelte +3 -2
- package/dist/overlays/DraggablePane.svelte +163 -58
- package/dist/overlays/DraggablePane.svelte.d.ts +2 -0
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +232 -77
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -2
- package/dist/phase-diagram/PhaseDiagramControls.svelte +32 -11
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +3 -2
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +103 -0
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +102 -95
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +7 -0
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +100 -26
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +6 -3
- package/dist/phase-diagram/index.d.ts +2 -0
- package/dist/phase-diagram/index.js +2 -0
- package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
- package/dist/phase-diagram/svg-to-diagram.js +865 -0
- package/dist/phase-diagram/types.d.ts +10 -0
- package/dist/phase-diagram/utils.d.ts +7 -4
- package/dist/phase-diagram/utils.js +149 -59
- package/dist/plot/AxisLabel.svelte +26 -0
- package/dist/plot/AxisLabel.svelte.d.ts +16 -0
- package/dist/plot/BarPlot.svelte +473 -228
- package/dist/plot/BarPlot.svelte.d.ts +3 -3
- package/dist/plot/BarPlotControls.svelte +3 -2
- package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
- package/dist/plot/ColorBar.svelte +54 -54
- package/dist/plot/ColorBar.svelte.d.ts +1 -1
- package/dist/plot/ColorScaleSelect.svelte +1 -1
- package/dist/plot/ElementScatter.svelte +3 -2
- package/dist/plot/FillArea.svelte +4 -1
- package/dist/plot/Histogram.svelte +320 -230
- package/dist/plot/Histogram.svelte.d.ts +2 -2
- package/dist/plot/HistogramControls.svelte +29 -10
- package/dist/plot/HistogramControls.svelte.d.ts +6 -2
- package/dist/plot/InteractiveAxisLabel.svelte.d.ts +2 -2
- package/dist/plot/PlotControls.svelte +109 -27
- package/dist/plot/PlotControls.svelte.d.ts +1 -1
- package/dist/plot/PlotLegend.svelte +1 -1
- package/dist/plot/PortalSelect.svelte +2 -1
- package/dist/plot/ReferenceLine.svelte +2 -1
- package/dist/plot/ReferenceLine.svelte.d.ts +1 -0
- package/dist/plot/ReferencePlane.svelte +1 -3
- package/dist/plot/ScatterPlot.svelte +343 -209
- package/dist/plot/ScatterPlot.svelte.d.ts +3 -3
- package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlot3DControls.svelte +203 -250
- package/dist/plot/ScatterPlot3DScene.svelte +4 -7
- package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlotControls.svelte +95 -55
- package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
- package/dist/plot/ZeroLines.svelte +44 -0
- package/dist/plot/ZeroLines.svelte.d.ts +32 -0
- package/dist/plot/ZoomRect.svelte +21 -0
- package/dist/plot/ZoomRect.svelte.d.ts +8 -0
- package/dist/plot/axis-utils.d.ts +1 -1
- package/dist/plot/index.d.ts +6 -2
- package/dist/plot/index.js +6 -2
- package/dist/plot/interactions.d.ts +8 -10
- package/dist/plot/interactions.js +2 -3
- package/dist/plot/layout.d.ts +7 -1
- package/dist/plot/layout.js +12 -4
- package/dist/plot/reference-line.d.ts +4 -21
- package/dist/plot/reference-line.js +7 -81
- package/dist/plot/types.d.ts +42 -17
- package/dist/plot/types.js +10 -0
- package/dist/plot/utils/label-placement.js +13 -10
- package/dist/plot/utils.d.ts +1 -0
- package/dist/plot/utils.js +14 -0
- package/dist/rdf/RdfPlot.svelte +55 -66
- package/dist/settings.d.ts +3 -0
- package/dist/settings.js +17 -3
- package/dist/spectral/Bands.svelte +515 -143
- package/dist/spectral/Bands.svelte.d.ts +22 -2
- package/dist/spectral/helpers.d.ts +23 -1
- package/dist/spectral/helpers.js +65 -9
- package/dist/spectral/types.d.ts +2 -0
- package/dist/structure/AtomLegend.svelte +29 -8
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/CellSelect.svelte +92 -22
- package/dist/structure/Structure.svelte +108 -118
- package/dist/structure/Structure.svelte.d.ts +1 -1
- package/dist/structure/StructureControls.svelte +25 -22
- package/dist/structure/StructureControls.svelte.d.ts +1 -1
- package/dist/structure/StructureInfoPane.svelte +7 -1
- package/dist/structure/StructureScene.svelte +104 -66
- package/dist/structure/StructureScene.svelte.d.ts +2 -1
- package/dist/structure/atom-properties.d.ts +6 -2
- package/dist/structure/atom-properties.js +38 -25
- package/dist/structure/export.js +10 -7
- package/dist/structure/ferrox-wasm-types.d.ts +3 -2
- package/dist/structure/ferrox-wasm-types.js +0 -3
- package/dist/structure/ferrox-wasm.d.ts +3 -2
- package/dist/structure/ferrox-wasm.js +1 -2
- package/dist/structure/index.d.ts +6 -0
- package/dist/structure/index.js +22 -0
- package/dist/structure/parse.js +19 -16
- package/dist/structure/partial-occupancy.d.ts +25 -0
- package/dist/structure/partial-occupancy.js +102 -0
- package/dist/structure/validation.js +6 -3
- package/dist/symmetry/SymmetryStats.svelte +18 -4
- package/dist/symmetry/WyckoffTable.svelte +18 -10
- package/dist/symmetry/index.d.ts +7 -4
- package/dist/symmetry/index.js +83 -18
- package/dist/table/HeatmapTable.svelte +425 -65
- package/dist/table/HeatmapTable.svelte.d.ts +12 -1
- package/dist/table/ToggleMenu.svelte +2 -0
- package/dist/table/index.d.ts +2 -0
- package/dist/trajectory/Trajectory.svelte +147 -145
- package/dist/trajectory/TrajectoryExportPane.svelte +13 -9
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +1 -1
- package/dist/trajectory/constants.d.ts +6 -0
- package/dist/trajectory/constants.js +7 -0
- package/dist/trajectory/extract.js +3 -5
- package/dist/trajectory/format-detect.d.ts +9 -0
- package/dist/trajectory/format-detect.js +76 -0
- package/dist/trajectory/frame-reader.d.ts +17 -0
- package/dist/trajectory/frame-reader.js +339 -0
- package/dist/trajectory/helpers.d.ts +15 -0
- package/dist/trajectory/helpers.js +187 -0
- package/dist/trajectory/index.d.ts +1 -0
- package/dist/trajectory/index.js +11 -4
- package/dist/trajectory/parse/ase.d.ts +2 -0
- package/dist/trajectory/parse/ase.js +76 -0
- package/dist/trajectory/parse/hdf5.d.ts +2 -0
- package/dist/trajectory/parse/hdf5.js +121 -0
- package/dist/trajectory/parse/index.d.ts +12 -0
- package/dist/trajectory/parse/index.js +304 -0
- package/dist/trajectory/parse/lammps.d.ts +5 -0
- package/dist/trajectory/parse/lammps.js +169 -0
- package/dist/trajectory/parse/vasp.d.ts +2 -0
- package/dist/trajectory/parse/vasp.js +65 -0
- package/dist/trajectory/parse/xyz.d.ts +2 -0
- package/dist/trajectory/parse/xyz.js +109 -0
- package/dist/trajectory/types.d.ts +11 -0
- package/dist/trajectory/types.js +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +4 -0
- package/dist/xrd/XrdPlot.svelte +6 -4
- package/dist/xrd/calc-xrd.js +0 -1
- package/package.json +30 -24
- package/readme.md +4 -4
- package/dist/trajectory/parse.d.ts +0 -42
- package/dist/trajectory/parse.js +0 -1267
- /package/dist/element/{data.json.d.ts → data.json.gz.d.ts} +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { marching_cubes } from '../marching-cubes';
|
|
5
5
|
import { T } from '@threlte/core';
|
|
6
6
|
import { BackSide, BufferAttribute, BufferGeometry, DoubleSide, FrontSide, Uint32BufferAttribute, } from 'three';
|
|
7
|
-
import { DEFAULT_ISOSURFACE_SETTINGS } from './types';
|
|
7
|
+
import { DEFAULT_ISOSURFACE_SETTINGS, downsample_grid, pad_periodic_grid, } from './types';
|
|
8
8
|
let { volume, settings = DEFAULT_ISOSURFACE_SETTINGS, } = $props();
|
|
9
9
|
// Resolve layers: use explicit layers array if provided, else build from single-isovalue settings
|
|
10
10
|
let resolved_layers = $derived.by(() => {
|
|
@@ -48,22 +48,34 @@ function build_geometry(vertices, faces) {
|
|
|
48
48
|
geometry.computeBoundingSphere();
|
|
49
49
|
return geometry;
|
|
50
50
|
}
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
// Downsample large grids once when volume changes to keep marching cubes interactive
|
|
52
|
+
let ds_result = $derived.by(() => {
|
|
53
|
+
if (!volume)
|
|
54
|
+
return undefined;
|
|
55
|
+
return downsample_grid(volume.grid, volume.grid_dims);
|
|
56
|
+
});
|
|
57
|
+
// Run marching cubes at the given isovalue with pre-prepared grid/lattice/shift.
|
|
58
|
+
function extract_surface(isovalue, mc_grid, mc_lattice, origin_shift) {
|
|
59
|
+
if (isovalue === 0)
|
|
56
60
|
return null;
|
|
57
|
-
const result = marching_cubes(
|
|
58
|
-
periodic:
|
|
61
|
+
const result = marching_cubes(mc_grid, isovalue, mc_lattice, {
|
|
62
|
+
periodic: false,
|
|
59
63
|
interpolate: true,
|
|
60
64
|
centered: false,
|
|
61
65
|
normals: false,
|
|
62
66
|
});
|
|
67
|
+
if (origin_shift) {
|
|
68
|
+
for (const vert of result.vertices) {
|
|
69
|
+
vert[0] += origin_shift[0];
|
|
70
|
+
vert[1] += origin_shift[1];
|
|
71
|
+
vert[2] += origin_shift[2];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
63
74
|
return build_geometry(result.vertices, result.faces);
|
|
64
75
|
}
|
|
65
76
|
let active_geometries = $state([]);
|
|
66
77
|
let raf_id = 0;
|
|
78
|
+
let debounce_id = 0;
|
|
67
79
|
// Dispose all current geometries
|
|
68
80
|
function dispose_all() {
|
|
69
81
|
for (const entry of active_geometries)
|
|
@@ -72,50 +84,94 @@ function dispose_all() {
|
|
|
72
84
|
}
|
|
73
85
|
// Dispose on unmount
|
|
74
86
|
$effect(() => () => dispose_all());
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const layers = resolved_layers;
|
|
78
|
-
const vol = volume;
|
|
79
|
-
if (!vol) {
|
|
80
|
-
dispose_all();
|
|
87
|
+
function rebuild_geometries(layers) {
|
|
88
|
+
if (!volume || !ds_result)
|
|
81
89
|
return;
|
|
90
|
+
const old = active_geometries;
|
|
91
|
+
const entries = [];
|
|
92
|
+
// Prepare grid/lattice/shift once for all layers.
|
|
93
|
+
// When halo > 0 for periodic volumes, the downsampled grid is padded with
|
|
94
|
+
// halo cells from the opposite face so isosurfaces extend beyond the unit
|
|
95
|
+
// cell and close into complete enclosed shapes around boundary atoms.
|
|
96
|
+
let mc_grid = ds_result.grid;
|
|
97
|
+
let mc_lattice = volume.lattice;
|
|
98
|
+
let origin_shift = null;
|
|
99
|
+
if (settings.halo > 0 && volume.periodic) {
|
|
100
|
+
const padded = pad_periodic_grid(ds_result.grid, ds_result.dims, settings.halo);
|
|
101
|
+
mc_grid = padded.grid;
|
|
102
|
+
// marching_cubes maps [0,1] fractional -> Cartesian via lattice.
|
|
103
|
+
// The padded grid covers a wider fractional range, so scale the lattice
|
|
104
|
+
// to match. Then shift all vertices by the fractional offset.
|
|
105
|
+
const [la, lb, lc] = volume.lattice;
|
|
106
|
+
const sx = padded.dims[0] / ds_result.dims[0];
|
|
107
|
+
const sy = padded.dims[1] / ds_result.dims[1];
|
|
108
|
+
const sz = padded.dims[2] / ds_result.dims[2];
|
|
109
|
+
mc_lattice = [
|
|
110
|
+
[la[0] * sx, la[1] * sx, la[2] * sx],
|
|
111
|
+
[lb[0] * sy, lb[1] * sy, lb[2] * sy],
|
|
112
|
+
[lc[0] * sz, lc[1] * sz, lc[2] * sz],
|
|
113
|
+
];
|
|
114
|
+
const [ox, oy, oz] = padded.offset;
|
|
115
|
+
origin_shift = [
|
|
116
|
+
ox * la[0] + oy * lb[0] + oz * lc[0],
|
|
117
|
+
ox * la[1] + oy * lb[1] + oz * lc[1],
|
|
118
|
+
ox * la[2] + oy * lb[2] + oz * lc[2],
|
|
119
|
+
];
|
|
82
120
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
121
|
+
const surface_at = (isovalue) => extract_surface(isovalue, mc_grid, mc_lattice, origin_shift);
|
|
122
|
+
// Render lower-isovalue (outer) shells earlier so per-layer back/front passes
|
|
123
|
+
// interleave back-to-front across shells and reduce transparency artefacts.
|
|
124
|
+
const layer_render_rank = new Map(layers
|
|
125
|
+
.map((layer, layer_idx) => ({ layer_idx, isovalue: layer.isovalue }))
|
|
126
|
+
.sort((layer_a, layer_b) => layer_a.isovalue - layer_b.isovalue)
|
|
127
|
+
.map(({ layer_idx }, rank) => [layer_idx, rank]));
|
|
128
|
+
for (let layer_idx = 0; layer_idx < layers.length; layer_idx++) {
|
|
129
|
+
const layer = layers[layer_idx];
|
|
130
|
+
if (!layer.visible || layer.isovalue <= 0)
|
|
131
|
+
continue;
|
|
132
|
+
// Each layer gets 4 slots (positive back/front + negative back/front).
|
|
133
|
+
const base_order = (layer_render_rank.get(layer_idx) ?? layer_idx) * 4;
|
|
134
|
+
const pos_geo = surface_at(layer.isovalue);
|
|
135
|
+
if (pos_geo) {
|
|
136
|
+
entries.push({
|
|
137
|
+
geometry: pos_geo,
|
|
138
|
+
color: layer.color,
|
|
139
|
+
opacity: layer.opacity,
|
|
140
|
+
render_order: base_order,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
if (layer.show_negative) {
|
|
144
|
+
const neg_geo = surface_at(-layer.isovalue);
|
|
145
|
+
if (neg_geo) {
|
|
95
146
|
entries.push({
|
|
96
|
-
geometry:
|
|
97
|
-
color: layer.
|
|
147
|
+
geometry: neg_geo,
|
|
148
|
+
color: layer.negative_color,
|
|
98
149
|
opacity: layer.opacity,
|
|
99
|
-
render_order: base_order,
|
|
150
|
+
render_order: base_order + 2,
|
|
100
151
|
});
|
|
101
152
|
}
|
|
102
|
-
if (layer.show_negative) {
|
|
103
|
-
const neg_geo = extract_surface(-layer.isovalue);
|
|
104
|
-
if (neg_geo) {
|
|
105
|
-
entries.push({
|
|
106
|
-
geometry: neg_geo,
|
|
107
|
-
color: layer.negative_color,
|
|
108
|
-
opacity: layer.opacity,
|
|
109
|
-
render_order: base_order + 2,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
153
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
154
|
+
}
|
|
155
|
+
active_geometries = entries;
|
|
156
|
+
for (const entry of old)
|
|
157
|
+
entry.geometry.dispose();
|
|
158
|
+
}
|
|
159
|
+
// Rebuild all layer geometries when layers or volume change.
|
|
160
|
+
// Debounces rapid changes (e.g. slider drags) to avoid repeated expensive marching cubes.
|
|
161
|
+
$effect(() => {
|
|
162
|
+
const layers = resolved_layers;
|
|
163
|
+
void settings.halo;
|
|
164
|
+
if (!ds_result) {
|
|
165
|
+
dispose_all();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
debounce_id = window.setTimeout(() => {
|
|
169
|
+
raf_id = requestAnimationFrame(() => rebuild_geometries(layers));
|
|
170
|
+
}, 50);
|
|
171
|
+
return () => {
|
|
172
|
+
clearTimeout(debounce_id);
|
|
173
|
+
cancelAnimationFrame(raf_id);
|
|
174
|
+
};
|
|
119
175
|
});
|
|
120
176
|
</script>
|
|
121
177
|
|
|
@@ -39,6 +39,7 @@ function update_layer(idx, updates) {
|
|
|
39
39
|
opacity: settings.opacity,
|
|
40
40
|
show_negative: settings.show_negative,
|
|
41
41
|
wireframe: settings.wireframe,
|
|
42
|
+
halo: settings.halo,
|
|
42
43
|
layers: n_layers,
|
|
43
44
|
}}
|
|
44
45
|
on_reset={() => {
|
|
@@ -205,6 +206,24 @@ function update_layer(idx, updates) {
|
|
|
205
206
|
</div>
|
|
206
207
|
{/if}
|
|
207
208
|
|
|
209
|
+
{#if volumes?.[active_volume_idx]?.periodic}
|
|
210
|
+
<label
|
|
211
|
+
{@attach tooltip({
|
|
212
|
+
content:
|
|
213
|
+
`Extend isosurface beyond cell boundaries to close partial spheres (fraction of cell)`,
|
|
214
|
+
})}
|
|
215
|
+
>
|
|
216
|
+
Halo: {format_num(settings.halo, `.2f`)}
|
|
217
|
+
<input
|
|
218
|
+
type="range"
|
|
219
|
+
min={0}
|
|
220
|
+
max={0.5}
|
|
221
|
+
step={0.01}
|
|
222
|
+
bind:value={settings.halo}
|
|
223
|
+
/>
|
|
224
|
+
</label>
|
|
225
|
+
{/if}
|
|
226
|
+
|
|
208
227
|
{#if volumes[active_volume_idx]}
|
|
209
228
|
<div class="grid-info">
|
|
210
229
|
{volumes[active_volume_idx].grid_dims.join(` × `)} grid | [{
|
package/dist/isosurface/parse.js
CHANGED
|
@@ -87,13 +87,11 @@ function read_lines(text, pos, count) {
|
|
|
87
87
|
}
|
|
88
88
|
return { lines: result, next: pos };
|
|
89
89
|
}
|
|
90
|
-
|
|
91
|
-
function build_grid(data, nx, ny, nz, divisor = 1) {
|
|
90
|
+
function build_grid({ data, nx, ny, nz, divisor = 1, data_order = `z_fastest` }) {
|
|
92
91
|
const grid = new Array(nx);
|
|
93
92
|
let min_val = Infinity;
|
|
94
93
|
let max_val = -Infinity;
|
|
95
94
|
let sum = 0;
|
|
96
|
-
const ny_nz = ny * nz;
|
|
97
95
|
const total = nx * ny * nz;
|
|
98
96
|
const data_len = Math.min(data.length, total);
|
|
99
97
|
if (data_len === 0) {
|
|
@@ -106,35 +104,65 @@ function build_grid(data, nx, ny, nz, divisor = 1) {
|
|
|
106
104
|
}
|
|
107
105
|
return { grid, data_range: { min: 0, max: 0, abs_max: 0, mean: 0 } };
|
|
108
106
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
107
|
+
if (data_order === `z_fastest`) {
|
|
108
|
+
// .cube convention: z varies fastest, then y, then x.
|
|
109
|
+
const ny_nz = ny * nz;
|
|
110
|
+
for (let ix = 0; ix < nx; ix++) {
|
|
111
|
+
const plane = new Array(ny);
|
|
112
|
+
for (let iy = 0; iy < ny; iy++) {
|
|
113
|
+
const row = new Array(nz).fill(0);
|
|
114
|
+
const base = ix * ny_nz + iy * nz;
|
|
115
|
+
const row_end = Math.min(base + nz, data_len);
|
|
116
|
+
for (let flat_idx = base; flat_idx < row_end; flat_idx++) {
|
|
117
|
+
const val = data[flat_idx] / divisor;
|
|
118
|
+
row[flat_idx - base] = val;
|
|
119
|
+
if (val < min_val)
|
|
120
|
+
min_val = val;
|
|
121
|
+
if (val > max_val)
|
|
122
|
+
max_val = val;
|
|
123
|
+
sum += val;
|
|
124
|
+
}
|
|
125
|
+
plane[iy] = row;
|
|
126
|
+
}
|
|
127
|
+
grid[ix] = plane;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
// VASP CHGCAR/ELFCAR/LOCPOT convention: x varies fastest, then y, then z.
|
|
132
|
+
for (let ix = 0; ix < nx; ix++) {
|
|
133
|
+
const plane = new Array(ny);
|
|
134
|
+
for (let iy = 0; iy < ny; iy++)
|
|
135
|
+
plane[iy] = new Array(nz).fill(0);
|
|
136
|
+
grid[ix] = plane;
|
|
137
|
+
}
|
|
138
|
+
let flat_idx = 0;
|
|
139
|
+
let data_exhausted = false;
|
|
140
|
+
for (let iz = 0; iz < nz; iz++) {
|
|
141
|
+
for (let iy = 0; iy < ny; iy++) {
|
|
142
|
+
for (let ix = 0; ix < nx; ix++) {
|
|
143
|
+
if (flat_idx >= data_len) {
|
|
144
|
+
data_exhausted = true;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
const val = data[flat_idx] / divisor;
|
|
148
|
+
grid[ix][iy][iz] = val;
|
|
149
|
+
if (val < min_val)
|
|
150
|
+
min_val = val;
|
|
151
|
+
if (val > max_val)
|
|
152
|
+
max_val = val;
|
|
153
|
+
sum += val;
|
|
154
|
+
flat_idx++;
|
|
155
|
+
}
|
|
156
|
+
if (data_exhausted)
|
|
157
|
+
break;
|
|
123
158
|
}
|
|
124
|
-
|
|
159
|
+
if (data_exhausted)
|
|
160
|
+
break;
|
|
125
161
|
}
|
|
126
|
-
grid[ix] = plane;
|
|
127
162
|
}
|
|
128
163
|
const abs_max = Math.max(Math.abs(min_val), Math.abs(max_val));
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
data_range: {
|
|
132
|
-
min: min_val,
|
|
133
|
-
max: max_val,
|
|
134
|
-
abs_max,
|
|
135
|
-
mean: sum / data_len,
|
|
136
|
-
},
|
|
137
|
-
};
|
|
164
|
+
const data_range = { min: min_val, max: max_val, abs_max, mean: sum / data_len };
|
|
165
|
+
return { grid, data_range };
|
|
138
166
|
}
|
|
139
167
|
// === CHGCAR Parser ===
|
|
140
168
|
// Parse VASP CHGCAR/AECCAR/ELFCAR/LOCPOT file format.
|
|
@@ -289,13 +317,21 @@ export function parse_chgcar(content) {
|
|
|
289
317
|
// Use Math.abs to guard against negative determinant (left-handed lattice).
|
|
290
318
|
const cell_volume = Math.abs(lattice_params.volume);
|
|
291
319
|
const divisor = cell_volume > 1e-30 ? cell_volume : 1;
|
|
292
|
-
const { grid, data_range } = build_grid(
|
|
320
|
+
const { grid, data_range } = build_grid({
|
|
321
|
+
data: data.subarray(0, parsed_count),
|
|
322
|
+
nx: ngx,
|
|
323
|
+
ny: ngy,
|
|
324
|
+
nz: ngz,
|
|
325
|
+
divisor,
|
|
326
|
+
data_order: `x_fastest`,
|
|
327
|
+
});
|
|
293
328
|
volumes.push({
|
|
294
329
|
grid,
|
|
295
330
|
grid_dims: [ngx, ngy, ngz],
|
|
296
331
|
lattice,
|
|
297
332
|
origin: [0, 0, 0],
|
|
298
333
|
data_range,
|
|
334
|
+
data_order: `x_fastest`,
|
|
299
335
|
periodic: true, // VASP grids span [0,1) with N points, wrapping at boundaries
|
|
300
336
|
label: volume_labels[vol_idx],
|
|
301
337
|
});
|
|
@@ -438,13 +474,20 @@ export function parse_cube(content, options = {}) {
|
|
|
438
474
|
return null;
|
|
439
475
|
}
|
|
440
476
|
}
|
|
441
|
-
const { grid, data_range } = build_grid(
|
|
477
|
+
const { grid, data_range } = build_grid({
|
|
478
|
+
data: data.subarray(0, parsed_count),
|
|
479
|
+
nx: n_grid[0],
|
|
480
|
+
ny: n_grid[1],
|
|
481
|
+
nz: n_grid[2],
|
|
482
|
+
data_order: `z_fastest`,
|
|
483
|
+
});
|
|
442
484
|
const volumes = [{
|
|
443
485
|
grid,
|
|
444
486
|
grid_dims: n_grid,
|
|
445
487
|
lattice,
|
|
446
488
|
origin,
|
|
447
489
|
data_range,
|
|
490
|
+
data_order: `z_fastest`,
|
|
448
491
|
periodic: is_periodic, // periodic systems wrap; molecular .cube files include both endpoints
|
|
449
492
|
label: `volumetric data`,
|
|
450
493
|
}];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Vec3 } from '../math';
|
|
1
2
|
import type { VolumetricData } from './types';
|
|
2
3
|
export interface SliceResult {
|
|
3
4
|
data: Float64Array;
|
|
@@ -7,4 +8,4 @@ export interface SliceResult {
|
|
|
7
8
|
max: number;
|
|
8
9
|
}
|
|
9
10
|
export declare function trilinear_interpolate(grid: number[][][], fx: number, fy: number, fz: number, periodic: boolean): number;
|
|
10
|
-
export declare function sample_hkl_slice(volume: VolumetricData, miller_indices:
|
|
11
|
+
export declare function sample_hkl_slice(volume: VolumetricData, miller_indices: Vec3, distance: number, n_points?: number): SliceResult | null;
|
package/dist/isosurface/slice.js
CHANGED
|
@@ -56,7 +56,7 @@ export function trilinear_interpolate(grid, fx, fy, fz, periodic) {
|
|
|
56
56
|
// `miller_indices` [h,k,l] defines the plane normal in reciprocal space.
|
|
57
57
|
// `distance` is fractional [0,1] along the normal direction within the cell.
|
|
58
58
|
// Returns null if indices are all zero.
|
|
59
|
-
export function sample_hkl_slice(volume, miller_indices, distance) {
|
|
59
|
+
export function sample_hkl_slice(volume, miller_indices, distance, n_points) {
|
|
60
60
|
const [h_idx, k_idx, l_idx] = miller_indices;
|
|
61
61
|
if (h_idx === 0 && k_idx === 0 && l_idx === 0)
|
|
62
62
|
return null;
|
|
@@ -113,8 +113,8 @@ export function sample_hkl_slice(volume, miller_indices, distance) {
|
|
|
113
113
|
}
|
|
114
114
|
// Plane position: fractional distance [0,1] along the normal extent
|
|
115
115
|
const d_cartesian = normal_min + distance * (normal_max - normal_min);
|
|
116
|
-
// Sampling resolution:
|
|
117
|
-
const width = Math.max(nx, ny, nz);
|
|
116
|
+
// Sampling resolution: caller-specified or default to max grid dimension
|
|
117
|
+
const width = n_points ?? Math.max(nx, ny, nz);
|
|
118
118
|
const height = width;
|
|
119
119
|
const data = new Float64Array(width * height);
|
|
120
120
|
let data_min = Infinity;
|
|
@@ -8,10 +8,11 @@ export interface DataRange {
|
|
|
8
8
|
}
|
|
9
9
|
export interface VolumetricData {
|
|
10
10
|
grid: number[][][];
|
|
11
|
-
grid_dims:
|
|
11
|
+
grid_dims: Vec3;
|
|
12
12
|
lattice: Matrix3x3;
|
|
13
13
|
origin: Vec3;
|
|
14
14
|
data_range: DataRange;
|
|
15
|
+
data_order?: `x_fastest` | `z_fastest`;
|
|
15
16
|
periodic: boolean;
|
|
16
17
|
label?: string;
|
|
17
18
|
}
|
|
@@ -34,10 +35,21 @@ export interface IsosurfaceSettings {
|
|
|
34
35
|
negative_color: string;
|
|
35
36
|
show_negative: boolean;
|
|
36
37
|
wireframe: boolean;
|
|
38
|
+
halo: number;
|
|
37
39
|
layers?: IsosurfaceLayer[];
|
|
38
40
|
}
|
|
39
41
|
export declare const LAYER_COLORS: readonly ["#3b82f6", "#ef4444", "#22c55e", "#a855f7", "#f97316", "#06b6d4", "#eab308", "#ec4899"];
|
|
40
42
|
export declare function grid_data_range(grid: number[][][]): DataRange;
|
|
43
|
+
export declare function pad_periodic_grid(grid: number[][][], dims: Vec3, pad_fraction: number): {
|
|
44
|
+
grid: number[][][];
|
|
45
|
+
dims: Vec3;
|
|
46
|
+
offset: Vec3;
|
|
47
|
+
};
|
|
48
|
+
export declare function downsample_grid(grid: number[][][], dims: Vec3): {
|
|
49
|
+
grid: number[][][];
|
|
50
|
+
dims: Vec3;
|
|
51
|
+
factor: number;
|
|
52
|
+
};
|
|
41
53
|
export declare const DEFAULT_ISOSURFACE_SETTINGS: IsosurfaceSettings;
|
|
42
54
|
export declare function auto_isosurface_settings(data_range: DataRange): IsosurfaceSettings;
|
|
43
55
|
export declare function generate_layers(data_range: DataRange, n_layers: number): IsosurfaceLayer[];
|
package/dist/isosurface/types.js
CHANGED
|
@@ -34,6 +34,103 @@ export function grid_data_range(grid) {
|
|
|
34
34
|
const abs_max = Math.max(Math.abs(min_val), Math.abs(max_val));
|
|
35
35
|
return { min: min_val, max: max_val, abs_max, mean: count > 0 ? sum / count : 0 };
|
|
36
36
|
}
|
|
37
|
+
// Pad a periodic 3D grid with halo cells from the opposite face so isosurfaces
|
|
38
|
+
// extend beyond the unit cell and close into complete enclosed shapes.
|
|
39
|
+
// Returns a larger grid with dims [nx+2*pad, ny+2*pad, nz+2*pad] and the
|
|
40
|
+
// fractional offset that the padded grid's origin has shifted by.
|
|
41
|
+
export function pad_periodic_grid(grid, dims, pad_fraction) {
|
|
42
|
+
const [nx, ny, nz] = dims;
|
|
43
|
+
const frac = Math.max(0, pad_fraction);
|
|
44
|
+
const px = Math.min(Math.ceil(nx * frac), Math.floor(nx / 2));
|
|
45
|
+
const py = Math.min(Math.ceil(ny * frac), Math.floor(ny / 2));
|
|
46
|
+
const pz = Math.min(Math.ceil(nz * frac), Math.floor(nz / 2));
|
|
47
|
+
if (px === 0 && py === 0 && pz === 0)
|
|
48
|
+
return { grid, dims, offset: [0, 0, 0] };
|
|
49
|
+
const out_nx = nx + 2 * px;
|
|
50
|
+
const out_ny = ny + 2 * py;
|
|
51
|
+
const out_nz = nz + 2 * pz;
|
|
52
|
+
const wrap = (val, size) => ((val % size) + size) % size;
|
|
53
|
+
const out = new Array(out_nx);
|
|
54
|
+
for (let ix = 0; ix < out_nx; ix++) {
|
|
55
|
+
const plane = new Array(out_ny);
|
|
56
|
+
const src_x = wrap(ix - px, nx);
|
|
57
|
+
for (let iy = 0; iy < out_ny; iy++) {
|
|
58
|
+
const row = new Array(out_nz);
|
|
59
|
+
const src_y = wrap(iy - py, ny);
|
|
60
|
+
for (let iz = 0; iz < out_nz; iz++) {
|
|
61
|
+
row[iz] = grid[src_x][src_y][wrap(iz - pz, nz)];
|
|
62
|
+
}
|
|
63
|
+
plane[iy] = row;
|
|
64
|
+
}
|
|
65
|
+
out[ix] = plane;
|
|
66
|
+
}
|
|
67
|
+
// Fractional offset: the padded grid starts at -pad/n in each axis
|
|
68
|
+
const offset = [-px / nx, -py / ny, -pz / nz];
|
|
69
|
+
return { grid: out, dims: [out_nx, out_ny, out_nz], offset };
|
|
70
|
+
}
|
|
71
|
+
// Max total grid points before downsampling is applied for isosurface extraction.
|
|
72
|
+
// 500K balances visual quality with interactive performance (<200ms marching cubes).
|
|
73
|
+
const MAX_GRID_POINTS = 500_000;
|
|
74
|
+
// Downsample a 3D volumetric grid to keep total point count under MAX_GRID_POINTS.
|
|
75
|
+
// Uses block averaging to preserve data fidelity while reducing grid dimensions.
|
|
76
|
+
// Returns original grid/dims if already within budget.
|
|
77
|
+
export function downsample_grid(grid, dims) {
|
|
78
|
+
const [nx, ny, nz] = dims;
|
|
79
|
+
const total = nx * ny * nz;
|
|
80
|
+
if (total <= MAX_GRID_POINTS)
|
|
81
|
+
return { grid, dims, factor: 1 };
|
|
82
|
+
// Increase factor until the clamped output fits within budget.
|
|
83
|
+
// A single cbrt step can overshoot for anisotropic grids where max(2,...)
|
|
84
|
+
// clamping prevents a small axis from shrinking below 2.
|
|
85
|
+
// clamp_dim: returns 1 for single-cell axes, otherwise clamps to [2, src]
|
|
86
|
+
const clamp_dim = (src, fac) => Math.min(src, Math.max(2, Math.ceil(src / fac)));
|
|
87
|
+
let factor = Math.ceil(Math.cbrt(total / MAX_GRID_POINTS));
|
|
88
|
+
let new_nx = clamp_dim(nx, factor);
|
|
89
|
+
let new_ny = clamp_dim(ny, factor);
|
|
90
|
+
let new_nz = clamp_dim(nz, factor);
|
|
91
|
+
while (new_nx * new_ny * new_nz > MAX_GRID_POINTS) {
|
|
92
|
+
factor++;
|
|
93
|
+
new_nx = clamp_dim(nx, factor);
|
|
94
|
+
new_ny = clamp_dim(ny, factor);
|
|
95
|
+
new_nz = clamp_dim(nz, factor);
|
|
96
|
+
}
|
|
97
|
+
// Proportional partitioning: evenly divides [0, n) into new_n non-empty blocks.
|
|
98
|
+
// Unlike fixed-stride (ix * factor), this is safe when max(2,...) clamping
|
|
99
|
+
// produces more output cells than ceil(n/factor) would — no empty blocks.
|
|
100
|
+
const partition = (n_out, n_src) => Array.from({ length: n_out }, (_, idx) => [
|
|
101
|
+
Math.round(idx * n_src / n_out),
|
|
102
|
+
Math.round((idx + 1) * n_src / n_out),
|
|
103
|
+
]);
|
|
104
|
+
const x_ranges = partition(new_nx, nx);
|
|
105
|
+
const y_ranges = partition(new_ny, ny);
|
|
106
|
+
const z_ranges = partition(new_nz, nz);
|
|
107
|
+
const out = new Array(new_nx);
|
|
108
|
+
for (let ix = 0; ix < new_nx; ix++) {
|
|
109
|
+
const plane = new Array(new_ny);
|
|
110
|
+
const [sx_start, sx_end] = x_ranges[ix];
|
|
111
|
+
for (let iy = 0; iy < new_ny; iy++) {
|
|
112
|
+
const row = new Array(new_nz);
|
|
113
|
+
const [sy_start, sy_end] = y_ranges[iy];
|
|
114
|
+
for (let iz = 0; iz < new_nz; iz++) {
|
|
115
|
+
let sum = 0;
|
|
116
|
+
const [sz_start, sz_end] = z_ranges[iz];
|
|
117
|
+
for (let sx = sx_start; sx < sx_end; sx++) {
|
|
118
|
+
const src_plane = grid[sx];
|
|
119
|
+
for (let sy = sy_start; sy < sy_end; sy++) {
|
|
120
|
+
const src_row = src_plane[sy];
|
|
121
|
+
for (let sz = sz_start; sz < sz_end; sz++) {
|
|
122
|
+
sum += src_row[sz];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
row[iz] = sum / ((sx_end - sx_start) * (sy_end - sy_start) * (sz_end - sz_start));
|
|
127
|
+
}
|
|
128
|
+
plane[iy] = row;
|
|
129
|
+
}
|
|
130
|
+
out[ix] = plane;
|
|
131
|
+
}
|
|
132
|
+
return { grid: out, dims: [new_nx, new_ny, new_nz], factor };
|
|
133
|
+
}
|
|
37
134
|
// Default isosurface rendering settings
|
|
38
135
|
export const DEFAULT_ISOSURFACE_SETTINGS = {
|
|
39
136
|
isovalue: 0.05,
|
|
@@ -42,6 +139,7 @@ export const DEFAULT_ISOSURFACE_SETTINGS = {
|
|
|
42
139
|
negative_color: `#ef4444`, // red
|
|
43
140
|
show_negative: false,
|
|
44
141
|
wireframe: false,
|
|
142
|
+
halo: 0,
|
|
45
143
|
};
|
|
46
144
|
// Compute reasonable isosurface settings from a volume's data range.
|
|
47
145
|
// Sets isovalue to 20% of abs_max and enables negative lobe when data has
|
package/dist/labels.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ChemicalElement, ElementCategory } from './element/types';
|
|
2
|
+
import type { Vec3 } from './math';
|
|
2
3
|
import type { SymbolType } from 'd3-shape';
|
|
3
4
|
import * as d3_symbols from 'd3-shape';
|
|
4
5
|
export type D3Symbol = keyof typeof d3_symbols & `symbol${Capitalize<string>}`;
|
|
@@ -12,7 +13,7 @@ export declare const ELEM_HEATMAP_LABELS: Partial<Record<string, keyof ChemicalE
|
|
|
12
13
|
export declare const DEFAULT_FMT: [string, string];
|
|
13
14
|
export declare const FRACTION_GLYPHS: ReadonlyArray<readonly [number, string]>;
|
|
14
15
|
export declare const format_num: (num: number, fmt?: string | number) => string;
|
|
15
|
-
export declare const format_vec3: (vec:
|
|
16
|
+
export declare const format_vec3: (vec: Readonly<Vec3>, fmt_spec?: string) => string;
|
|
16
17
|
export declare const format_bytes: (bytes?: number) => string;
|
|
17
18
|
export declare function format_fractional(value: number): string;
|
|
18
19
|
export declare function parse_si_float<T extends string | number | null | undefined>(value: T): T | number | string;
|
package/dist/labels.js
CHANGED
|
@@ -56,6 +56,7 @@ export const ELEM_PROPERTY_LABELS = {
|
|
|
56
56
|
electronegativity: [`Electronegativity`, null],
|
|
57
57
|
first_ionization: [`First Ionization Energy`, `eV`],
|
|
58
58
|
melting_point: [`Melting Point`, `K`],
|
|
59
|
+
mendeleev_number: [`Mendeleev Number`, null],
|
|
59
60
|
// molar_heat: [`Molar Heat`, `J/(mol·K)`],
|
|
60
61
|
n_shells: [`Number of Shells`, null],
|
|
61
62
|
n_valence: [`Electron Valency`, null],
|