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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Async wrapper for compute_chempot_diagram via Web Worker.
|
|
2
2
|
// Falls back to synchronous main-thread computation during SSR.
|
|
3
3
|
import { compute_chempot_diagram, formula_key_from_composition } from './compute';
|
|
4
|
+
import { to_error } from '../utils';
|
|
4
5
|
let worker = null;
|
|
5
6
|
let next_id = 0;
|
|
6
7
|
const pending = new Map();
|
|
@@ -28,6 +29,7 @@ function get_worker() {
|
|
|
28
29
|
if (typeof Worker === `undefined`)
|
|
29
30
|
return null;
|
|
30
31
|
if (!worker) {
|
|
32
|
+
// oxlint-disable-next-line eslint-plugin-unicorn/relative-url-style -- Vite worker detection requires the `./` prefix
|
|
31
33
|
worker = new Worker(new URL(`./chempot-worker.js`, import.meta.url), { type: `module` });
|
|
32
34
|
worker.addEventListener(`message`, ({ data: { id, result, error } }) => {
|
|
33
35
|
const req = pending.get(id);
|
|
@@ -71,7 +73,7 @@ export function compute_chempot_async(entries, config = {}) {
|
|
|
71
73
|
}
|
|
72
74
|
catch (err) {
|
|
73
75
|
pending.delete(id);
|
|
74
|
-
reject(
|
|
76
|
+
reject(to_error(err));
|
|
75
77
|
}
|
|
76
78
|
});
|
|
77
79
|
return track_pending(request_key, promise);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { compute_chempot_diagram } from './compute';
|
|
2
|
+
import { to_error } from '../utils';
|
|
2
3
|
self.addEventListener(`message`, (event) => {
|
|
3
4
|
const { id, entries, config } = event.data;
|
|
4
5
|
try {
|
|
@@ -6,6 +7,6 @@ self.addEventListener(`message`, (event) => {
|
|
|
6
7
|
postMessage({ id, result, error: null });
|
|
7
8
|
}
|
|
8
9
|
catch (err) {
|
|
9
|
-
postMessage({ id, result: null, error: err
|
|
10
|
+
postMessage({ id, result: null, error: to_error(err).message });
|
|
10
11
|
}
|
|
11
12
|
});
|
|
@@ -8,7 +8,7 @@ export declare function get_min_entries_and_el_refs(entries: PhaseData[]): {
|
|
|
8
8
|
};
|
|
9
9
|
export declare function compute_form_energy_per_atom(entry: PhaseData, el_refs: Record<string, PhaseData>): number;
|
|
10
10
|
export declare function best_form_energy_for_formula(entries: PhaseData[], formula: string, el_refs: Record<string, PhaseData>): number | undefined;
|
|
11
|
-
export declare
|
|
11
|
+
export declare const renormalize_entries: (entries: PhaseData[], el_refs: Record<string, PhaseData>, elements: string[]) => PhaseData[];
|
|
12
12
|
export declare function build_hyperplanes(min_entries: PhaseData[], el_refs: Record<string, PhaseData>, elements: string[]): {
|
|
13
13
|
hyperplanes: number[][];
|
|
14
14
|
hyperplane_entries: PhaseData[];
|
|
@@ -112,24 +112,22 @@ export function best_form_energy_for_formula(entries, formula, el_refs) {
|
|
|
112
112
|
}
|
|
113
113
|
// Renormalize entry energies to be relative to elemental references (formal chemical potentials).
|
|
114
114
|
// For each entry, subtracts sum(x_i * E_ref_i) from its energy per atom.
|
|
115
|
-
export
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
});
|
|
132
|
-
}
|
|
115
|
+
export const renormalize_entries = (entries, el_refs, elements) => entries.map((entry) => {
|
|
116
|
+
const atoms = count_atoms_in_composition(entry.composition);
|
|
117
|
+
let renorm_energy = 0;
|
|
118
|
+
for (const el of elements) {
|
|
119
|
+
const frac = atoms > 0 ? (entry.composition[el] ?? 0) / atoms : 0;
|
|
120
|
+
const ref = el_refs[el];
|
|
121
|
+
if (ref)
|
|
122
|
+
renorm_energy += frac * get_energy_per_atom(ref);
|
|
123
|
+
}
|
|
124
|
+
const new_energy_per_atom = get_energy_per_atom(entry) - renorm_energy;
|
|
125
|
+
return {
|
|
126
|
+
...entry,
|
|
127
|
+
energy: new_energy_per_atom * atoms,
|
|
128
|
+
energy_per_atom: new_energy_per_atom,
|
|
129
|
+
};
|
|
130
|
+
});
|
|
133
131
|
// Build hyperplane representation for minimum entries.
|
|
134
132
|
// Each row is [x_1, ..., x_n, -E_per_atom].
|
|
135
133
|
// Filters to entries with negative formation energy plus all elemental refs.
|
|
@@ -782,7 +780,7 @@ export function compute_chempot_diagram(entries, config = {}) {
|
|
|
782
780
|
if (is_projection) {
|
|
783
781
|
const col_indices = display_elements.map((element) => {
|
|
784
782
|
const idx = compute_elements.indexOf(element);
|
|
785
|
-
if (idx
|
|
783
|
+
if (idx === -1) {
|
|
786
784
|
throw new Error(`Display element ${element} not present in compute element set`);
|
|
787
785
|
}
|
|
788
786
|
return idx;
|
package/dist/colors/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { rgb } from 'd3-color';
|
|
1
|
+
import { color as d3_color, rgb } from 'd3-color';
|
|
2
2
|
import * as d3_sc from 'd3-scale-chromatic';
|
|
3
3
|
import alloy_colors from './alloy-colors.json' with { type: 'json' };
|
|
4
4
|
import dark_mode_colors from './dark-mode-colors.json' with { type: 'json' };
|
|
@@ -55,13 +55,14 @@ export const ELEMENT_COLOR_SCHEMES = {
|
|
|
55
55
|
'Dark Mode': dark_mode_hex,
|
|
56
56
|
};
|
|
57
57
|
export const default_element_colors = { ...vesta_hex };
|
|
58
|
-
//
|
|
58
|
+
// Detect if a value is a CSS color string. d3-color parses hex, rgb()/rgba(),
|
|
59
|
+
// hsl()/hsla(), and named colors case-insensitively, rejecting arbitrary words like
|
|
60
|
+
// `pending`. It doesn't parse var()/color()/currentcolor, so match those explicitly.
|
|
59
61
|
export const is_color = (val) => {
|
|
60
62
|
if (typeof val !== `string`)
|
|
61
63
|
return false;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return /^(#[0-9a-f]{3,8}|rgba?\([^)]+\)|hsla?\([^)]+\)|color\([^)]+\)|var\([^)]+\)|(?!rgb$|hsl$|var$|color$)[a-z]+)$/i.test(val.trim());
|
|
64
|
+
const trimmed = val.trim();
|
|
65
|
+
return /^(?:var|color)\([^)]+\)$|^currentcolor$/i.test(trimmed) || d3_color(trimmed) !== null;
|
|
65
66
|
};
|
|
66
67
|
export const PLOT_COLORS = [
|
|
67
68
|
// Color series for e.g. line plots
|
|
@@ -338,10 +338,10 @@
|
|
|
338
338
|
normalized = normalized.replaceAll(superscript, ascii)
|
|
339
339
|
}
|
|
340
340
|
return normalized
|
|
341
|
-
|
|
342
|
-
.replaceAll(`⋅`,
|
|
341
|
+
// keep hydrate dots (deleting would glue digits: CuSO4·5H2O -> CuSO45H2O)
|
|
342
|
+
.replaceAll(`⋅`, `·`)
|
|
343
343
|
.replaceAll(`−`, `-`)
|
|
344
|
-
.
|
|
344
|
+
.replaceAll(/\s+/g, ``)
|
|
345
345
|
}
|
|
346
346
|
|
|
347
347
|
function normalize_exact_formula(input: string): string {
|
|
@@ -361,7 +361,7 @@
|
|
|
361
361
|
const wildcard_tokens = tokens.filter((token) => token.element === null)
|
|
362
362
|
|
|
363
363
|
// Merge explicit element counts before sorting.
|
|
364
|
-
const merged_explicit:
|
|
364
|
+
const merged_explicit: { element: string; count: number }[] = []
|
|
365
365
|
for (const token of explicit) {
|
|
366
366
|
const existing = merged_explicit.find((item) =>
|
|
367
367
|
item.element === token.element
|
|
@@ -609,14 +609,20 @@
|
|
|
609
609
|
const reformatted = format_for_mode(elements, next_mode)
|
|
610
610
|
|
|
611
611
|
search_mode = next_mode
|
|
612
|
-
|
|
612
|
+
// set last_synced too to prevent effect re-inference
|
|
613
|
+
last_synced = reformatted
|
|
614
|
+
value = reformatted
|
|
615
|
+
input_value = reformatted
|
|
613
616
|
run_validation(reformatted, next_mode)
|
|
614
617
|
onchange?.(reformatted, next_mode)
|
|
615
618
|
}
|
|
616
619
|
|
|
617
620
|
function set_value(new_value: string, forced_mode?: FormulaSearchMode): void {
|
|
618
621
|
const mode = forced_mode ?? (mode_locked ? search_mode : infer_mode(new_value))
|
|
619
|
-
|
|
622
|
+
// set last_synced too to prevent effect re-inference
|
|
623
|
+
last_synced = new_value
|
|
624
|
+
value = new_value
|
|
625
|
+
input_value = new_value
|
|
620
626
|
search_mode = mode
|
|
621
627
|
if (new_value.trim()) add_to_history(new_value)
|
|
622
628
|
close_history()
|
|
@@ -151,11 +151,9 @@
|
|
|
151
151
|
} else if (is_medium_slice) {
|
|
152
152
|
// Medium slices: place closer to outer edge, proportional to chart size
|
|
153
153
|
label_radius = outer_radius - outer_radius * 0.3
|
|
154
|
-
is_outside_slice = false
|
|
155
154
|
} else {
|
|
156
155
|
// Large slices: place in middle of ring
|
|
157
156
|
label_radius = (outer_radius + inner_radius_adjusted) / 2
|
|
158
|
-
is_outside_slice = false
|
|
159
157
|
}
|
|
160
158
|
|
|
161
159
|
// Calculate font scale based on slice size and smart text fitting
|
|
@@ -293,9 +291,15 @@
|
|
|
293
291
|
.pie-segment.interactive:focus {
|
|
294
292
|
outline: none;
|
|
295
293
|
}
|
|
294
|
+
svg {
|
|
295
|
+
/* very thin slices place their labels outside the pie at 1.2x the outer radius,
|
|
296
|
+
past the square viewBox - the default svg overflow: hidden would clip them */
|
|
297
|
+
overflow: visible;
|
|
298
|
+
}
|
|
296
299
|
foreignobject {
|
|
297
300
|
pointer-events: none;
|
|
298
301
|
transition: all 0.2s ease;
|
|
302
|
+
overflow: visible;
|
|
299
303
|
}
|
|
300
304
|
foreignobject.hovered {
|
|
301
305
|
font-weight: 700;
|
|
@@ -310,9 +314,6 @@
|
|
|
310
314
|
transition: all 0.2s ease;
|
|
311
315
|
white-space: nowrap;
|
|
312
316
|
}
|
|
313
|
-
foreignobject {
|
|
314
|
-
overflow: visible;
|
|
315
|
-
}
|
|
316
317
|
.pie-label.hovered {
|
|
317
318
|
font-weight: 700;
|
|
318
319
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SunburstNode } from '../plot/core/types';
|
|
2
|
+
export interface ChemSysSunburstMetadata {
|
|
3
|
+
chem_sys: string;
|
|
4
|
+
arity: number;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
export declare const arity_name: (arity: number) => string;
|
|
8
|
+
export declare function chem_sys_sunburst_data(entries: readonly string[]): SunburstNode<ChemSysSunburstMetadata>[];
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Build arity -> chemical-system hierarchy data for the Sunburst component
|
|
2
|
+
// (counterpart to pymatviz's chem_sys_sunburst).
|
|
3
|
+
import { is_valid_element, parse_formula } from './parse';
|
|
4
|
+
const ARITY_NAMES = [
|
|
5
|
+
``,
|
|
6
|
+
`unary`,
|
|
7
|
+
`binary`,
|
|
8
|
+
`ternary`,
|
|
9
|
+
`quaternary`,
|
|
10
|
+
`quinary`,
|
|
11
|
+
`senary`,
|
|
12
|
+
`septenary`,
|
|
13
|
+
`octonary`,
|
|
14
|
+
`nonary`,
|
|
15
|
+
`denary`,
|
|
16
|
+
];
|
|
17
|
+
// || (not ??) so the empty index-0 placeholder also falls through to "0-ary"
|
|
18
|
+
export const arity_name = (arity) => ARITY_NAMES[arity] || `${arity}-ary`;
|
|
19
|
+
// Build arity -> chemical-system sunburst data from a list of chemical systems
|
|
20
|
+
// ("Li-Fe-O") and/or formulas ("LiFePO4"), one entry per occurrence (counts become
|
|
21
|
+
// leaf values). Systems are normalized to alphabetical element order, so "O-Li" and
|
|
22
|
+
// "Li2O" both count toward "Li-O". Ids follow the "<arity>/<system>" scheme.
|
|
23
|
+
export function chem_sys_sunburst_data(entries) {
|
|
24
|
+
// Inputs are one entry per occurrence, so the same formula typically repeats many
|
|
25
|
+
// times - memoize raw entry -> normalized system (null = invalid) to parse each
|
|
26
|
+
// distinct string only once
|
|
27
|
+
const normalized = new Map();
|
|
28
|
+
const normalize = (entry) => {
|
|
29
|
+
let elements;
|
|
30
|
+
if (entry.includes(`-`)) {
|
|
31
|
+
elements = entry.split(`-`).map((el) => el.trim());
|
|
32
|
+
if (!elements.every(is_valid_element))
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
try {
|
|
37
|
+
elements = Object.keys(parse_formula(entry));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (elements.length === 0)
|
|
44
|
+
return null;
|
|
45
|
+
return [...new Set(elements)].sort().join(`-`);
|
|
46
|
+
};
|
|
47
|
+
const counts = new Map();
|
|
48
|
+
let n_invalid = 0;
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
let chem_sys = normalized.get(entry);
|
|
51
|
+
if (chem_sys === undefined) {
|
|
52
|
+
chem_sys = normalize(entry);
|
|
53
|
+
normalized.set(entry, chem_sys);
|
|
54
|
+
}
|
|
55
|
+
if (chem_sys === null) {
|
|
56
|
+
n_invalid += 1;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
counts.set(chem_sys, (counts.get(chem_sys) ?? 0) + 1);
|
|
60
|
+
}
|
|
61
|
+
if (n_invalid > 0) {
|
|
62
|
+
console.warn(`chem_sys_sunburst_data: skipped ${n_invalid} invalid entr${n_invalid === 1 ? `y` : `ies`} (expected chemical systems like "Li-Fe-O" or formulas like "LiFePO4")`);
|
|
63
|
+
}
|
|
64
|
+
// One composite sort (arity ascending, then count descending) puts systems in
|
|
65
|
+
// final order; consecutive same-arity runs then collapse into one branch each
|
|
66
|
+
const sorted = [...counts]
|
|
67
|
+
.map(([chem_sys, count]) => ({ chem_sys, count, arity: chem_sys.split(`-`).length }))
|
|
68
|
+
.sort((sys_a, sys_b) => sys_a.arity - sys_b.arity || sys_b.count - sys_a.count);
|
|
69
|
+
const roots = [];
|
|
70
|
+
let branch;
|
|
71
|
+
for (const { chem_sys, count, arity } of sorted) {
|
|
72
|
+
const name = arity_name(arity);
|
|
73
|
+
if (branch?.id !== name) {
|
|
74
|
+
branch = { id: name, label: name, children: [] };
|
|
75
|
+
roots.push(branch);
|
|
76
|
+
}
|
|
77
|
+
branch.children?.push({
|
|
78
|
+
id: `${name}/${chem_sys}`,
|
|
79
|
+
label: chem_sys,
|
|
80
|
+
value: count,
|
|
81
|
+
metadata: { chem_sys, arity },
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return roots;
|
|
85
|
+
}
|
|
@@ -24,10 +24,12 @@ export const format_composition_formula = (composition, sort_fn, plain_text = fa
|
|
|
24
24
|
return sort_fn(symbols)
|
|
25
25
|
.filter((el) => composition[el] && composition[el] > 0)
|
|
26
26
|
.map((el) => {
|
|
27
|
-
const amount = composition[el];
|
|
27
|
+
const amount = Number(composition[el]);
|
|
28
28
|
if (amount === 1)
|
|
29
29
|
return el;
|
|
30
|
-
|
|
30
|
+
// avoid d3 SI prefixes for sub-1 amounts (`s` formats render 0.5 as 500m)
|
|
31
|
+
const fmt = amount_format.endsWith(`s`) && Math.abs(amount) < 1 ? `.3~g` : amount_format;
|
|
32
|
+
const formatted_amount = format_num(amount, fmt);
|
|
31
33
|
return plain_text ? `${el}${formatted_amount}` : `${el}<sub>${formatted_amount}</sub>`;
|
|
32
34
|
})
|
|
33
35
|
.join(delim);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ElementSymbol } from '../element';
|
|
2
2
|
export { default as BarChart } from './BarChart.svelte';
|
|
3
3
|
export { default as BubbleChart } from './BubbleChart.svelte';
|
|
4
|
+
export * from './chem-sys';
|
|
4
5
|
export { default as Composition } from './Composition.svelte';
|
|
5
6
|
export * from './format';
|
|
6
7
|
export { default as Formula } from './Formula.svelte';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as BarChart } from './BarChart.svelte';
|
|
2
2
|
export { default as BubbleChart } from './BubbleChart.svelte';
|
|
3
|
+
export * from './chem-sys';
|
|
3
4
|
export { default as Composition } from './Composition.svelte';
|
|
4
5
|
export * from './format';
|
|
5
6
|
export { default as Formula } from './Formula.svelte';
|
|
@@ -65,26 +65,38 @@ export const atomic_symbol_to_num = (symbol_composition) => {
|
|
|
65
65
|
// Expand parentheses in chemical formulas
|
|
66
66
|
const expand_parentheses = (formula) => {
|
|
67
67
|
while (formula.includes(`(`)) {
|
|
68
|
-
|
|
68
|
+
const expanded = formula.replaceAll(/\(([^()]+)\)(\d+(?:\.\d+)?|\.\d+)?/g, (_match, group, multiplier) => {
|
|
69
69
|
const mult = parse_count(multiplier);
|
|
70
|
-
return group.
|
|
70
|
+
return group.replaceAll(/([A-Z][a-z]?)(\d+(?:\.\d+)?|\.\d+)?/g, (_m, element, count) => {
|
|
71
71
|
const count_str = format_count(parse_count(count) * mult);
|
|
72
72
|
return element + (count_str === `1` ? `` : count_str);
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
|
+
if (expanded === formula) {
|
|
76
|
+
// unclosed/empty parens match nothing -> would loop forever
|
|
77
|
+
throw new Error(`Unbalanced or empty parentheses in formula: ${formula}`);
|
|
78
|
+
}
|
|
79
|
+
formula = expanded;
|
|
75
80
|
}
|
|
76
81
|
return formula;
|
|
77
82
|
};
|
|
78
|
-
// Parse chemical formula string into composition object
|
|
83
|
+
// Parse chemical formula string into composition object. Hydrate/adduct segments
|
|
84
|
+
// joined by ·, ⋅, or * are scaled by their leading coefficient (CuSO4·5H2O -> Cu S O9 H10)
|
|
79
85
|
export const parse_formula = (formula) => {
|
|
80
86
|
const composition = {};
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
const cleaned = formula.replaceAll(/\s/g, ``);
|
|
88
|
+
const segments = cleaned.split(/[·⋅*]/).filter(Boolean);
|
|
89
|
+
for (const [seg_idx, segment] of segments.entries()) {
|
|
90
|
+
// only hydrate segments (after a separator) carry a leading multiplier
|
|
91
|
+
const coeff = seg_idx > 0 ? /^(?:\d+(?:\.\d+)?|\.\d+)/.exec(segment)?.[0] : undefined;
|
|
92
|
+
const multiplier = coeff ? parseFloat(coeff) : 1;
|
|
93
|
+
const expanded = expand_parentheses(segment.slice(coeff?.length ?? 0));
|
|
94
|
+
for (const match of expanded.matchAll(/([A-Z][a-z]?)(\d+(?:\.\d+)?|\.\d+)?/g)) {
|
|
95
|
+
const [, element, count] = match;
|
|
96
|
+
if (!is_valid_element(element))
|
|
97
|
+
throw new Error(`Invalid element symbol: ${element}`);
|
|
98
|
+
composition[element] = (composition[element] ?? 0) + parse_count(count) * multiplier;
|
|
99
|
+
}
|
|
88
100
|
}
|
|
89
101
|
return composition;
|
|
90
102
|
};
|
|
@@ -210,7 +222,7 @@ const parse_oxidation_state = (oxidation_str) => {
|
|
|
210
222
|
// When strict=true, throws on conflicting oxidation states for the same element.
|
|
211
223
|
export const parse_formula_with_oxidation = (formula, strict = false) => {
|
|
212
224
|
const elements = [];
|
|
213
|
-
const cleaned_formula = expand_parentheses(formula.
|
|
225
|
+
const cleaned_formula = expand_parentheses(formula.replaceAll(/\s/g, ``));
|
|
214
226
|
// Regex to match: Element, optional oxidation state and/or count in either order
|
|
215
227
|
// Pattern: ([A-Z][a-z]?) - element symbol
|
|
216
228
|
// Followed by one of:
|
|
@@ -332,7 +344,7 @@ export const has_wildcards = (input) => input.includes(`*`);
|
|
|
332
344
|
// Throws if any non-wildcard token is not a valid element symbol.
|
|
333
345
|
export function parse_chemsys_with_wildcards(input) {
|
|
334
346
|
const tokens = input
|
|
335
|
-
.
|
|
347
|
+
.replaceAll('-', `,`)
|
|
336
348
|
.split(`,`)
|
|
337
349
|
.map((tok) => tok.trim())
|
|
338
350
|
.filter(Boolean);
|
|
@@ -368,7 +380,7 @@ export const ELEM_WILDCARD = {
|
|
|
368
380
|
export function parse_formula_with_wildcards(formula) {
|
|
369
381
|
const tokens = [];
|
|
370
382
|
// Expand parentheses, treating * as a pseudo-element (temporarily replace to protect it)
|
|
371
|
-
let cleaned = formula.
|
|
383
|
+
let cleaned = formula.replaceAll(/\s/g, ``);
|
|
372
384
|
// Protect wildcards from parentheses expansion by replacing * with placeholder
|
|
373
385
|
cleaned = cleaned.replace(ELEM_WILDCARD.to_placeholder, ELEM_WILDCARD.placeholder);
|
|
374
386
|
cleaned = expand_parentheses(cleaned);
|
|
@@ -320,7 +320,7 @@
|
|
|
320
320
|
let copy_feedback = $state({ visible: false, position: { x: 0, y: 0 } })
|
|
321
321
|
|
|
322
322
|
// Structure popup state
|
|
323
|
-
let structure_popup = $state<{
|
|
323
|
+
let structure_popup = $state.raw<{
|
|
324
324
|
open: boolean
|
|
325
325
|
structure: AnyStructure | null
|
|
326
326
|
entry: ConvexHullEntry | null
|
|
@@ -381,17 +381,17 @@
|
|
|
381
381
|
const hl = is_highlighted(entry) ? merged_highlight_style : null
|
|
382
382
|
|
|
383
383
|
point_style[idx] = {
|
|
384
|
-
fill: hl
|
|
385
|
-
? hl
|
|
384
|
+
fill: hl?.effect === `color` || hl?.effect === `both`
|
|
385
|
+
? hl?.color
|
|
386
386
|
: is_energy_mode
|
|
387
387
|
? undefined
|
|
388
388
|
: merged_config.colors?.[is_stable ? `stable` : `unstable`],
|
|
389
389
|
stroke: is_stable ? `#ffffff` : `#000000`,
|
|
390
|
-
radius: hl
|
|
391
|
-
? base_radius * hl
|
|
390
|
+
radius: hl?.effect === `size` || hl?.effect === `both`
|
|
391
|
+
? base_radius * (hl?.size_multiplier ?? 1)
|
|
392
392
|
: base_radius,
|
|
393
393
|
symbol_type: marker_to_d3_symbol(entry.marker),
|
|
394
|
-
is_highlighted:
|
|
394
|
+
is_highlighted: Boolean(hl),
|
|
395
395
|
highlight_effect: hl?.effect,
|
|
396
396
|
highlight_color: hl?.color,
|
|
397
397
|
}
|
|
@@ -436,8 +436,10 @@
|
|
|
436
436
|
const selected_scatter_point = $derived.by(() => {
|
|
437
437
|
const entry = selected_entry
|
|
438
438
|
if (!entry) return null
|
|
439
|
-
|
|
440
|
-
|
|
439
|
+
// match by entry_id (same_entry), not reference: selected_entry may be a proxied/
|
|
440
|
+
// different instance than visible_entries elements when bound to a parent $state
|
|
441
|
+
const idx = visible_entries.findIndex((vis_entry) => helpers.same_entry(vis_entry, entry))
|
|
442
|
+
return idx === -1 ? null : { series_idx: 0, point_idx: idx }
|
|
441
443
|
})
|
|
442
444
|
|
|
443
445
|
// Convex hull statistics - compute internally and expose via bindable prop
|
|
@@ -489,11 +491,11 @@
|
|
|
489
491
|
)
|
|
490
492
|
|
|
491
493
|
// Custom hover tooltip state used with ScatterPlot events
|
|
492
|
-
let hover_data = $state<HoverData3D<ConvexHullEntry> | null>(null)
|
|
494
|
+
let hover_data = $state.raw<HoverData3D<ConvexHullEntry> | null>(null)
|
|
493
495
|
$effect(() => {
|
|
494
496
|
const current_selection = helpers.current_entry(selected_entry, plot_entries)
|
|
495
497
|
if (selected_entry && !current_selection) selected_entry = null
|
|
496
|
-
else if (current_selection && current_selection
|
|
498
|
+
else if (current_selection && !helpers.same_entry(current_selection, selected_entry)) {
|
|
497
499
|
selected_entry = current_selection
|
|
498
500
|
}
|
|
499
501
|
const current_hover = helpers.current_entry(hover_data?.entry, plot_entries)
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
} from '../layout'
|
|
24
24
|
import { to_radians, type Point3D, type Vec3 } from '../math'
|
|
25
25
|
import { ColorBar, PlotTooltip } from '../plot'
|
|
26
|
-
import { centered_rect, pad_rect, rects_overlap, rect_within_rect } from '../plot/layout'
|
|
27
|
-
import type { Rect } from '../plot/layout'
|
|
26
|
+
import { centered_rect, pad_rect, rects_overlap, rect_within_rect } from '../plot/core/layout'
|
|
27
|
+
import type { Rect } from '../plot/core/layout'
|
|
28
28
|
import { create_pulse_animation } from '../effects.svelte'
|
|
29
29
|
import { DEFAULTS } from '../settings'
|
|
30
30
|
import type { AnyStructure } from '../structure'
|
|
@@ -422,7 +422,7 @@
|
|
|
422
422
|
let is_dragging = $state(false)
|
|
423
423
|
let drag_started = $state(false)
|
|
424
424
|
let last_mouse = $state({ x: 0, y: 0 })
|
|
425
|
-
let hover_data = $state<HoverData3D<ConvexHullEntry> | null>(null)
|
|
425
|
+
let hover_data = $state.raw<HoverData3D<ConvexHullEntry> | null>(null)
|
|
426
426
|
let copy_feedback = $state({ visible: false, position: { x: 0, y: 0 } })
|
|
427
427
|
|
|
428
428
|
// Drag and drop state
|
|
@@ -436,7 +436,7 @@
|
|
|
436
436
|
const current_selection = helpers.current_entry(selected_entry, plot_entries)
|
|
437
437
|
const stale_selection = selected_entry && !current_selection
|
|
438
438
|
if (stale_selection) selected_entry = null
|
|
439
|
-
else if (current_selection && current_selection
|
|
439
|
+
else if (current_selection && !helpers.same_entry(current_selection, selected_entry)) {
|
|
440
440
|
selected_entry = current_selection
|
|
441
441
|
}
|
|
442
442
|
const current_hover = helpers.current_entry(hover_data?.entry, plot_entries)
|
|
@@ -963,7 +963,7 @@
|
|
|
963
963
|
|
|
964
964
|
// Formation energy color bar helpers
|
|
965
965
|
const e_form_range = $derived.by((): [number, number] => {
|
|
966
|
-
const min_fe = plot_entries.length ? energy_range.min : -1
|
|
966
|
+
const min_fe = plot_entries.length > 0 ? energy_range.min : -1
|
|
967
967
|
return [min_fe, 0]
|
|
968
968
|
})
|
|
969
969
|
|
|
@@ -326,7 +326,7 @@
|
|
|
326
326
|
let is_dragging = $state(false)
|
|
327
327
|
let drag_started = $state(false)
|
|
328
328
|
let last_mouse = $state({ x: 0, y: 0 })
|
|
329
|
-
let hover_data = $state<HoverData3D<ConvexHullEntry> | null>(null)
|
|
329
|
+
let hover_data = $state.raw<HoverData3D<ConvexHullEntry> | null>(null)
|
|
330
330
|
let copy_feedback = $state({ visible: false, position: { x: 0, y: 0 } })
|
|
331
331
|
|
|
332
332
|
// Drag and drop state
|
|
@@ -340,7 +340,7 @@
|
|
|
340
340
|
const current_selection = helpers.current_entry(selected_entry, plot_entries)
|
|
341
341
|
const stale_selection = selected_entry && !current_selection
|
|
342
342
|
if (stale_selection) selected_entry = null
|
|
343
|
-
else if (current_selection && current_selection
|
|
343
|
+
else if (current_selection && !helpers.same_entry(current_selection, selected_entry)) {
|
|
344
344
|
selected_entry = current_selection
|
|
345
345
|
}
|
|
346
346
|
const current_hover = helpers.current_entry(hover_data?.entry, plot_entries)
|
|
@@ -394,12 +394,11 @@
|
|
|
394
394
|
const total_entries = effective_entries.length
|
|
395
395
|
if (total_entries > label_threshold) {
|
|
396
396
|
show_stable_labels = false
|
|
397
|
-
show_unstable_labels = false
|
|
398
397
|
} else {
|
|
399
398
|
// For smaller datasets, show stable labels by default
|
|
400
399
|
show_stable_labels = true
|
|
401
|
-
show_unstable_labels = false
|
|
402
400
|
}
|
|
401
|
+
show_unstable_labels = false
|
|
403
402
|
})
|
|
404
403
|
|
|
405
404
|
// Function to extract structure data from a convex hull entry
|
|
@@ -630,11 +629,8 @@
|
|
|
630
629
|
for (let idx = 0; idx < 4; idx++) {
|
|
631
630
|
const vx = vertices[idx]
|
|
632
631
|
// Direction from centroid to vertex
|
|
633
|
-
const
|
|
634
|
-
|
|
635
|
-
y: vx.y - centroid.y,
|
|
636
|
-
z: vx.z - centroid.z,
|
|
637
|
-
}
|
|
632
|
+
const { x: cx, y: cy, z: cz } = centroid
|
|
633
|
+
const dir = { x: vx.x - cx, y: vx.y - cy, z: vx.z - cz }
|
|
638
634
|
const len = Math.hypot(dir.x, dir.y, dir.z) || 1
|
|
639
635
|
const label_pos = {
|
|
640
636
|
x: vx.x + (dir.x / len) * distance,
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import Icon from '../Icon.svelte'
|
|
8
8
|
import { format_num } from '../labels'
|
|
9
9
|
import { sanitize_html } from '../sanitize'
|
|
10
|
-
import Histogram from '../plot/Histogram.svelte'
|
|
10
|
+
import Histogram from '../plot/histogram/Histogram.svelte'
|
|
11
11
|
import type { Label, RowData } from '../table'
|
|
12
12
|
import HeatmapTable from '../table/HeatmapTable.svelte'
|
|
13
13
|
import type { HTMLAttributes } from 'svelte/elements'
|
|
@@ -254,20 +254,20 @@
|
|
|
254
254
|
// Escape HTML special chars to prevent XSS when rendering user-supplied strings via {@html}
|
|
255
255
|
const escape_html = (str: string): string =>
|
|
256
256
|
str
|
|
257
|
-
.
|
|
258
|
-
.
|
|
259
|
-
.
|
|
260
|
-
.
|
|
261
|
-
.
|
|
257
|
+
.replaceAll('&', `&`)
|
|
258
|
+
.replaceAll('<', `<`)
|
|
259
|
+
.replaceAll('>', `>`)
|
|
260
|
+
.replaceAll('"', `"`)
|
|
261
|
+
.replaceAll('\'', `'`)
|
|
262
262
|
const unescape_html = (str: string, max_rounds = 5): string => {
|
|
263
263
|
let decoded = str
|
|
264
264
|
for (let round_idx = 0; round_idx < max_rounds; round_idx++) {
|
|
265
265
|
const next_decoded = decoded
|
|
266
|
-
.
|
|
267
|
-
.
|
|
268
|
-
.
|
|
269
|
-
.
|
|
270
|
-
.
|
|
266
|
+
.replaceAll('&', `&`)
|
|
267
|
+
.replaceAll('<', `<`)
|
|
268
|
+
.replaceAll('>', `>`)
|
|
269
|
+
.replaceAll('"', `"`)
|
|
270
|
+
.replaceAll(''', `'`)
|
|
271
271
|
if (next_decoded === decoded) break
|
|
272
272
|
decoded = next_decoded
|
|
273
273
|
}
|
|
@@ -336,7 +336,7 @@
|
|
|
336
336
|
// Match by entry_id or common data fields (mat_id, structure_id)
|
|
337
337
|
// since entry_id may be wrapped in HTML (e.g. <a> tags)
|
|
338
338
|
const entry_data = entry.data as Record<string, unknown> | undefined
|
|
339
|
-
const is_highlighted =
|
|
339
|
+
const is_highlighted = Boolean(highlighted_entry_id && (
|
|
340
340
|
entry.entry_id === highlighted_entry_id ||
|
|
341
341
|
entry_data?.mat_id === highlighted_entry_id ||
|
|
342
342
|
entry_data?.structure_id === highlighted_entry_id
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
|
|
65
65
|
// Convert slider position (0-100) to pressure
|
|
66
66
|
const slider_to_pressure = (value: number): number =>
|
|
67
|
-
|
|
67
|
+
10 ** (LOG_P_MIN + (value / 100) * LOG_P_RANGE)
|
|
68
68
|
|
|
69
69
|
// Format gas name for display (subscript numbers)
|
|
70
70
|
const format_gas_name = (gas: GasSpecies): string =>
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
gas: GasSpecies,
|
|
95
95
|
event: Event & { currentTarget: HTMLInputElement },
|
|
96
96
|
): void {
|
|
97
|
-
const P = slider_to_pressure(
|
|
97
|
+
const P = slider_to_pressure(Number(event.currentTarget.value))
|
|
98
98
|
pressures = { ...pressures, [gas]: P }
|
|
99
99
|
// Clear only this gas's preview (don't reset other sliders being dragged simultaneously)
|
|
100
100
|
const { [gas]: _removed_preview, ...remaining_previews } = preview_pressures
|
|
@@ -103,8 +103,8 @@
|
|
|
103
103
|
|
|
104
104
|
function set_pressure_direct(gas: GasSpecies, value: number): void {
|
|
105
105
|
const clamped = Math.max(
|
|
106
|
-
|
|
107
|
-
Math.min(
|
|
106
|
+
10 ** LOG_P_MIN,
|
|
107
|
+
Math.min(10 ** LOG_P_MAX, value),
|
|
108
108
|
)
|
|
109
109
|
pressures = { ...pressures, [gas]: clamped }
|
|
110
110
|
}
|