matterviz 0.4.0 → 0.4.1
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/brillouin/BrillouinZone.svelte +68 -145
- package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -14
- package/dist/brillouin/BrillouinZoneExportPane.svelte +43 -96
- package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +9 -32
- package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
- package/dist/brillouin/BrillouinZoneScene.svelte +49 -203
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +3 -23
- package/dist/brillouin/ReciprocalVectors.svelte +39 -0
- package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
- package/dist/brillouin/compute.d.ts +2 -0
- package/dist/brillouin/compute.js +80 -77
- package/dist/brillouin/geometry.d.ts +8 -0
- package/dist/brillouin/geometry.js +57 -0
- package/dist/brillouin/index.d.ts +2 -0
- package/dist/brillouin/index.js +2 -0
- package/dist/brillouin/types.d.ts +2 -2
- package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +100 -191
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +176 -464
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
- package/dist/chempot-diagram/color.d.ts +3 -6
- package/dist/chempot-diagram/color.js +5 -5
- package/dist/chempot-diagram/compute.d.ts +3 -3
- package/dist/chempot-diagram/compute.js +3 -1
- package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
- package/dist/chempot-diagram/controls-state.svelte.js +42 -0
- package/dist/chempot-diagram/export.d.ts +47 -0
- package/dist/chempot-diagram/export.js +133 -0
- package/dist/chempot-diagram/index.d.ts +1 -0
- package/dist/chempot-diagram/index.js +1 -0
- package/dist/chempot-diagram/pointer.d.ts +0 -10
- package/dist/chempot-diagram/pointer.js +4 -4
- package/dist/chempot-diagram/types.d.ts +3 -3
- package/dist/colors/index.js +2 -2
- package/dist/composition/FormulaFilter.svelte +6 -5
- package/dist/composition/PieChart.svelte +5 -5
- package/dist/composition/chem-sys.js +3 -2
- package/dist/composition/format.js +3 -2
- package/dist/composition/parse.d.ts +0 -1
- package/dist/composition/parse.js +17 -19
- package/dist/controls.d.ts +1 -0
- package/dist/controls.js +0 -1
- package/dist/convex-hull/ConvexHull.svelte +8 -10
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
- package/dist/convex-hull/ConvexHull2D.svelte +94 -175
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +176 -680
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +180 -680
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullChrome.svelte +268 -0
- package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
- package/dist/convex-hull/ConvexHullControls.svelte +88 -7
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
- package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
- package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
- package/dist/convex-hull/ConvexHullStats.svelte +29 -168
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
- package/dist/convex-hull/ConvexHullTooltip.svelte +11 -2
- package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
- package/dist/convex-hull/barycentric-coords.d.ts +2 -4
- package/dist/convex-hull/barycentric-coords.js +6 -33
- package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
- package/dist/convex-hull/canvas-interactions.svelte.js +278 -0
- package/dist/convex-hull/helpers.d.ts +39 -7
- package/dist/convex-hull/helpers.js +154 -69
- package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
- package/dist/convex-hull/hull-state.svelte.js +124 -0
- package/dist/convex-hull/index.d.ts +9 -7
- package/dist/convex-hull/index.js +7 -2
- package/dist/convex-hull/thermodynamics.js +91 -920
- package/dist/convex-hull/types.d.ts +12 -4
- package/dist/convex-hull/types.js +12 -0
- package/dist/coordination/CoordinationBarPlot.svelte +4 -11
- package/dist/element/BohrAtom.svelte +2 -1
- package/dist/element/ElementTile.svelte.d.ts +1 -1
- package/dist/element/index.d.ts +4 -0
- package/dist/element/index.js +18 -0
- package/dist/feedback/DragOverlay.svelte +3 -1
- package/dist/feedback/DragOverlay.svelte.d.ts +1 -0
- package/dist/feedback/StatusMessage.svelte +13 -3
- package/dist/fermi-surface/FermiSurface.svelte +67 -146
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -14
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +72 -224
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
- package/dist/fermi-surface/compute.js +11 -10
- package/dist/fermi-surface/export.js +4 -15
- package/dist/fermi-surface/index.d.ts +0 -1
- package/dist/fermi-surface/index.js +0 -1
- package/dist/fermi-surface/parse.d.ts +1 -1
- package/dist/fermi-surface/parse.js +64 -75
- package/dist/fermi-surface/types.d.ts +2 -2
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +55 -40
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +4 -3
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +3 -2
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
- package/dist/heatmap-matrix/index.d.ts +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/io/ExportPane.svelte +166 -0
- package/dist/io/ExportPane.svelte.d.ts +17 -0
- package/dist/io/decompress.js +1 -2
- package/dist/io/export.d.ts +5 -1
- package/dist/io/export.js +32 -28
- package/dist/io/fetch.d.ts +2 -1
- package/dist/io/file-drop.d.ts +7 -0
- package/dist/io/file-drop.js +13 -0
- package/dist/io/index.d.ts +2 -0
- package/dist/io/index.js +10 -0
- package/dist/io/types.d.ts +13 -0
- package/dist/isosurface/parse.js +46 -44
- package/dist/labels.js +1 -1
- package/dist/layout/FullscreenButton.svelte +33 -0
- package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
- package/dist/layout/FullscreenToggle.svelte +8 -14
- package/dist/layout/ViewerChrome.svelte +116 -0
- package/dist/layout/ViewerChrome.svelte.d.ts +17 -0
- package/dist/layout/fullscreen.d.ts +4 -0
- package/dist/layout/fullscreen.svelte.d.ts +8 -0
- package/dist/layout/fullscreen.svelte.js +37 -0
- package/dist/layout/index.d.ts +3 -0
- package/dist/layout/index.js +3 -0
- package/dist/math.d.ts +7 -3
- package/dist/math.js +18 -21
- package/dist/overlays/index.d.ts +4 -0
- package/dist/periodic-table/PeriodicTable.svelte +9 -8
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramControls.svelte +3 -2
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +47 -132
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
- package/dist/phase-diagram/colors.js +1 -1
- package/dist/phase-diagram/parse.d.ts +2 -1
- package/dist/plot/bar/BarPlot.svelte +79 -316
- package/dist/plot/bar/BarPlot.svelte.d.ts +7 -15
- package/dist/plot/bar/BarPlotControls.svelte.d.ts +1 -1
- package/dist/plot/bar/SpacegroupBarPlot.svelte +2 -1
- package/dist/plot/box/BoxPlot.svelte +76 -246
- package/dist/plot/box/BoxPlot.svelte.d.ts +4 -3
- package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
- package/dist/plot/box/Violin.svelte.d.ts +1 -1
- package/dist/plot/box/box-plot.d.ts +3 -2
- package/dist/plot/box/box-plot.js +5 -2
- package/dist/plot/box/kde.d.ts +2 -1
- package/dist/plot/box/kde.js +4 -4
- package/dist/plot/core/auto-place.d.ts +1 -1
- package/dist/plot/core/auto-place.js +4 -1
- package/dist/plot/core/components/ColorBar.svelte +5 -5
- package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
- package/dist/plot/core/components/Line.svelte +3 -2
- package/dist/plot/core/components/Line.svelte.d.ts +3 -2
- package/dist/plot/core/components/PlotAxis.svelte +2 -1
- package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
- package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
- package/dist/plot/core/components/ReferenceLine3D.svelte +2 -2
- package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
- package/dist/plot/core/components/ReferencePlane.svelte +2 -2
- package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
- package/dist/plot/core/data-cleaning.js +18 -18
- package/dist/plot/core/fill-utils.d.ts +4 -3
- package/dist/plot/core/fill-utils.js +6 -3
- package/dist/plot/core/interactions.d.ts +5 -1
- package/dist/plot/core/interactions.js +14 -0
- package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
- package/dist/plot/core/pan-zoom.svelte.js +221 -0
- package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
- package/dist/plot/core/placed-tween.svelte.js +68 -0
- package/dist/plot/core/reference-line.d.ts +10 -10
- package/dist/plot/core/reference-line.js +6 -6
- package/dist/plot/core/scales.d.ts +17 -25
- package/dist/plot/core/scales.js +10 -8
- package/dist/plot/core/svg.d.ts +2 -1
- package/dist/plot/core/types.d.ts +18 -7
- package/dist/plot/core/utils/label-placement.d.ts +1 -1
- package/dist/plot/core/utils/label-placement.js +3 -3
- package/dist/plot/core/utils.d.ts +2 -1
- package/dist/plot/histogram/Histogram.svelte +77 -314
- package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
- package/dist/plot/sankey/Sankey.svelte +2 -5
- package/dist/plot/sankey/Sankey.svelte.d.ts +1 -1
- package/dist/plot/sankey/sankey.js +3 -1
- package/dist/plot/scatter/BinnedScatterPlot.svelte +3 -5
- package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +4 -4
- package/dist/plot/scatter/ScatterPlot.svelte +160 -450
- package/dist/plot/scatter/ScatterPlot.svelte.d.ts +7 -15
- package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
- package/dist/plot/scatter/binned-scatter-types.d.ts +4 -11
- package/dist/plot/scatter/index.d.ts +1 -1
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte +15 -26
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
- package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +9 -10
- package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +122 -121
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
- package/dist/plot/scatter-3d/Surface3D.svelte +6 -5
- package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
- package/dist/plot/sunburst/Sunburst.svelte +16 -20
- package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
- package/dist/plot/sunburst/SunburstControls.svelte.d.ts +1 -1
- package/dist/plot/sunburst/sunburst.js +4 -1
- package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
- package/dist/sanitize.js +13 -2
- package/dist/scene/SceneCamera.svelte +62 -0
- package/dist/scene/SceneCamera.svelte.d.ts +19 -0
- package/dist/scene/bind-renderer.svelte.d.ts +2 -0
- package/dist/scene/bind-renderer.svelte.js +14 -0
- package/dist/scene/index.d.ts +4 -0
- package/dist/scene/index.js +5 -0
- package/dist/scene/props.js +52 -0
- package/dist/scene/types.d.ts +26 -0
- package/dist/scene/types.js +1 -0
- package/dist/settings.d.ts +14 -2
- package/dist/settings.js +59 -1
- package/dist/spectral/Bands.svelte +8 -7
- package/dist/spectral/Bands.svelte.d.ts +3 -2
- package/dist/spectral/BandsAndDos.svelte +22 -24
- package/dist/spectral/BrillouinBandsDos.svelte +3 -3
- package/dist/spectral/Dos.svelte +5 -4
- package/dist/spectral/Dos.svelte.d.ts +2 -1
- package/dist/spectral/helpers.d.ts +6 -6
- package/dist/spectral/helpers.js +43 -37
- package/dist/state.svelte.d.ts +0 -7
- package/dist/state.svelte.js +0 -6
- package/dist/structure/Arrow.svelte +2 -4
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/CanvasTooltip.svelte +1 -0
- package/dist/structure/CellSelect.svelte +11 -3
- package/dist/structure/CellSelect.svelte.d.ts +2 -1
- package/dist/structure/Lattice.svelte +2 -2
- package/dist/structure/Structure.svelte +291 -355
- package/dist/structure/Structure.svelte.d.ts +5 -15
- package/dist/structure/StructureControls.svelte +217 -2
- package/dist/structure/StructureControls.svelte.d.ts +5 -3
- package/dist/structure/StructureExportPane.svelte +54 -156
- package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
- package/dist/structure/StructureInfoPane.svelte +5 -3
- package/dist/structure/StructureInfoPane.svelte.d.ts +5 -5
- package/dist/structure/StructureScene.svelte +365 -198
- package/dist/structure/StructureScene.svelte.d.ts +22 -20
- package/dist/structure/{label-placement.d.ts → atom-label-placement.d.ts} +3 -3
- package/dist/structure/{label-placement.js → atom-label-placement.js} +12 -2
- package/dist/structure/atom-properties.d.ts +1 -1
- package/dist/structure/atom-properties.js +11 -16
- package/dist/structure/bond-order-perception.js +2 -4
- package/dist/structure/bonding.d.ts +3 -0
- package/dist/structure/bonding.js +91 -48
- package/dist/structure/export.d.ts +24 -4
- package/dist/structure/export.js +64 -122
- package/dist/structure/index.d.ts +2 -0
- package/dist/structure/index.js +2 -0
- package/dist/structure/parse.d.ts +3 -2
- package/dist/structure/parse.js +333 -370
- package/dist/structure/partial-occupancy.d.ts +0 -1
- package/dist/structure/partial-occupancy.js +1 -1
- package/dist/structure/pbc.d.ts +1 -1
- package/dist/structure/pbc.js +186 -13
- package/dist/structure/polyhedra.d.ts +41 -0
- package/dist/structure/polyhedra.js +602 -0
- package/dist/structure/site.d.ts +4 -0
- package/dist/structure/site.js +1 -0
- package/dist/structure/supercell.js +3 -2
- package/dist/structure/validation.js +5 -6
- package/dist/symmetry/SymmetryElementControls.svelte +69 -0
- package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
- package/dist/symmetry/SymmetryElements.svelte +354 -0
- package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
- package/dist/symmetry/SymmetryStats.svelte +111 -6
- package/dist/symmetry/WyckoffTable.svelte +68 -7
- package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
- package/dist/symmetry/cell-transform.js +7 -14
- package/dist/symmetry/index.d.ts +14 -4
- package/dist/symmetry/index.js +301 -80
- package/dist/symmetry/spacegroups.d.ts +5 -1
- package/dist/symmetry/spacegroups.js +15 -1
- package/dist/symmetry/symmetry-elements.d.ts +33 -0
- package/dist/symmetry/symmetry-elements.js +521 -0
- package/dist/symmetry/wyckoff-db.d.ts +9 -0
- package/dist/symmetry/wyckoff-db.js +87 -0
- package/dist/table/HeatmapTable.svelte +4 -15
- package/dist/table/HeatmapTable.svelte.d.ts +1 -1
- package/dist/trajectory/Trajectory.svelte +58 -61
- package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
- package/dist/trajectory/TrajectoryExportPane.svelte +15 -24
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
- package/dist/trajectory/TrajectoryInfoPane.svelte +3 -2
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
- package/dist/trajectory/constants.js +6 -2
- package/dist/trajectory/extract.js +17 -37
- package/dist/trajectory/format-detect.d.ts +0 -1
- package/dist/trajectory/format-detect.js +3 -9
- package/dist/trajectory/frame-reader.d.ts +0 -1
- package/dist/trajectory/frame-reader.js +62 -128
- package/dist/trajectory/helpers.d.ts +10 -2
- package/dist/trajectory/helpers.js +56 -36
- package/dist/trajectory/parse/ase.d.ts +9 -1
- package/dist/trajectory/parse/ase.js +47 -32
- package/dist/trajectory/parse/diagnostics.d.ts +3 -0
- package/dist/trajectory/parse/diagnostics.js +14 -0
- package/dist/trajectory/parse/index.d.ts +1 -1
- package/dist/trajectory/parse/index.js +54 -102
- package/dist/trajectory/parse/lammps.d.ts +0 -2
- package/dist/trajectory/parse/lammps.js +8 -6
- package/dist/trajectory/parse/pymatgen.d.ts +2 -0
- package/dist/trajectory/parse/pymatgen.js +74 -0
- package/dist/trajectory/parse/vasp.js +4 -3
- package/dist/trajectory/parse/xyz.d.ts +9 -21
- package/dist/trajectory/parse/xyz.js +28 -33
- package/dist/trajectory/plotting.d.ts +0 -1
- package/dist/trajectory/plotting.js +3 -100
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +1 -1
- package/dist/xrd/XrdPlot.svelte +14 -29
- package/dist/xrd/broadening.d.ts +2 -1
- package/dist/xrd/calc-xrd.js +6 -11
- package/dist/xrd/index.d.ts +2 -2
- package/package.json +29 -16
- package/dist/element/data.json +0 -11864
- package/dist/fermi-surface/marching-cubes.d.ts +0 -2
- package/dist/fermi-surface/marching-cubes.js +0 -2
- package/dist/plot/core/hover-lock.svelte.d.ts +0 -14
- package/dist/plot/core/hover-lock.svelte.js +0 -45
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
import TemperatureSlider from '../convex-hull/TemperatureSlider.svelte'
|
|
7
7
|
import type { PhaseData } from '../convex-hull/types'
|
|
8
8
|
import Spinner from '../feedback/Spinner.svelte'
|
|
9
|
-
import
|
|
9
|
+
import type { ExportSection } from '../io'
|
|
10
|
+
import ExportPane from '../io/ExportPane.svelte'
|
|
10
11
|
import { format_num } from '../labels'
|
|
11
|
-
import {
|
|
12
|
+
import { FullscreenButton, type FullscreenToggleProp, SettingsSection, toggle_fullscreen } from '../layout'
|
|
13
|
+
import { sync_fullscreen } from '../layout/fullscreen.svelte'
|
|
12
14
|
import type { Vec2, Vec3 } from '../math'
|
|
13
15
|
import {
|
|
14
16
|
convex_hull_2d,
|
|
@@ -32,15 +34,29 @@
|
|
|
32
34
|
import { Canvas, T } from '@threlte/core'
|
|
33
35
|
import * as extras from '@threlte/extras'
|
|
34
36
|
import { scaleLinear } from 'd3-scale'
|
|
37
|
+
import type { Snippet } from 'svelte'
|
|
35
38
|
import { onDestroy, onMount, untrack } from 'svelte'
|
|
36
39
|
import { SvelteMap, SvelteSet } from 'svelte/reactivity'
|
|
37
40
|
import * as THREE from 'three'
|
|
38
41
|
import type { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
|
|
39
|
-
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js'
|
|
40
42
|
import { ConvexGeometry } from 'three/examples/jsm/geometries/ConvexGeometry.js'
|
|
41
43
|
import { compute_chempot_async } from './async-compute.svelte'
|
|
42
44
|
import ChemPotScene3D from './ChemPotScene3D.svelte'
|
|
43
45
|
import { get_chempot_color_bar_config, make_chempot_color_scale } from './color'
|
|
46
|
+
import {
|
|
47
|
+
CHEMPOT_COLOR_MODE_OPTIONS,
|
|
48
|
+
CHEMPOT_COLOR_SCALE_OPTIONS,
|
|
49
|
+
create_chempot_overrides,
|
|
50
|
+
} from './controls-state.svelte'
|
|
51
|
+
import {
|
|
52
|
+
export_glb_file,
|
|
53
|
+
export_json_file,
|
|
54
|
+
export_png_file,
|
|
55
|
+
export_svg_file,
|
|
56
|
+
export_view_json_file,
|
|
57
|
+
get_json_string,
|
|
58
|
+
get_view_settings,
|
|
59
|
+
} from './export'
|
|
44
60
|
import {
|
|
45
61
|
apply_element_padding,
|
|
46
62
|
bbox_diagonal,
|
|
@@ -85,6 +101,11 @@
|
|
|
85
101
|
max_interpolation_gap = CHEMPOT_DEFAULTS.max_interpolation_gap,
|
|
86
102
|
hover_info = $bindable<ChemPotHoverInfo | null>(null),
|
|
87
103
|
render_local_tooltip = true,
|
|
104
|
+
wrapper = $bindable(),
|
|
105
|
+
fullscreen = $bindable(false),
|
|
106
|
+
fullscreen_toggle = true,
|
|
107
|
+
controls_open = $bindable(false),
|
|
108
|
+
export_pane_open = $bindable(false),
|
|
88
109
|
}: {
|
|
89
110
|
entries: PhaseData[]
|
|
90
111
|
config?: ChemPotDiagramConfig
|
|
@@ -95,54 +116,41 @@
|
|
|
95
116
|
max_interpolation_gap?: number
|
|
96
117
|
hover_info?: ChemPotHoverInfo | null
|
|
97
118
|
render_local_tooltip?: boolean
|
|
119
|
+
// bindable: top-level wrapper element
|
|
120
|
+
wrapper?: HTMLDivElement
|
|
121
|
+
// bindable: fullscreen state
|
|
122
|
+
fullscreen?: boolean
|
|
123
|
+
// show/hide the fullscreen button (or custom snippet to render it)
|
|
124
|
+
fullscreen_toggle?: FullscreenToggleProp
|
|
125
|
+
// bindable: whether the controls pane is currently open
|
|
126
|
+
controls_open?: boolean
|
|
127
|
+
// bindable: whether the export pane is currently open
|
|
128
|
+
export_pane_open?: boolean
|
|
98
129
|
} = $props()
|
|
99
130
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
)
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
formulas_to_draw_override ?? (config.formulas_to_draw ?? []),
|
|
124
|
-
)
|
|
125
|
-
const draw_formula_meshes = $derived(
|
|
126
|
-
draw_formula_meshes_override ??
|
|
127
|
-
(config.draw_formula_meshes ?? CHEMPOT_DEFAULTS.draw_formula_meshes),
|
|
128
|
-
)
|
|
129
|
-
const draw_formula_lines = $derived(
|
|
130
|
-
draw_formula_lines_override ??
|
|
131
|
-
(config.draw_formula_lines ?? CHEMPOT_DEFAULTS.draw_formula_lines),
|
|
132
|
-
)
|
|
133
|
-
let color_mode_override = $state<ChemPotColorMode | null>(null)
|
|
134
|
-
let color_scale_override = $state<D3InterpolateName | null>(null)
|
|
135
|
-
let reverse_color_scale_override = $state<boolean | null>(null)
|
|
136
|
-
const color_mode = $derived(
|
|
137
|
-
color_mode_override ?? (config.color_mode ?? `arity`),
|
|
138
|
-
)
|
|
139
|
-
const color_scale = $derived(
|
|
140
|
-
color_scale_override ?? (config.color_scale ?? CHEMPOT_DEFAULTS.color_scale),
|
|
141
|
-
)
|
|
142
|
-
const reverse_color_scale = $derived(
|
|
143
|
-
reverse_color_scale_override ??
|
|
144
|
-
(config.reverse_color_scale ?? CHEMPOT_DEFAULTS.reverse_color_scale),
|
|
145
|
-
)
|
|
131
|
+
// Control overrides (override ?? config ?? default, cleared by Reset)
|
|
132
|
+
const overrides = create_chempot_overrides(() => config, [
|
|
133
|
+
`formal_chempots`,
|
|
134
|
+
`label_stable`,
|
|
135
|
+
`element_padding`,
|
|
136
|
+
`default_min_limit`,
|
|
137
|
+
`formulas_to_draw`,
|
|
138
|
+
`draw_formula_meshes`,
|
|
139
|
+
`draw_formula_lines`,
|
|
140
|
+
`color_mode`,
|
|
141
|
+
`color_scale`,
|
|
142
|
+
`reverse_color_scale`,
|
|
143
|
+
], { color_mode: `arity`, formulas_to_draw: [] })
|
|
144
|
+
const formal_chempots = $derived(overrides.resolve(`formal_chempots`))
|
|
145
|
+
const label_stable = $derived(overrides.resolve(`label_stable`))
|
|
146
|
+
const element_padding = $derived(overrides.resolve(`element_padding`))
|
|
147
|
+
const default_min_limit = $derived(overrides.resolve(`default_min_limit`))
|
|
148
|
+
const formulas_to_draw = $derived(overrides.resolve(`formulas_to_draw`))
|
|
149
|
+
const draw_formula_meshes = $derived(overrides.resolve(`draw_formula_meshes`))
|
|
150
|
+
const draw_formula_lines = $derived(overrides.resolve(`draw_formula_lines`))
|
|
151
|
+
const color_mode = $derived(overrides.resolve(`color_mode`))
|
|
152
|
+
const color_scale = $derived(overrides.resolve(`color_scale`))
|
|
153
|
+
const reverse_color_scale = $derived(overrides.resolve(`reverse_color_scale`))
|
|
146
154
|
const show_tooltip = $derived(config.show_tooltip ?? CHEMPOT_DEFAULTS.show_tooltip)
|
|
147
155
|
const tooltip_detail_level = $derived(
|
|
148
156
|
config.tooltip_detail_level ?? CHEMPOT_DEFAULTS.tooltip_detail_level,
|
|
@@ -167,11 +175,7 @@
|
|
|
167
175
|
return deduped
|
|
168
176
|
}
|
|
169
177
|
|
|
170
|
-
let wrapper = $state<HTMLDivElement>()
|
|
171
|
-
let fullscreen = $state(false)
|
|
172
|
-
let export_pane_open = $state(false)
|
|
173
178
|
let formula_picker_open = $state(false)
|
|
174
|
-
let controls_open = $state(false)
|
|
175
179
|
|
|
176
180
|
// Mutual exclusion: only one pane open at a time.
|
|
177
181
|
// Separate effects so each reacts to its own pane opening independently —
|
|
@@ -180,8 +184,6 @@
|
|
|
180
184
|
$effect(() => { if (export_pane_open) { formula_picker_open = false; controls_open = false } })
|
|
181
185
|
$effect(() => { if (formula_picker_open) { export_pane_open = false; controls_open = false } })
|
|
182
186
|
$effect(() => { if (controls_open) { export_pane_open = false; formula_picker_open = false } })
|
|
183
|
-
let copy_status = $state(false)
|
|
184
|
-
let copy_timeout_id: ReturnType<typeof setTimeout> | null = null
|
|
185
187
|
let container_width = $state(0)
|
|
186
188
|
let container_height = $state(0)
|
|
187
189
|
const base_aspect_ratio = $derived(height > 0 && width > 0 ? height / width : 1)
|
|
@@ -797,7 +799,7 @@
|
|
|
797
799
|
for (const [pa, pb] of get_domain_edges(swizzled)) {
|
|
798
800
|
const ka = pa.map((coord) => coord.toFixed(4)).join(`,`)
|
|
799
801
|
const kb = pb.map((coord) => coord.toFixed(4)).join(`,`)
|
|
800
|
-
const key = ka
|
|
802
|
+
const key = edge_key(ka, kb)
|
|
801
803
|
if (seen.has(key)) continue
|
|
802
804
|
seen.add(key)
|
|
803
805
|
positions.push(pa[0], pa[1], pa[2], pb[0], pb[1], pb[2])
|
|
@@ -934,7 +936,7 @@
|
|
|
934
936
|
// coplanar neighbors, then assign each group to its most-common domain.
|
|
935
937
|
if (n_faces > 1) {
|
|
936
938
|
const tol = 1e-3
|
|
937
|
-
const round = (
|
|
939
|
+
const round = (val: number): number => Math.round(val / tol)
|
|
938
940
|
const vkey = (vert_idx: number): string =>
|
|
939
941
|
`${round(pos.getX(vert_idx))},${round(pos.getY(vert_idx))},${
|
|
940
942
|
round(pos.getZ(vert_idx))
|
|
@@ -974,12 +976,12 @@
|
|
|
974
976
|
}
|
|
975
977
|
// Union-find for coplanar adjacent faces
|
|
976
978
|
const parent = Array.from({ length: n_faces }, (_, idx) => idx)
|
|
977
|
-
const find = (
|
|
978
|
-
while (parent[
|
|
979
|
-
parent[
|
|
980
|
-
|
|
979
|
+
const find = (node: number): number => {
|
|
980
|
+
while (parent[node] !== node) {
|
|
981
|
+
parent[node] = parent[parent[node]]
|
|
982
|
+
node = parent[node]
|
|
981
983
|
}
|
|
982
|
-
return
|
|
984
|
+
return node
|
|
983
985
|
}
|
|
984
986
|
const union = (a_idx: number, b_idx: number): void => {
|
|
985
987
|
const ra = find(a_idx), rb = find(b_idx)
|
|
@@ -1194,7 +1196,7 @@
|
|
|
1194
1196
|
|
|
1195
1197
|
function get_touches_limits(
|
|
1196
1198
|
points_3d: number[][],
|
|
1197
|
-
lims: [
|
|
1199
|
+
lims: Vec2[],
|
|
1198
1200
|
): string[] {
|
|
1199
1201
|
const limit_tol = 1e-3
|
|
1200
1202
|
const touches_limits: string[] = []
|
|
@@ -1486,10 +1488,10 @@
|
|
|
1486
1488
|
// Place axis label just past the outer end of the axis (the end closer to 0).
|
|
1487
1489
|
// In isometric 3D, the end near 0 projects outward at the front edge of the
|
|
1488
1490
|
// bounding box, while the negative end projects inward toward the center.
|
|
1489
|
-
const outer_end = (range:
|
|
1491
|
+
const outer_end = (range: Vec2): number =>
|
|
1490
1492
|
Math.abs(range[0]) <= Math.abs(range[1]) ? range[0] : range[1]
|
|
1491
1493
|
// Direction from range center toward outer end (to extend the label beyond the grid)
|
|
1492
|
-
const outer_direction = (range:
|
|
1494
|
+
const outer_direction = (range: Vec2): number => {
|
|
1493
1495
|
const end = outer_end(range)
|
|
1494
1496
|
const mid = (range[0] + range[1]) / 2
|
|
1495
1497
|
return end >= mid ? 1 : -1
|
|
@@ -1759,8 +1761,12 @@
|
|
|
1759
1761
|
schedule_label_occlusion_update()
|
|
1760
1762
|
})
|
|
1761
1763
|
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
+
// Drive the browser Fullscreen API from the bindable `fullscreen` prop (parent-controllable), keep it in sync with Esc/external exits
|
|
1765
|
+
sync_fullscreen({
|
|
1766
|
+
get_wrapper: () => wrapper,
|
|
1767
|
+
get_fullscreen: () => fullscreen,
|
|
1768
|
+
set_fullscreen: (val) => (fullscreen = val),
|
|
1769
|
+
bg_css_var: `--chempot-3d-bg-fullscreen`,
|
|
1764
1770
|
})
|
|
1765
1771
|
|
|
1766
1772
|
$effect(() => {
|
|
@@ -1789,7 +1795,7 @@
|
|
|
1789
1795
|
key: string
|
|
1790
1796
|
pos: Vec3
|
|
1791
1797
|
rot: Vec3
|
|
1792
|
-
size:
|
|
1798
|
+
size: Vec2
|
|
1793
1799
|
color: string
|
|
1794
1800
|
}[] = []
|
|
1795
1801
|
if (projections.xy) {
|
|
@@ -1860,17 +1866,8 @@
|
|
|
1860
1866
|
})
|
|
1861
1867
|
|
|
1862
1868
|
function reset_controls(): void {
|
|
1863
|
-
|
|
1864
|
-
label_stable_override = null
|
|
1865
|
-
element_padding_override = null
|
|
1866
|
-
default_min_limit_override = null
|
|
1867
|
-
draw_formula_meshes_override = null
|
|
1868
|
-
draw_formula_lines_override = null
|
|
1869
|
-
color_mode_override = null
|
|
1870
|
-
color_scale_override = null
|
|
1871
|
-
reverse_color_scale_override = null
|
|
1869
|
+
overrides.reset()
|
|
1872
1870
|
projection_elements_override = null
|
|
1873
|
-
formulas_to_draw_override = null
|
|
1874
1871
|
formula_filter_query = ``
|
|
1875
1872
|
}
|
|
1876
1873
|
|
|
@@ -1902,270 +1899,94 @@
|
|
|
1902
1899
|
const selected_formulas = new SvelteSet(formulas_to_draw)
|
|
1903
1900
|
if (selected_formulas.has(formula)) selected_formulas.delete(formula)
|
|
1904
1901
|
else selected_formulas.add(formula)
|
|
1905
|
-
|
|
1902
|
+
overrides.set(`formulas_to_draw`, [...selected_formulas])
|
|
1906
1903
|
}
|
|
1907
1904
|
|
|
1908
1905
|
function select_surface_formulas(): void {
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1906
|
+
overrides.set(
|
|
1907
|
+
`formulas_to_draw`,
|
|
1908
|
+
render_domains
|
|
1909
|
+
.filter((domain) => surface_formulas.has(domain.formula))
|
|
1910
|
+
.map((domain) => domain.formula),
|
|
1911
|
+
)
|
|
1912
1912
|
}
|
|
1913
1913
|
|
|
1914
1914
|
function select_neighbor_formulas(): void {
|
|
1915
1915
|
if (hover_info?.view !== `3d`) return
|
|
1916
1916
|
const neighbors = domain_neighbors.get(hover_info.formula) ?? []
|
|
1917
|
-
|
|
1918
|
-
}
|
|
1919
|
-
|
|
1920
|
-
function download_blob(blob: Blob, filename: string): void {
|
|
1921
|
-
const url = URL.createObjectURL(blob)
|
|
1922
|
-
const link = document.createElement(`a`)
|
|
1923
|
-
link.href = url
|
|
1924
|
-
link.download = filename
|
|
1925
|
-
link.click()
|
|
1926
|
-
URL.revokeObjectURL(url)
|
|
1917
|
+
overrides.set(`formulas_to_draw`, [hover_info.formula, ...neighbors])
|
|
1927
1918
|
}
|
|
1928
1919
|
|
|
1929
1920
|
let png_dpi = $state(150)
|
|
1930
1921
|
const export_basename = $derived(`chempot-${plot_elements.join(`-`)}`)
|
|
1931
1922
|
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
const view_camera_target = orbit_controls_ref?.target
|
|
1935
|
-
return {
|
|
1923
|
+
const current_view_settings = (): Record<string, unknown> =>
|
|
1924
|
+
get_view_settings({
|
|
1936
1925
|
elements: plot_elements,
|
|
1937
1926
|
camera_projection,
|
|
1938
1927
|
auto_rotate,
|
|
1939
1928
|
color_mode,
|
|
1940
1929
|
color_scale,
|
|
1941
1930
|
reverse_color_scale,
|
|
1942
|
-
camera_position:
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
camera_target: view_camera_target
|
|
1946
|
-
? [view_camera_target.x, view_camera_target.y, view_camera_target.z]
|
|
1947
|
-
: null,
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
|
|
1951
|
-
interface OverlayTextItem {
|
|
1952
|
-
x: number
|
|
1953
|
-
y: number
|
|
1954
|
-
text: string
|
|
1955
|
-
font: string
|
|
1956
|
-
font_size: string
|
|
1957
|
-
font_family: string
|
|
1958
|
-
font_weight: string
|
|
1959
|
-
color: string
|
|
1960
|
-
}
|
|
1961
|
-
function get_overlay_text_items(canvas_rect: DOMRect): OverlayTextItem[] {
|
|
1962
|
-
if (!wrapper) return []
|
|
1963
|
-
const text_items: OverlayTextItem[] = []
|
|
1964
|
-
for (
|
|
1965
|
-
const element of wrapper.querySelectorAll(
|
|
1966
|
-
`.tick-label, .axis-label, .domain-label`,
|
|
1967
|
-
)
|
|
1968
|
-
) {
|
|
1969
|
-
const html_element = element as HTMLElement
|
|
1970
|
-
const style = getComputedStyle(html_element)
|
|
1971
|
-
if (style.display === `none` || style.visibility === `hidden`) continue
|
|
1972
|
-
const element_rect = html_element.getBoundingClientRect()
|
|
1973
|
-
text_items.push({
|
|
1974
|
-
x: element_rect.left + element_rect.width / 2 - canvas_rect.left,
|
|
1975
|
-
y: element_rect.top + element_rect.height / 2 - canvas_rect.top,
|
|
1976
|
-
text: html_element.textContent ?? ``,
|
|
1977
|
-
font: style.font || `${style.fontSize} ${style.fontFamily}`,
|
|
1978
|
-
font_size: style.fontSize || `11px`,
|
|
1979
|
-
font_family: style.fontFamily || `sans-serif`,
|
|
1980
|
-
font_weight: style.fontWeight || `400`,
|
|
1981
|
-
color: style.color || `#333`,
|
|
1982
|
-
})
|
|
1983
|
-
}
|
|
1984
|
-
return text_items
|
|
1985
|
-
}
|
|
1986
|
-
|
|
1987
|
-
function export_png_file(): void {
|
|
1988
|
-
if (!wrapper) return
|
|
1989
|
-
const gl_canvas = wrapper.querySelector(`canvas`)
|
|
1990
|
-
if (!(gl_canvas instanceof HTMLCanvasElement)) return
|
|
1991
|
-
|
|
1992
|
-
// Composite WebGL canvas + HTML overlay labels into a single image
|
|
1993
|
-
const rect = gl_canvas.getBoundingClientRect()
|
|
1994
|
-
const scale = Math.min(png_dpi / 72, 10)
|
|
1995
|
-
const out = document.createElement(`canvas`)
|
|
1996
|
-
out.width = Math.round(rect.width * scale)
|
|
1997
|
-
out.height = Math.round(rect.height * scale)
|
|
1998
|
-
const ctx = out.getContext(`2d`)
|
|
1999
|
-
if (!ctx) return
|
|
2000
|
-
ctx.scale(scale, scale)
|
|
2001
|
-
|
|
2002
|
-
// Draw the WebGL canvas as background
|
|
2003
|
-
ctx.drawImage(gl_canvas, 0, 0, rect.width, rect.height)
|
|
2004
|
-
|
|
2005
|
-
// Draw all HTML overlay text (tick labels, axis labels, domain labels)
|
|
2006
|
-
for (const text_item of get_overlay_text_items(rect)) {
|
|
2007
|
-
ctx.font = text_item.font
|
|
2008
|
-
ctx.fillStyle = text_item.color
|
|
2009
|
-
ctx.textAlign = `center`
|
|
2010
|
-
ctx.textBaseline = `middle`
|
|
2011
|
-
ctx.fillText(text_item.text, text_item.x, text_item.y)
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
|
-
out.toBlob((blob) => {
|
|
2015
|
-
if (!blob) return
|
|
2016
|
-
download_blob(blob, `${export_basename}.png`)
|
|
2017
|
-
}, `image/png`)
|
|
2018
|
-
}
|
|
2019
|
-
|
|
2020
|
-
const xml_escape = (text: string): string =>
|
|
2021
|
-
text
|
|
2022
|
-
.replaceAll(`&`, `&`)
|
|
2023
|
-
.replaceAll(`<`, `<`)
|
|
2024
|
-
.replaceAll(`>`, `>`)
|
|
2025
|
-
.replaceAll(`"`, `"`)
|
|
2026
|
-
.replaceAll(`'`, `'`)
|
|
2027
|
-
|
|
2028
|
-
function export_svg_file(): void {
|
|
2029
|
-
if (!wrapper) return
|
|
2030
|
-
const gl_canvas = wrapper.querySelector(`canvas`)
|
|
2031
|
-
if (!(gl_canvas instanceof HTMLCanvasElement)) return
|
|
2032
|
-
const canvas_rect = gl_canvas.getBoundingClientRect()
|
|
2033
|
-
if (canvas_rect.width === 0 || canvas_rect.height === 0) return
|
|
2034
|
-
const png_data_url = gl_canvas.toDataURL(`image/png`)
|
|
2035
|
-
const text_nodes = get_overlay_text_items(canvas_rect).map((text_item) =>
|
|
2036
|
-
`<text x="${text_item.x.toFixed(2)}" y="${
|
|
2037
|
-
text_item.y.toFixed(2)
|
|
2038
|
-
}" text-anchor="middle" dominant-baseline="central" fill="${
|
|
2039
|
-
xml_escape(text_item.color)
|
|
2040
|
-
}" font-size="${xml_escape(text_item.font_size)}" font-family="${
|
|
2041
|
-
xml_escape(text_item.font_family)
|
|
2042
|
-
}" font-weight="${xml_escape(text_item.font_weight)}">${
|
|
2043
|
-
xml_escape(text_item.text)
|
|
2044
|
-
}</text>`
|
|
2045
|
-
)
|
|
2046
|
-
const metadata = xml_escape(JSON.stringify(get_view_settings()))
|
|
2047
|
-
const svg = [
|
|
2048
|
-
`<?xml version="1.0" encoding="UTF-8"?>`,
|
|
2049
|
-
`<svg xmlns="http://www.w3.org/2000/svg" width="${canvas_rect.width}" height="${canvas_rect.height}" viewBox="0 0 ${canvas_rect.width} ${canvas_rect.height}">`,
|
|
2050
|
-
`<metadata>${metadata}</metadata>`,
|
|
2051
|
-
`<image href="${png_data_url}" x="0" y="0" width="${canvas_rect.width}" height="${canvas_rect.height}" />`,
|
|
2052
|
-
...text_nodes,
|
|
2053
|
-
`</svg>`,
|
|
2054
|
-
].join(``)
|
|
2055
|
-
download_blob(
|
|
2056
|
-
new Blob([svg], { type: `image/svg+xml` }),
|
|
2057
|
-
`${export_basename}.svg`,
|
|
2058
|
-
)
|
|
2059
|
-
}
|
|
2060
|
-
|
|
2061
|
-
function export_view_json_file(): void {
|
|
2062
|
-
const json_text = JSON.stringify(get_view_settings(), null, 2)
|
|
2063
|
-
download_blob(
|
|
2064
|
-
new Blob([json_text], { type: `application/json` }),
|
|
2065
|
-
`${export_basename}-view.json`,
|
|
2066
|
-
)
|
|
2067
|
-
}
|
|
2068
|
-
|
|
2069
|
-
function export_glb_file(): void {
|
|
2070
|
-
const gltf_exporter = new GLTFExporter()
|
|
2071
|
-
const export_root = new THREE.Group()
|
|
2072
|
-
if (colored_hull_geometry) {
|
|
2073
|
-
export_root.add(
|
|
2074
|
-
new THREE.Mesh(
|
|
2075
|
-
colored_hull_geometry.clone(),
|
|
2076
|
-
new THREE.MeshBasicMaterial({
|
|
2077
|
-
vertexColors: true,
|
|
2078
|
-
transparent: true,
|
|
2079
|
-
opacity: color_mode === `none` ? 0.25 : 0.4,
|
|
2080
|
-
side: THREE.DoubleSide,
|
|
2081
|
-
}),
|
|
2082
|
-
),
|
|
2083
|
-
)
|
|
2084
|
-
}
|
|
2085
|
-
export_root.add(
|
|
2086
|
-
new THREE.LineSegments(
|
|
2087
|
-
edge_geometry.clone(),
|
|
2088
|
-
new THREE.LineBasicMaterial({ color: 0x333333 }),
|
|
2089
|
-
),
|
|
2090
|
-
)
|
|
2091
|
-
for (const { geometry, color } of formula_mesh_data) {
|
|
2092
|
-
export_root.add(
|
|
2093
|
-
new THREE.Mesh(
|
|
2094
|
-
geometry.clone(),
|
|
2095
|
-
new THREE.MeshBasicMaterial({
|
|
2096
|
-
color: new THREE.Color(color),
|
|
2097
|
-
transparent: true,
|
|
2098
|
-
opacity: 0.13,
|
|
2099
|
-
side: THREE.DoubleSide,
|
|
2100
|
-
}),
|
|
2101
|
-
),
|
|
2102
|
-
)
|
|
2103
|
-
}
|
|
2104
|
-
if (draw_formula_lines) {
|
|
2105
|
-
for (const { geometry, color } of formula_edge_data) {
|
|
2106
|
-
export_root.add(
|
|
2107
|
-
new THREE.LineSegments(
|
|
2108
|
-
geometry.clone(),
|
|
2109
|
-
new THREE.LineBasicMaterial({ color: new THREE.Color(color) }),
|
|
2110
|
-
),
|
|
2111
|
-
)
|
|
2112
|
-
}
|
|
2113
|
-
}
|
|
2114
|
-
gltf_exporter.parse(
|
|
2115
|
-
export_root,
|
|
2116
|
-
(result) => {
|
|
2117
|
-
if (!(result instanceof ArrayBuffer)) return
|
|
2118
|
-
download_blob(
|
|
2119
|
-
new Blob([result], { type: `model/gltf-binary` }),
|
|
2120
|
-
`${export_basename}.glb`,
|
|
2121
|
-
)
|
|
2122
|
-
},
|
|
2123
|
-
(err) => {
|
|
2124
|
-
console.error(`Failed to export GLB:`, err)
|
|
2125
|
-
},
|
|
2126
|
-
{ binary: true, onlyVisible: false },
|
|
2127
|
-
)
|
|
2128
|
-
}
|
|
2129
|
-
|
|
2130
|
-
const get_json_string = (): string =>
|
|
2131
|
-
JSON.stringify(
|
|
2132
|
-
{
|
|
2133
|
-
elements: diagram_data?.elements ?? [],
|
|
2134
|
-
domains: render_domains.map((domain) => ({
|
|
2135
|
-
formula: domain.formula,
|
|
2136
|
-
points_3d: domain.points_3d,
|
|
2137
|
-
})),
|
|
2138
|
-
lims: diagram_data?.lims ?? [],
|
|
2139
|
-
view: get_view_settings(),
|
|
2140
|
-
},
|
|
2141
|
-
null,
|
|
2142
|
-
2,
|
|
2143
|
-
)
|
|
1931
|
+
camera_position: orbit_controls_ref?.object?.position ?? null,
|
|
1932
|
+
camera_target: orbit_controls_ref?.target ?? null,
|
|
1933
|
+
})
|
|
2144
1934
|
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
1935
|
+
const export_json_payload = (): Record<string, unknown> => ({
|
|
1936
|
+
elements: diagram_data?.elements ?? [],
|
|
1937
|
+
domains: render_domains.map((domain) => ({
|
|
1938
|
+
formula: domain.formula,
|
|
1939
|
+
points_3d: domain.points_3d,
|
|
1940
|
+
})),
|
|
1941
|
+
lims: diagram_data?.lims ?? [],
|
|
1942
|
+
view: current_view_settings(),
|
|
1943
|
+
})
|
|
2151
1944
|
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
1945
|
+
const export_sections = $derived<ExportSection[]>([
|
|
1946
|
+
{
|
|
1947
|
+
title: `Export Image`,
|
|
1948
|
+
items: [
|
|
1949
|
+
{
|
|
1950
|
+
label: `SVG`,
|
|
1951
|
+
on_download: () =>
|
|
1952
|
+
export_svg_file(wrapper, export_basename, current_view_settings()),
|
|
1953
|
+
},
|
|
1954
|
+
{
|
|
1955
|
+
label: `PNG`,
|
|
1956
|
+
show_dpi: true,
|
|
1957
|
+
on_download: () => export_png_file(wrapper, export_basename, png_dpi),
|
|
1958
|
+
},
|
|
1959
|
+
],
|
|
1960
|
+
},
|
|
1961
|
+
{
|
|
1962
|
+
title: `Export Data`,
|
|
1963
|
+
items: [
|
|
1964
|
+
{
|
|
1965
|
+
label: `JSON`,
|
|
1966
|
+
on_download: () => export_json_file(export_json_payload(), export_basename),
|
|
1967
|
+
copy_text: () => get_json_string(export_json_payload()),
|
|
1968
|
+
},
|
|
1969
|
+
{
|
|
1970
|
+
label: `View`,
|
|
1971
|
+
on_download: () =>
|
|
1972
|
+
export_view_json_file(current_view_settings(), export_basename),
|
|
1973
|
+
},
|
|
1974
|
+
{
|
|
1975
|
+
label: `GLB`,
|
|
1976
|
+
on_download: () =>
|
|
1977
|
+
export_glb_file({
|
|
1978
|
+
hull_geometry: colored_hull_geometry,
|
|
1979
|
+
hull_opacity: color_mode === `none` ? 0.25 : 0.4,
|
|
1980
|
+
edge_geometry,
|
|
1981
|
+
formula_meshes: formula_mesh_data,
|
|
1982
|
+
formula_edges: draw_formula_lines ? formula_edge_data : [],
|
|
1983
|
+
}, export_basename),
|
|
1984
|
+
},
|
|
1985
|
+
],
|
|
1986
|
+
},
|
|
1987
|
+
])
|
|
2166
1988
|
|
|
2167
1989
|
onDestroy(() => {
|
|
2168
|
-
if (copy_timeout_id !== null) clearTimeout(copy_timeout_id)
|
|
2169
1990
|
if (label_occlusion_frame !== null) cancelAnimationFrame(label_occlusion_frame)
|
|
2170
1991
|
})
|
|
2171
1992
|
|
|
@@ -2212,25 +2033,13 @@
|
|
|
2212
2033
|
}
|
|
2213
2034
|
|
|
2214
2035
|
// Color mode cycling (keyboard shortcut 'c')
|
|
2215
|
-
const color_modes
|
|
2216
|
-
`none`,
|
|
2217
|
-
`energy`,
|
|
2218
|
-
`formation_energy`,
|
|
2219
|
-
`arity`,
|
|
2220
|
-
`entries`,
|
|
2221
|
-
]
|
|
2036
|
+
const color_modes = CHEMPOT_COLOR_MODE_OPTIONS.map(([value]) => value)
|
|
2222
2037
|
function cycle_color_mode(): void {
|
|
2223
2038
|
const idx = color_modes.indexOf(color_mode)
|
|
2224
|
-
|
|
2039
|
+
overrides.set(`color_mode`, color_modes[(idx + 1) % color_modes.length])
|
|
2225
2040
|
}
|
|
2226
2041
|
</script>
|
|
2227
2042
|
|
|
2228
|
-
<svelte:document
|
|
2229
|
-
onfullscreenchange={() => {
|
|
2230
|
-
fullscreen = document.fullscreenElement === wrapper
|
|
2231
|
-
}}
|
|
2232
|
-
/>
|
|
2233
|
-
|
|
2234
2043
|
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
2235
2044
|
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
2236
2045
|
<div
|
|
@@ -2250,7 +2059,7 @@
|
|
|
2250
2059
|
) return
|
|
2251
2060
|
if (event.key === `Escape`) clear_hover_lock()
|
|
2252
2061
|
else if (event.key === `c`) cycle_color_mode()
|
|
2253
|
-
else if (event.key === `f`) toggle_fullscreen(wrapper)
|
|
2062
|
+
else if (event.key === `f` && fullscreen_toggle) toggle_fullscreen(wrapper)
|
|
2254
2063
|
}}
|
|
2255
2064
|
onpointerdown={(event) => {
|
|
2256
2065
|
const target = event.target
|
|
@@ -2263,72 +2072,16 @@
|
|
|
2263
2072
|
}}
|
|
2264
2073
|
>
|
|
2265
2074
|
<section>
|
|
2266
|
-
<
|
|
2267
|
-
bind:
|
|
2268
|
-
|
|
2269
|
-
|
|
2075
|
+
<ExportPane
|
|
2076
|
+
bind:export_pane_open
|
|
2077
|
+
bind:png_dpi
|
|
2078
|
+
sections={export_sections}
|
|
2270
2079
|
pane_props={{ class: `chempot-export-pane` }}
|
|
2271
2080
|
toggle_props={{
|
|
2272
2081
|
class: `chempot-export-toggle`,
|
|
2273
2082
|
title: `Export chemical potential diagram`,
|
|
2274
2083
|
}}
|
|
2275
|
-
|
|
2276
|
-
<h4 id="export-image">Export Image</h4>
|
|
2277
|
-
<div class="export-row">
|
|
2278
|
-
<label>
|
|
2279
|
-
SVG
|
|
2280
|
-
<button type="button" onclick={export_svg_file} title="SVG snapshot export">
|
|
2281
|
-
⬇
|
|
2282
|
-
</button>
|
|
2283
|
-
</label>
|
|
2284
|
-
<label>
|
|
2285
|
-
PNG
|
|
2286
|
-
<button type="button" onclick={export_png_file} title="PNG ({png_dpi} DPI)">
|
|
2287
|
-
⬇
|
|
2288
|
-
</button>
|
|
2289
|
-
(DPI: <input
|
|
2290
|
-
type="number"
|
|
2291
|
-
min={50}
|
|
2292
|
-
max={500}
|
|
2293
|
-
bind:value={png_dpi}
|
|
2294
|
-
title="Export resolution in dots per inch"
|
|
2295
|
-
style="margin: 0 0 0 2pt"
|
|
2296
|
-
/>)
|
|
2297
|
-
</label>
|
|
2298
|
-
</div>
|
|
2299
|
-
<h4 id="export-data">Export Data</h4>
|
|
2300
|
-
<div class="export-row">
|
|
2301
|
-
<label>
|
|
2302
|
-
JSON
|
|
2303
|
-
<button type="button" onclick={export_json_file} aria-label="Download JSON">
|
|
2304
|
-
⬇
|
|
2305
|
-
</button>
|
|
2306
|
-
<button
|
|
2307
|
-
type="button"
|
|
2308
|
-
onclick={copy_json}
|
|
2309
|
-
aria-label="Copy JSON to clipboard"
|
|
2310
|
-
>
|
|
2311
|
-
{copy_status ? `✅` : `📋`}
|
|
2312
|
-
</button>
|
|
2313
|
-
</label>
|
|
2314
|
-
<label>
|
|
2315
|
-
View
|
|
2316
|
-
<button
|
|
2317
|
-
type="button"
|
|
2318
|
-
onclick={export_view_json_file}
|
|
2319
|
-
aria-label="Download view JSON"
|
|
2320
|
-
>
|
|
2321
|
-
⬇
|
|
2322
|
-
</button>
|
|
2323
|
-
</label>
|
|
2324
|
-
<label>
|
|
2325
|
-
GLB
|
|
2326
|
-
<button type="button" onclick={export_glb_file} aria-label="Download GLB">
|
|
2327
|
-
⬇
|
|
2328
|
-
</button>
|
|
2329
|
-
</label>
|
|
2330
|
-
</div>
|
|
2331
|
-
</DraggablePane>
|
|
2084
|
+
/>
|
|
2332
2085
|
<DraggablePane
|
|
2333
2086
|
bind:show={formula_picker_open}
|
|
2334
2087
|
open_icon="Cross"
|
|
@@ -2341,7 +2094,7 @@
|
|
|
2341
2094
|
>
|
|
2342
2095
|
<h4 id="formula-overlays">Formula Overlays</h4>
|
|
2343
2096
|
<div class="overlay-actions">
|
|
2344
|
-
<button type="button" onclick={() =>
|
|
2097
|
+
<button type="button" onclick={() => overrides.set(`formulas_to_draw`, [])}>
|
|
2345
2098
|
Clear
|
|
2346
2099
|
</button>
|
|
2347
2100
|
<button type="button" onclick={select_surface_formulas}>Surface</button>
|
|
@@ -2464,36 +2217,29 @@
|
|
|
2464
2217
|
<input
|
|
2465
2218
|
type="checkbox"
|
|
2466
2219
|
checked={formal_chempots}
|
|
2467
|
-
onchange={() =>
|
|
2468
|
-
formal_chempots_override = !formal_chempots
|
|
2469
|
-
}}
|
|
2220
|
+
onchange={() => overrides.set(`formal_chempots`, !formal_chempots)}
|
|
2470
2221
|
/> Formal
|
|
2471
2222
|
</label>
|
|
2472
2223
|
<label>
|
|
2473
2224
|
<input
|
|
2474
2225
|
type="checkbox"
|
|
2475
2226
|
checked={label_stable}
|
|
2476
|
-
onchange={() =>
|
|
2477
|
-
label_stable_override = !label_stable
|
|
2478
|
-
}}
|
|
2227
|
+
onchange={() => overrides.set(`label_stable`, !label_stable)}
|
|
2479
2228
|
/> Labels
|
|
2480
2229
|
</label>
|
|
2481
2230
|
<label>
|
|
2482
2231
|
<input
|
|
2483
2232
|
type="checkbox"
|
|
2484
2233
|
checked={draw_formula_meshes}
|
|
2485
|
-
onchange={() =>
|
|
2486
|
-
|
|
2487
|
-
}}
|
|
2234
|
+
onchange={() =>
|
|
2235
|
+
overrides.set(`draw_formula_meshes`, !draw_formula_meshes)}
|
|
2488
2236
|
/> Meshes
|
|
2489
2237
|
</label>
|
|
2490
2238
|
<label>
|
|
2491
2239
|
<input
|
|
2492
2240
|
type="checkbox"
|
|
2493
2241
|
checked={draw_formula_lines}
|
|
2494
|
-
onchange={() =>
|
|
2495
|
-
draw_formula_lines_override = !draw_formula_lines
|
|
2496
|
-
}}
|
|
2242
|
+
onchange={() => overrides.set(`draw_formula_lines`, !draw_formula_lines)}
|
|
2497
2243
|
/> Lines
|
|
2498
2244
|
</label>
|
|
2499
2245
|
</div>
|
|
@@ -2505,9 +2251,8 @@
|
|
|
2505
2251
|
min="0"
|
|
2506
2252
|
step="0.1"
|
|
2507
2253
|
value={element_padding}
|
|
2508
|
-
oninput={(event) =>
|
|
2509
|
-
|
|
2510
|
-
}}
|
|
2254
|
+
oninput={(event) =>
|
|
2255
|
+
overrides.set(`element_padding`, Number(event.currentTarget.value))}
|
|
2511
2256
|
/>
|
|
2512
2257
|
</label>
|
|
2513
2258
|
<label>
|
|
@@ -2517,11 +2262,8 @@
|
|
|
2517
2262
|
max="0"
|
|
2518
2263
|
step="1"
|
|
2519
2264
|
value={default_min_limit}
|
|
2520
|
-
oninput={(event) =>
|
|
2521
|
-
|
|
2522
|
-
event.currentTarget.value,
|
|
2523
|
-
)
|
|
2524
|
-
}}
|
|
2265
|
+
oninput={(event) =>
|
|
2266
|
+
overrides.set(`default_min_limit`, Number(event.currentTarget.value))}
|
|
2525
2267
|
/>
|
|
2526
2268
|
</label>
|
|
2527
2269
|
</div>
|
|
@@ -2530,16 +2272,12 @@
|
|
|
2530
2272
|
<select
|
|
2531
2273
|
id="chempot-color-mode"
|
|
2532
2274
|
value={color_mode}
|
|
2533
|
-
onchange={(event) =>
|
|
2534
|
-
|
|
2535
|
-
.value as ChemPotColorMode
|
|
2536
|
-
}}
|
|
2275
|
+
onchange={(event) =>
|
|
2276
|
+
overrides.set(`color_mode`, event.currentTarget.value as ChemPotColorMode)}
|
|
2537
2277
|
>
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
<option value="arity">Element count</option>
|
|
2542
|
-
<option value="entries">Entry count</option>
|
|
2278
|
+
{#each CHEMPOT_COLOR_MODE_OPTIONS as [value, label] (value)}
|
|
2279
|
+
<option {value}>{label}</option>
|
|
2280
|
+
{/each}
|
|
2543
2281
|
</select>
|
|
2544
2282
|
</div>
|
|
2545
2283
|
{#if color_mode !== `none` && color_mode !== `arity`}
|
|
@@ -2548,27 +2286,22 @@
|
|
|
2548
2286
|
<select
|
|
2549
2287
|
id="chempot-color-scale"
|
|
2550
2288
|
value={color_scale}
|
|
2551
|
-
onchange={(event) =>
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2289
|
+
onchange={(event) =>
|
|
2290
|
+
overrides.set(
|
|
2291
|
+
`color_scale`,
|
|
2292
|
+
event.currentTarget.value as D3InterpolateName,
|
|
2293
|
+
)}
|
|
2555
2294
|
>
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
<option value="interpolateMagma">Magma</option>
|
|
2560
|
-
<option value="interpolateCividis">Cividis</option>
|
|
2561
|
-
<option value="interpolateTurbo">Turbo</option>
|
|
2562
|
-
<option value="interpolateRdYlBu">RdYlBu</option>
|
|
2563
|
-
<option value="interpolateSpectral">Spectral</option>
|
|
2295
|
+
{#each CHEMPOT_COLOR_SCALE_OPTIONS as [value, label] (value)}
|
|
2296
|
+
<option {value}>{label}</option>
|
|
2297
|
+
{/each}
|
|
2564
2298
|
</select>
|
|
2565
2299
|
<label>
|
|
2566
2300
|
<input
|
|
2567
2301
|
type="checkbox"
|
|
2568
2302
|
checked={reverse_color_scale}
|
|
2569
|
-
onchange={() =>
|
|
2570
|
-
|
|
2571
|
-
}}
|
|
2303
|
+
onchange={() =>
|
|
2304
|
+
overrides.set(`reverse_color_scale`, !reverse_color_scale)}
|
|
2572
2305
|
/> Rev
|
|
2573
2306
|
</label>
|
|
2574
2307
|
</div>
|
|
@@ -2576,13 +2309,9 @@
|
|
|
2576
2309
|
</SettingsSection>
|
|
2577
2310
|
</ScatterPlot3DControls>
|
|
2578
2311
|
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
title="{fullscreen ? `Exit` : `Enter`} fullscreen"
|
|
2583
|
-
>
|
|
2584
|
-
<Icon icon="{fullscreen ? `Exit` : ``}Fullscreen" />
|
|
2585
|
-
</button>
|
|
2312
|
+
{#if fullscreen_toggle}
|
|
2313
|
+
<FullscreenButton {fullscreen} toggle={fullscreen_toggle} {wrapper} />
|
|
2314
|
+
{/if}
|
|
2586
2315
|
</section>
|
|
2587
2316
|
{#if show_temperature_slider && temperature !== undefined}
|
|
2588
2317
|
<TemperatureSlider
|
|
@@ -2963,23 +2692,6 @@
|
|
|
2963
2692
|
gap: 4pt;
|
|
2964
2693
|
font-size: 0.9em;
|
|
2965
2694
|
}
|
|
2966
|
-
.chempot-diagram-3d :global(.export-row) {
|
|
2967
|
-
display: flex;
|
|
2968
|
-
flex-wrap: wrap;
|
|
2969
|
-
gap: 4pt 10pt;
|
|
2970
|
-
margin: 0 0 4pt;
|
|
2971
|
-
}
|
|
2972
|
-
.chempot-diagram-3d :global(.export-row > label) {
|
|
2973
|
-
margin: 0;
|
|
2974
|
-
}
|
|
2975
|
-
.chempot-diagram-3d :global(.export-row button) {
|
|
2976
|
-
width: 1.4em;
|
|
2977
|
-
height: 1.4em;
|
|
2978
|
-
padding: 0;
|
|
2979
|
-
display: inline-flex;
|
|
2980
|
-
align-items: center;
|
|
2981
|
-
justify-content: center;
|
|
2982
|
-
}
|
|
2983
2695
|
.chempot-diagram-3d :global(.chempot-checks) {
|
|
2984
2696
|
display: flex;
|
|
2985
2697
|
flex-wrap: wrap;
|