matterviz 0.3.7 → 0.4.0
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/Icon.svelte +7 -4
- package/dist/MillerIndexInput.svelte +1 -1
- package/dist/api/optimade.js +32 -26
- package/dist/app.css +0 -3
- package/dist/brillouin/BrillouinZone.svelte +8 -3
- package/dist/brillouin/BrillouinZone.svelte.d.ts +2 -1
- package/dist/brillouin/BrillouinZoneScene.svelte +52 -6
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -0
- package/dist/brillouin/BrillouinZoneTooltip.svelte +16 -25
- package/dist/brillouin/compute.js +10 -14
- package/dist/chempot-diagram/ChemPotDiagram.svelte +14 -13
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +12 -15
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +8 -10
- package/dist/chempot-diagram/async-compute.svelte.js +3 -1
- package/dist/chempot-diagram/chempot-worker.js +2 -1
- package/dist/chempot-diagram/compute.d.ts +1 -1
- package/dist/chempot-diagram/compute.js +17 -19
- package/dist/colors/index.js +6 -5
- package/dist/composition/FormulaFilter.svelte +12 -6
- package/dist/composition/PieChart.svelte +6 -5
- package/dist/composition/chem-sys.d.ts +8 -0
- package/dist/composition/chem-sys.js +85 -0
- package/dist/composition/format.js +4 -2
- package/dist/composition/index.d.ts +1 -0
- package/dist/composition/index.js +1 -0
- package/dist/composition/parse.js +25 -13
- package/dist/convex-hull/ConvexHull2D.svelte +12 -10
- package/dist/convex-hull/ConvexHull3D.svelte +5 -5
- package/dist/convex-hull/ConvexHull4D.svelte +5 -9
- package/dist/convex-hull/ConvexHullStats.svelte +12 -12
- package/dist/convex-hull/GasPressureControls.svelte +4 -4
- package/dist/convex-hull/TemperatureSlider.svelte +2 -2
- package/dist/convex-hull/demo-temperature.d.ts +1 -1
- package/dist/convex-hull/demo-temperature.js +20 -22
- package/dist/convex-hull/gas-thermodynamics.d.ts +2 -2
- package/dist/convex-hull/gas-thermodynamics.js +22 -30
- package/dist/convex-hull/helpers.d.ts +3 -0
- package/dist/convex-hull/helpers.js +17 -9
- package/dist/convex-hull/index.d.ts +1 -1
- package/dist/convex-hull/thermodynamics.js +83 -78
- package/dist/convex-hull/types.d.ts +1 -1
- package/dist/coordination/CoordinationBarPlot.svelte +23 -23
- package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
- package/dist/element/ElementTile.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSlice.svelte +13 -5
- package/dist/fermi-surface/FermiSurface.svelte +11 -5
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceControls.svelte +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +3 -0
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte +8 -34
- package/dist/fermi-surface/compute.js +59 -59
- package/dist/fermi-surface/export.js +3 -2
- package/dist/fermi-surface/parse.js +7 -4
- package/dist/fermi-surface/types.d.ts +1 -0
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +23 -21
- package/dist/heatmap-matrix/index.js +1 -1
- package/dist/io/decompress.js +4 -2
- package/dist/io/export.d.ts +4 -4
- package/dist/io/export.js +47 -25
- package/dist/io/fetch.js +5 -1
- package/dist/io/file-drop.d.ts +1 -1
- package/dist/io/file-drop.js +35 -36
- package/dist/io/url-drop.js +64 -33
- package/dist/isosurface/parse.js +6 -7
- package/dist/isosurface/slice.js +5 -4
- package/dist/isosurface/types.js +1 -1
- package/dist/keyboard.d.ts +3 -0
- package/dist/keyboard.js +23 -0
- package/dist/labels.d.ts +1 -1
- package/dist/labels.js +8 -7
- package/dist/layout/PropertyFilter.svelte +3 -2
- package/dist/layout/SettingsSection.svelte +1 -1
- package/dist/layout/json-tree/JsonNode.svelte +1 -1
- package/dist/layout/json-tree/JsonTree.svelte +2 -2
- package/dist/layout/json-tree/utils.js +5 -4
- package/dist/marching-cubes.js +8 -13
- package/dist/math.d.ts +5 -1
- package/dist/math.js +24 -9
- package/dist/overlays/DraggablePane.svelte +4 -4
- package/dist/periodic-table/PeriodicTable.svelte +20 -9
- package/dist/periodic-table/PropertySelect.svelte +1 -0
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +9 -3
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +1 -1
- package/dist/phase-diagram/build-diagram.js +2 -2
- package/dist/phase-diagram/parse.js +6 -5
- package/dist/phase-diagram/types.d.ts +1 -1
- package/dist/phase-diagram/utils.d.ts +3 -3
- package/dist/phase-diagram/utils.js +8 -12
- package/dist/plot/{BarPlot.svelte → bar/BarPlot.svelte} +229 -587
- package/dist/plot/{BarPlot.svelte.d.ts → bar/BarPlot.svelte.d.ts} +5 -5
- package/dist/plot/{BarPlotControls.svelte → bar/BarPlotControls.svelte} +6 -5
- package/dist/plot/{BarPlotControls.svelte.d.ts → bar/BarPlotControls.svelte.d.ts} +3 -3
- package/dist/plot/{SpacegroupBarPlot.svelte → bar/SpacegroupBarPlot.svelte} +6 -6
- package/dist/plot/{SpacegroupBarPlot.svelte.d.ts → bar/SpacegroupBarPlot.svelte.d.ts} +1 -1
- package/dist/plot/bar/data.d.ts +40 -0
- package/dist/plot/bar/data.js +154 -0
- package/dist/plot/bar/geometry.d.ts +39 -0
- package/dist/plot/bar/geometry.js +60 -0
- package/dist/plot/bar/index.d.ts +3 -0
- package/dist/plot/bar/index.js +3 -0
- package/dist/plot/box/BoxPlot.svelte +1462 -0
- package/dist/plot/box/BoxPlot.svelte.d.ts +94 -0
- package/dist/plot/box/BoxPlotControls.svelte +109 -0
- package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
- package/dist/plot/box/Violin.svelte +14 -0
- package/dist/plot/box/Violin.svelte.d.ts +70 -0
- package/dist/plot/box/box-plot.d.ts +55 -0
- package/dist/plot/box/box-plot.js +126 -0
- package/dist/plot/box/index.d.ts +5 -0
- package/dist/plot/box/index.js +5 -0
- package/dist/plot/box/kde.d.ts +16 -0
- package/dist/plot/box/kde.js +160 -0
- package/dist/plot/box/quantile.d.ts +3 -0
- package/dist/plot/box/quantile.js +53 -0
- package/dist/plot/{auto-place.js → core/auto-place.js} +2 -2
- package/dist/plot/core/axis-utils.d.ts +46 -0
- package/dist/plot/core/axis-utils.js +110 -0
- package/dist/plot/{AxisLabel.svelte → core/components/AxisLabel.svelte} +2 -2
- package/dist/plot/{AxisLabel.svelte.d.ts → core/components/AxisLabel.svelte.d.ts} +1 -1
- package/dist/plot/{ColorBar.svelte → core/components/ColorBar.svelte} +36 -33
- package/dist/plot/{ColorBar.svelte.d.ts → core/components/ColorBar.svelte.d.ts} +2 -2
- package/dist/plot/{ColorScaleSelect.svelte → core/components/ColorScaleSelect.svelte} +4 -3
- package/dist/plot/{ColorScaleSelect.svelte.d.ts → core/components/ColorScaleSelect.svelte.d.ts} +2 -2
- package/dist/plot/core/components/ControlPane.svelte +46 -0
- package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
- package/dist/plot/{FillArea.svelte → core/components/FillArea.svelte} +17 -6
- package/dist/plot/{FillArea.svelte.d.ts → core/components/FillArea.svelte.d.ts} +1 -1
- package/dist/plot/{InteractiveAxisLabel.svelte → core/components/InteractiveAxisLabel.svelte} +3 -3
- package/dist/plot/{InteractiveAxisLabel.svelte.d.ts → core/components/InteractiveAxisLabel.svelte.d.ts} +2 -2
- package/dist/plot/{Line.svelte → core/components/Line.svelte} +30 -13
- package/dist/plot/{PlotAxis.svelte → core/components/PlotAxis.svelte} +7 -5
- package/dist/plot/{PlotAxis.svelte.d.ts → core/components/PlotAxis.svelte.d.ts} +3 -2
- package/dist/plot/{PlotControls.svelte → core/components/PlotControls.svelte} +17 -29
- package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
- package/dist/plot/{PlotLegend.svelte → core/components/PlotLegend.svelte} +21 -10
- package/dist/plot/{PlotLegend.svelte.d.ts → core/components/PlotLegend.svelte.d.ts} +3 -2
- package/dist/plot/{PlotTooltip.svelte → core/components/PlotTooltip.svelte} +17 -1
- package/dist/plot/{PlotTooltip.svelte.d.ts → core/components/PlotTooltip.svelte.d.ts} +8 -0
- package/dist/plot/{PortalSelect.svelte → core/components/PortalSelect.svelte} +11 -7
- package/dist/plot/{ReferenceLine.svelte → core/components/ReferenceLine.svelte} +3 -3
- package/dist/plot/{ReferenceLine.svelte.d.ts → core/components/ReferenceLine.svelte.d.ts} +1 -1
- package/dist/plot/{ReferenceLine3D.svelte → core/components/ReferenceLine3D.svelte} +4 -4
- package/dist/plot/{ReferenceLine3D.svelte.d.ts → core/components/ReferenceLine3D.svelte.d.ts} +2 -2
- package/dist/plot/{ReferencePlane.svelte → core/components/ReferencePlane.svelte} +7 -7
- package/dist/plot/{ReferencePlane.svelte.d.ts → core/components/ReferencePlane.svelte.d.ts} +2 -2
- package/dist/plot/{ZeroLines.svelte → core/components/ZeroLines.svelte} +3 -3
- package/dist/plot/{ZeroLines.svelte.d.ts → core/components/ZeroLines.svelte.d.ts} +3 -3
- package/dist/plot/{ZoomRect.svelte → core/components/ZoomRect.svelte} +1 -1
- package/dist/plot/{ZoomRect.svelte.d.ts → core/components/ZoomRect.svelte.d.ts} +1 -1
- package/dist/plot/core/components/index.d.ts +17 -0
- package/dist/plot/core/components/index.js +17 -0
- package/dist/plot/{data-cleaning.d.ts → core/data-cleaning.d.ts} +71 -1
- package/dist/plot/{data-cleaning.js → core/data-cleaning.js} +3 -5
- package/dist/plot/{data-transform.d.ts → core/data-transform.d.ts} +2 -2
- package/dist/plot/{data-transform.js → core/data-transform.js} +3 -3
- package/dist/plot/core/fill-utils.d.ts +33 -0
- package/dist/plot/core/fill-utils.js +388 -0
- package/dist/plot/{hover-lock.svelte.js → core/hover-lock.svelte.js} +5 -6
- package/dist/plot/core/index.d.ts +10 -0
- package/dist/plot/core/index.js +11 -0
- package/dist/plot/core/interactions.d.ts +35 -0
- package/dist/plot/core/interactions.js +195 -0
- package/dist/plot/{layout.d.ts → core/layout.d.ts} +1 -0
- package/dist/plot/{layout.js → core/layout.js} +16 -8
- package/dist/plot/{reference-line.d.ts → core/reference-line.d.ts} +1 -1
- package/dist/plot/{reference-line.js → core/reference-line.js} +23 -36
- package/dist/plot/{scales.d.ts → core/scales.d.ts} +2 -2
- package/dist/plot/{scales.js → core/scales.js} +84 -85
- package/dist/plot/core/svg.d.ts +2 -0
- package/dist/plot/core/svg.js +41 -0
- package/dist/plot/{types.d.ts → core/types.d.ts} +19 -79
- package/dist/plot/{types.js → core/types.js} +1 -1
- package/dist/plot/{utils → core/utils}/label-placement.d.ts +2 -2
- package/dist/plot/core/utils/series-visibility.d.ts +26 -0
- package/dist/plot/{utils → core/utils}/series-visibility.js +29 -2
- package/dist/plot/core/utils.d.ts +11 -0
- package/dist/plot/core/utils.js +27 -0
- package/dist/plot/{Histogram.svelte → histogram/Histogram.svelte} +154 -294
- package/dist/plot/{Histogram.svelte.d.ts → histogram/Histogram.svelte.d.ts} +2 -2
- package/dist/plot/{HistogramControls.svelte → histogram/HistogramControls.svelte} +6 -6
- package/dist/plot/{HistogramControls.svelte.d.ts → histogram/HistogramControls.svelte.d.ts} +4 -4
- package/dist/plot/histogram/index.d.ts +2 -0
- package/dist/plot/histogram/index.js +2 -0
- package/dist/plot/index.d.ts +8 -41
- package/dist/plot/index.js +10 -39
- package/dist/plot/sankey/Sankey.svelte +700 -0
- package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
- package/dist/plot/sankey/SankeyControls.svelte +98 -0
- package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
- package/dist/plot/sankey/index.d.ts +4 -0
- package/dist/plot/sankey/index.js +3 -0
- package/dist/plot/sankey/sankey-types.d.ts +42 -0
- package/dist/plot/sankey/sankey-types.js +4 -0
- package/dist/plot/sankey/sankey.d.ts +52 -0
- package/dist/plot/sankey/sankey.js +187 -0
- package/dist/plot/{BinnedScatterPlot.svelte → scatter/BinnedScatterPlot.svelte} +61 -59
- package/dist/plot/{BinnedScatterPlot.svelte.d.ts → scatter/BinnedScatterPlot.svelte.d.ts} +4 -4
- package/dist/plot/{ElementScatter.svelte → scatter/ElementScatter.svelte} +6 -6
- package/dist/plot/{ElementScatter.svelte.d.ts → scatter/ElementScatter.svelte.d.ts} +2 -2
- package/dist/plot/{ScatterPlot.svelte → scatter/ScatterPlot.svelte} +221 -642
- package/dist/plot/{ScatterPlot.svelte.d.ts → scatter/ScatterPlot.svelte.d.ts} +7 -7
- package/dist/plot/{ScatterPlotControls.svelte → scatter/ScatterPlotControls.svelte} +6 -5
- package/dist/plot/{ScatterPlotControls.svelte.d.ts → scatter/ScatterPlotControls.svelte.d.ts} +1 -1
- package/dist/plot/{ScatterPoint.svelte → scatter/ScatterPoint.svelte} +7 -7
- package/dist/plot/{ScatterPoint.svelte.d.ts → scatter/ScatterPoint.svelte.d.ts} +3 -3
- package/dist/plot/{adaptive-density.d.ts → scatter/adaptive-density.d.ts} +14 -4
- package/dist/plot/{adaptive-density.js → scatter/adaptive-density.js} +46 -20
- package/dist/plot/{binned-scatter-types.d.ts → scatter/binned-scatter-types.d.ts} +3 -3
- package/dist/plot/scatter/index.d.ts +7 -0
- package/dist/plot/scatter/index.js +5 -0
- package/dist/plot/scatter/scatter-data.d.ts +19 -0
- package/dist/plot/scatter/scatter-data.js +212 -0
- package/dist/plot/{ScatterPlot3D.svelte → scatter-3d/ScatterPlot3D.svelte} +12 -10
- package/dist/plot/{ScatterPlot3D.svelte.d.ts → scatter-3d/ScatterPlot3D.svelte.d.ts} +7 -7
- package/dist/plot/{ScatterPlot3DControls.svelte → scatter-3d/ScatterPlot3DControls.svelte} +5 -4
- package/dist/plot/{ScatterPlot3DControls.svelte.d.ts → scatter-3d/ScatterPlot3DControls.svelte.d.ts} +2 -2
- package/dist/plot/{ScatterPlot3DScene.svelte → scatter-3d/ScatterPlot3DScene.svelte} +11 -11
- package/dist/plot/{ScatterPlot3DScene.svelte.d.ts → scatter-3d/ScatterPlot3DScene.svelte.d.ts} +3 -3
- package/dist/plot/{Surface3D.svelte → scatter-3d/Surface3D.svelte} +1 -1
- package/dist/plot/{Surface3D.svelte.d.ts → scatter-3d/Surface3D.svelte.d.ts} +1 -1
- package/dist/plot/scatter-3d/index.d.ts +4 -0
- package/dist/plot/scatter-3d/index.js +4 -0
- package/dist/plot/sunburst/Sunburst.svelte +1045 -0
- package/dist/plot/sunburst/Sunburst.svelte.d.ts +96 -0
- package/dist/plot/sunburst/SunburstControls.svelte +200 -0
- package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
- package/dist/plot/sunburst/index.d.ts +4 -0
- package/dist/plot/sunburst/index.js +4 -0
- package/dist/plot/sunburst/render.d.ts +34 -0
- package/dist/plot/sunburst/render.js +122 -0
- package/dist/plot/sunburst/sunburst.d.ts +62 -0
- package/dist/plot/sunburst/sunburst.js +266 -0
- package/dist/rdf/RdfPlot.svelte +2 -1
- package/dist/rdf/calc-rdf.js +11 -24
- package/dist/sanitize.js +1 -1
- package/dist/settings.d.ts +65 -1
- package/dist/settings.js +262 -0
- package/dist/spectral/Bands.svelte +39 -29
- package/dist/spectral/Bands.svelte.d.ts +3 -4
- package/dist/spectral/BandsAndDos.svelte +1 -1
- package/dist/spectral/BrillouinBandsDos.svelte +39 -27
- package/dist/spectral/Dos.svelte +10 -19
- package/dist/spectral/Dos.svelte.d.ts +2 -2
- package/dist/spectral/helpers.d.ts +3 -1
- package/dist/spectral/helpers.js +95 -29
- package/dist/structure/AtomLegend.svelte +8 -9
- package/dist/structure/CellSelect.svelte +1 -2
- package/dist/structure/Cylinder.svelte +12 -8
- package/dist/structure/Cylinder.svelte.d.ts +4 -1
- package/dist/structure/Structure.svelte +78 -72
- package/dist/structure/Structure.svelte.d.ts +1 -1
- package/dist/structure/StructureInfoPane.svelte +5 -6
- package/dist/structure/StructureScene.svelte +11 -10
- package/dist/structure/atom-properties.js +6 -6
- package/dist/structure/bond-order-perception.js +1 -1
- package/dist/structure/bonding.d.ts +1 -0
- package/dist/structure/bonding.js +43 -15
- package/dist/structure/export.js +27 -23
- package/dist/structure/index.d.ts +2 -4
- package/dist/structure/index.js +1 -3
- package/dist/structure/label-placement.js +4 -4
- package/dist/structure/measure.d.ts +3 -2
- package/dist/structure/measure.js +6 -5
- package/dist/structure/parse.js +121 -103
- package/dist/structure/pbc.js +4 -0
- package/dist/symmetry/SymmetryStats.svelte +2 -2
- package/dist/symmetry/index.d.ts +1 -1
- package/dist/symmetry/index.js +22 -24
- package/dist/symmetry/spacegroups.d.ts +7 -0
- package/dist/symmetry/spacegroups.js +48 -13
- package/dist/table/HeatmapTable.svelte +63 -11
- package/dist/table/HeatmapTable.svelte.d.ts +1 -1
- package/dist/table/index.d.ts +1 -3
- package/dist/table/index.js +1 -1
- package/dist/theme/index.js +8 -8
- package/dist/tooltip/KCoords.svelte +45 -0
- package/dist/tooltip/KCoords.svelte.d.ts +8 -0
- package/dist/tooltip/index.d.ts +1 -0
- package/dist/tooltip/index.js +1 -0
- package/dist/trajectory/Trajectory.svelte +66 -40
- package/dist/trajectory/Trajectory.svelte.d.ts +2 -1
- package/dist/trajectory/TrajectoryExportPane.svelte +2 -1
- package/dist/trajectory/TrajectoryInfoPane.svelte +2 -1
- package/dist/trajectory/format-detect.d.ts +1 -0
- package/dist/trajectory/format-detect.js +25 -11
- package/dist/trajectory/frame-reader.js +17 -50
- package/dist/trajectory/helpers.js +1 -1
- package/dist/trajectory/index.js +1 -1
- package/dist/trajectory/parse/hdf5.js +1 -1
- package/dist/trajectory/parse/index.js +14 -6
- package/dist/trajectory/parse/vasp.js +36 -17
- package/dist/trajectory/parse/xyz.d.ts +24 -0
- package/dist/trajectory/parse/xyz.js +102 -89
- package/dist/trajectory/plotting.d.ts +1 -1
- package/dist/trajectory/plotting.js +15 -15
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +6 -4
- package/dist/xrd/XrdPlot.svelte +2 -1
- package/dist/xrd/calc-xrd.js +15 -12
- package/dist/xrd/parse.js +2 -2
- package/package.json +22 -18
- package/dist/plot/PlotControls.svelte.d.ts +0 -4
- package/dist/plot/axis-utils.d.ts +0 -19
- package/dist/plot/axis-utils.js +0 -78
- package/dist/plot/defaults.d.ts +0 -19
- package/dist/plot/defaults.js +0 -9
- package/dist/plot/fill-utils.d.ts +0 -46
- package/dist/plot/fill-utils.js +0 -322
- package/dist/plot/interactions.d.ts +0 -12
- package/dist/plot/interactions.js +0 -101
- package/dist/plot/svg.d.ts +0 -1
- package/dist/plot/svg.js +0 -11
- package/dist/plot/utils/series-visibility.d.ts +0 -15
- package/dist/plot/utils.d.ts +0 -1
- package/dist/plot/utils.js +0 -14
- /package/dist/plot/{auto-place.d.ts → core/auto-place.d.ts} +0 -0
- /package/dist/plot/{Line.svelte.d.ts → core/components/Line.svelte.d.ts} +0 -0
- /package/dist/plot/{PortalSelect.svelte.d.ts → core/components/PortalSelect.svelte.d.ts} +0 -0
- /package/dist/plot/{hover-lock.svelte.d.ts → core/hover-lock.svelte.d.ts} +0 -0
- /package/dist/plot/{utils → core/utils}/label-placement.js +0 -0
- /package/dist/plot/{binned-scatter-types.js → scatter/binned-scatter-types.js} +0 -0
|
@@ -40,24 +40,20 @@ export function spacegroup_num_to_crystal_sys(spacegroup) {
|
|
|
40
40
|
}
|
|
41
41
|
// Convert space group (number or symbol) to crystal system
|
|
42
42
|
export function spacegroup_to_crystal_sys(spacegroup) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// Try to parse as symbol
|
|
46
|
-
const number = SPACEGROUP_SYMBOL_TO_NUM[spacegroup];
|
|
47
|
-
if (number !== undefined)
|
|
48
|
-
return spacegroup_num_to_crystal_sys(number);
|
|
49
|
-
// Try to parse string as number
|
|
50
|
-
const parsed = parseInt(spacegroup, 10);
|
|
51
|
-
if (!isNaN(parsed))
|
|
52
|
-
return spacegroup_num_to_crystal_sys(parsed);
|
|
53
|
-
return null;
|
|
43
|
+
const num = normalize_spacegroup(spacegroup);
|
|
44
|
+
return num == null ? null : spacegroup_num_to_crystal_sys(num);
|
|
54
45
|
}
|
|
55
|
-
// Normalize space group input
|
|
46
|
+
// Normalize space group input (number, Hermann-Mauguin symbol, or numeric string
|
|
47
|
+
// like "225") to a space group number in [1, 230], or null if invalid
|
|
56
48
|
export function normalize_spacegroup(spacegroup) {
|
|
57
49
|
if (typeof spacegroup === `number`) {
|
|
58
50
|
return spacegroup >= 1 && spacegroup <= 230 ? spacegroup : null;
|
|
59
51
|
}
|
|
60
|
-
|
|
52
|
+
const from_symbol = SPACEGROUP_SYMBOL_TO_NUM[spacegroup];
|
|
53
|
+
if (from_symbol !== undefined)
|
|
54
|
+
return from_symbol;
|
|
55
|
+
const parsed = parseInt(spacegroup, 10);
|
|
56
|
+
return isNaN(parsed) ? null : normalize_spacegroup(parsed);
|
|
61
57
|
}
|
|
62
58
|
export const SPACEGROUP_SYMBOL_TO_NUM = {
|
|
63
59
|
// Triclinic
|
|
@@ -392,3 +388,42 @@ export const SPACEGROUP_NUM_TO_SYMBOL = Object.entries(SPACEGROUP_SYMBOL_TO_NUM)
|
|
|
392
388
|
acc[num] = symbol;
|
|
393
389
|
return acc;
|
|
394
390
|
}, {});
|
|
391
|
+
// Build crystal-system -> spacegroup hierarchy data for the Sunburst component from a
|
|
392
|
+
// list of spacegroup numbers or symbols (one entry per occurrence; counts become leaf
|
|
393
|
+
// values). Leaf ids follow the pymatviz spacegroup_sunburst scheme, e.g. "cubic/225".
|
|
394
|
+
export function spacegroup_sunburst_data(spacegroups) {
|
|
395
|
+
const counts = new Map();
|
|
396
|
+
let n_invalid = 0;
|
|
397
|
+
for (const spacegroup of spacegroups) {
|
|
398
|
+
const num = normalize_spacegroup(spacegroup); // numbers, symbols, numeric strings
|
|
399
|
+
if (num == null) {
|
|
400
|
+
n_invalid += 1;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
counts.set(num, (counts.get(num) ?? 0) + 1);
|
|
404
|
+
}
|
|
405
|
+
if (n_invalid > 0) {
|
|
406
|
+
console.warn(`spacegroup_sunburst_data: skipped ${n_invalid} invalid spacegroup(s) (expected numbers 1-230 or Hermann-Mauguin symbols)`);
|
|
407
|
+
}
|
|
408
|
+
// Emit crystal systems in canonical (space group number) order, only those present
|
|
409
|
+
return CRYSTAL_SYSTEMS.flatMap((system) => {
|
|
410
|
+
const nums = [...counts.keys()]
|
|
411
|
+
.filter((num) => spacegroup_num_to_crystal_sys(num) === system)
|
|
412
|
+
.sort((num_a, num_b) => num_a - num_b);
|
|
413
|
+
if (nums.length === 0)
|
|
414
|
+
return [];
|
|
415
|
+
return [
|
|
416
|
+
{
|
|
417
|
+
id: system,
|
|
418
|
+
label: system,
|
|
419
|
+
color: CRYSTAL_SYSTEM_COLORS[system],
|
|
420
|
+
children: nums.map((num) => ({
|
|
421
|
+
id: `${system}/${num}`,
|
|
422
|
+
label: SPACEGROUP_NUM_TO_SYMBOL[num] ?? `${num}`,
|
|
423
|
+
value: counts.get(num),
|
|
424
|
+
metadata: { spacegroup: num, crystal_system: system },
|
|
425
|
+
})),
|
|
426
|
+
},
|
|
427
|
+
];
|
|
428
|
+
});
|
|
429
|
+
}
|
|
@@ -32,6 +32,57 @@
|
|
|
32
32
|
const is_invalid = (val: unknown) =>
|
|
33
33
|
val == null || (typeof val === `number` && Number.isNaN(val))
|
|
34
34
|
|
|
35
|
+
// tooltip() wires [title]/[aria-label]/[data-title] elements once when it runs.
|
|
36
|
+
// Table cells are replaced when the table re-renders (sort, filter, data or
|
|
37
|
+
// pagination changes), which would silently drop their tooltips. Observe the
|
|
38
|
+
// container and incrementally wire newly added elements / unwire removed ones,
|
|
39
|
+
// instead of tearing down and rebuilding every tooltip on each unrelated DOM
|
|
40
|
+
// mutation (dropdowns, panes, pagination, context menu).
|
|
41
|
+
const tooltip_selector = `[title], [aria-label], [data-title]`
|
|
42
|
+
function table_tooltips(node: HTMLElement) {
|
|
43
|
+
const options = { allow_html: true } as const
|
|
44
|
+
// Per-element cleanups so individual nodes can be unwired as they leave the DOM.
|
|
45
|
+
const wired = new SvelteMap<Element, () => void>()
|
|
46
|
+
|
|
47
|
+
const wire = (root: Element) => {
|
|
48
|
+
const targets = root.matches(tooltip_selector)
|
|
49
|
+
? [root, ...root.querySelectorAll(tooltip_selector)]
|
|
50
|
+
: [...root.querySelectorAll(tooltip_selector)]
|
|
51
|
+
for (const el of targets) {
|
|
52
|
+
if (!(el instanceof HTMLElement) || wired.has(el)) continue
|
|
53
|
+
// tooltip() only mutates attributes (title -> data-original-title), never
|
|
54
|
+
// childList, so wiring here can't re-trigger the childList observer below.
|
|
55
|
+
const cleanup = tooltip(options)(el)
|
|
56
|
+
if (cleanup) wired.set(el, cleanup)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
wire(node)
|
|
61
|
+
const observer = new MutationObserver((mutations) => {
|
|
62
|
+
// Unwire elements that left the DOM. isConnected stays true for moved nodes
|
|
63
|
+
// (e.g. row reordering on sort), so those keep their tooltips without churn.
|
|
64
|
+
// Deleting the current entry mid-iteration is safe for Map.
|
|
65
|
+
for (const [el, cleanup] of wired) {
|
|
66
|
+
if (!el.isConnected) {
|
|
67
|
+
cleanup()
|
|
68
|
+
wired.delete(el)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Wire only the freshly added subtrees, not the whole container.
|
|
72
|
+
for (const { addedNodes } of mutations) {
|
|
73
|
+
for (const added of addedNodes) {
|
|
74
|
+
if (added instanceof Element) wire(added)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
observer.observe(node, { childList: true, subtree: true })
|
|
79
|
+
return () => {
|
|
80
|
+
observer.disconnect()
|
|
81
|
+
for (const cleanup of wired.values()) cleanup()
|
|
82
|
+
wired.clear()
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
35
86
|
const NUMERIC_WITH_ERROR_RE =
|
|
36
87
|
/^([-+−]?(?:\d+\.?\d*|\d*\.\d+)(?:[eE][-+−]?\d+)?)\s*(?:±|\+[-−]|\()/
|
|
37
88
|
|
|
@@ -484,7 +535,7 @@
|
|
|
484
535
|
|
|
485
536
|
// Push invalid values to bottom
|
|
486
537
|
if (is_invalid(val1) || is_invalid(val2)) {
|
|
487
|
-
return
|
|
538
|
+
return Number(is_invalid(val1)) - Number(is_invalid(val2))
|
|
488
539
|
}
|
|
489
540
|
|
|
490
541
|
const sort_val1 = get_sort_val(val1)
|
|
@@ -497,10 +548,11 @@
|
|
|
497
548
|
sensitivity: `base`,
|
|
498
549
|
})
|
|
499
550
|
if (cmp !== 0) return cmp * modifier
|
|
500
|
-
} else {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
551
|
+
} else if (typeof sort_val1 !== typeof sort_val2) {
|
|
552
|
+
// number<string is false both ways, breaking the comparator: numbers sort first
|
|
553
|
+
return (typeof sort_val1 === `number` ? -1 : 1) * modifier
|
|
554
|
+
} else if (sort_val1 !== sort_val2) {
|
|
555
|
+
return (sort_val1 ?? 0) < (sort_val2 ?? 0) ? -modifier : modifier
|
|
504
556
|
}
|
|
505
557
|
}
|
|
506
558
|
return 0
|
|
@@ -558,7 +610,7 @@
|
|
|
558
610
|
// Shift+click for multi-column sort
|
|
559
611
|
if (event.shiftKey) {
|
|
560
612
|
const existing_idx = multi_sort.findIndex((sort_entry) => sort_entry.column === col_id)
|
|
561
|
-
if (existing_idx
|
|
613
|
+
if (existing_idx !== -1) {
|
|
562
614
|
// Toggle direction or remove if clicked again
|
|
563
615
|
const existing = multi_sort[existing_idx]
|
|
564
616
|
if (existing.ascending === (col.better === `lower`)) {
|
|
@@ -684,7 +736,7 @@
|
|
|
684
736
|
|
|
685
737
|
// Check multi-sort first
|
|
686
738
|
const multi_idx = multi_sort.findIndex((sort_entry) => sort_entry.column === col_id)
|
|
687
|
-
if (multi_idx
|
|
739
|
+
if (multi_idx !== -1) {
|
|
688
740
|
const arrow = multi_sort[multi_idx].ascending ? `↓` : `↑`
|
|
689
741
|
const badge = multi_sort.length > 1 ? `<sup>${multi_idx + 1}</sup>` : ``
|
|
690
742
|
return `<span style="font-size: 0.8em;">${arrow}${badge}</span>`
|
|
@@ -716,7 +768,7 @@
|
|
|
716
768
|
function toggle_row_select(row: RowData) {
|
|
717
769
|
const row_id = get_row_id(row)
|
|
718
770
|
const idx = selected_rows.findIndex((selected_row) => get_row_id(selected_row) === row_id)
|
|
719
|
-
if (idx
|
|
771
|
+
if (idx !== -1) {
|
|
720
772
|
selected_rows = selected_rows.filter((_, i) => i !== idx)
|
|
721
773
|
} else {
|
|
722
774
|
selected_rows = [...selected_rows, row]
|
|
@@ -755,7 +807,7 @@
|
|
|
755
807
|
const quote = (str: string) => {
|
|
756
808
|
if (!csv_quote) return str
|
|
757
809
|
if (str.includes(`,`) || str.includes(`"`) || str.includes(`\n`)) {
|
|
758
|
-
return `"${str.
|
|
810
|
+
return `"${str.replaceAll('"', `""`)}"`
|
|
759
811
|
}
|
|
760
812
|
return str
|
|
761
813
|
}
|
|
@@ -799,7 +851,7 @@
|
|
|
799
851
|
const link = document.createElement(`a`)
|
|
800
852
|
link.href = url
|
|
801
853
|
link.download = filename
|
|
802
|
-
document.body.
|
|
854
|
+
document.body.append(link)
|
|
803
855
|
link.click()
|
|
804
856
|
document.body.removeChild(link)
|
|
805
857
|
URL.revokeObjectURL(url)
|
|
@@ -869,7 +921,7 @@
|
|
|
869
921
|
{/snippet}
|
|
870
922
|
|
|
871
923
|
<div
|
|
872
|
-
{@attach
|
|
924
|
+
{@attach table_tooltips}
|
|
873
925
|
{...rest_props}
|
|
874
926
|
bind:this={container_el}
|
|
875
927
|
class="table-container {rest_props.class ?? ``}"
|
|
@@ -44,6 +44,6 @@ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
|
|
|
44
44
|
}]>;
|
|
45
45
|
footer?: Snippet;
|
|
46
46
|
};
|
|
47
|
-
declare const HeatmapTable: import("svelte").Component<$$ComponentProps, {}, "sort" | "data" | "show_controls" | "
|
|
47
|
+
declare const HeatmapTable: import("svelte").Component<$$ComponentProps, {}, "sort" | "data" | "show_controls" | "controls_open" | "show_heatmap" | "column_order" | "selected_rows" | "hidden_columns" | "loading" | "heatmap_opacity">;
|
|
48
48
|
type HeatmapTable = ReturnType<typeof HeatmapTable>;
|
|
49
49
|
export default HeatmapTable;
|
package/dist/table/index.d.ts
CHANGED
|
@@ -2,9 +2,7 @@ import * as d3sc from 'd3-scale-chromatic';
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
export { default as HeatmapTable } from './HeatmapTable.svelte';
|
|
4
4
|
export { default as ToggleMenu } from './ToggleMenu.svelte';
|
|
5
|
-
export type CellVal = string | number | boolean | undefined | null | Record<string, unknown> |
|
|
6
|
-
[key: string]: string | number | null | undefined | boolean;
|
|
7
|
-
}[];
|
|
5
|
+
export type CellVal = string | number | boolean | undefined | null | Record<string, unknown> | Record<string, string | number | null | undefined | boolean>[];
|
|
8
6
|
export type RowData = {
|
|
9
7
|
style?: string;
|
|
10
8
|
class?: string;
|
package/dist/table/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import * as d3sc from 'd3-scale-chromatic';
|
|
|
5
5
|
export { default as HeatmapTable } from './HeatmapTable.svelte';
|
|
6
6
|
export { default as ToggleMenu } from './ToggleMenu.svelte';
|
|
7
7
|
// Strip HTML tags from a string (for search, export, etc.)
|
|
8
|
-
export const strip_html = (str) => str.
|
|
8
|
+
export const strip_html = (str) => str.replaceAll(/<[^>]*>/g, ``);
|
|
9
9
|
// Calculate table cell background color based on its value and column config
|
|
10
10
|
export function calc_cell_color(val, // cell value
|
|
11
11
|
all_values, // all values in the column
|
package/dist/theme/index.js
CHANGED
|
@@ -33,7 +33,7 @@ export const get_theme_preference = () => {
|
|
|
33
33
|
return AUTO_THEME;
|
|
34
34
|
try {
|
|
35
35
|
const saved = localStorage[storage_key];
|
|
36
|
-
return is_valid_theme_mode(saved
|
|
36
|
+
return is_valid_theme_mode(saved ?? ``) ? saved : AUTO_THEME;
|
|
37
37
|
}
|
|
38
38
|
catch {
|
|
39
39
|
return AUTO_THEME;
|
|
@@ -57,8 +57,8 @@ export const apply_theme_to_dom = (mode) => {
|
|
|
57
57
|
if (!resolved || !(resolved in THEME_TYPE)) {
|
|
58
58
|
throw new Error(`Invalid theme mode: ${resolved}`);
|
|
59
59
|
}
|
|
60
|
-
const theme = globalThis.MATTERVIZ_THEMES?.[resolved]
|
|
61
|
-
const css_vars = globalThis.MATTERVIZ_CSS_MAP
|
|
60
|
+
const theme = globalThis.MATTERVIZ_THEMES?.[resolved] ?? {};
|
|
61
|
+
const css_vars = globalThis.MATTERVIZ_CSS_MAP ?? {};
|
|
62
62
|
const root = document.documentElement;
|
|
63
63
|
Object.entries(theme).forEach(([key, value]) => {
|
|
64
64
|
const css_var = css_vars[key];
|
|
@@ -72,8 +72,8 @@ export const apply_theme_to_dom = (mode) => {
|
|
|
72
72
|
root.style.setProperty(`color-scheme`, color_scheme);
|
|
73
73
|
};
|
|
74
74
|
// Theme getters
|
|
75
|
-
export const light_theme = () => globalThis.MATTERVIZ_THEMES?.[COLOR_THEMES.light]
|
|
76
|
-
export const dark_theme = () => globalThis.MATTERVIZ_THEMES?.[COLOR_THEMES.dark]
|
|
77
|
-
export const white_theme = () => globalThis.MATTERVIZ_THEMES?.[COLOR_THEMES.white]
|
|
78
|
-
export const black_theme = () => globalThis.MATTERVIZ_THEMES?.[COLOR_THEMES.black]
|
|
79
|
-
export const get_theme_by_name = (name) => globalThis.MATTERVIZ_THEMES?.[name]
|
|
75
|
+
export const light_theme = () => globalThis.MATTERVIZ_THEMES?.[COLOR_THEMES.light] ?? {};
|
|
76
|
+
export const dark_theme = () => globalThis.MATTERVIZ_THEMES?.[COLOR_THEMES.dark] ?? {};
|
|
77
|
+
export const white_theme = () => globalThis.MATTERVIZ_THEMES?.[COLOR_THEMES.white] ?? {};
|
|
78
|
+
export const black_theme = () => globalThis.MATTERVIZ_THEMES?.[COLOR_THEMES.black] ?? {};
|
|
79
|
+
export const get_theme_by_name = (name) => globalThis.MATTERVIZ_THEMES?.[name] ?? {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// Shared k-point coordinate rows for hover tooltips (Brillouin zone + Fermi surface)
|
|
3
|
+
import { format_vec3 } from '../labels'
|
|
4
|
+
import type { Vec3 } from '../math'
|
|
5
|
+
|
|
6
|
+
let { cartesian, fractional = null }: {
|
|
7
|
+
cartesian: Vec3
|
|
8
|
+
fractional?: Vec3 | null
|
|
9
|
+
} = $props()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<div class="k-coord-row">
|
|
13
|
+
<span class="k-coord-label"><span class="vec">k</span> (Å⁻¹):</span>
|
|
14
|
+
<span>{format_vec3(cartesian)}</span>
|
|
15
|
+
</div>
|
|
16
|
+
{#if fractional}
|
|
17
|
+
<div class="k-coord-row">
|
|
18
|
+
<span class="k-coord-label"><span class="vec">k</span> (frac):</span>
|
|
19
|
+
<span>{format_vec3(fractional)}</span>
|
|
20
|
+
</div>
|
|
21
|
+
{/if}
|
|
22
|
+
|
|
23
|
+
<style>
|
|
24
|
+
.k-coord-row {
|
|
25
|
+
display: flex;
|
|
26
|
+
gap: 4px;
|
|
27
|
+
}
|
|
28
|
+
.k-coord-label {
|
|
29
|
+
opacity: 0.8;
|
|
30
|
+
min-width: 50px;
|
|
31
|
+
}
|
|
32
|
+
.vec {
|
|
33
|
+
position: relative;
|
|
34
|
+
font-style: italic;
|
|
35
|
+
}
|
|
36
|
+
.vec::after {
|
|
37
|
+
content: '→';
|
|
38
|
+
position: absolute;
|
|
39
|
+
left: 50%;
|
|
40
|
+
top: -0.85em;
|
|
41
|
+
transform: translateX(-50%);
|
|
42
|
+
font-size: 0.6em;
|
|
43
|
+
font-style: normal;
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Vec3 } from '../math';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
cartesian: Vec3;
|
|
4
|
+
fractional?: Vec3 | null;
|
|
5
|
+
};
|
|
6
|
+
declare const KCoords: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type KCoords = ReturnType<typeof KCoords>;
|
|
8
|
+
export default KCoords;
|
package/dist/tooltip/index.d.ts
CHANGED
package/dist/tooltip/index.js
CHANGED
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
import Spinner from '../feedback/Spinner.svelte'
|
|
7
7
|
import Icon from '../Icon.svelte'
|
|
8
8
|
import { handle_url_drop, load_from_url } from '../io'
|
|
9
|
+
import { forward_window_keydown, handle_and_prevent } from '../keyboard'
|
|
9
10
|
import { format_num, trajectory_property_config } from '../labels'
|
|
10
11
|
import { sanitize_html } from '../sanitize'
|
|
11
12
|
import { toggle_fullscreen } from '../layout'
|
|
12
13
|
import type { ControlsConfig, DataSeries, Orientation, Point } from '../plot'
|
|
13
|
-
import type { ScatterHandlerProps } from '../plot/types'
|
|
14
|
+
import type { ScatterHandlerProps } from '../plot/core/types'
|
|
14
15
|
import { Histogram, ScatterPlot } from '../plot'
|
|
15
|
-
import { toggle_series_visibility } from '../plot/utils/series-visibility'
|
|
16
|
+
import { toggle_series_visibility } from '../plot/core/utils/series-visibility'
|
|
16
17
|
import { DEFAULTS } from '../settings'
|
|
17
18
|
import Structure from '../structure/Structure.svelte'
|
|
18
19
|
import { scaleLinear } from 'd3-scale'
|
|
@@ -31,7 +32,6 @@
|
|
|
31
32
|
import { TrajectoryError, TrajectoryExportPane, TrajectoryInfoPane } from './index'
|
|
32
33
|
import type { AtomTypeMapping, LoadingOptions } from './parse'
|
|
33
34
|
import {
|
|
34
|
-
create_frame_loader,
|
|
35
35
|
get_unsupported_format_message,
|
|
36
36
|
MAX_BIN_FILE_SIZE,
|
|
37
37
|
MAX_TEXT_FILE_SIZE,
|
|
@@ -98,6 +98,7 @@
|
|
|
98
98
|
loading_options = {},
|
|
99
99
|
atom_type_mapping,
|
|
100
100
|
plot_skimming = true,
|
|
101
|
+
hovered = $bindable(false),
|
|
101
102
|
...rest
|
|
102
103
|
}: EventHandlers & HTMLAttributes<HTMLDivElement> & {
|
|
103
104
|
// trajectory data - can be provided directly or loaded from file
|
|
@@ -184,6 +185,8 @@
|
|
|
184
185
|
atom_type_mapping?: AtomTypeMapping
|
|
185
186
|
// Disable plot skimming (mouse over plot doesn't update structure/step slider)
|
|
186
187
|
plot_skimming?: boolean
|
|
188
|
+
// bindable: true while the pointer is over the viewer (drives hover-scoped shortcuts)
|
|
189
|
+
hovered?: boolean
|
|
187
190
|
} = $props()
|
|
188
191
|
|
|
189
192
|
let dragover = $state(false)
|
|
@@ -341,19 +344,28 @@
|
|
|
341
344
|
// Prevent circular updates when syncing legend toggles back to bindable visible_properties.
|
|
342
345
|
let syncing_visible_properties = false
|
|
343
346
|
|
|
344
|
-
// Regenerate plot series when trajectory, config, or visible_properties change
|
|
347
|
+
// Regenerate plot series when trajectory, config, or visible_properties change.
|
|
348
|
+
// Read ALL reactive deps before the syncing guard can return: a guarded run that
|
|
349
|
+
// reads no dependencies leaves the effect dep-less, and Svelte permanently unlinks
|
|
350
|
+
// dep-less effects - trajectory changes would then never regenerate the plot.
|
|
345
351
|
$effect(() => {
|
|
352
|
+
const [traj, extractor, config, keys] = [
|
|
353
|
+
trajectory,
|
|
354
|
+
data_extractor,
|
|
355
|
+
extended_config,
|
|
356
|
+
visible_properties,
|
|
357
|
+
]
|
|
346
358
|
if (syncing_visible_properties) return
|
|
347
|
-
const keys_set =
|
|
359
|
+
const keys_set = keys ? new Set(keys) : undefined
|
|
348
360
|
|
|
349
|
-
if (
|
|
350
|
-
plot_series = generate_streaming_plot_series(
|
|
351
|
-
property_config:
|
|
361
|
+
if (traj?.plot_metadata) {
|
|
362
|
+
plot_series = generate_streaming_plot_series(traj.plot_metadata, {
|
|
363
|
+
property_config: config,
|
|
352
364
|
default_visible_properties: keys_set,
|
|
353
365
|
})
|
|
354
|
-
} else if (
|
|
355
|
-
plot_series = generate_plot_series(
|
|
356
|
-
property_config:
|
|
366
|
+
} else if (traj) {
|
|
367
|
+
plot_series = generate_plot_series(traj, extractor, {
|
|
368
|
+
property_config: config,
|
|
357
369
|
default_visible_properties: keys_set,
|
|
358
370
|
})
|
|
359
371
|
} else {
|
|
@@ -363,7 +375,7 @@
|
|
|
363
375
|
|
|
364
376
|
// Update visible_properties binding when user toggles series visibility in legend
|
|
365
377
|
$effect(() => {
|
|
366
|
-
if (
|
|
378
|
+
if (plot_series.length === 0) return
|
|
367
379
|
|
|
368
380
|
// Extract property keys from visible series metadata
|
|
369
381
|
const visible_keys = plot_series.flatMap((srs) => {
|
|
@@ -477,8 +489,8 @@
|
|
|
477
489
|
}
|
|
478
490
|
|
|
479
491
|
// Helper function to read file content
|
|
480
|
-
|
|
481
|
-
|
|
492
|
+
const read_file_content = (file: File): Promise<string | ArrayBuffer> =>
|
|
493
|
+
new Promise((resolve, reject) => {
|
|
482
494
|
const reader = new FileReader()
|
|
483
495
|
reader.addEventListener(`load`, () => resolve(reader.result as string | ArrayBuffer))
|
|
484
496
|
reader.addEventListener(`error`, () => reject(new Error(`Failed to read file`)))
|
|
@@ -488,7 +500,6 @@
|
|
|
488
500
|
reader.readAsText(file)
|
|
489
501
|
} else reader.readAsArrayBuffer(file)
|
|
490
502
|
})
|
|
491
|
-
}
|
|
492
503
|
|
|
493
504
|
// Play/pause functionality
|
|
494
505
|
function toggle_play() {
|
|
@@ -506,7 +517,7 @@
|
|
|
506
517
|
is_playing = false
|
|
507
518
|
if (trajectory) {
|
|
508
519
|
on_pause?.({
|
|
509
|
-
trajectory
|
|
520
|
+
trajectory,
|
|
510
521
|
step_idx: current_step_idx,
|
|
511
522
|
frame_count: total_frames,
|
|
512
523
|
})
|
|
@@ -517,9 +528,10 @@
|
|
|
517
528
|
const playing = is_playing
|
|
518
529
|
const rate_ms = 1000 / fps
|
|
519
530
|
|
|
531
|
+
// Read current interval once (untrack to avoid circular dependency)
|
|
532
|
+
const current_interval = untrack(() => play_interval)
|
|
520
533
|
if (playing) {
|
|
521
|
-
// Clear existing interval if it exists
|
|
522
|
-
const current_interval = untrack(() => play_interval)
|
|
534
|
+
// Clear existing interval if it exists
|
|
523
535
|
if (current_interval !== undefined) clearInterval(current_interval)
|
|
524
536
|
|
|
525
537
|
// Create new interval with current frame rate
|
|
@@ -539,13 +551,10 @@
|
|
|
539
551
|
}
|
|
540
552
|
} else next_step()
|
|
541
553
|
}, rate_ms)
|
|
542
|
-
} else {
|
|
543
|
-
// Clear interval when not playing
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
clearInterval(current_interval)
|
|
547
|
-
play_interval = undefined
|
|
548
|
-
}
|
|
554
|
+
} else if (current_interval !== undefined) {
|
|
555
|
+
// Clear interval when not playing
|
|
556
|
+
clearInterval(current_interval)
|
|
557
|
+
play_interval = undefined
|
|
549
558
|
}
|
|
550
559
|
})
|
|
551
560
|
|
|
@@ -624,6 +633,9 @@
|
|
|
624
633
|
// Read file content directly
|
|
625
634
|
const content = await read_file_content(file)
|
|
626
635
|
await load_trajectory_data(content, file.name)
|
|
636
|
+
// Don't fall through: drops from IDEs/file managers often also carry a
|
|
637
|
+
// text/plain payload (the file path) which would clobber the loaded data
|
|
638
|
+
return
|
|
627
639
|
}
|
|
628
640
|
|
|
629
641
|
// Check for plain text data (fallback)
|
|
@@ -631,7 +643,6 @@
|
|
|
631
643
|
if (text_data) {
|
|
632
644
|
file_size = new Blob([text_data]).size // Calculate byte size of text data
|
|
633
645
|
await load_trajectory_data(text_data, `trajectory.json`)
|
|
634
|
-
return
|
|
635
646
|
}
|
|
636
647
|
} catch (error) {
|
|
637
648
|
console.error(`File drop failed:`, error)
|
|
@@ -674,7 +685,7 @@
|
|
|
674
685
|
|
|
675
686
|
// Watch for frame rate changes
|
|
676
687
|
$effect(() => {
|
|
677
|
-
on_frame_rate_change?.({ trajectory, fps
|
|
688
|
+
on_frame_rate_change?.({ trajectory, fps })
|
|
678
689
|
})
|
|
679
690
|
|
|
680
691
|
async function load_trajectory_data(data: string | ArrayBuffer, filename: string) {
|
|
@@ -751,9 +762,10 @@
|
|
|
751
762
|
parsing_progress = progress
|
|
752
763
|
}, merged_options)
|
|
753
764
|
|
|
754
|
-
//
|
|
755
|
-
|
|
756
|
-
|
|
765
|
+
// Keep original data for on-demand frame loads only when indexed parsing attached a
|
|
766
|
+
// frame_loader. Direct-parse fallbacks (e.g. large JSON or extensionless blob:
|
|
767
|
+
// filenames) load all frames upfront, so retaining a full duplicate payload wastes memory.
|
|
768
|
+
orig_data = trajectory?.frame_loader ? data : null
|
|
757
769
|
} catch (error) {
|
|
758
770
|
console.error(`Indexed loading failed:`, error)
|
|
759
771
|
throw error
|
|
@@ -783,9 +795,10 @@
|
|
|
783
795
|
}
|
|
784
796
|
}
|
|
785
797
|
|
|
786
|
-
// Handle keyboard shortcuts
|
|
787
|
-
|
|
788
|
-
|
|
798
|
+
// Handle keyboard shortcuts. Returns true if the key was handled, so the caller
|
|
799
|
+
// (handle_and_prevent / forward_window_keydown) can suppress the browser default.
|
|
800
|
+
function onkeydown(event: KeyboardEvent): boolean {
|
|
801
|
+
if (!trajectory) return false
|
|
789
802
|
|
|
790
803
|
// Don't handle shortcuts if user is typing in an input field (but allow if it's our step input and not focused)
|
|
791
804
|
const target = event.target instanceof HTMLElement ? event.target : null
|
|
@@ -794,18 +807,25 @@
|
|
|
794
807
|
target?.tagName === `INPUT` || target?.tagName === `TEXTAREA`
|
|
795
808
|
|
|
796
809
|
// Skip if typing in an input that's not our step input
|
|
797
|
-
if (is_input_focused && !is_step_input) return
|
|
810
|
+
if (is_input_focused && !is_step_input) return false
|
|
798
811
|
|
|
799
812
|
// If typing in step input, only handle certain navigation keys
|
|
800
813
|
if (is_step_input && is_input_focused) {
|
|
801
814
|
// Allow normal typing, but handle special navigation keys
|
|
802
815
|
if ([`Escape`, `Enter`].includes(event.key)) target?.blur() // Remove focus from input
|
|
803
|
-
return
|
|
816
|
+
return false
|
|
804
817
|
}
|
|
805
818
|
|
|
806
819
|
const is_cmd_or_ctrl = event.metaKey || event.ctrlKey
|
|
807
820
|
|
|
808
|
-
//
|
|
821
|
+
// Only the Arrow keys intentionally use Cmd/Ctrl (jump to first/last). For any
|
|
822
|
+
// other key a Cmd/Ctrl combo is a browser/OS shortcut (find, tab switch, zoom)
|
|
823
|
+
// — bail so we neither hijack it nor preventDefault the browser's own action.
|
|
824
|
+
if (is_cmd_or_ctrl && event.key !== `ArrowLeft` && event.key !== `ArrowRight`) return false
|
|
825
|
+
|
|
826
|
+
// Track whether a shortcut fired so callers suppress browser defaults (page
|
|
827
|
+
// scroll on Space/arrows/PageUp-Down/Home/End) only when we handled the key.
|
|
828
|
+
let handled = true
|
|
809
829
|
if (event.key === ` `) toggle_play()
|
|
810
830
|
else if (event.key === `ArrowLeft`) {
|
|
811
831
|
if (is_cmd_or_ctrl) go_to_step(0)
|
|
@@ -829,10 +849,10 @@
|
|
|
829
849
|
// Playback speed shortcuts (only when playing)
|
|
830
850
|
else if ((event.key === `=` || event.key === `+`) && is_playing) {
|
|
831
851
|
fps = Math.min(fps_range[1], fps + 0.2)
|
|
832
|
-
on_frame_rate_change?.({ trajectory, fps
|
|
852
|
+
on_frame_rate_change?.({ trajectory, fps })
|
|
833
853
|
} else if (event.key === `-` && is_playing) {
|
|
834
854
|
fps = Math.max(fps_range[0], fps - 0.2)
|
|
835
|
-
on_frame_rate_change?.({ trajectory, fps
|
|
855
|
+
on_frame_rate_change?.({ trajectory, fps })
|
|
836
856
|
} // System shortcuts
|
|
837
857
|
else if (event.key === `Escape`) {
|
|
838
858
|
if (document.fullscreenElement) document.exitFullscreen()
|
|
@@ -841,7 +861,9 @@
|
|
|
841
861
|
} // Number keys 0-9 - jump to percentage of trajectory
|
|
842
862
|
else if (event.key >= `0` && event.key <= `9`) {
|
|
843
863
|
go_to_step(Math.floor((parseInt(event.key, 10) / 10) * (total_frames - 1)))
|
|
844
|
-
}
|
|
864
|
+
} else handled = false
|
|
865
|
+
|
|
866
|
+
return handled
|
|
845
867
|
}
|
|
846
868
|
|
|
847
869
|
// Separate state variables for each pane to match component prop types
|
|
@@ -859,6 +881,8 @@
|
|
|
859
881
|
}}
|
|
860
882
|
/>
|
|
861
883
|
|
|
884
|
+
<svelte:window onkeydown={forward_window_keydown(() => hovered, onkeydown)} />
|
|
885
|
+
|
|
862
886
|
<div
|
|
863
887
|
class:dragover
|
|
864
888
|
class:active={is_playing || structure_info_open || structure_controls_open ||
|
|
@@ -869,6 +893,8 @@
|
|
|
869
893
|
role="button"
|
|
870
894
|
tabindex="0"
|
|
871
895
|
aria-label="Drop trajectory file here to load"
|
|
896
|
+
onmouseenter={() => (hovered = true)}
|
|
897
|
+
onmouseleave={() => (hovered = false)}
|
|
872
898
|
ondrop={handle_file_drop}
|
|
873
899
|
ondragover={(event) => {
|
|
874
900
|
event.preventDefault()
|
|
@@ -880,7 +906,7 @@
|
|
|
880
906
|
dragover = false
|
|
881
907
|
}}
|
|
882
908
|
onclick={handle_click_outside}
|
|
883
|
-
{onkeydown}
|
|
909
|
+
onkeydown={handle_and_prevent(onkeydown)}
|
|
884
910
|
{...rest}
|
|
885
911
|
class="trajectory {actual_layout} {rest.class ?? ``}"
|
|
886
912
|
class:show-both-views={[`structure+scatter`, `structure+histogram`].includes(display_mode) &&
|
|
@@ -71,7 +71,8 @@ type $$ComponentProps = EventHandlers & HTMLAttributes<HTMLDivElement> & {
|
|
|
71
71
|
loading_options?: LoadingOptions;
|
|
72
72
|
atom_type_mapping?: AtomTypeMapping;
|
|
73
73
|
plot_skimming?: boolean;
|
|
74
|
+
hovered?: boolean;
|
|
74
75
|
};
|
|
75
|
-
declare const Trajectory: import("svelte").Component<$$ComponentProps, {}, "trajectory" | "fps" | "display_mode" | "current_step_idx" | "visible_properties">;
|
|
76
|
+
declare const Trajectory: import("svelte").Component<$$ComponentProps, {}, "trajectory" | "hovered" | "fps" | "display_mode" | "current_step_idx" | "visible_properties">;
|
|
76
77
|
type Trajectory = ReturnType<typeof Trajectory>;
|
|
77
78
|
export default Trajectory;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import type { TrajectoryType } from './'
|
|
9
9
|
import type { ComponentProps } from 'svelte'
|
|
10
10
|
import { tooltip } from 'svelte-multiselect/attachments'
|
|
11
|
+
import { to_error } from '../utils'
|
|
11
12
|
|
|
12
13
|
let {
|
|
13
14
|
export_pane_open = $bindable(false),
|
|
@@ -123,7 +124,7 @@
|
|
|
123
124
|
}, 1000)
|
|
124
125
|
} catch (error) {
|
|
125
126
|
console.error(`Export failed:`, error)
|
|
126
|
-
export_error = error
|
|
127
|
+
export_error = to_error(error).message
|
|
127
128
|
is_exporting = false
|
|
128
129
|
export_progress = 0
|
|
129
130
|
}
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
frames.map((frame) => frame.metadata?.[prop]).filter(is_valid_number)
|
|
46
46
|
|
|
47
47
|
const format_range = (values: number[], unit = ``, decimals = `.2~f`) => {
|
|
48
|
-
if (
|
|
48
|
+
if (values.length === 0) return null
|
|
49
49
|
if (values.length === 1) {
|
|
50
50
|
return `${format_num(values[0], decimals)} ${unit}`.trim()
|
|
51
51
|
}
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
tooltip?: string,
|
|
62
62
|
): InfoItem | null => value ? { label, value, key, tooltip } : null
|
|
63
63
|
|
|
64
|
+
// oxlint-disable-next-line eslint-plugin-unicorn/prefer-native-coercion-functions -- type predicate needed for narrowing
|
|
64
65
|
const is_info_item = (item: unknown): item is InfoItem => Boolean(item)
|
|
65
66
|
|
|
66
67
|
const safe_formula = (structure: AnyStructure) => {
|