matterviz 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/EmptyState.svelte +10 -4
- package/dist/FilePicker.svelte +12 -14
- package/dist/Icon.svelte +7 -4
- package/dist/MillerIndexInput.svelte +2 -2
- package/dist/app.css +53 -0
- package/dist/brillouin/BrillouinZone.svelte +75 -85
- package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
- package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
- package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
- package/dist/brillouin/BrillouinZoneScene.svelte +26 -39
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +62 -74
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +511 -547
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
- package/dist/chempot-diagram/async-compute.svelte.js +1 -1
- package/dist/chempot-diagram/controls-state.svelte.js +1 -1
- package/dist/colors/index.d.ts +0 -4
- package/dist/colors/index.js +19 -20
- package/dist/composition/BarChart.svelte +37 -31
- package/dist/composition/BubbleChart.svelte +17 -17
- package/dist/composition/Composition.svelte +7 -11
- package/dist/composition/Formula.svelte +18 -25
- package/dist/composition/FormulaFilter.svelte +92 -95
- package/dist/composition/PieChart.svelte +55 -41
- package/dist/composition/format.js +1 -1
- package/dist/composition/index.d.ts +2 -0
- package/dist/composition/index.js +14 -0
- package/dist/composition/parse.d.ts +2 -2
- package/dist/composition/parse.js +11 -10
- package/dist/constants.js +11 -9
- package/dist/convex-hull/ConvexHull.svelte +12 -15
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull2D.svelte +93 -92
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +109 -140
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +75 -94
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
- package/dist/convex-hull/ConvexHullControls.svelte +46 -48
- package/dist/convex-hull/ConvexHullStats.svelte +193 -195
- package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
- package/dist/convex-hull/GasPressureControls.svelte +5 -12
- package/dist/convex-hull/StructurePopup.svelte +17 -21
- package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
- package/dist/convex-hull/TemperatureSlider.svelte +4 -10
- package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
- package/dist/convex-hull/helpers.d.ts +8 -10
- package/dist/convex-hull/helpers.js +36 -36
- package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
- package/dist/convex-hull/thermodynamics.js +18 -17
- package/dist/coordination/CoordinationBarPlot.svelte +38 -33
- package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
- package/dist/coordination/calc-coordination.d.ts +1 -1
- package/dist/coordination/calc-coordination.js +28 -25
- package/dist/element/BohrAtom.svelte +5 -8
- package/dist/element/ElementHeading.svelte +4 -1
- package/dist/element/ElementPhoto.svelte +11 -9
- package/dist/element/ElementStats.svelte +12 -10
- package/dist/element/ElementTile.svelte +24 -29
- package/dist/element/Nucleus.svelte +4 -2
- package/dist/element/data.d.ts +1 -2
- package/dist/element/helpers.d.ts +4 -0
- package/dist/element/helpers.js +18 -0
- package/dist/element/index.d.ts +1 -4
- package/dist/element/index.js +3 -18
- package/dist/feedback/DragOverlay.svelte +5 -5
- package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
- package/dist/feedback/StatusMessage.svelte +7 -4
- package/dist/fermi-surface/FermiSlice.svelte +21 -18
- package/dist/fermi-surface/FermiSurface.svelte +14 -22
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -7
- package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +37 -64
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
- package/dist/fermi-surface/compute.js +3 -3
- package/dist/fermi-surface/parse.js +22 -24
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +109 -148
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
- package/dist/heatmap-matrix/index.d.ts +5 -0
- package/dist/icons.d.ts +4 -0
- package/dist/icons.js +4 -0
- package/dist/io/ExportPane.svelte +10 -6
- package/dist/io/decompress.d.ts +2 -1
- package/dist/io/decompress.js +22 -35
- package/dist/io/export.d.ts +4 -0
- package/dist/io/export.js +5 -1
- package/dist/io/fetch.d.ts +0 -3
- package/dist/io/fetch.js +0 -11
- package/dist/io/index.d.ts +0 -1
- package/dist/io/index.js +2 -9
- package/dist/io/is-binary.d.ts +9 -0
- package/dist/io/is-binary.js +45 -1
- package/dist/io/url-drop.js +13 -25
- package/dist/isosurface/Isosurface.svelte +17 -23
- package/dist/isosurface/IsosurfaceControls.svelte +37 -42
- package/dist/isosurface/parse-vaspwave.d.ts +3 -0
- package/dist/isosurface/parse-vaspwave.js +138 -0
- package/dist/isosurface/parse.js +6 -6
- package/dist/labels.d.ts +6 -2
- package/dist/labels.js +43 -13
- package/dist/layout/FullscreenButton.svelte +2 -1
- package/dist/layout/FullscreenToggle.svelte +10 -4
- package/dist/layout/InfoCard.svelte +7 -18
- package/dist/layout/InfoTag.svelte +1 -3
- package/dist/layout/NumberRangeInput.svelte +46 -0
- package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
- package/dist/layout/PropertyFilter.svelte +2 -6
- package/dist/layout/SettingsSection.svelte +21 -17
- package/dist/layout/SubpageGrid.svelte +3 -1
- package/dist/layout/ViewerChrome.svelte +9 -10
- package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
- package/dist/layout/fullscreen.js +3 -5
- package/dist/layout/fullscreen.svelte.js +1 -2
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.js +1 -0
- package/dist/layout/json-tree/JsonNode.svelte +8 -11
- package/dist/layout/json-tree/JsonTree.svelte +53 -77
- package/dist/layout/json-tree/JsonValue.svelte +7 -15
- package/dist/layout/json-tree/utils.js +14 -23
- package/dist/math.d.ts +2 -0
- package/dist/math.js +19 -0
- package/dist/overlays/ContextMenu.svelte +4 -2
- package/dist/overlays/CopyButton.svelte +11 -5
- package/dist/overlays/DragControlTab.svelte +6 -1
- package/dist/overlays/DraggablePane.svelte +81 -26
- package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
- package/dist/overlays/GlassChip.svelte +30 -0
- package/dist/overlays/GlassChip.svelte.d.ts +8 -0
- package/dist/overlays/InfoPaneCards.svelte +11 -23
- package/dist/overlays/index.d.ts +7 -0
- package/dist/overlays/index.js +26 -0
- package/dist/overlays/portal.d.ts +2 -0
- package/dist/overlays/portal.js +14 -0
- package/dist/periodic-table/PeriodicTable.svelte +113 -145
- package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
- package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
- package/dist/periodic-table/TableInset.svelte +9 -4
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
- package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
- package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
- package/dist/phase-diagram/build-diagram.js +3 -3
- package/dist/phase-diagram/diagram-input.d.ts +1 -2
- package/dist/phase-diagram/parse.js +15 -15
- package/dist/phase-diagram/svg-to-diagram.js +21 -15
- package/dist/phase-diagram/utils.js +2 -3
- package/dist/plot/bar/BarPlot.svelte +430 -391
- package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
- package/dist/plot/bar/BarPlotControls.svelte +1 -3
- package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
- package/dist/plot/bar/SpacegroupBarPlot.svelte +29 -36
- package/dist/plot/bar/data.d.ts +5 -4
- package/dist/plot/bar/data.js +2 -1
- package/dist/plot/box/BoxPlot.svelte +301 -209
- package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
- package/dist/plot/box/Violin.svelte.d.ts +1 -0
- package/dist/plot/box/box-plot.js +1 -1
- package/dist/plot/core/auto-place.js +1 -1
- package/dist/plot/core/axis-utils.d.ts +12 -7
- package/dist/plot/core/axis-utils.js +48 -48
- package/dist/plot/core/components/AxisLabel.svelte +82 -20
- package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
- package/dist/plot/core/components/ColorBar.svelte +101 -106
- package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
- package/dist/plot/core/components/FillArea.svelte +10 -17
- package/dist/plot/core/components/HierarchyControls.svelte +249 -0
- package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
- package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
- package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
- package/dist/plot/core/components/Line.svelte +18 -9
- package/dist/plot/core/components/Line.svelte.d.ts +2 -0
- package/dist/plot/core/components/PlotAxis.svelte +40 -17
- package/dist/plot/core/components/PlotControls.svelte +65 -41
- package/dist/plot/core/components/PlotLegend.svelte +31 -35
- package/dist/plot/core/components/PlotMarginals.svelte +616 -0
- package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
- package/dist/plot/core/components/PlotTooltip.svelte +1 -1
- package/dist/plot/core/components/PortalSelect.svelte +4 -8
- package/dist/plot/core/components/ReferenceLine.svelte +27 -24
- package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
- package/dist/plot/core/components/ReferencePlane.svelte +7 -8
- package/dist/plot/core/components/ZeroLines.svelte +4 -8
- package/dist/plot/core/components/ZoomRect.svelte +1 -2
- package/dist/plot/core/components/index.d.ts +1 -0
- package/dist/plot/core/components/index.js +1 -0
- package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
- package/dist/plot/core/data-cleaning-signal.js +467 -0
- package/dist/plot/core/data-cleaning.d.ts +2 -42
- package/dist/plot/core/data-cleaning.js +27 -474
- package/dist/plot/core/data-transform.js +9 -5
- package/dist/plot/core/fill-utils.d.ts +3 -1
- package/dist/plot/core/fill-utils.js +28 -6
- package/dist/plot/core/index.d.ts +1 -0
- package/dist/plot/core/index.js +1 -0
- package/dist/plot/core/interactions.js +0 -2
- package/dist/plot/core/layout.d.ts +3 -1
- package/dist/plot/core/layout.js +22 -13
- package/dist/plot/core/marginals.d.ts +170 -0
- package/dist/plot/core/marginals.js +436 -0
- package/dist/plot/core/reference-line.js +1 -1
- package/dist/plot/core/scales.d.ts +23 -0
- package/dist/plot/core/scales.js +39 -13
- package/dist/plot/core/types/fills.d.ts +101 -0
- package/dist/plot/core/types/fills.js +15 -0
- package/dist/plot/core/types/plot-3d.d.ts +87 -0
- package/dist/plot/core/types/plot-3d.js +4 -0
- package/dist/plot/core/types/reference-lines.d.ts +140 -0
- package/dist/plot/core/types/reference-lines.js +9 -0
- package/dist/plot/core/types.d.ts +29 -324
- package/dist/plot/core/types.js +23 -20
- package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
- package/dist/plot/core/utils/hierarchy-chart.js +179 -0
- package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
- package/dist/plot/core/utils/hierarchy-labels.js +99 -0
- package/dist/plot/core/utils/label-placement.js +2 -2
- package/dist/plot/histogram/Histogram.svelte +304 -325
- package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
- package/dist/plot/histogram/HistogramControls.svelte +30 -28
- package/dist/plot/histogram/histogram.d.ts +31 -0
- package/dist/plot/histogram/histogram.js +70 -0
- package/dist/plot/histogram/index.d.ts +1 -0
- package/dist/plot/histogram/index.js +1 -0
- package/dist/plot/index.d.ts +1 -0
- package/dist/plot/index.js +1 -0
- package/dist/plot/sankey/Sankey.svelte +78 -69
- package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
- package/dist/plot/sankey/SankeyControls.svelte +22 -16
- package/dist/plot/scatter/BinnedScatterPlot.svelte +263 -109
- package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
- package/dist/plot/scatter/ElementScatter.svelte +4 -1
- package/dist/plot/scatter/ScatterPlot.svelte +477 -385
- package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
- package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
- package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
- package/dist/plot/scatter/ScatterPoint.svelte +16 -9
- package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
- package/dist/plot/scatter/binned-scatter-types.js +6 -1
- package/dist/plot/scatter/scatter-data.d.ts +1 -1
- package/dist/plot/scatter/scatter-data.js +8 -7
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
- package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
- package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
- package/dist/plot/sunburst/Sunburst.svelte +251 -329
- package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
- package/dist/plot/sunburst/index.d.ts +1 -1
- package/dist/plot/sunburst/index.js +2 -1
- package/dist/plot/sunburst/render.d.ts +2 -2
- package/dist/plot/sunburst/render.js +47 -22
- package/dist/plot/sunburst/sunburst.d.ts +5 -1
- package/dist/plot/sunburst/sunburst.js +10 -3
- package/dist/plot/treemap/Treemap.svelte +907 -0
- package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
- package/dist/plot/treemap/index.d.ts +3 -0
- package/dist/plot/treemap/index.js +4 -0
- package/dist/plot/treemap/treemap.d.ts +26 -0
- package/dist/plot/treemap/treemap.js +99 -0
- package/dist/rdf/RdfPlot.svelte +22 -26
- package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
- package/dist/rdf/calc-rdf.js +4 -8
- package/dist/sanitize.js +1 -1
- package/dist/scene/bind-renderer.svelte.js +14 -6
- package/dist/settings.d.ts +19 -9
- package/dist/settings.js +77 -50
- package/dist/spectral/Bands.svelte +223 -230
- package/dist/spectral/BandsAndDos.svelte +11 -9
- package/dist/spectral/BrillouinBandsDos.svelte +19 -27
- package/dist/spectral/Dos.svelte +70 -73
- package/dist/spectral/helpers.d.ts +3 -3
- package/dist/spectral/helpers.js +25 -35
- package/dist/state.svelte.js +5 -18
- package/dist/structure/Arrow.svelte +5 -18
- package/dist/structure/ArrowInstances.svelte +160 -0
- package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
- package/dist/structure/AtomLegend.svelte +115 -75
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/Bond.svelte +31 -23
- package/dist/structure/CanvasTooltip.svelte +15 -3
- package/dist/structure/CellSelect.svelte +11 -26
- package/dist/structure/Cylinder.svelte +24 -40
- package/dist/structure/InstancedAtoms.svelte +114 -0
- package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
- package/dist/structure/Lattice.svelte +85 -149
- package/dist/structure/SiteLabels.svelte +122 -0
- package/dist/structure/SiteLabels.svelte.d.ts +18 -0
- package/dist/structure/Structure.svelte +473 -419
- package/dist/structure/Structure.svelte.d.ts +4 -2
- package/dist/structure/StructureCarousel.svelte +630 -0
- package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
- package/dist/structure/StructureControls.svelte +157 -399
- package/dist/structure/StructureControls.svelte.d.ts +1 -1
- package/dist/structure/StructureExportPane.svelte +17 -21
- package/dist/structure/StructureInfoPane.svelte +72 -66
- package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
- package/dist/structure/StructureScene.svelte +467 -476
- package/dist/structure/StructureScene.svelte.d.ts +3 -1
- package/dist/structure/StructureViewport.svelte +386 -0
- package/dist/structure/StructureViewport.svelte.d.ts +63 -0
- package/dist/structure/atom-label-placement.d.ts +16 -12
- package/dist/structure/atom-label-placement.js +70 -37
- package/dist/structure/atom-properties.d.ts +2 -0
- package/dist/structure/atom-properties.js +104 -38
- package/dist/structure/bonding.d.ts +10 -3
- package/dist/structure/bonding.js +84 -28
- package/dist/structure/edit-history.d.ts +6 -0
- package/dist/structure/edit-history.js +27 -0
- package/dist/structure/export.d.ts +1 -0
- package/dist/structure/export.js +39 -31
- package/dist/structure/format-detect.d.ts +1 -0
- package/dist/structure/format-detect.js +22 -0
- package/dist/structure/geometry.d.ts +9 -0
- package/dist/structure/geometry.js +27 -0
- package/dist/structure/index.d.ts +16 -1
- package/dist/structure/index.js +13 -2
- package/dist/structure/measure.d.ts +1 -1
- package/dist/structure/measure.js +6 -12
- package/dist/structure/parse.d.ts +2 -1
- package/dist/structure/parse.js +243 -222
- package/dist/structure/partial-occupancy.js +4 -2
- package/dist/structure/pbc.js +78 -98
- package/dist/structure/polyhedra.d.ts +0 -1
- package/dist/structure/polyhedra.js +3 -18
- package/dist/structure/supercell.d.ts +1 -2
- package/dist/structure/supercell.js +7 -13
- package/dist/symmetry/SymmetryElements.svelte +11 -15
- package/dist/symmetry/SymmetryStats.svelte +56 -68
- package/dist/symmetry/WyckoffTable.svelte +5 -24
- package/dist/symmetry/cell-transform.js +1 -0
- package/dist/symmetry/index.d.ts +1 -0
- package/dist/symmetry/index.js +8 -2
- package/dist/symmetry/spacegroups.js +3 -2
- package/dist/table/HeatmapTable.svelte +1102 -365
- package/dist/table/HeatmapTable.svelte.d.ts +12 -2
- package/dist/table/ToggleMenu.svelte +5 -12
- package/dist/table/index.d.ts +21 -6
- package/dist/table/index.js +34 -21
- package/dist/theme/ThemeControl.svelte +16 -8
- package/dist/theme/index.d.ts +1 -5
- package/dist/theme/index.js +4 -10
- package/dist/theme/themes.mjs +14 -7
- package/dist/tooltip/KCoords.svelte +4 -1
- package/dist/tooltip/TooltipContent.svelte +2 -5
- package/dist/trajectory/Trajectory.svelte +515 -308
- package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
- package/dist/trajectory/TrajectoryError.svelte +11 -8
- package/dist/trajectory/TrajectoryExportPane.svelte +14 -31
- package/dist/trajectory/TrajectoryInfoPane.svelte +85 -97
- package/dist/trajectory/extract.js +56 -34
- package/dist/trajectory/format-detect.js +11 -9
- package/dist/trajectory/frame-reader.d.ts +2 -0
- package/dist/trajectory/frame-reader.js +33 -29
- package/dist/trajectory/helpers.d.ts +2 -0
- package/dist/trajectory/helpers.js +18 -7
- package/dist/trajectory/index.d.ts +1 -0
- package/dist/trajectory/index.js +3 -0
- package/dist/trajectory/parse/h5-utils.d.ts +13 -0
- package/dist/trajectory/parse/h5-utils.js +109 -0
- package/dist/trajectory/parse/hdf5.d.ts +1 -1
- package/dist/trajectory/parse/hdf5.js +116 -106
- package/dist/trajectory/parse/index.d.ts +2 -3
- package/dist/trajectory/parse/index.js +17 -20
- package/dist/trajectory/parse/lammps.js +8 -12
- package/dist/trajectory/parse/vasp.js +10 -7
- package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
- package/dist/trajectory/parse/vaspout-electronic.js +207 -0
- package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
- package/dist/trajectory/parse/vaspout-h5.js +284 -0
- package/dist/trajectory/parse/xyz.js +11 -7
- package/dist/trajectory/plotting.d.ts +8 -9
- package/dist/trajectory/plotting.js +99 -27
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +7 -0
- package/dist/xrd/XrdPlot.svelte +47 -61
- package/dist/xrd/broadening.js +2 -1
- package/dist/xrd/calc-xrd.js +2 -4
- package/dist/xrd/parse.d.ts +0 -1
- package/dist/xrd/parse.js +56 -73
- package/package.json +61 -33
- package/dist/api/mp.d.ts +0 -6
- package/dist/api/mp.js +0 -22
- package/dist/plot/sunburst/SunburstControls.svelte +0 -200
|
@@ -9,22 +9,18 @@
|
|
|
9
9
|
import type { ExportSection } from '../io'
|
|
10
10
|
import ExportPane from '../io/ExportPane.svelte'
|
|
11
11
|
import { format_num } from '../labels'
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
FullscreenButton,
|
|
14
|
+
type FullscreenToggleProp,
|
|
15
|
+
SettingsSection,
|
|
16
|
+
toggle_fullscreen,
|
|
17
|
+
} from '../layout'
|
|
13
18
|
import { sync_fullscreen } from '../layout/fullscreen.svelte'
|
|
14
19
|
import type { Vec2, Vec3 } from '../math'
|
|
15
|
-
import {
|
|
16
|
-
convex_hull_2d,
|
|
17
|
-
cross_3d,
|
|
18
|
-
merge_coplanar_triangles,
|
|
19
|
-
normalize_vec,
|
|
20
|
-
} from '../math'
|
|
20
|
+
import { convex_hull_2d, cross_3d, merge_coplanar_triangles, normalize_vec } from '../math'
|
|
21
21
|
import DraggablePane from '../overlays/DraggablePane.svelte'
|
|
22
22
|
import { ColorBar, ScatterPlot3DControls } from '../plot'
|
|
23
|
-
import {
|
|
24
|
-
constrain_tooltip_position,
|
|
25
|
-
pad_rect,
|
|
26
|
-
rects_overlap,
|
|
27
|
-
} from '../plot/core/layout'
|
|
23
|
+
import { constrain_tooltip_position, pad_rect, rects_overlap } from '../plot/core/layout'
|
|
28
24
|
import type {
|
|
29
25
|
AxisConfig3D,
|
|
30
26
|
CameraProjection3D,
|
|
@@ -129,18 +125,22 @@
|
|
|
129
125
|
} = $props()
|
|
130
126
|
|
|
131
127
|
// Control overrides (override ?? config ?? default, cleared by Reset)
|
|
132
|
-
const overrides = create_chempot_overrides(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
128
|
+
const overrides = create_chempot_overrides(
|
|
129
|
+
() => config,
|
|
130
|
+
[
|
|
131
|
+
`formal_chempots`,
|
|
132
|
+
`label_stable`,
|
|
133
|
+
`element_padding`,
|
|
134
|
+
`default_min_limit`,
|
|
135
|
+
`formulas_to_draw`,
|
|
136
|
+
`draw_formula_meshes`,
|
|
137
|
+
`draw_formula_lines`,
|
|
138
|
+
`color_mode`,
|
|
139
|
+
`color_scale`,
|
|
140
|
+
`reverse_color_scale`,
|
|
141
|
+
],
|
|
142
|
+
{ color_mode: `arity`, formulas_to_draw: [] },
|
|
143
|
+
)
|
|
144
144
|
const formal_chempots = $derived(overrides.resolve(`formal_chempots`))
|
|
145
145
|
const label_stable = $derived(overrides.resolve(`label_stable`))
|
|
146
146
|
const element_padding = $derived(overrides.resolve(`element_padding`))
|
|
@@ -156,9 +156,7 @@
|
|
|
156
156
|
config.tooltip_detail_level ?? CHEMPOT_DEFAULTS.tooltip_detail_level,
|
|
157
157
|
)
|
|
158
158
|
const formula_colors = $derived(
|
|
159
|
-
config.formula_colors?.length
|
|
160
|
-
? config.formula_colors
|
|
161
|
-
: CHEMPOT_DEFAULTS.formula_colors,
|
|
159
|
+
config.formula_colors?.length ? config.formula_colors : CHEMPOT_DEFAULTS.formula_colors,
|
|
162
160
|
)
|
|
163
161
|
|
|
164
162
|
const formula_label_segments = (formula: string): FormulaLabelSegment[] =>
|
|
@@ -181,21 +179,38 @@
|
|
|
181
179
|
// Separate effects so each reacts to its own pane opening independently —
|
|
182
180
|
// a single $derived ternary would create priority ordering where opening
|
|
183
181
|
// a "lower" pane while a "higher" one is open fails silently.
|
|
184
|
-
$effect(() => {
|
|
185
|
-
|
|
186
|
-
|
|
182
|
+
$effect(() => {
|
|
183
|
+
if (export_pane_open) {
|
|
184
|
+
formula_picker_open = false
|
|
185
|
+
controls_open = false
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
$effect(() => {
|
|
189
|
+
if (formula_picker_open) {
|
|
190
|
+
export_pane_open = false
|
|
191
|
+
controls_open = false
|
|
192
|
+
}
|
|
193
|
+
})
|
|
194
|
+
$effect(() => {
|
|
195
|
+
if (controls_open) {
|
|
196
|
+
export_pane_open = false
|
|
197
|
+
formula_picker_open = false
|
|
198
|
+
}
|
|
199
|
+
})
|
|
187
200
|
let container_width = $state(0)
|
|
188
201
|
let container_height = $state(0)
|
|
189
202
|
const base_aspect_ratio = $derived(height > 0 && width > 0 ? height / width : 1)
|
|
190
203
|
const render_width = $derived(container_width > 0 ? container_width : width)
|
|
191
204
|
const render_height = $derived(
|
|
192
205
|
fullscreen
|
|
193
|
-
?
|
|
206
|
+
? container_height > 0
|
|
207
|
+
? container_height
|
|
208
|
+
: height
|
|
194
209
|
: Math.round(render_width * base_aspect_ratio),
|
|
195
210
|
)
|
|
196
211
|
|
|
197
212
|
let mounted = $state(false)
|
|
198
|
-
onMount(() => mounted = true)
|
|
213
|
+
onMount(() => (mounted = true))
|
|
199
214
|
let orbit_controls_ref = $state<OrbitControls | undefined>(undefined)
|
|
200
215
|
// Backside tracking: axes/ticks/labels render on the far side from the camera
|
|
201
216
|
// back[i] = backside data coordinate value for data axis i
|
|
@@ -248,9 +263,7 @@
|
|
|
248
263
|
if (next_temperature !== temperature) temperature = next_temperature
|
|
249
264
|
})
|
|
250
265
|
|
|
251
|
-
const show_temperature_slider = $derived(
|
|
252
|
-
has_temp_data && available_temperatures.length > 0,
|
|
253
|
-
)
|
|
266
|
+
const show_temperature_slider = $derived(has_temp_data && available_temperatures.length > 0)
|
|
254
267
|
|
|
255
268
|
const projection_source_entries = $derived(
|
|
256
269
|
get_projection_source_entries(entries, temp_filtered_entries),
|
|
@@ -262,10 +275,10 @@
|
|
|
262
275
|
projection_source_entries.flatMap((entry) =>
|
|
263
276
|
Object.entries(entry.composition)
|
|
264
277
|
.filter(([, amount]) => amount > 0)
|
|
265
|
-
.map(([element]) => element)
|
|
278
|
+
.map(([element]) => element),
|
|
266
279
|
),
|
|
267
280
|
),
|
|
268
|
-
).sort()
|
|
281
|
+
).sort(),
|
|
269
282
|
)
|
|
270
283
|
const has_multinary_system = $derived(all_entry_elements.length > 3)
|
|
271
284
|
let projection_elements_override = $state<string[] | null>(null)
|
|
@@ -287,9 +300,7 @@
|
|
|
287
300
|
})
|
|
288
301
|
const effective_config = $derived({
|
|
289
302
|
...config,
|
|
290
|
-
elements: projection_elements.length === 3
|
|
291
|
-
? projection_elements
|
|
292
|
-
: config.elements,
|
|
303
|
+
elements: projection_elements.length === 3 ? projection_elements : config.elements,
|
|
293
304
|
formal_chempots,
|
|
294
305
|
label_stable,
|
|
295
306
|
element_padding,
|
|
@@ -319,7 +330,9 @@
|
|
|
319
330
|
diagram_data = null
|
|
320
331
|
diagram_computing = false
|
|
321
332
|
})
|
|
322
|
-
return () => {
|
|
333
|
+
return () => {
|
|
334
|
+
cancelled = true
|
|
335
|
+
}
|
|
323
336
|
})
|
|
324
337
|
|
|
325
338
|
const plot_elements = $derived(diagram_data?.elements ?? projection_elements)
|
|
@@ -348,15 +361,11 @@
|
|
|
348
361
|
})
|
|
349
362
|
const current_projection_key = $derived(plot_elements.join(`|`))
|
|
350
363
|
let formula_filter_query = $state(``)
|
|
351
|
-
const available_formulas = $derived.by(() =>
|
|
352
|
-
Object.keys(diagram_data?.domains ?? {}).sort()
|
|
353
|
-
)
|
|
364
|
+
const available_formulas = $derived.by(() => Object.keys(diagram_data?.domains ?? {}).sort())
|
|
354
365
|
const filtered_formulas = $derived.by(() => {
|
|
355
366
|
const query = formula_filter_query.trim().toLowerCase()
|
|
356
367
|
if (!query) return available_formulas
|
|
357
|
-
return available_formulas.filter((formula) =>
|
|
358
|
-
formula.toLowerCase().includes(query)
|
|
359
|
-
)
|
|
368
|
+
return available_formulas.filter((formula) => formula.toLowerCase().includes(query))
|
|
360
369
|
})
|
|
361
370
|
|
|
362
371
|
// Process domains for rendering
|
|
@@ -380,45 +389,49 @@
|
|
|
380
389
|
max_energy_per_atom: number | null
|
|
381
390
|
}
|
|
382
391
|
type NumericColorMode = Exclude<ChemPotColorMode, `none` | `arity`>
|
|
392
|
+
const domain_annotation_cache = new Map<string, number[]>()
|
|
393
|
+
|
|
394
|
+
function get_domain_ann_loc(points_3d: number[][]): number[] {
|
|
395
|
+
if (points_3d.length >= 3) {
|
|
396
|
+
const cache_key = points_3d.map((point) => point.join(`,`)).join(`;`)
|
|
397
|
+
const cached = domain_annotation_cache.get(cache_key)
|
|
398
|
+
if (cached) return cached
|
|
399
|
+
const ann_loc = get_3d_domain_simplexes_and_ann_loc(points_3d).ann_loc
|
|
400
|
+
domain_annotation_cache.set(cache_key, ann_loc)
|
|
401
|
+
return ann_loc
|
|
402
|
+
}
|
|
403
|
+
return points_3d[0].map(
|
|
404
|
+
(_, col_idx) =>
|
|
405
|
+
points_3d.reduce((sum, point) => sum + point[col_idx], 0) / points_3d.length,
|
|
406
|
+
)
|
|
407
|
+
}
|
|
383
408
|
|
|
384
409
|
const render_domains = $derived.by((): DomainRenderData[] => {
|
|
385
410
|
if (!diagram_data || plot_elements.length < 2) return []
|
|
386
411
|
|
|
387
412
|
const dim = diagram_data.elements.length
|
|
388
413
|
const indices = Array.from({ length: dim }, (_, idx) => idx)
|
|
389
|
-
const new_lims =
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
414
|
+
const new_lims =
|
|
415
|
+
element_padding > 0
|
|
416
|
+
? apply_element_padding(
|
|
417
|
+
diagram_data.domains,
|
|
418
|
+
indices,
|
|
419
|
+
element_padding,
|
|
420
|
+
default_min_limit,
|
|
421
|
+
)
|
|
422
|
+
: null
|
|
397
423
|
|
|
398
424
|
const result: DomainRenderData[] = []
|
|
399
425
|
for (const [formula, pts] of Object.entries(diagram_data.domains)) {
|
|
400
426
|
const padded = new_lims
|
|
401
|
-
? pad_domain_points(
|
|
402
|
-
pts,
|
|
403
|
-
indices,
|
|
404
|
-
new_lims,
|
|
405
|
-
default_min_limit,
|
|
406
|
-
element_padding,
|
|
407
|
-
)
|
|
427
|
+
? pad_domain_points(pts, indices, new_lims, default_min_limit, element_padding)
|
|
408
428
|
: pts
|
|
409
429
|
if (padded.length < 2) continue
|
|
410
|
-
const is_draw = formulas_to_draw.includes(formula)
|
|
411
|
-
const centroid = padded[0].map((_, col_idx) =>
|
|
412
|
-
padded.reduce((sum, point) => sum + point[col_idx], 0) / padded.length
|
|
413
|
-
)
|
|
414
|
-
const ann_loc = padded.length >= 3
|
|
415
|
-
? get_3d_domain_simplexes_and_ann_loc(padded).ann_loc
|
|
416
|
-
: centroid
|
|
417
430
|
result.push({
|
|
418
431
|
formula,
|
|
419
432
|
points_3d: padded,
|
|
420
|
-
ann_loc,
|
|
421
|
-
is_draw_formula:
|
|
433
|
+
ann_loc: get_domain_ann_loc(padded),
|
|
434
|
+
is_draw_formula: formulas_to_draw.includes(formula),
|
|
422
435
|
label_font_size: bbox_diagonal(padded),
|
|
423
436
|
})
|
|
424
437
|
}
|
|
@@ -469,9 +482,7 @@
|
|
|
469
482
|
// Original (non-renormalized) elemental references for formation energy computation.
|
|
470
483
|
// diagram_data.el_refs may be renormalized to zero when formal_chempots is true,
|
|
471
484
|
// so we compute our own from the raw entries to get true DFT reference energies.
|
|
472
|
-
const raw_el_refs = $derived(
|
|
473
|
-
get_min_entries_and_el_refs(temp_filtered_entries).el_refs,
|
|
474
|
-
)
|
|
485
|
+
const raw_el_refs = $derived(get_min_entries_and_el_refs(temp_filtered_entries).el_refs)
|
|
475
486
|
|
|
476
487
|
const color_mode_labels: Record<NumericColorMode, string> = {
|
|
477
488
|
energy: `Energy per atom (eV)`,
|
|
@@ -486,11 +497,7 @@
|
|
|
486
497
|
return entry_energy_stats_by_formula.get(formula)?.min_energy_per_atom ?? null
|
|
487
498
|
}
|
|
488
499
|
if (active_color_mode === `formation_energy`) {
|
|
489
|
-
return best_form_energy_for_formula(
|
|
490
|
-
temp_filtered_entries,
|
|
491
|
-
formula,
|
|
492
|
-
raw_el_refs,
|
|
493
|
-
) ?? null
|
|
500
|
+
return best_form_energy_for_formula(temp_filtered_entries, formula, raw_el_refs) ?? null
|
|
494
501
|
}
|
|
495
502
|
return entry_energy_stats_by_formula.get(formula)?.matching_entry_count ?? 0
|
|
496
503
|
}
|
|
@@ -537,24 +544,22 @@
|
|
|
537
544
|
})
|
|
538
545
|
|
|
539
546
|
// Range and label for the color bar (null for none/arity which are categorical)
|
|
540
|
-
const color_range = $derived.by(
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
},
|
|
557
|
-
)
|
|
547
|
+
const color_range = $derived.by((): { min: number; max: number; label: string } | null => {
|
|
548
|
+
const values = domain_color_values?.values ?? []
|
|
549
|
+
if (values.length === 0) return null
|
|
550
|
+
let lo = values[0],
|
|
551
|
+
hi = values[0]
|
|
552
|
+
for (let idx = 1; idx < values.length; idx++) {
|
|
553
|
+
if (values[idx] < lo) lo = values[idx]
|
|
554
|
+
if (values[idx] > hi) hi = values[idx]
|
|
555
|
+
}
|
|
556
|
+
return {
|
|
557
|
+
min: lo,
|
|
558
|
+
max: Math.max(hi, lo + 1e-6),
|
|
559
|
+
label:
|
|
560
|
+
color_mode === `none` || color_mode === `arity` ? `` : color_mode_labels[color_mode],
|
|
561
|
+
}
|
|
562
|
+
})
|
|
558
563
|
|
|
559
564
|
const arity_legend_labels = $derived.by((): string[] => {
|
|
560
565
|
let has_four_plus_regions = false
|
|
@@ -574,9 +579,12 @@
|
|
|
574
579
|
const render_axis_scale = $derived.by((): Vec3 => {
|
|
575
580
|
const points = render_domains.flatMap((domain) => domain.points_3d)
|
|
576
581
|
if (points.length === 0) return [1, 1, 1]
|
|
577
|
-
let min0 = Infinity,
|
|
578
|
-
|
|
579
|
-
let
|
|
582
|
+
let min0 = Infinity,
|
|
583
|
+
max0 = -Infinity
|
|
584
|
+
let min1 = Infinity,
|
|
585
|
+
max1 = -Infinity
|
|
586
|
+
let min2 = Infinity,
|
|
587
|
+
max2 = -Infinity
|
|
580
588
|
for (const point of points) {
|
|
581
589
|
if (point[0] < min0) min0 = point[0]
|
|
582
590
|
if (point[0] > max0) max0 = point[0]
|
|
@@ -616,11 +624,7 @@
|
|
|
616
624
|
sum_z += z_val
|
|
617
625
|
}
|
|
618
626
|
const n_points = points.length
|
|
619
|
-
const center = new THREE.Vector3(
|
|
620
|
-
sum_x / n_points,
|
|
621
|
-
sum_y / n_points,
|
|
622
|
-
sum_z / n_points,
|
|
623
|
-
)
|
|
627
|
+
const center = new THREE.Vector3(sum_x / n_points, sum_y / n_points, sum_z / n_points)
|
|
624
628
|
// Compute max distance from center
|
|
625
629
|
let max_dist = 0
|
|
626
630
|
for (const point of points) {
|
|
@@ -635,30 +639,22 @@
|
|
|
635
639
|
data_center.y + data_extent,
|
|
636
640
|
data_center.z + data_extent,
|
|
637
641
|
])
|
|
638
|
-
const default_camera_target = $derived<Vec3>([
|
|
639
|
-
data_center.x,
|
|
640
|
-
data_center.y,
|
|
641
|
-
data_center.z,
|
|
642
|
-
])
|
|
642
|
+
const default_camera_target = $derived<Vec3>([data_center.x, data_center.y, data_center.z])
|
|
643
643
|
const default_orthographic_zoom = $derived(
|
|
644
644
|
Math.min(render_width, render_height) / (data_extent * 1.6),
|
|
645
645
|
)
|
|
646
646
|
let camera_position_override = $state<Vec3 | null>(null)
|
|
647
647
|
let camera_target_override = $state<Vec3 | null>(null)
|
|
648
648
|
let orthographic_zoom_override = $state<number | null>(null)
|
|
649
|
-
const camera_position = $derived(
|
|
650
|
-
|
|
651
|
-
)
|
|
652
|
-
const camera_target = $derived(
|
|
653
|
-
camera_target_override ?? default_camera_target,
|
|
654
|
-
)
|
|
655
|
-
const orthographic_zoom = $derived(
|
|
656
|
-
orthographic_zoom_override ?? default_orthographic_zoom,
|
|
657
|
-
)
|
|
649
|
+
const camera_position = $derived(camera_position_override ?? default_camera_position)
|
|
650
|
+
const camera_target = $derived(camera_target_override ?? default_camera_target)
|
|
651
|
+
const orthographic_zoom = $derived(orthographic_zoom_override ?? default_orthographic_zoom)
|
|
658
652
|
// Label scale factor: zoom relative to default, so labels grow/shrink with zoom
|
|
659
653
|
// Labels scale sub-linearly with zoom so they grow but don't dominate when zoomed in
|
|
660
654
|
const zoom_scale = $derived(
|
|
661
|
-
default_orthographic_zoom > 0
|
|
655
|
+
default_orthographic_zoom > 0
|
|
656
|
+
? Math.sqrt(orthographic_zoom / default_orthographic_zoom)
|
|
657
|
+
: 1,
|
|
662
658
|
)
|
|
663
659
|
let last_data_center: Vec3 | null = null
|
|
664
660
|
let last_data_extent: number | null = null
|
|
@@ -667,14 +663,16 @@
|
|
|
667
663
|
// Each domain in a chem pot diagram is a convex polygon/polyhedron. We project
|
|
668
664
|
// to 2D (trying all 3 axis-aligned planes) and use the best projection's
|
|
669
665
|
// convex hull boundary. This reliably handles both flat and 3D domains.
|
|
670
|
-
function get_domain_edges(
|
|
671
|
-
pts: number[][],
|
|
672
|
-
): [number[], number[]][] {
|
|
666
|
+
function get_domain_edges(pts: number[][]): [number[], number[]][] {
|
|
673
667
|
const unique = dedup_3d(pts)
|
|
674
668
|
if (unique.length < 2) return []
|
|
675
669
|
if (unique.length === 2) return [[unique[0], unique[1]]]
|
|
676
670
|
if (unique.length === 3) {
|
|
677
|
-
return [
|
|
671
|
+
return [
|
|
672
|
+
[unique[0], unique[1]],
|
|
673
|
+
[unique[1], unique[2]],
|
|
674
|
+
[unique[0], unique[2]],
|
|
675
|
+
]
|
|
678
676
|
}
|
|
679
677
|
return get_2d_hull_edges(unique)
|
|
680
678
|
}
|
|
@@ -694,9 +692,7 @@
|
|
|
694
692
|
// (largest non-degenerate hull area). Unioning multiple projections can add
|
|
695
693
|
// non-physical diagonals for nearly coplanar domains.
|
|
696
694
|
// Called only from get_domain_edges with 4+ unique points
|
|
697
|
-
function get_2d_hull_edges(
|
|
698
|
-
pts: number[][],
|
|
699
|
-
): [number[], number[]][] {
|
|
695
|
+
function get_2d_hull_edges(pts: number[][]): [number[], number[]][] {
|
|
700
696
|
let selected_hull: Vec2[] = []
|
|
701
697
|
let selected_coord_to_idx: SvelteMap<string, number> | null = null
|
|
702
698
|
let selected_hull_area = -1
|
|
@@ -706,15 +702,20 @@
|
|
|
706
702
|
|
|
707
703
|
// Skip this projection if points collapse to a line (near-zero range in
|
|
708
704
|
// either projected axis). This avoids spurious edges from edge-on views.
|
|
709
|
-
let min0 = Infinity,
|
|
705
|
+
let min0 = Infinity,
|
|
706
|
+
max0 = -Infinity,
|
|
707
|
+
min1 = Infinity,
|
|
708
|
+
max1 = -Infinity
|
|
710
709
|
for (const pt of pts) {
|
|
711
|
-
const v0 = pt[axes[0]],
|
|
710
|
+
const v0 = pt[axes[0]],
|
|
711
|
+
v1 = pt[axes[1]]
|
|
712
712
|
if (v0 < min0) min0 = v0
|
|
713
713
|
if (v0 > max0) max0 = v0
|
|
714
714
|
if (v1 < min1) min1 = v1
|
|
715
715
|
if (v1 > max1) max1 = v1
|
|
716
716
|
}
|
|
717
|
-
const range0 = max0 - min0,
|
|
717
|
+
const range0 = max0 - min0,
|
|
718
|
+
range1 = max1 - min1
|
|
718
719
|
const max_2d_range = Math.max(range0, range1)
|
|
719
720
|
if (max_2d_range < 1e-6 || Math.min(range0, range1) < max_2d_range * 0.01) {
|
|
720
721
|
continue
|
|
@@ -752,7 +753,9 @@
|
|
|
752
753
|
`${point_b[0].toFixed(6)},${point_b[1].toFixed(6)}`,
|
|
753
754
|
)
|
|
754
755
|
if (
|
|
755
|
-
point_a_idx == null ||
|
|
756
|
+
point_a_idx == null ||
|
|
757
|
+
point_b_idx == null ||
|
|
758
|
+
point_a_idx >= pts.length ||
|
|
756
759
|
point_b_idx >= pts.length
|
|
757
760
|
) {
|
|
758
761
|
console.warn(`get_2d_hull_edges: invalid edge`, {
|
|
@@ -846,7 +849,9 @@
|
|
|
846
849
|
const n_verts = pos.count
|
|
847
850
|
const n_faces = n_verts / 3
|
|
848
851
|
// Hull centroid for orienting face normals outward
|
|
849
|
-
let hx = 0,
|
|
852
|
+
let hx = 0,
|
|
853
|
+
hy = 0,
|
|
854
|
+
hz = 0
|
|
850
855
|
for (let vert_idx = 0; vert_idx < n_verts; vert_idx++) {
|
|
851
856
|
hx += pos.getX(vert_idx)
|
|
852
857
|
hy += pos.getY(vert_idx)
|
|
@@ -900,7 +905,9 @@
|
|
|
900
905
|
const centroids = render_domains
|
|
901
906
|
.filter((domain) => !domain.is_draw_formula && domain.points_3d.length > 0)
|
|
902
907
|
.map((domain) => {
|
|
903
|
-
let sx = 0,
|
|
908
|
+
let sx = 0,
|
|
909
|
+
sy = 0,
|
|
910
|
+
sz = 0
|
|
904
911
|
for (const pt of domain.points_3d) {
|
|
905
912
|
const [x_val, y_val, z_val] = to_render_xyz(pt)
|
|
906
913
|
sx += x_val
|
|
@@ -908,7 +915,12 @@
|
|
|
908
915
|
sz += z_val
|
|
909
916
|
}
|
|
910
917
|
const n_points = domain.points_3d.length
|
|
911
|
-
return {
|
|
918
|
+
return {
|
|
919
|
+
formula: domain.formula,
|
|
920
|
+
cx: sx / n_points,
|
|
921
|
+
cy: sy / n_points,
|
|
922
|
+
cz: sz / n_points,
|
|
923
|
+
}
|
|
912
924
|
})
|
|
913
925
|
|
|
914
926
|
// Assign each face to the nearest domain centroid
|
|
@@ -938,9 +950,9 @@
|
|
|
938
950
|
const tol = 1e-3
|
|
939
951
|
const round = (val: number): number => Math.round(val / tol)
|
|
940
952
|
const vkey = (vert_idx: number): string =>
|
|
941
|
-
`${round(pos.getX(vert_idx))},${round(pos.getY(vert_idx))},${
|
|
942
|
-
|
|
943
|
-
}`
|
|
953
|
+
`${round(pos.getX(vert_idx))},${round(pos.getY(vert_idx))},${round(
|
|
954
|
+
pos.getZ(vert_idx),
|
|
955
|
+
)}`
|
|
944
956
|
// Compute face normals
|
|
945
957
|
const normals: Vec3[] = []
|
|
946
958
|
for (let face_idx = 0; face_idx < n_faces; face_idx++) {
|
|
@@ -962,13 +974,11 @@
|
|
|
962
974
|
for (let face_idx = 0; face_idx < n_faces; face_idx++) {
|
|
963
975
|
const base = face_idx * 3
|
|
964
976
|
const keys = [vkey(base), vkey(base + 1), vkey(base + 2)]
|
|
965
|
-
for (
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
]
|
|
971
|
-
) {
|
|
977
|
+
for (const ek of [
|
|
978
|
+
edge_key(keys[0], keys[1]),
|
|
979
|
+
edge_key(keys[1], keys[2]),
|
|
980
|
+
edge_key(keys[0], keys[2]),
|
|
981
|
+
]) {
|
|
972
982
|
const list = edge_faces.get(ek)
|
|
973
983
|
if (list) list.push(face_idx)
|
|
974
984
|
else edge_faces.set(ek, [face_idx])
|
|
@@ -984,13 +994,15 @@
|
|
|
984
994
|
return node
|
|
985
995
|
}
|
|
986
996
|
const union = (a_idx: number, b_idx: number): void => {
|
|
987
|
-
const ra = find(a_idx),
|
|
997
|
+
const ra = find(a_idx),
|
|
998
|
+
rb = find(b_idx)
|
|
988
999
|
if (ra !== rb) parent[ra] = rb
|
|
989
1000
|
}
|
|
990
1001
|
for (const pair of edge_faces.values()) {
|
|
991
1002
|
if (pair.length !== 2) continue
|
|
992
1003
|
const [fa, fb] = pair
|
|
993
|
-
const na = normals[fa],
|
|
1004
|
+
const na = normals[fa],
|
|
1005
|
+
nb = normals[fb]
|
|
994
1006
|
if (Math.abs(na[0] * nb[0] + na[1] * nb[1] + na[2] * nb[2]) > 1 - tol) {
|
|
995
1007
|
union(fa, fb)
|
|
996
1008
|
}
|
|
@@ -1140,15 +1152,9 @@
|
|
|
1140
1152
|
|
|
1141
1153
|
const controls_series = $derived<DataSeries3D[]>([
|
|
1142
1154
|
{
|
|
1143
|
-
x: render_domains.flatMap((domain) =>
|
|
1144
|
-
|
|
1145
|
-
),
|
|
1146
|
-
y: render_domains.flatMap((domain) =>
|
|
1147
|
-
domain.points_3d.map((point) => point[2])
|
|
1148
|
-
),
|
|
1149
|
-
z: render_domains.flatMap((domain) =>
|
|
1150
|
-
domain.points_3d.map((point) => point[0])
|
|
1151
|
-
),
|
|
1155
|
+
x: render_domains.flatMap((domain) => domain.points_3d.map((point) => point[1])),
|
|
1156
|
+
y: render_domains.flatMap((domain) => domain.points_3d.map((point) => point[2])),
|
|
1157
|
+
z: render_domains.flatMap((domain) => domain.points_3d.map((point) => point[0])),
|
|
1152
1158
|
label: `domains`,
|
|
1153
1159
|
},
|
|
1154
1160
|
])
|
|
@@ -1159,8 +1165,7 @@
|
|
|
1159
1165
|
const result: { geometry: THREE.BufferGeometry; color: string }[] = []
|
|
1160
1166
|
for (const domain of render_domains) {
|
|
1161
1167
|
if (!domain.is_draw_formula) continue
|
|
1162
|
-
const color_idx = formulas_to_draw.indexOf(domain.formula) %
|
|
1163
|
-
formula_colors.length
|
|
1168
|
+
const color_idx = formulas_to_draw.indexOf(domain.formula) % formula_colors.length
|
|
1164
1169
|
const swizzled = domain.points_3d.map((point) => to_render_xyz(point))
|
|
1165
1170
|
const positions: number[] = []
|
|
1166
1171
|
for (const [pa, pb] of get_domain_edges(swizzled)) {
|
|
@@ -1179,8 +1184,7 @@
|
|
|
1179
1184
|
if (!draw_formula_meshes) return result
|
|
1180
1185
|
for (const domain of render_domains) {
|
|
1181
1186
|
if (!domain.is_draw_formula || domain.points_3d.length < 4) continue
|
|
1182
|
-
const color_idx = formulas_to_draw.indexOf(domain.formula) %
|
|
1183
|
-
formula_colors.length
|
|
1187
|
+
const color_idx = formulas_to_draw.indexOf(domain.formula) % formula_colors.length
|
|
1184
1188
|
const unique = dedup_3d(domain.points_3d)
|
|
1185
1189
|
if (unique.length < 4) continue
|
|
1186
1190
|
const vectors = unique.map((pt) => to_vec3(pt))
|
|
@@ -1194,10 +1198,7 @@
|
|
|
1194
1198
|
return result
|
|
1195
1199
|
})
|
|
1196
1200
|
|
|
1197
|
-
function get_touches_limits(
|
|
1198
|
-
points_3d: number[][],
|
|
1199
|
-
lims: Vec2[],
|
|
1200
|
-
): string[] {
|
|
1201
|
+
function get_touches_limits(points_3d: number[][], lims: Vec2[]): string[] {
|
|
1201
1202
|
const limit_tol = 1e-3
|
|
1202
1203
|
const touches_limits: string[] = []
|
|
1203
1204
|
for (
|
|
@@ -1207,11 +1208,11 @@
|
|
|
1207
1208
|
) {
|
|
1208
1209
|
const [axis_min, axis_max] = lims[axis_idx]
|
|
1209
1210
|
const axis_name = plot_elements[axis_idx] ?? `axis_${axis_idx}`
|
|
1210
|
-
const touches_min = points_3d.some(
|
|
1211
|
-
Math.abs(point[axis_idx] - axis_min) < limit_tol
|
|
1211
|
+
const touches_min = points_3d.some(
|
|
1212
|
+
(point) => Math.abs(point[axis_idx] - axis_min) < limit_tol,
|
|
1212
1213
|
)
|
|
1213
|
-
const touches_max = points_3d.some(
|
|
1214
|
-
Math.abs(point[axis_idx] - axis_max) < limit_tol
|
|
1214
|
+
const touches_max = points_3d.some(
|
|
1215
|
+
(point) => Math.abs(point[axis_idx] - axis_max) < limit_tol,
|
|
1215
1216
|
)
|
|
1216
1217
|
if (touches_min) touches_limits.push(`${axis_name} lower bound`)
|
|
1217
1218
|
if (touches_max) touches_limits.push(`${axis_name} upper bound`)
|
|
@@ -1269,9 +1270,7 @@
|
|
|
1269
1270
|
const vertex_owners = new SvelteMap<string, string[]>()
|
|
1270
1271
|
for (const domain of render_domains) {
|
|
1271
1272
|
for (const pt of domain.points_3d) {
|
|
1272
|
-
const key = pt.map((val) => (Math.round(val / tol) * tol).toFixed(4)).join(
|
|
1273
|
-
`,`,
|
|
1274
|
-
)
|
|
1273
|
+
const key = pt.map((val) => (Math.round(val / tol) * tol).toFixed(4)).join(`,`)
|
|
1275
1274
|
const owners = vertex_owners.get(key)
|
|
1276
1275
|
if (owners) {
|
|
1277
1276
|
if (!owners.includes(domain.formula)) owners.push(domain.formula)
|
|
@@ -1349,9 +1348,7 @@
|
|
|
1349
1348
|
geometry.dispose()
|
|
1350
1349
|
}
|
|
1351
1350
|
|
|
1352
|
-
function dispose_geometries(
|
|
1353
|
-
geometries: (THREE.BufferGeometry | null | undefined)[],
|
|
1354
|
-
): void {
|
|
1351
|
+
function dispose_geometries(geometries: (THREE.BufferGeometry | null | undefined)[]): void {
|
|
1355
1352
|
for (const geometry of geometries) dispose_geometry(geometry)
|
|
1356
1353
|
}
|
|
1357
1354
|
|
|
@@ -1455,10 +1452,7 @@
|
|
|
1455
1452
|
})
|
|
1456
1453
|
|
|
1457
1454
|
// Helper to create a line geometry from two Vec3 arrays
|
|
1458
|
-
function make_line_geom(
|
|
1459
|
-
start: Vec3,
|
|
1460
|
-
end: Vec3,
|
|
1461
|
-
): THREE.BufferGeometry {
|
|
1455
|
+
function make_line_geom(start: Vec3, end: Vec3): THREE.BufferGeometry {
|
|
1462
1456
|
const geom = new THREE.BufferGeometry()
|
|
1463
1457
|
geom.setAttribute(
|
|
1464
1458
|
`position`,
|
|
@@ -1506,11 +1500,12 @@
|
|
|
1506
1500
|
return [0, 1, 2].map((axis) => {
|
|
1507
1501
|
const ticks = data_ticks[axis]
|
|
1508
1502
|
const color = axis_colors[axis]
|
|
1509
|
-
const label =
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1503
|
+
const label =
|
|
1504
|
+
axis === 0
|
|
1505
|
+
? z_axis.label || chem_axis_label(0)
|
|
1506
|
+
: axis === 1
|
|
1507
|
+
? x_axis.label || chem_axis_label(1)
|
|
1508
|
+
: y_axis.label || chem_axis_label(2)
|
|
1514
1509
|
|
|
1515
1510
|
const tick_geoms: THREE.BufferGeometry[] = []
|
|
1516
1511
|
const grid_geoms: THREE.BufferGeometry[] = []
|
|
@@ -1530,16 +1525,14 @@
|
|
|
1530
1525
|
back[2] + out_y * tick_label_dist,
|
|
1531
1526
|
)
|
|
1532
1527
|
for (const val of ticks) {
|
|
1533
|
-
tick_geoms.push(
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
make_line_geom(swiz(val, r1[0], back[2]), swiz(val, r1[1], back[2])),
|
|
1539
|
-
)
|
|
1540
|
-
grid_geoms.push(
|
|
1541
|
-
make_line_geom(swiz(val, back[1], r2[0]), swiz(val, back[1], r2[1])),
|
|
1528
|
+
tick_geoms.push(
|
|
1529
|
+
make_line_geom(
|
|
1530
|
+
swiz(val, back[1], back[2]),
|
|
1531
|
+
swiz(val, back[1], back[2] + out_y * tick_size),
|
|
1532
|
+
),
|
|
1542
1533
|
)
|
|
1534
|
+
grid_geoms.push(make_line_geom(swiz(val, r1[0], back[2]), swiz(val, r1[1], back[2])))
|
|
1535
|
+
grid_geoms.push(make_line_geom(swiz(val, back[1], r2[0]), swiz(val, back[1], r2[1])))
|
|
1543
1536
|
tick_labels.push({
|
|
1544
1537
|
pos: swiz(
|
|
1545
1538
|
val,
|
|
@@ -1560,16 +1553,14 @@
|
|
|
1560
1553
|
back[2] + out_y * tick_label_dist,
|
|
1561
1554
|
)
|
|
1562
1555
|
for (const val of ticks) {
|
|
1563
|
-
tick_geoms.push(
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
make_line_geom(swiz(r0[0], val, back[2]), swiz(r0[1], val, back[2])),
|
|
1569
|
-
)
|
|
1570
|
-
grid_geoms.push(
|
|
1571
|
-
make_line_geom(swiz(back[0], val, r2[0]), swiz(back[0], val, r2[1])),
|
|
1556
|
+
tick_geoms.push(
|
|
1557
|
+
make_line_geom(
|
|
1558
|
+
swiz(back[0], val, back[2]),
|
|
1559
|
+
swiz(back[0], val, back[2] + out_y * tick_size),
|
|
1560
|
+
),
|
|
1572
1561
|
)
|
|
1562
|
+
grid_geoms.push(make_line_geom(swiz(r0[0], val, back[2]), swiz(r0[1], val, back[2])))
|
|
1563
|
+
grid_geoms.push(make_line_geom(swiz(back[0], val, r2[0]), swiz(back[0], val, r2[1])))
|
|
1573
1564
|
tick_labels.push({
|
|
1574
1565
|
pos: swiz(back[0], val, back[2] + out_y * tick_label_dist),
|
|
1575
1566
|
text: format_num(val, `.3~g`),
|
|
@@ -1586,16 +1577,14 @@
|
|
|
1586
1577
|
outer_end(r2) + outer_direction(r2) * axis_label_dist,
|
|
1587
1578
|
)
|
|
1588
1579
|
for (const val of ticks) {
|
|
1589
|
-
tick_geoms.push(
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
make_line_geom(swiz(r0[0], back[1], val), swiz(r0[1], back[1], val)),
|
|
1595
|
-
)
|
|
1596
|
-
grid_geoms.push(
|
|
1597
|
-
make_line_geom(swiz(back[0], r1[0], val), swiz(back[0], r1[1], val)),
|
|
1580
|
+
tick_geoms.push(
|
|
1581
|
+
make_line_geom(
|
|
1582
|
+
swiz(back[0], back[1], val),
|
|
1583
|
+
swiz(back[0], back[1] + out_x * tick_size, val),
|
|
1584
|
+
),
|
|
1598
1585
|
)
|
|
1586
|
+
grid_geoms.push(make_line_geom(swiz(r0[0], back[1], val), swiz(r0[1], back[1], val)))
|
|
1587
|
+
grid_geoms.push(make_line_geom(swiz(back[0], r1[0], val), swiz(back[0], r1[1], val)))
|
|
1599
1588
|
tick_labels.push({
|
|
1600
1589
|
pos: swiz(back[0], back[1] + out_x * tick_label_dist, val),
|
|
1601
1590
|
text: format_num(val, `.3~g`),
|
|
@@ -1623,16 +1612,12 @@
|
|
|
1623
1612
|
|
|
1624
1613
|
function update_label_occlusion(): void {
|
|
1625
1614
|
if (!wrapper) return
|
|
1626
|
-
const tick_labels = Array.from(
|
|
1627
|
-
wrapper.querySelectorAll<HTMLElement>(`.axis-tick-label`),
|
|
1628
|
-
)
|
|
1615
|
+
const tick_labels = Array.from(wrapper.querySelectorAll<HTMLElement>(`.axis-tick-label`))
|
|
1629
1616
|
tick_labels_occluded = false
|
|
1630
1617
|
for (const tick_label of tick_labels) {
|
|
1631
1618
|
tick_label.style.visibility = ``
|
|
1632
1619
|
}
|
|
1633
|
-
const domain_rects = Array.from(
|
|
1634
|
-
wrapper.querySelectorAll<HTMLElement>(`.domain-label`),
|
|
1635
|
-
)
|
|
1620
|
+
const domain_rects = Array.from(wrapper.querySelectorAll<HTMLElement>(`.domain-label`))
|
|
1636
1621
|
.filter((domain_label) => {
|
|
1637
1622
|
const style = getComputedStyle(domain_label)
|
|
1638
1623
|
return style.display !== `none` && style.visibility !== `hidden`
|
|
@@ -1700,11 +1685,7 @@
|
|
|
1700
1685
|
}
|
|
1701
1686
|
const controls_target = controls?.target
|
|
1702
1687
|
if (controls_target) {
|
|
1703
|
-
camera_target_override = [
|
|
1704
|
-
controls_target.x,
|
|
1705
|
-
controls_target.y,
|
|
1706
|
-
controls_target.z,
|
|
1707
|
-
]
|
|
1688
|
+
camera_target_override = [controls_target.x, controls_target.y, controls_target.z]
|
|
1708
1689
|
}
|
|
1709
1690
|
}
|
|
1710
1691
|
|
|
@@ -1788,9 +1769,8 @@
|
|
|
1788
1769
|
const projections = display.projections
|
|
1789
1770
|
if (!projections) return []
|
|
1790
1771
|
const [r0, r1, r2] = niced_range
|
|
1791
|
-
const
|
|
1792
|
-
const s1 = (
|
|
1793
|
-
const s2 = (r2[1] - r2[0]) * (display.projection_scale ?? 0.5)
|
|
1772
|
+
const projection_scale = display.projection_scale ?? 0.5
|
|
1773
|
+
const [s0, s1, s2] = niced_range.map(([lo, hi]) => (hi - lo) * projection_scale)
|
|
1794
1774
|
const planes: {
|
|
1795
1775
|
key: string
|
|
1796
1776
|
pos: Vec3
|
|
@@ -1880,18 +1860,12 @@
|
|
|
1880
1860
|
next_projection[current_owner_idx] = next_projection[axis_idx]
|
|
1881
1861
|
}
|
|
1882
1862
|
next_projection[axis_idx] = element
|
|
1883
|
-
const normalized = normalize_projection_triplet(
|
|
1884
|
-
next_projection,
|
|
1885
|
-
all_entry_elements,
|
|
1886
|
-
)
|
|
1863
|
+
const normalized = normalize_projection_triplet(next_projection, all_entry_elements)
|
|
1887
1864
|
if (normalized) projection_elements_override = normalized
|
|
1888
1865
|
}
|
|
1889
1866
|
|
|
1890
1867
|
function apply_projection_preset(preset_elements: string[]): void {
|
|
1891
|
-
const normalized = normalize_projection_triplet(
|
|
1892
|
-
preset_elements,
|
|
1893
|
-
all_entry_elements,
|
|
1894
|
-
)
|
|
1868
|
+
const normalized = normalize_projection_triplet(preset_elements, all_entry_elements)
|
|
1895
1869
|
if (normalized) projection_elements_override = normalized
|
|
1896
1870
|
}
|
|
1897
1871
|
|
|
@@ -1968,19 +1942,21 @@
|
|
|
1968
1942
|
},
|
|
1969
1943
|
{
|
|
1970
1944
|
label: `View`,
|
|
1971
|
-
on_download: () =>
|
|
1972
|
-
export_view_json_file(current_view_settings(), export_basename),
|
|
1945
|
+
on_download: () => export_view_json_file(current_view_settings(), export_basename),
|
|
1973
1946
|
},
|
|
1974
1947
|
{
|
|
1975
1948
|
label: `GLB`,
|
|
1976
1949
|
on_download: () =>
|
|
1977
|
-
export_glb_file(
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1950
|
+
export_glb_file(
|
|
1951
|
+
{
|
|
1952
|
+
hull_geometry: colored_hull_geometry,
|
|
1953
|
+
hull_opacity: color_mode === `none` ? 0.25 : 0.4,
|
|
1954
|
+
edge_geometry,
|
|
1955
|
+
formula_meshes: formula_mesh_data,
|
|
1956
|
+
formula_edges: draw_formula_lines ? formula_edge_data : [],
|
|
1957
|
+
},
|
|
1958
|
+
export_basename,
|
|
1959
|
+
),
|
|
1984
1960
|
},
|
|
1985
1961
|
],
|
|
1986
1962
|
},
|
|
@@ -1997,10 +1973,12 @@
|
|
|
1997
1973
|
const pointer = hover_info?.pointer
|
|
1998
1974
|
if (!pointer) return { x: 4, y: 4 }
|
|
1999
1975
|
return constrain_tooltip_position(
|
|
2000
|
-
pointer.x,
|
|
1976
|
+
pointer.x,
|
|
1977
|
+
pointer.y,
|
|
2001
1978
|
tooltip_el?.offsetWidth ?? 200,
|
|
2002
1979
|
tooltip_el?.offsetHeight ?? 100,
|
|
2003
|
-
container_width,
|
|
1980
|
+
container_width,
|
|
1981
|
+
container_height,
|
|
2004
1982
|
{ offset: 0 },
|
|
2005
1983
|
)
|
|
2006
1984
|
})
|
|
@@ -2018,12 +1996,25 @@
|
|
|
2018
1996
|
hover_info = null
|
|
2019
1997
|
}
|
|
2020
1998
|
|
|
1999
|
+
function stop_phase_pointer_event(raw_event: unknown): void {
|
|
2000
|
+
if (!raw_event || typeof raw_event !== `object`) return
|
|
2001
|
+
|
|
2002
|
+
const event = raw_event as { nativeEvent?: unknown; stopPropagation?: () => void }
|
|
2003
|
+
event.stopPropagation?.()
|
|
2004
|
+
|
|
2005
|
+
const native_event = event.nativeEvent
|
|
2006
|
+
if (!native_event || typeof native_event !== `object`) return
|
|
2007
|
+
const native_pointer_event = native_event as { stopPropagation?: () => void }
|
|
2008
|
+
native_pointer_event.stopPropagation?.()
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2021
2011
|
function handle_phase_hover(domain_data: HoverMeshData, raw_event: unknown): void {
|
|
2022
2012
|
if (locked_hover_formula && locked_hover_formula !== domain_data.formula) return
|
|
2023
2013
|
set_hover_info(domain_data, raw_event)
|
|
2024
2014
|
}
|
|
2025
2015
|
|
|
2026
2016
|
function toggle_phase_lock(domain_data: HoverMeshData, raw_event: unknown): void {
|
|
2017
|
+
stop_phase_pointer_event(raw_event)
|
|
2027
2018
|
if (locked_hover_formula === domain_data.formula) {
|
|
2028
2019
|
clear_hover_lock()
|
|
2029
2020
|
return
|
|
@@ -2053,20 +2044,15 @@
|
|
|
2053
2044
|
role="application"
|
|
2054
2045
|
tabindex="0"
|
|
2055
2046
|
onkeydown={(event) => {
|
|
2056
|
-
if (
|
|
2057
|
-
|
|
2058
|
-
event.target instanceof HTMLSelectElement
|
|
2059
|
-
) return
|
|
2047
|
+
if (event.target instanceof HTMLInputElement || event.target instanceof HTMLSelectElement)
|
|
2048
|
+
return
|
|
2060
2049
|
if (event.key === `Escape`) clear_hover_lock()
|
|
2061
2050
|
else if (event.key === `c`) cycle_color_mode()
|
|
2062
2051
|
else if (event.key === `f` && fullscreen_toggle) toggle_fullscreen(wrapper)
|
|
2063
2052
|
}}
|
|
2064
2053
|
onpointerdown={(event) => {
|
|
2065
2054
|
const target = event.target
|
|
2066
|
-
if (
|
|
2067
|
-
locked_hover_formula &&
|
|
2068
|
-
(target === wrapper || target instanceof HTMLCanvasElement)
|
|
2069
|
-
) {
|
|
2055
|
+
if (locked_hover_formula && (target === wrapper || target instanceof HTMLCanvasElement)) {
|
|
2070
2056
|
clear_hover_lock()
|
|
2071
2057
|
}
|
|
2072
2058
|
}}
|
|
@@ -2102,11 +2088,7 @@
|
|
|
2102
2088
|
</div>
|
|
2103
2089
|
<label class="overlay-search">
|
|
2104
2090
|
Search:
|
|
2105
|
-
<input
|
|
2106
|
-
type="text"
|
|
2107
|
-
placeholder="Formula filter"
|
|
2108
|
-
bind:value={formula_filter_query}
|
|
2109
|
-
/>
|
|
2091
|
+
<input type="text" placeholder="Formula filter" bind:value={formula_filter_query} />
|
|
2110
2092
|
</label>
|
|
2111
2093
|
<div class="formula-list">
|
|
2112
2094
|
{#if filtered_formulas.length === 0}
|
|
@@ -2117,14 +2099,14 @@
|
|
|
2117
2099
|
<label>
|
|
2118
2100
|
<input
|
|
2119
2101
|
type="checkbox"
|
|
2120
|
-
checked={
|
|
2102
|
+
checked={formula_overlay_idx !== -1}
|
|
2121
2103
|
onchange={() => toggle_formula_selection(formula)}
|
|
2122
2104
|
/>
|
|
2123
2105
|
<span
|
|
2124
2106
|
class="formula-color-dot"
|
|
2125
2107
|
style:background={formula_colors[
|
|
2126
2108
|
(formula_overlay_idx >= 0 ? formula_overlay_idx : formula_idx) %
|
|
2127
|
-
|
|
2109
|
+
formula_colors.length
|
|
2128
2110
|
]}
|
|
2129
2111
|
></span>
|
|
2130
2112
|
{get_electro_neg_formula(formula, true, ``, `.3~s`)}
|
|
@@ -2231,8 +2213,7 @@
|
|
|
2231
2213
|
<input
|
|
2232
2214
|
type="checkbox"
|
|
2233
2215
|
checked={draw_formula_meshes}
|
|
2234
|
-
onchange={() =>
|
|
2235
|
-
overrides.set(`draw_formula_meshes`, !draw_formula_meshes)}
|
|
2216
|
+
onchange={() => overrides.set(`draw_formula_meshes`, !draw_formula_meshes)}
|
|
2236
2217
|
/> Meshes
|
|
2237
2218
|
</label>
|
|
2238
2219
|
<label>
|
|
@@ -2252,7 +2233,7 @@
|
|
|
2252
2233
|
step="0.1"
|
|
2253
2234
|
value={element_padding}
|
|
2254
2235
|
oninput={(event) =>
|
|
2255
|
-
|
|
2236
|
+
overrides.set(`element_padding`, Number(event.currentTarget.value))}
|
|
2256
2237
|
/>
|
|
2257
2238
|
</label>
|
|
2258
2239
|
<label>
|
|
@@ -2263,7 +2244,7 @@
|
|
|
2263
2244
|
step="1"
|
|
2264
2245
|
value={default_min_limit}
|
|
2265
2246
|
oninput={(event) =>
|
|
2266
|
-
|
|
2247
|
+
overrides.set(`default_min_limit`, Number(event.currentTarget.value))}
|
|
2267
2248
|
/>
|
|
2268
2249
|
</label>
|
|
2269
2250
|
</div>
|
|
@@ -2273,7 +2254,7 @@
|
|
|
2273
2254
|
id="chempot-color-mode"
|
|
2274
2255
|
value={color_mode}
|
|
2275
2256
|
onchange={(event) =>
|
|
2276
|
-
|
|
2257
|
+
overrides.set(`color_mode`, event.currentTarget.value as ChemPotColorMode)}
|
|
2277
2258
|
>
|
|
2278
2259
|
{#each CHEMPOT_COLOR_MODE_OPTIONS as [value, label] (value)}
|
|
2279
2260
|
<option {value}>{label}</option>
|
|
@@ -2287,10 +2268,7 @@
|
|
|
2287
2268
|
id="chempot-color-scale"
|
|
2288
2269
|
value={color_scale}
|
|
2289
2270
|
onchange={(event) =>
|
|
2290
|
-
|
|
2291
|
-
`color_scale`,
|
|
2292
|
-
event.currentTarget.value as D3InterpolateName,
|
|
2293
|
-
)}
|
|
2271
|
+
overrides.set(`color_scale`, event.currentTarget.value as D3InterpolateName)}
|
|
2294
2272
|
>
|
|
2295
2273
|
{#each CHEMPOT_COLOR_SCALE_OPTIONS as [value, label] (value)}
|
|
2296
2274
|
<option {value}>{label}</option>
|
|
@@ -2300,8 +2278,7 @@
|
|
|
2300
2278
|
<input
|
|
2301
2279
|
type="checkbox"
|
|
2302
2280
|
checked={reverse_color_scale}
|
|
2303
|
-
onchange={() =>
|
|
2304
|
-
overrides.set(`reverse_color_scale`, !reverse_color_scale)}
|
|
2281
|
+
onchange={() => overrides.set(`reverse_color_scale`, !reverse_color_scale)}
|
|
2305
2282
|
/> Rev
|
|
2306
2283
|
</label>
|
|
2307
2284
|
</div>
|
|
@@ -2314,312 +2291,300 @@
|
|
|
2314
2291
|
{/if}
|
|
2315
2292
|
</section>
|
|
2316
2293
|
{#if show_temperature_slider && temperature !== undefined}
|
|
2317
|
-
<TemperatureSlider
|
|
2318
|
-
class="chempot-temp-slider"
|
|
2319
|
-
{available_temperatures}
|
|
2320
|
-
bind:temperature
|
|
2321
|
-
/>
|
|
2294
|
+
<TemperatureSlider class="chempot-temp-slider" {available_temperatures} bind:temperature />
|
|
2322
2295
|
{/if}
|
|
2323
2296
|
<div class="canvas-clip">
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2297
|
+
{#if diagram_computing}
|
|
2298
|
+
<div class="computing-state">
|
|
2299
|
+
<Spinner
|
|
2300
|
+
text="Computing chemical potential domains..."
|
|
2301
|
+
style="--spinner-size: 1.2em"
|
|
2302
|
+
/>
|
|
2303
|
+
</div>
|
|
2304
|
+
{:else if !diagram_data}
|
|
2305
|
+
<div class="error-state" role="alert" aria-live="polite">
|
|
2306
|
+
<p>Cannot compute chemical potential diagram.</p>
|
|
2307
|
+
<p>Need at least 2 elements with elemental reference entries.</p>
|
|
2308
|
+
</div>
|
|
2309
|
+
{:else if mounted && typeof WebGLRenderingContext !== `undefined`}
|
|
2310
|
+
<Canvas
|
|
2311
|
+
createRenderer={(cvs) =>
|
|
2312
|
+
new THREE.WebGLRenderer({
|
|
2313
|
+
canvas: cvs,
|
|
2314
|
+
alpha: true,
|
|
2315
|
+
antialias: true,
|
|
2316
|
+
preserveDrawingBuffer: true,
|
|
2317
|
+
})}
|
|
2318
|
+
>
|
|
2319
|
+
<ChemPotScene3D>
|
|
2320
|
+
{#if camera_projection === `orthographic`}
|
|
2321
|
+
<!-- Orthographic camera matching pymatgen's projection style -->
|
|
2322
|
+
<T.OrthographicCamera
|
|
2323
|
+
makeDefault
|
|
2324
|
+
position={camera_position}
|
|
2325
|
+
zoom={orthographic_zoom}
|
|
2326
|
+
near={0.1}
|
|
2327
|
+
far={data_extent * 10}
|
|
2328
|
+
>
|
|
2329
|
+
<extras.OrbitControls
|
|
2330
|
+
bind:ref={orbit_controls_ref}
|
|
2331
|
+
enableRotate
|
|
2332
|
+
enableZoom
|
|
2333
|
+
enablePan
|
|
2334
|
+
autoRotate={auto_rotate > 0}
|
|
2335
|
+
autoRotateSpeed={auto_rotate}
|
|
2336
|
+
target={camera_target}
|
|
2337
|
+
/>
|
|
2338
|
+
</T.OrthographicCamera>
|
|
2339
|
+
{:else}
|
|
2340
|
+
<T.PerspectiveCamera
|
|
2341
|
+
makeDefault
|
|
2342
|
+
position={camera_position}
|
|
2343
|
+
fov={50}
|
|
2344
|
+
near={0.1}
|
|
2345
|
+
far={data_extent * 10}
|
|
2346
|
+
>
|
|
2347
|
+
<extras.OrbitControls
|
|
2348
|
+
bind:ref={orbit_controls_ref}
|
|
2349
|
+
enableRotate
|
|
2350
|
+
enableZoom
|
|
2351
|
+
enablePan
|
|
2352
|
+
autoRotate={auto_rotate > 0}
|
|
2353
|
+
autoRotateSpeed={auto_rotate}
|
|
2354
|
+
target={camera_target}
|
|
2355
|
+
/>
|
|
2356
|
+
</T.PerspectiveCamera>
|
|
2357
|
+
{/if}
|
|
2382
2358
|
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2359
|
+
<!-- Ambient light for visibility -->
|
|
2360
|
+
<T.AmbientLight intensity={0.8} />
|
|
2361
|
+
<T.DirectionalLight position={[1, 1, 1]} intensity={0.5} />
|
|
2386
2362
|
|
|
2387
|
-
|
|
2363
|
+
<!-- Vertex-colored hull for both plain and colored modes.
|
|
2388
2364
|
{#key domain_colors} forces Threlte to re-create the mesh whenever
|
|
2389
2365
|
colors change (covers color_mode, color_scale, and data updates),
|
|
2390
2366
|
since on-demand rendering won't detect mutated vertex color buffers. -->
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2367
|
+
{#if colored_hull_geometry}
|
|
2368
|
+
{#key domain_colors}
|
|
2369
|
+
<T.Mesh geometry={colored_hull_geometry}>
|
|
2370
|
+
<T.MeshBasicMaterial
|
|
2371
|
+
vertexColors
|
|
2372
|
+
transparent
|
|
2373
|
+
opacity={color_mode === `none` ? 0.25 : 0.4}
|
|
2374
|
+
side={THREE.DoubleSide}
|
|
2375
|
+
polygonOffset
|
|
2376
|
+
polygonOffsetFactor={1}
|
|
2377
|
+
polygonOffsetUnits={1}
|
|
2378
|
+
/>
|
|
2379
|
+
</T.Mesh>
|
|
2380
|
+
{/key}
|
|
2381
|
+
{/if}
|
|
2382
|
+
|
|
2383
|
+
<!-- Domain boundary edges (wireframe on top of opaque fills) -->
|
|
2384
|
+
<T.LineSegments geometry={edge_geometry}>
|
|
2385
|
+
<T.LineBasicMaterial color={0x333333} linewidth={1} />
|
|
2386
|
+
</T.LineSegments>
|
|
2387
|
+
|
|
2388
|
+
<!-- Invisible pick meshes for per-phase hover tooltip -->
|
|
2389
|
+
{#each hover_mesh_data as domain_hover (domain_hover.formula)}
|
|
2390
|
+
<T.Mesh
|
|
2391
|
+
geometry={domain_hover.geometry}
|
|
2392
|
+
onpointerenter={(event: unknown) => handle_phase_hover(domain_hover, event)}
|
|
2393
|
+
onpointermove={(event: unknown) => handle_phase_hover(domain_hover, event)}
|
|
2394
|
+
onpointerdown={(event: unknown) => toggle_phase_lock(domain_hover, event)}
|
|
2395
|
+
onpointerleave={() => {
|
|
2396
|
+
if (!locked_hover_formula && hover_info?.formula === domain_hover.formula) {
|
|
2397
|
+
hover_info = null
|
|
2398
|
+
}
|
|
2399
|
+
}}
|
|
2400
|
+
>
|
|
2394
2401
|
<T.MeshBasicMaterial
|
|
2395
|
-
vertexColors
|
|
2396
2402
|
transparent
|
|
2397
|
-
opacity={
|
|
2403
|
+
opacity={0}
|
|
2398
2404
|
side={THREE.DoubleSide}
|
|
2399
|
-
|
|
2400
|
-
polygonOffsetFactor={1}
|
|
2401
|
-
polygonOffsetUnits={1}
|
|
2405
|
+
depthWrite={false}
|
|
2402
2406
|
/>
|
|
2403
2407
|
</T.Mesh>
|
|
2404
|
-
{/
|
|
2405
|
-
{/if}
|
|
2408
|
+
{/each}
|
|
2406
2409
|
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
onpointerdown={(event: unknown) => toggle_phase_lock(domain_hover, event)}
|
|
2419
|
-
onpointerleave={() => {
|
|
2420
|
-
if (
|
|
2421
|
-
!locked_hover_formula &&
|
|
2422
|
-
hover_info?.formula === domain_hover.formula
|
|
2423
|
-
) {
|
|
2424
|
-
hover_info = null
|
|
2425
|
-
}
|
|
2426
|
-
}}
|
|
2427
|
-
>
|
|
2428
|
-
<T.MeshBasicMaterial
|
|
2429
|
-
transparent
|
|
2430
|
-
opacity={0}
|
|
2431
|
-
side={THREE.DoubleSide}
|
|
2432
|
-
depthWrite={false}
|
|
2433
|
-
/>
|
|
2434
|
-
</T.Mesh>
|
|
2435
|
-
{/each}
|
|
2436
|
-
|
|
2437
|
-
<!-- Formula overlay meshes (semi-transparent colored fill) -->
|
|
2438
|
-
{#each formula_mesh_data as { geometry, color }, mesh_idx (mesh_idx)}
|
|
2439
|
-
<T.Mesh {geometry}>
|
|
2440
|
-
<T.MeshBasicMaterial
|
|
2441
|
-
color={new THREE.Color(color)}
|
|
2442
|
-
transparent
|
|
2443
|
-
opacity={0.13}
|
|
2444
|
-
side={THREE.DoubleSide}
|
|
2445
|
-
depthWrite={false}
|
|
2446
|
-
/>
|
|
2447
|
-
</T.Mesh>
|
|
2448
|
-
{/each}
|
|
2449
|
-
|
|
2450
|
-
<!-- Formula overlay edges (colored, thicker) -->
|
|
2451
|
-
{#if draw_formula_lines}
|
|
2452
|
-
{#each formula_edge_data as { geometry, color }, edge_idx (edge_idx)}
|
|
2453
|
-
<T.LineSegments {geometry}>
|
|
2454
|
-
<T.LineBasicMaterial color={new THREE.Color(color)} linewidth={2} />
|
|
2455
|
-
</T.LineSegments>
|
|
2410
|
+
<!-- Formula overlay meshes (semi-transparent colored fill) -->
|
|
2411
|
+
{#each formula_mesh_data as { geometry, color }, mesh_idx (mesh_idx)}
|
|
2412
|
+
<T.Mesh {geometry}>
|
|
2413
|
+
<T.MeshBasicMaterial
|
|
2414
|
+
color={new THREE.Color(color)}
|
|
2415
|
+
transparent
|
|
2416
|
+
opacity={0.13}
|
|
2417
|
+
side={THREE.DoubleSide}
|
|
2418
|
+
depthWrite={false}
|
|
2419
|
+
/>
|
|
2420
|
+
</T.Mesh>
|
|
2456
2421
|
{/each}
|
|
2457
|
-
{/if}
|
|
2458
2422
|
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
depthWrite={false}
|
|
2468
|
-
/>
|
|
2469
|
-
</T.Mesh>
|
|
2470
|
-
{/each}
|
|
2423
|
+
<!-- Formula overlay edges (colored, thicker) -->
|
|
2424
|
+
{#if draw_formula_lines}
|
|
2425
|
+
{#each formula_edge_data as { geometry, color }, edge_idx (edge_idx)}
|
|
2426
|
+
<T.LineSegments {geometry}>
|
|
2427
|
+
<T.LineBasicMaterial color={new THREE.Color(color)} linewidth={2} />
|
|
2428
|
+
</T.LineSegments>
|
|
2429
|
+
{/each}
|
|
2430
|
+
{/if}
|
|
2471
2431
|
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2432
|
+
{#each projection_planes as plane (`${plane.key}-${projection_opacity}`)}
|
|
2433
|
+
<T.Mesh position={plane.pos} rotation={plane.rot}>
|
|
2434
|
+
<T.PlaneGeometry args={plane.size} />
|
|
2435
|
+
<T.MeshBasicMaterial
|
|
2436
|
+
color={plane.color}
|
|
2437
|
+
opacity={projection_opacity}
|
|
2438
|
+
transparent
|
|
2439
|
+
side={THREE.DoubleSide}
|
|
2440
|
+
depthWrite={false}
|
|
2441
|
+
/>
|
|
2442
|
+
</T.Mesh>
|
|
2443
|
+
{/each}
|
|
2477
2444
|
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
<T.Line geometry={gc.line_geom}>
|
|
2483
|
-
<T.LineBasicMaterial color={gc.color} linewidth={2} />
|
|
2484
|
-
</T.Line>
|
|
2485
|
-
<!-- Tick marks -->
|
|
2486
|
-
{#each gc.tick_geoms as tick_geom, tdx (tdx)}
|
|
2487
|
-
<T.Line geometry={tick_geom}>
|
|
2488
|
-
<T.LineBasicMaterial color={gc.color} />
|
|
2489
|
-
</T.Line>
|
|
2490
|
-
{/each}
|
|
2445
|
+
{#if display.show_bounding_box}
|
|
2446
|
+
<T.LineSegments geometry={bounding_box_geometry}>
|
|
2447
|
+
<T.LineBasicMaterial color="#666" opacity={0.6} transparent />
|
|
2448
|
+
</T.LineSegments>
|
|
2491
2449
|
{/if}
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2450
|
+
|
|
2451
|
+
<!-- Axes, ticks, grid lines, and labels -->
|
|
2452
|
+
{#each grid_config as gc (gc.axis)}
|
|
2453
|
+
{#if display.show_axes}
|
|
2454
|
+
<!-- Main axis line -->
|
|
2455
|
+
<T.Line geometry={gc.line_geom}>
|
|
2456
|
+
<T.LineBasicMaterial color={gc.color} linewidth={2} />
|
|
2497
2457
|
</T.Line>
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2458
|
+
<!-- Tick marks -->
|
|
2459
|
+
{#each gc.tick_geoms as tick_geom, tdx (tdx)}
|
|
2460
|
+
<T.Line geometry={tick_geom}>
|
|
2461
|
+
<T.LineBasicMaterial color={gc.color} />
|
|
2462
|
+
</T.Line>
|
|
2463
|
+
{/each}
|
|
2464
|
+
{/if}
|
|
2465
|
+
{#if display.show_grid}
|
|
2466
|
+
<!-- Grid lines -->
|
|
2467
|
+
{#each gc.grid_geoms as grid_geom, gdx (gdx)}
|
|
2468
|
+
<T.Line geometry={grid_geom}>
|
|
2469
|
+
<T.LineBasicMaterial color="#888" opacity={0.3} transparent />
|
|
2470
|
+
</T.Line>
|
|
2471
|
+
{/each}
|
|
2472
|
+
{/if}
|
|
2473
|
+
{#if display.show_axis_labels}
|
|
2474
|
+
<!-- Tick labels (billboarded, always face camera) -->
|
|
2475
|
+
{#each gc.tick_labels as tick, tick_idx (tick_idx)}
|
|
2476
|
+
<extras.HTML position={tick.pos} center portal={wrapper} zIndexRange={[1, 0]}>
|
|
2477
|
+
<span class="tick-label axis-tick-label">{tick.text}</span>
|
|
2478
|
+
</extras.HTML>
|
|
2479
|
+
{/each}
|
|
2480
|
+
<!-- Axis label -->
|
|
2503
2481
|
<extras.HTML
|
|
2504
|
-
position={
|
|
2482
|
+
position={gc.label_pos}
|
|
2505
2483
|
center
|
|
2506
2484
|
portal={wrapper}
|
|
2507
2485
|
zIndexRange={[1, 0]}
|
|
2508
2486
|
>
|
|
2509
|
-
<span class="
|
|
2487
|
+
<span class="axis-label" style:color={gc.color}>{@html gc.label}</span>
|
|
2488
|
+
</extras.HTML>
|
|
2489
|
+
{/if}
|
|
2490
|
+
{/each}
|
|
2491
|
+
|
|
2492
|
+
<!-- Domain labels -->
|
|
2493
|
+
{#if label_stable}
|
|
2494
|
+
{#each visible_domain_labels as domain (domain.formula)}
|
|
2495
|
+
<extras.HTML
|
|
2496
|
+
position={domain.position}
|
|
2497
|
+
center
|
|
2498
|
+
portal={wrapper}
|
|
2499
|
+
zIndexRange={[5, 5]}
|
|
2500
|
+
>
|
|
2501
|
+
<span
|
|
2502
|
+
class="domain-label"
|
|
2503
|
+
style:font-size="{(domain.label_font_size * zoom_scale).toFixed(1)}px"
|
|
2504
|
+
>
|
|
2505
|
+
{#each formula_label_segments(domain.formula) as segment}
|
|
2506
|
+
<span class:formula-subscript={segment.subscript}>{segment.text}</span>
|
|
2507
|
+
{/each}
|
|
2508
|
+
</span>
|
|
2510
2509
|
</extras.HTML>
|
|
2511
2510
|
{/each}
|
|
2512
|
-
<!-- Axis label -->
|
|
2513
|
-
<extras.HTML
|
|
2514
|
-
position={gc.label_pos}
|
|
2515
|
-
center
|
|
2516
|
-
portal={wrapper}
|
|
2517
|
-
zIndexRange={[1, 0]}
|
|
2518
|
-
>
|
|
2519
|
-
<span class="axis-label" style:color={gc.color}>{@html gc.label}</span>
|
|
2520
|
-
</extras.HTML>
|
|
2521
2511
|
{/if}
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2512
|
+
</ChemPotScene3D>
|
|
2513
|
+
</Canvas>
|
|
2514
|
+
<!-- Color bar for continuous modes -->
|
|
2515
|
+
{#if color_mode !== `none` && color_mode !== `arity` && color_range}
|
|
2516
|
+
{@const color_bar_config = get_chempot_color_bar_config(
|
|
2517
|
+
color_scale,
|
|
2518
|
+
reverse_color_scale,
|
|
2519
|
+
)}
|
|
2520
|
+
<ColorBar
|
|
2521
|
+
title={color_range.label}
|
|
2522
|
+
range={[color_range.min, color_range.max]}
|
|
2523
|
+
color_scale_fn={color_bar_config.color_scale_fn}
|
|
2524
|
+
color_scale_domain={color_bar_config.color_scale_domain}
|
|
2525
|
+
wrapper_style="position: absolute; bottom: 16px; left: 1em; width: 200px; z-index: 10;"
|
|
2526
|
+
bar_style="height: 12px;"
|
|
2527
|
+
title_style="margin-bottom: 4px;"
|
|
2528
|
+
/>
|
|
2529
|
+
{/if}
|
|
2530
|
+
<!-- Categorical legend for arity mode -->
|
|
2531
|
+
{#if color_mode === `arity`}
|
|
2532
|
+
<div class="arity-legend">
|
|
2533
|
+
{#each arity_legend_labels as label, idx (label)}
|
|
2534
|
+
<span>
|
|
2535
|
+
<span style:background={arity_colors[idx]}></span>
|
|
2536
|
+
{label}
|
|
2537
|
+
</span>
|
|
2542
2538
|
{/each}
|
|
2543
|
-
|
|
2544
|
-
</ChemPotScene3D>
|
|
2545
|
-
</Canvas>
|
|
2546
|
-
<!-- Color bar for continuous modes -->
|
|
2547
|
-
{#if color_mode !== `none` && color_mode !== `arity` && color_range}
|
|
2548
|
-
{@const color_bar_config = get_chempot_color_bar_config(
|
|
2549
|
-
color_scale,
|
|
2550
|
-
reverse_color_scale,
|
|
2551
|
-
)}
|
|
2552
|
-
<ColorBar
|
|
2553
|
-
title={color_range.label}
|
|
2554
|
-
range={[color_range.min, color_range.max]}
|
|
2555
|
-
color_scale_fn={color_bar_config.color_scale_fn}
|
|
2556
|
-
color_scale_domain={color_bar_config.color_scale_domain}
|
|
2557
|
-
wrapper_style="position: absolute; bottom: 16px; left: 1em; width: 200px; z-index: 10;"
|
|
2558
|
-
bar_style="height: 12px;"
|
|
2559
|
-
title_style="margin-bottom: 4px;"
|
|
2560
|
-
/>
|
|
2561
|
-
{/if}
|
|
2562
|
-
<!-- Categorical legend for arity mode -->
|
|
2563
|
-
{#if color_mode === `arity`}
|
|
2564
|
-
<div class="arity-legend">
|
|
2565
|
-
{#each arity_legend_labels as label, idx (label)}
|
|
2566
|
-
<span>
|
|
2567
|
-
<span style:background={arity_colors[idx]}></span>
|
|
2568
|
-
{label}
|
|
2569
|
-
</span>
|
|
2570
|
-
{/each}
|
|
2571
|
-
</div>
|
|
2572
|
-
{/if}
|
|
2573
|
-
{/if}
|
|
2574
|
-
{#if render_local_tooltip && show_tooltip && hover_info?.view === `3d`}
|
|
2575
|
-
<aside
|
|
2576
|
-
bind:this={tooltip_el}
|
|
2577
|
-
class="phase-tooltip"
|
|
2578
|
-
style:left="{tooltip_pos.x}px"
|
|
2579
|
-
style:top="{tooltip_pos.y}px"
|
|
2580
|
-
>
|
|
2581
|
-
<h4>
|
|
2582
|
-
{#each formula_label_segments(hover_info.formula) as segment}
|
|
2583
|
-
<span class:formula-subscript={segment.subscript}>{segment.text}</span>
|
|
2584
|
-
{/each}
|
|
2585
|
-
</h4>
|
|
2586
|
-
{#if locked_hover_formula === hover_info.formula}
|
|
2587
|
-
<p>Pinned · Press Esc to unlock</p>
|
|
2539
|
+
</div>
|
|
2588
2540
|
{/if}
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
{
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2541
|
+
{/if}
|
|
2542
|
+
{#if render_local_tooltip && show_tooltip && hover_info?.view === `3d`}
|
|
2543
|
+
<aside
|
|
2544
|
+
bind:this={tooltip_el}
|
|
2545
|
+
class="phase-tooltip"
|
|
2546
|
+
style:left="{tooltip_pos.x}px"
|
|
2547
|
+
style:top="{tooltip_pos.y}px"
|
|
2548
|
+
>
|
|
2549
|
+
<h4>
|
|
2550
|
+
{#each formula_label_segments(hover_info.formula) as segment}
|
|
2551
|
+
<span class:formula-subscript={segment.subscript}>{segment.text}</span>
|
|
2552
|
+
{/each}
|
|
2553
|
+
</h4>
|
|
2554
|
+
{#if locked_hover_formula === hover_info.formula}
|
|
2555
|
+
<p>Pinned · Press Esc to unlock</p>
|
|
2599
2556
|
{/if}
|
|
2600
|
-
</p>
|
|
2601
|
-
{#if tooltip_detail_level === `detailed`}
|
|
2602
|
-
<h5 id="axis-ranges">Axis ranges</h5>
|
|
2603
|
-
{#each hover_info.axis_ranges as axis_range (axis_range.element)}
|
|
2604
|
-
<p>
|
|
2605
|
-
{axis_range.element}: {format_num(axis_range.min_val, `.4~g`)} to
|
|
2606
|
-
{format_num(axis_range.max_val, `.4~g`)} eV
|
|
2607
|
-
</p>
|
|
2608
|
-
{/each}
|
|
2609
2557
|
<p>
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
`, `,
|
|
2613
|
-
)
|
|
2614
|
-
})
|
|
2558
|
+
Vertices: {hover_info.n_vertices} · Edges: {hover_info.n_edges} · Points:
|
|
2559
|
+
{hover_info.n_points}
|
|
2615
2560
|
</p>
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2561
|
+
<p>
|
|
2562
|
+
Entries: {hover_info.matching_entry_count}
|
|
2563
|
+
{#if hover_info.min_energy_per_atom !== null && hover_info.max_energy_per_atom !== null}
|
|
2564
|
+
· E/atom: {format_num(hover_info.min_energy_per_atom, `.4~g`)}
|
|
2565
|
+
to {format_num(hover_info.max_energy_per_atom, `.4~g`)} eV
|
|
2566
|
+
{/if}
|
|
2567
|
+
</p>
|
|
2568
|
+
{#if tooltip_detail_level === `detailed`}
|
|
2569
|
+
<h5 id="axis-ranges">Axis ranges</h5>
|
|
2570
|
+
{#each hover_info.axis_ranges as axis_range (axis_range.element)}
|
|
2571
|
+
<p>
|
|
2572
|
+
{axis_range.element}: {format_num(axis_range.min_val, `.4~g`)} to
|
|
2573
|
+
{format_num(axis_range.max_val, `.4~g`)} eV
|
|
2574
|
+
</p>
|
|
2575
|
+
{/each}
|
|
2576
|
+
<p>
|
|
2577
|
+
Centroid: ({hover_info.ann_loc
|
|
2578
|
+
.map((value) => format_num(value, `.3~g`))
|
|
2579
|
+
.join(`, `)})
|
|
2580
|
+
</p>
|
|
2581
|
+
{#if hover_info.touches_limits.length > 0}
|
|
2582
|
+
<h5 id="touches-bounds">Touches bounds</h5>
|
|
2583
|
+
<p>{hover_info.touches_limits.join(`, `)}</p>
|
|
2584
|
+
{/if}
|
|
2619
2585
|
{/if}
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
{/if}
|
|
2586
|
+
</aside>
|
|
2587
|
+
{/if}
|
|
2623
2588
|
</div>
|
|
2624
2589
|
</div>
|
|
2625
2590
|
|
|
@@ -2708,8 +2673,10 @@
|
|
|
2708
2673
|
}
|
|
2709
2674
|
.chempot-diagram-3d :global(.projection-controls .pane-row) {
|
|
2710
2675
|
display: grid;
|
|
2711
|
-
grid-template-columns:
|
|
2712
|
-
|
|
2676
|
+
grid-template-columns: auto minmax(4.5em, 1fr) auto minmax(4.5em, 1fr) auto minmax(
|
|
2677
|
+
4.5em,
|
|
2678
|
+
1fr
|
|
2679
|
+
);
|
|
2713
2680
|
align-items: center;
|
|
2714
2681
|
gap: 3pt;
|
|
2715
2682
|
}
|
|
@@ -2849,10 +2816,7 @@
|
|
|
2849
2816
|
.phase-tooltip {
|
|
2850
2817
|
position: absolute;
|
|
2851
2818
|
max-width: min(32rem, 92vw);
|
|
2852
|
-
background: var(
|
|
2853
|
-
--tooltip-bg,
|
|
2854
|
-
light-dark(rgba(255, 255, 255, 0.95), rgba(0, 0, 0, 0.9))
|
|
2855
|
-
);
|
|
2819
|
+
background: var(--tooltip-bg, light-dark(rgba(255, 255, 255, 0.95), rgba(0, 0, 0, 0.9)));
|
|
2856
2820
|
color: var(--tooltip-text, var(--text-color, #222));
|
|
2857
2821
|
border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
|
|
2858
2822
|
border-radius: 6px;
|