matterviz 0.3.2 → 0.3.4

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.
Files changed (281) hide show
  1. package/dist/EmptyState.svelte +10 -2
  2. package/dist/FilePicker.svelte +123 -82
  3. package/dist/Icon.svelte +18 -12
  4. package/dist/MillerIndexInput.svelte +27 -21
  5. package/dist/api/optimade.js +6 -6
  6. package/dist/app.css +216 -207
  7. package/dist/brillouin/BrillouinZone.svelte +292 -149
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +69 -42
  11. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte +275 -163
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  15. package/dist/brillouin/BrillouinZoneTooltip.svelte +17 -7
  16. package/dist/brillouin/compute.js +11 -6
  17. package/dist/chempot-diagram/ChemPotDiagram.svelte +162 -27
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +451 -281
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2148 -1642
  20. package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -5
  21. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  22. package/dist/chempot-diagram/async-compute.svelte.js +77 -0
  23. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  24. package/dist/chempot-diagram/chempot-worker.js +11 -0
  25. package/dist/chempot-diagram/color.js +1 -2
  26. package/dist/chempot-diagram/compute.d.ts +10 -0
  27. package/dist/chempot-diagram/compute.js +250 -88
  28. package/dist/chempot-diagram/index.d.ts +2 -1
  29. package/dist/chempot-diagram/index.js +2 -1
  30. package/dist/chempot-diagram/temperature.js +8 -9
  31. package/dist/chempot-diagram/types.d.ts +3 -0
  32. package/dist/chempot-diagram/types.js +1 -0
  33. package/dist/colors/index.d.ts +1 -1
  34. package/dist/colors/index.js +5 -3
  35. package/dist/composition/BarChart.svelte +128 -55
  36. package/dist/composition/BubbleChart.svelte +102 -49
  37. package/dist/composition/Composition.svelte +100 -79
  38. package/dist/composition/Formula.svelte +108 -62
  39. package/dist/composition/FormulaFilter.svelte +665 -537
  40. package/dist/composition/PieChart.svelte +183 -108
  41. package/dist/composition/format.d.ts +5 -0
  42. package/dist/composition/format.js +20 -3
  43. package/dist/composition/parse.js +14 -9
  44. package/dist/convex-hull/ConvexHull.svelte +93 -40
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +549 -360
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +1296 -827
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +1004 -688
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullControls.svelte +115 -28
  53. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
  54. package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
  55. package/dist/convex-hull/ConvexHullStats.svelte +425 -328
  56. package/dist/convex-hull/ConvexHullTooltip.svelte +40 -16
  57. package/dist/convex-hull/GasPressureControls.svelte +104 -61
  58. package/dist/convex-hull/StructurePopup.svelte +25 -4
  59. package/dist/convex-hull/TemperatureSlider.svelte +45 -25
  60. package/dist/convex-hull/barycentric-coords.js +13 -7
  61. package/dist/convex-hull/demo-temperature.js +8 -4
  62. package/dist/convex-hull/gas-thermodynamics.js +17 -12
  63. package/dist/convex-hull/helpers.d.ts +9 -0
  64. package/dist/convex-hull/helpers.js +77 -34
  65. package/dist/convex-hull/thermodynamics.js +61 -56
  66. package/dist/convex-hull/types.d.ts +9 -14
  67. package/dist/convex-hull/types.js +0 -17
  68. package/dist/coordination/CoordinationBarPlot.svelte +227 -154
  69. package/dist/element/BohrAtom.svelte +55 -12
  70. package/dist/element/ElementHeading.svelte +7 -2
  71. package/dist/element/ElementPhoto.svelte +15 -9
  72. package/dist/element/ElementStats.svelte +10 -4
  73. package/dist/element/ElementTile.svelte +137 -73
  74. package/dist/element/Nucleus.svelte +39 -11
  75. package/dist/element/data.js +1 -1
  76. package/dist/feedback/ClickFeedback.svelte +16 -5
  77. package/dist/feedback/DragOverlay.svelte +10 -2
  78. package/dist/feedback/Spinner.svelte +4 -2
  79. package/dist/feedback/StatusMessage.svelte +8 -2
  80. package/dist/fermi-surface/FermiSlice.svelte +118 -88
  81. package/dist/fermi-surface/FermiSurface.svelte +328 -187
  82. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  83. package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
  84. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  85. package/dist/fermi-surface/FermiSurfaceScene.svelte +535 -342
  86. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  87. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
  88. package/dist/fermi-surface/compute.js +16 -20
  89. package/dist/fermi-surface/parse.js +24 -14
  90. package/dist/fermi-surface/symmetry.js +2 -7
  91. package/dist/fermi-surface/types.d.ts +3 -5
  92. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1019 -765
  93. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +1 -1
  94. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +76 -22
  95. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +2 -3
  96. package/dist/icons.js +47 -0
  97. package/dist/index.d.ts +2 -1
  98. package/dist/index.js +2 -1
  99. package/dist/io/decompress.js +1 -1
  100. package/dist/io/export.d.ts +3 -0
  101. package/dist/io/export.js +129 -143
  102. package/dist/io/is-binary.js +2 -3
  103. package/dist/io/url-drop.js +1 -2
  104. package/dist/isosurface/Isosurface.svelte +202 -148
  105. package/dist/isosurface/IsosurfaceControls.svelte +46 -28
  106. package/dist/isosurface/parse.js +34 -29
  107. package/dist/isosurface/slice.js +5 -10
  108. package/dist/isosurface/types.d.ts +2 -1
  109. package/dist/isosurface/types.js +61 -12
  110. package/dist/labels.js +11 -8
  111. package/dist/layout/FullscreenToggle.svelte +11 -2
  112. package/dist/layout/InfoCard.svelte +38 -6
  113. package/dist/layout/InfoTag.svelte +63 -32
  114. package/dist/layout/PropertyFilter.svelte +82 -37
  115. package/dist/layout/SettingsSection.svelte +85 -55
  116. package/dist/layout/SubpageGrid.svelte +10 -2
  117. package/dist/layout/json-tree/JsonNode.svelte +183 -138
  118. package/dist/layout/json-tree/JsonTree.svelte +499 -413
  119. package/dist/layout/json-tree/JsonValue.svelte +127 -99
  120. package/dist/layout/json-tree/utils.js +4 -2
  121. package/dist/marching-cubes.js +25 -2
  122. package/dist/math.d.ts +13 -17
  123. package/dist/math.js +133 -67
  124. package/dist/overlays/ContextMenu.svelte +65 -40
  125. package/dist/overlays/DraggablePane.svelte +211 -139
  126. package/dist/periodic-table/PeriodicTable.svelte +278 -145
  127. package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
  128. package/dist/periodic-table/PropertySelect.svelte +25 -7
  129. package/dist/periodic-table/TableInset.svelte +8 -3
  130. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +446 -309
  131. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  132. package/dist/phase-diagram/PhaseDiagramControls.svelte +102 -43
  133. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  134. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +63 -40
  135. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +71 -28
  136. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +1 -1
  137. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +158 -101
  138. package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
  139. package/dist/phase-diagram/build-diagram.js +9 -9
  140. package/dist/phase-diagram/colors.js +1 -3
  141. package/dist/phase-diagram/parse.js +10 -9
  142. package/dist/phase-diagram/svg-to-diagram.js +53 -49
  143. package/dist/phase-diagram/utils.d.ts +1 -0
  144. package/dist/phase-diagram/utils.js +80 -25
  145. package/dist/plot/AxisLabel.svelte +28 -3
  146. package/dist/plot/BarPlot.svelte +1182 -734
  147. package/dist/plot/BarPlot.svelte.d.ts +2 -2
  148. package/dist/plot/BarPlotControls.svelte +31 -5
  149. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  150. package/dist/plot/ColorBar.svelte +479 -329
  151. package/dist/plot/ColorScaleSelect.svelte +27 -6
  152. package/dist/plot/ElementScatter.svelte +36 -15
  153. package/dist/plot/FillArea.svelte +152 -95
  154. package/dist/plot/Histogram.svelte +934 -571
  155. package/dist/plot/Histogram.svelte.d.ts +1 -1
  156. package/dist/plot/HistogramControls.svelte +53 -9
  157. package/dist/plot/HistogramControls.svelte.d.ts +1 -1
  158. package/dist/plot/InteractiveAxisLabel.svelte +34 -11
  159. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
  160. package/dist/plot/Line.svelte +63 -28
  161. package/dist/plot/PlotControls.svelte +157 -114
  162. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  163. package/dist/plot/PlotLegend.svelte +174 -91
  164. package/dist/plot/PlotTooltip.svelte +45 -6
  165. package/dist/plot/PortalSelect.svelte +175 -147
  166. package/dist/plot/ReferenceLine.svelte +76 -22
  167. package/dist/plot/ReferenceLine3D.svelte +132 -107
  168. package/dist/plot/ReferencePlane.svelte +146 -121
  169. package/dist/plot/ScatterPlot.svelte +1681 -1091
  170. package/dist/plot/ScatterPlot.svelte.d.ts +2 -2
  171. package/dist/plot/ScatterPlot3D.svelte +256 -131
  172. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  173. package/dist/plot/ScatterPlot3DControls.svelte +113 -63
  174. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
  175. package/dist/plot/ScatterPlot3DScene.svelte +608 -403
  176. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  177. package/dist/plot/ScatterPlotControls.svelte +65 -25
  178. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  179. package/dist/plot/ScatterPoint.svelte +98 -26
  180. package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
  181. package/dist/plot/SpacegroupBarPlot.svelte +142 -85
  182. package/dist/plot/Surface3D.svelte +159 -108
  183. package/dist/plot/ZeroLines.svelte +55 -3
  184. package/dist/plot/ZoomRect.svelte +4 -2
  185. package/dist/plot/axis-utils.js +1 -3
  186. package/dist/plot/data-cleaning.js +12 -28
  187. package/dist/plot/data-transform.js +2 -1
  188. package/dist/plot/fill-utils.js +2 -0
  189. package/dist/plot/layout.d.ts +4 -1
  190. package/dist/plot/layout.js +33 -14
  191. package/dist/plot/reference-line.d.ts +2 -2
  192. package/dist/plot/reference-line.js +7 -5
  193. package/dist/plot/scales.js +24 -36
  194. package/dist/plot/types.d.ts +11 -23
  195. package/dist/plot/types.js +6 -11
  196. package/dist/plot/utils/label-placement.d.ts +32 -15
  197. package/dist/plot/utils/label-placement.js +227 -66
  198. package/dist/plot/utils/series-visibility.js +2 -3
  199. package/dist/rdf/RdfPlot.svelte +143 -91
  200. package/dist/rdf/calc-rdf.js +4 -5
  201. package/dist/sanitize.d.ts +4 -0
  202. package/dist/sanitize.js +107 -0
  203. package/dist/settings.d.ts +18 -6
  204. package/dist/settings.js +46 -16
  205. package/dist/spectral/Bands.svelte +632 -453
  206. package/dist/spectral/BandsAndDos.svelte +90 -49
  207. package/dist/spectral/BrillouinBandsDos.svelte +151 -93
  208. package/dist/spectral/Dos.svelte +389 -258
  209. package/dist/spectral/helpers.js +55 -43
  210. package/dist/state.svelte.d.ts +1 -1
  211. package/dist/state.svelte.js +3 -2
  212. package/dist/structure/Arrow.svelte +59 -20
  213. package/dist/structure/AtomLegend.svelte +215 -134
  214. package/dist/structure/Bond.svelte +73 -47
  215. package/dist/structure/CanvasTooltip.svelte +10 -2
  216. package/dist/structure/CellSelect.svelte +72 -45
  217. package/dist/structure/Cylinder.svelte +33 -17
  218. package/dist/structure/Lattice.svelte +88 -33
  219. package/dist/structure/Structure.svelte +1063 -797
  220. package/dist/structure/Structure.svelte.d.ts +1 -1
  221. package/dist/structure/StructureControls.svelte +349 -118
  222. package/dist/structure/StructureExportPane.svelte +124 -89
  223. package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
  224. package/dist/structure/StructureInfoPane.svelte +304 -237
  225. package/dist/structure/StructureScene.svelte +879 -443
  226. package/dist/structure/StructureScene.svelte.d.ts +15 -7
  227. package/dist/structure/atom-properties.js +8 -8
  228. package/dist/structure/bonding.js +6 -7
  229. package/dist/structure/export.js +14 -29
  230. package/dist/structure/ferrox-wasm.js +1 -1
  231. package/dist/structure/index.d.ts +13 -3
  232. package/dist/structure/index.js +83 -23
  233. package/dist/structure/measure.d.ts +2 -2
  234. package/dist/structure/measure.js +4 -44
  235. package/dist/structure/parse.js +113 -141
  236. package/dist/structure/partial-occupancy.js +7 -10
  237. package/dist/structure/pbc.d.ts +1 -0
  238. package/dist/structure/pbc.js +16 -6
  239. package/dist/structure/supercell.d.ts +2 -2
  240. package/dist/structure/supercell.js +12 -22
  241. package/dist/structure/validation.js +1 -2
  242. package/dist/symmetry/SymmetryStats.svelte +84 -41
  243. package/dist/symmetry/WyckoffTable.svelte +26 -6
  244. package/dist/symmetry/cell-transform.js +5 -3
  245. package/dist/symmetry/index.js +8 -7
  246. package/dist/symmetry/spacegroups.js +148 -148
  247. package/dist/table/HeatmapTable.svelte +790 -554
  248. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  249. package/dist/table/ToggleMenu.svelte +125 -92
  250. package/dist/table/index.js +2 -4
  251. package/dist/theme/ThemeControl.svelte +21 -12
  252. package/dist/time.js +4 -1
  253. package/dist/tooltip/TooltipContent.svelte +33 -8
  254. package/dist/trajectory/Trajectory.svelte +758 -558
  255. package/dist/trajectory/TrajectoryError.svelte +14 -3
  256. package/dist/trajectory/TrajectoryExportPane.svelte +137 -83
  257. package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
  258. package/dist/trajectory/extract.js +10 -26
  259. package/dist/trajectory/format-detect.js +5 -5
  260. package/dist/trajectory/frame-reader.d.ts +1 -1
  261. package/dist/trajectory/frame-reader.js +5 -12
  262. package/dist/trajectory/helpers.d.ts +0 -1
  263. package/dist/trajectory/helpers.js +2 -17
  264. package/dist/trajectory/index.js +14 -12
  265. package/dist/trajectory/parse/ase.js +5 -4
  266. package/dist/trajectory/parse/hdf5.js +26 -18
  267. package/dist/trajectory/parse/index.js +13 -18
  268. package/dist/trajectory/parse/lammps.js +17 -7
  269. package/dist/trajectory/parse/vasp.js +5 -2
  270. package/dist/trajectory/parse/xyz.js +8 -7
  271. package/dist/trajectory/plotting.js +13 -8
  272. package/dist/utils.d.ts +1 -0
  273. package/dist/utils.js +13 -0
  274. package/dist/xrd/XrdPlot.svelte +337 -247
  275. package/dist/xrd/broadening.js +14 -9
  276. package/dist/xrd/calc-xrd.js +12 -18
  277. package/dist/xrd/parse.d.ts +1 -1
  278. package/dist/xrd/parse.js +17 -17
  279. package/package.json +99 -103
  280. package/readme.md +1 -1
  281. /package/dist/theme/{themes.js → themes.mjs} +0 -0
@@ -78,6 +78,6 @@ type $$ComponentProps = {
78
78
  on_camera_move?: EventHandler;
79
79
  on_camera_reset?: EventHandler;
80
80
  } & Omit<ComponentProps<typeof StructureControls>, `children` | `onclose`> & Omit<HTMLAttributes<HTMLDivElement>, `children`>;
81
- declare const Structure: import("svelte").Component<$$ComponentProps, {}, "structure" | "height" | "width" | "dragover" | "controls_open" | "loading" | "fullscreen" | "hovered" | "color_scheme" | "background_color" | "background_opacity" | "show_image_atoms" | "info_pane_open" | "wrapper" | "sym_data" | "error_msg" | "atom_color_config" | "hidden_elements" | "hidden_prop_vals" | "element_mapping" | "element_radius_overrides" | "site_radius_overrides" | "selected_sites" | "supercell_scaling" | "cell_type" | "active_volume_idx" | "measured_sites" | "scene_props" | "lattice_props" | "volumetric_data" | "isosurface_settings" | "png_dpi" | "measure_mode" | "enable_measure_mode" | "performance_mode" | "displayed_structure" | "symmetry_settings">;
81
+ declare const Structure: import("svelte").Component<$$ComponentProps, {}, "structure" | "height" | "width" | "dragover" | "fullscreen" | "hovered" | "controls_open" | "loading" | "color_scheme" | "background_color" | "background_opacity" | "show_image_atoms" | "info_pane_open" | "wrapper" | "sym_data" | "png_dpi" | "error_msg" | "atom_color_config" | "hidden_elements" | "hidden_prop_vals" | "element_mapping" | "element_radius_overrides" | "site_radius_overrides" | "selected_sites" | "supercell_scaling" | "cell_type" | "active_volume_idx" | "measured_sites" | "scene_props" | "lattice_props" | "volumetric_data" | "isosurface_settings" | "measure_mode" | "enable_measure_mode" | "performance_mode" | "displayed_structure" | "symmetry_settings">;
82
82
  type Structure = ReturnType<typeof Structure>;
83
83
  export default Structure;
@@ -1,104 +1,199 @@
1
- <script lang="ts">import { AXIS_COLORS, ELEMENT_COLOR_SCHEMES } from '../colors';
2
- import IsosurfaceControls from '../isosurface/IsosurfaceControls.svelte';
3
- import { format_num } from '../labels';
4
- import { SettingsSection } from '../layout';
5
- import { to_degrees, to_radians } from '../math';
6
- import DraggablePane from '../overlays/DraggablePane.svelte';
7
- import { ColorScaleSelect } from '../plot';
8
- import { DEFAULTS, SETTINGS_CONFIG } from '../settings';
9
- import { Lattice, StructureScene } from './';
10
- import { is_valid_supercell_input } from './supercell';
11
- import Select from 'svelte-multiselect';
12
- import { tooltip } from 'svelte-multiselect/attachments';
13
- let { controls_open = $bindable(false), scene_props = $bindable({}), lattice_props = $bindable({
14
- show_cell_vectors: DEFAULTS.structure.show_cell_vectors,
15
- cell_edge_color: DEFAULTS.structure.cell_edge_color,
16
- cell_edge_opacity: DEFAULTS.structure.cell_edge_opacity,
17
- cell_surface_color: DEFAULTS.structure.cell_surface_color,
18
- cell_surface_opacity: DEFAULTS.structure.cell_surface_opacity,
19
- cell_edge_width: DEFAULTS.structure.cell_edge_width,
20
- }), show_image_atoms = $bindable(DEFAULTS.structure.show_image_atoms), supercell_scaling = $bindable(`1x1x1`), background_color = $bindable(), background_opacity = $bindable(DEFAULTS.background_opacity), color_scheme = $bindable(DEFAULTS.color_scheme), atom_color_config = $bindable({
21
- mode: DEFAULTS.structure.atom_color_mode,
22
- scale: DEFAULTS.structure.atom_color_scale,
23
- scale_type: DEFAULTS.structure.atom_color_scale_type,
24
- }), structure = undefined, supercell_loading = $bindable(false), sym_data = null, cell_type = $bindable(`original`), volumetric_data = $bindable(), isosurface_settings = $bindable(), active_volume_idx = $bindable(0), pane_props = {}, toggle_props = {}, ...rest } = $props();
25
- // Color scheme selection state
26
- let color_scheme_selected = $state([color_scheme]);
27
- $effect(() => {
1
+ <script lang="ts">
2
+ import type { ColorSchemeName, D3InterpolateName } from '../colors'
3
+ import { AXIS_COLORS, ELEMENT_COLOR_SCHEMES } from '../colors'
4
+ import IsosurfaceControls from '../isosurface/IsosurfaceControls.svelte'
5
+ import type { IsosurfaceSettings, VolumetricData } from '../isosurface/types'
6
+ import { format_num } from '../labels'
7
+ import { SettingsSection } from '../layout'
8
+ import { to_degrees, to_radians } from '../math'
9
+ import DraggablePane from '../overlays/DraggablePane.svelte'
10
+ import { ColorScaleSelect } from '../plot'
11
+ import type { VectorLayerConfig } from '../settings'
12
+ import { DEFAULTS, SETTINGS_CONFIG, VECTOR_COLOR_MODES } from '../settings'
13
+ import type { AnyStructure } from './'
14
+ import {
15
+ default_vector_configs,
16
+ get_structure_vector_keys,
17
+ Lattice,
18
+ StructureScene,
19
+ VECTOR_PALETTE,
20
+ } from './'
21
+ import type { AtomColorConfig } from './atom-properties'
22
+ import { is_valid_supercell_input } from './supercell'
23
+ import type { CellType } from '../symmetry'
24
+ import type { MoyoDataset } from '@spglib/moyo-wasm'
25
+ import type { ComponentProps } from 'svelte'
26
+ import Select from 'svelte-multiselect'
27
+ import { tooltip } from 'svelte-multiselect/attachments'
28
+
29
+ let {
30
+ controls_open = $bindable(false),
31
+ scene_props = $bindable({}),
32
+ lattice_props = $bindable({
33
+ show_cell_vectors: DEFAULTS.structure.show_cell_vectors,
34
+ cell_edge_color: DEFAULTS.structure.cell_edge_color,
35
+ cell_edge_opacity: DEFAULTS.structure.cell_edge_opacity,
36
+ cell_surface_color: DEFAULTS.structure.cell_surface_color,
37
+ cell_surface_opacity: DEFAULTS.structure.cell_surface_opacity,
38
+ cell_edge_width: DEFAULTS.structure.cell_edge_width,
39
+ }),
40
+ show_image_atoms = $bindable(DEFAULTS.structure.show_image_atoms),
41
+ supercell_scaling = $bindable(`1x1x1`),
42
+ background_color = $bindable(),
43
+ background_opacity = $bindable(DEFAULTS.background_opacity),
44
+ color_scheme = $bindable(DEFAULTS.color_scheme),
45
+ atom_color_config = $bindable({
46
+ mode: DEFAULTS.structure.atom_color_mode,
47
+ scale: DEFAULTS.structure.atom_color_scale,
48
+ scale_type: DEFAULTS.structure.atom_color_scale_type,
49
+ }),
50
+ structure = undefined,
51
+ supercell_loading = $bindable(false),
52
+ sym_data = null,
53
+ cell_type = $bindable(`original`),
54
+ volumetric_data = $bindable<VolumetricData[]>(),
55
+ isosurface_settings = $bindable<IsosurfaceSettings>(),
56
+ active_volume_idx = $bindable(0),
57
+ pane_props = {},
58
+ toggle_props = {},
59
+ ...rest
60
+ }: Omit<ComponentProps<typeof DraggablePane>, `children`> & {
61
+ controls_open?: boolean // Control pane state
62
+ scene_props?: ComponentProps<typeof StructureScene>
63
+ lattice_props?: ComponentProps<typeof Lattice>
64
+ show_image_atoms?: boolean
65
+ supercell_scaling?: string
66
+ background_color?: string
67
+ background_opacity?: number
68
+ color_scheme?: string
69
+ atom_color_config?: Partial<AtomColorConfig>
70
+ structure?: AnyStructure
71
+ supercell_loading?: boolean
72
+ sym_data?: MoyoDataset | null
73
+ cell_type?: CellType // Cell type: original, conventional, or primitive
74
+ volumetric_data?: VolumetricData[] // Volumetric data volumes for isosurface controls
75
+ isosurface_settings?: IsosurfaceSettings // Isosurface rendering settings
76
+ active_volume_idx?: number // Active volume index
77
+ pane_props?: ComponentProps<typeof DraggablePane>[`pane_props`]
78
+ toggle_props?: ComponentProps<typeof DraggablePane>[`toggle_props`]
79
+ } = $props()
80
+
81
+ // Color scheme selection state
82
+ let color_scheme_selected = $state([color_scheme])
83
+ $effect(() => {
28
84
  if (color_scheme_selected.length > 0) {
29
- color_scheme = color_scheme_selected[0];
85
+ color_scheme = color_scheme_selected[0] as string
30
86
  }
31
- });
32
- // Atom color config selection state
33
- let color_scale_selected = $state([
87
+ })
88
+
89
+ // Atom color config selection state
90
+ let color_scale_selected = $state<D3InterpolateName[]>([
34
91
  atom_color_config.scale || DEFAULTS.structure.atom_color_scale,
35
- ]);
36
- // Sync local selection to config
37
- $effect(() => {
38
- if (color_scale_selected[0] && color_scale_selected[0] !== atom_color_config.scale)
39
- atom_color_config.scale = color_scale_selected[0];
40
- });
41
- // Sync config to local selection (for external updates)
42
- $effect(() => {
43
- if (atom_color_config.scale && atom_color_config.scale !== color_scale_selected[0])
44
- color_scale_selected = [atom_color_config.scale];
45
- });
46
- // Auto-set scale_type based on mode
47
- $effect(() => {
92
+ ])
93
+
94
+ // Sync local selection to config
95
+ $effect(() => {
96
+ if (
97
+ color_scale_selected[0] && color_scale_selected[0] !== atom_color_config.scale
98
+ ) atom_color_config.scale = color_scale_selected[0]
99
+ })
100
+ // Sync config to local selection (for external updates)
101
+ $effect(() => {
102
+ if (
103
+ atom_color_config.scale && atom_color_config.scale !== color_scale_selected[0]
104
+ ) color_scale_selected = [atom_color_config.scale]
105
+ })
106
+ // Auto-set scale_type based on mode
107
+ $effect(() => {
48
108
  if (atom_color_config.mode === `wyckoff`) {
49
- atom_color_config.scale_type = `categorical`;
50
- }
51
- else if (atom_color_config.mode === `coordination`) {
52
- atom_color_config.scale_type = `continuous`;
109
+ atom_color_config.scale_type = `categorical`
110
+ } else if (atom_color_config.mode === `coordination`) {
111
+ atom_color_config.scale_type = `continuous`
53
112
  }
54
- });
55
- // Atom label color management
56
- let site_label_hex_color = $state(scene_props.site_label_color || DEFAULTS.structure.site_label_color);
57
- let site_label_bg_hex_color = $state(scene_props.site_label_bg_color || DEFAULTS.structure.site_label_bg_color);
58
- let site_label_background_opacity = $state(0);
59
- $effect(() => {
60
- scene_props.site_label_color = site_label_hex_color;
113
+ })
114
+
115
+ // Atom label color management
116
+ let site_label_hex_color = $state(
117
+ scene_props.site_label_color || DEFAULTS.structure.site_label_color,
118
+ )
119
+ let site_label_bg_hex_color = $state(
120
+ scene_props.site_label_bg_color || DEFAULTS.structure.site_label_bg_color,
121
+ )
122
+ let site_label_background_opacity = $state(0)
123
+
124
+ $effect(() => {
125
+ scene_props.site_label_color = site_label_hex_color
61
126
  scene_props.site_label_bg_color =
62
- `color-mix(in srgb, ${site_label_bg_hex_color} ${format_num(site_label_background_opacity, `.1~%`)}, transparent)`;
63
- });
64
- // Ensure site_label_offset is always available
65
- scene_props.site_label_offset ??= [...DEFAULTS.structure.site_label_offset];
66
- // Detect if structure has force data
67
- let has_forces = $derived(structure?.sites?.some((site) => site.properties?.force && Array.isArray(site.properties.force)) ?? false);
68
- // Detect if structure has lattice (can create supercells)
69
- let has_lattice = $derived(structure && `lattice` in structure && structure.lattice !== undefined);
70
- // Validate supercell input
71
- let supercell_input_valid = $derived(is_valid_supercell_input(supercell_scaling));
72
- // Ensure rotation is always an array
73
- $effect(() => {
74
- scene_props.rotation ??= [...DEFAULTS.structure.rotation];
75
- });
76
- let rotation_degrees = $derived(scene_props.rotation?.map((rad) => {
77
- const deg = to_degrees(rad);
78
- // Convert to [0, 360] range for UI display
79
- return ((deg % 360) + 360) % 360;
80
- }) ?? [0, 0, 0]);
81
- function update_rotation(axis, degrees) {
82
- scene_props.rotation ??= [0, 0, 0];
83
- const axis_index = { x: 0, y: 1, z: 2 }[axis];
84
- const clamped = Math.max(0, Math.min(360, degrees));
85
- const norm = ((clamped % 360) + 360) % 360;
86
- scene_props.rotation[axis_index] = to_radians(norm);
127
+ `color-mix(in srgb, ${site_label_bg_hex_color} ${
128
+ format_num(site_label_background_opacity, `.1~%`)
129
+ }, transparent)`
130
+ })
131
+
132
+ // Ensure site_label_offset is always available
133
+ scene_props.site_label_offset ??= [...DEFAULTS.structure.site_label_offset]
134
+
135
+ // Collect available vector property keys from the structure
136
+ let available_vector_keys = $derived(
137
+ structure ? get_structure_vector_keys(structure) : [],
138
+ )
139
+ function is_key_visible(key: string): boolean {
140
+ return scene_props.vector_configs?.[key]?.visible !== false
141
+ }
142
+
143
+ let any_vectors_visible = $derived(available_vector_keys.some(is_key_visible))
144
+
145
+ function update_vector_config(key: string, patch: Partial<VectorLayerConfig>) {
146
+ const configs = { ...scene_props.vector_configs }
147
+ configs[key] = {
148
+ ...(configs[key] ?? { visible: true, color: null, scale: null }),
149
+ ...patch,
150
+ }
151
+ scene_props.vector_configs = configs
152
+ }
153
+
154
+ // Detect if structure has lattice (can create supercells)
155
+ let has_lattice = $derived(
156
+ structure && `lattice` in structure && structure.lattice !== undefined,
157
+ )
158
+
159
+ // Validate supercell input
160
+ let supercell_input_valid = $derived(is_valid_supercell_input(supercell_scaling))
161
+
162
+ // Ensure rotation is always an array
163
+ $effect(() => {
164
+ scene_props.rotation ??= [...DEFAULTS.structure.rotation]
165
+ })
166
+
167
+ let rotation_degrees = $derived(
168
+ scene_props.rotation?.map((rad) => {
169
+ const deg = to_degrees(rad)
170
+ // Convert to [0, 360] range for UI display
171
+ return ((deg % 360) + 360) % 360
172
+ }) ?? [0, 0, 0],
173
+ )
174
+
175
+ function update_rotation(axis: `x` | `y` | `z`, degrees: number) {
176
+ scene_props.rotation ??= [0, 0, 0]
177
+ const axis_index = { x: 0, y: 1, z: 2 }[axis]
178
+ const clamped = Math.max(0, Math.min(360, degrees))
179
+ const norm = ((clamped % 360) + 360) % 360
180
+ scene_props.rotation[axis_index] = to_radians(norm)
87
181
  // Trigger reactivity by creating new array
88
- scene_props.rotation = [...scene_props.rotation];
89
- }
90
- // Helper function to get example set of colors from an element color scheme
91
- function get_representative_colors(scheme_name) {
92
- const scheme = ELEMENT_COLOR_SCHEMES[scheme_name];
93
- if (!scheme)
94
- return [];
182
+ scene_props.rotation = [...scene_props.rotation]
183
+ }
184
+
185
+ // Helper function to get example set of colors from an element color scheme
186
+ function get_representative_colors(scheme_name: string): string[] {
187
+ const scheme = ELEMENT_COLOR_SCHEMES[scheme_name as ColorSchemeName]
188
+ if (!scheme) return []
189
+
95
190
  // Get colors for common elements: H, C, N, O, Fe, Ca, Si, Al
96
- const sample_elements = [`H`, `C`, `N`, `O`, `Fe`, `Ca`, `Si`, `Al`];
191
+ const sample_elements = [`H`, `C`, `N`, `O`, `Fe`, `Ca`, `Si`, `Al`]
97
192
  return sample_elements
98
- .slice(0, 4) // Take first 4
99
- .map((el) => scheme[el] || scheme.H || `#cccccc`)
100
- .filter(Boolean);
101
- }
193
+ .slice(0, 4) // Take first 4
194
+ .map((el) => scheme[el] || scheme.H || `#cccccc`)
195
+ .filter(Boolean)
196
+ }
102
197
  </script>
103
198
 
104
199
  <DraggablePane
@@ -132,7 +227,7 @@ function get_representative_colors(scheme_name) {
132
227
  show_image_atoms,
133
228
  show_site_labels: scene_props.show_site_labels,
134
229
  show_site_indices: scene_props.show_site_indices,
135
- show_force_vectors: scene_props.show_force_vectors,
230
+ vector_configs: scene_props.vector_configs,
136
231
  show_cell_vectors: lattice_props.show_cell_vectors,
137
232
  }}
138
233
  on_reset={() => {
@@ -140,7 +235,7 @@ function get_representative_colors(scheme_name) {
140
235
  scene_props.show_bonds = DEFAULTS.structure.show_bonds
141
236
  scene_props.show_site_labels = DEFAULTS.structure.show_site_labels
142
237
  scene_props.show_site_indices = DEFAULTS.structure.show_site_indices
143
- scene_props.show_force_vectors = DEFAULTS.structure.show_force_vectors
238
+ scene_props.vector_configs = default_vector_configs(available_vector_keys)
144
239
  show_image_atoms = DEFAULTS.structure.show_image_atoms
145
240
  lattice_props.show_cell_vectors = DEFAULTS.structure.show_cell_vectors
146
241
  }}
@@ -180,16 +275,43 @@ function get_representative_colors(scheme_name) {
180
275
  <input type="checkbox" bind:checked={scene_props.show_site_indices} />
181
276
  Site Indices
182
277
  </label>
183
- {#if has_forces}
184
- <label
185
- {@attach tooltip({
186
- content: SETTINGS_CONFIG.structure.show_force_vectors.description,
187
- })}
188
- style="gap: 6pt"
189
- >
190
- <input type="checkbox" bind:checked={scene_props.show_force_vectors} />
191
- Force Vectors
192
- </label>
278
+ {#if available_vector_keys.length > 0}
279
+ {#each available_vector_keys as key, idx (key)}
280
+ <label
281
+ {@attach tooltip({
282
+ content: `Toggle ${key} vectors`,
283
+ })}
284
+ style="gap: 4pt"
285
+ >
286
+ <input
287
+ type="checkbox"
288
+ checked={is_key_visible(key)}
289
+ onchange={() => update_vector_config(key, { visible: !is_key_visible(key) })}
290
+ />
291
+ <input
292
+ type="color"
293
+ aria-label={`${key} vector color`}
294
+ value={scene_props.vector_configs?.[key]?.color ??
295
+ VECTOR_PALETTE[idx % VECTOR_PALETTE.length]}
296
+ onchange={(evt) =>
297
+ update_vector_config(key, {
298
+ color: (evt.target as HTMLInputElement).value,
299
+ })}
300
+ style="width: 22px; height: 22px; padding: 0; border: none; cursor: pointer"
301
+ />
302
+ {key}
303
+ {#if scene_props.vector_configs?.[key]?.color != null}
304
+ <button
305
+ type="button"
306
+ aria-label={`Reset ${key} color to default`}
307
+ onclick={() => update_vector_config(key, { color: null })}
308
+ style="padding: 0 3pt; font-size: 0.8em; line-height: 1; cursor: pointer"
309
+ >
310
+ ×
311
+ </button>
312
+ {/if}
313
+ </label>
314
+ {/each}
193
315
  {/if}
194
316
  <label style="gap: 6pt">
195
317
  <input type="checkbox" bind:checked={lattice_props.show_cell_vectors} />
@@ -473,7 +595,7 @@ function get_representative_colors(scheme_name) {
473
595
  {@attach tooltip({ content: SETTINGS_CONFIG.structure.atom_color_mode.description })}
474
596
  >
475
597
  Atom coloring
476
- <select bind:value={atom_color_config.mode} style="font-size: 0.95em">
598
+ <select bind:value={atom_color_config.mode}>
477
599
  {#each Object.entries(SETTINGS_CONFIG.structure.atom_color_mode.enum || {}) as
478
600
  [value, label]
479
601
  (value)
@@ -493,7 +615,6 @@ function get_representative_colors(scheme_name) {
493
615
  colorbar={{
494
616
  tick_labels: 0,
495
617
  wrapper_style: `width: 100%;`,
496
- title_style: `font-size: 0.95em;`,
497
618
  }}
498
619
  style="flex: 1; min-width: 0; border: none"
499
620
  aria-label="Color scale"
@@ -598,39 +719,149 @@ function get_representative_colors(scheme_name) {
598
719
  </SettingsSection>
599
720
  {/if}
600
721
 
601
- {#if has_forces && scene_props.show_force_vectors}
722
+ {#if available_vector_keys.length > 0 && any_vectors_visible}
602
723
  <SettingsSection
603
- title="Force Vectors"
724
+ title="Site Vectors"
604
725
  current_values={{
605
- force_scale: scene_props.force_scale,
606
- force_color: scene_props.force_color,
726
+ vector_scale: scene_props.vector_scale,
727
+ vector_color: scene_props.vector_color,
728
+ vector_normalize: scene_props.vector_normalize,
729
+ vector_uniform_thickness: scene_props.vector_uniform_thickness,
730
+ vector_color_mode: scene_props.vector_color_mode,
731
+ vector_color_scale: scene_props.vector_color_scale,
732
+ vector_origin_gap: scene_props.vector_origin_gap,
607
733
  }}
608
734
  on_reset={() => {
609
- scene_props.force_scale = DEFAULTS.structure.force_scale
610
- scene_props.force_color = DEFAULTS.structure.force_color
735
+ scene_props.vector_scale = DEFAULTS.structure.vector_scale
736
+ scene_props.vector_color = DEFAULTS.structure.vector_color
737
+ scene_props.vector_color_mode = DEFAULTS.structure.vector_color_mode
738
+ scene_props.vector_color_scale = DEFAULTS.structure.vector_color_scale
739
+ scene_props.vector_normalize = DEFAULTS.structure.vector_normalize
740
+ scene_props.vector_uniform_thickness =
741
+ DEFAULTS.structure.vector_uniform_thickness
742
+ scene_props.vector_origin_gap = DEFAULTS.structure.vector_origin_gap
743
+ for (const key of available_vector_keys) {
744
+ update_vector_config(key, { scale: null })
745
+ }
611
746
  }}
612
747
  >
613
748
  <label>
614
- Scale
749
+ Global Scale
615
750
  <input
616
751
  type="number"
617
752
  min={0.001}
618
753
  max={5}
619
754
  step={0.001}
620
- bind:value={scene_props.force_scale}
755
+ bind:value={scene_props.vector_scale}
621
756
  />
622
757
  <input
623
758
  type="range"
624
759
  min={0.001}
625
760
  max={5}
626
761
  step={0.001}
627
- bind:value={scene_props.force_scale}
762
+ bind:value={scene_props.vector_scale}
628
763
  />
629
764
  </label>
630
- <label>
631
- Color
632
- <input type="color" bind:value={scene_props.force_color} />
765
+ <label
766
+ {@attach tooltip({
767
+ content: SETTINGS_CONFIG.structure.vector_normalize.description,
768
+ })}
769
+ style="gap: 6pt"
770
+ >
771
+ <input type="checkbox" bind:checked={scene_props.vector_normalize} />
772
+ Normalize
773
+ </label>
774
+ <label
775
+ {@attach tooltip({
776
+ content: SETTINGS_CONFIG.structure.vector_uniform_thickness.description,
777
+ })}
778
+ style="gap: 6pt"
779
+ >
780
+ <input type="checkbox" bind:checked={scene_props.vector_uniform_thickness} />
781
+ Uniform Thickness
633
782
  </label>
783
+ <label
784
+ {@attach tooltip({
785
+ content: SETTINGS_CONFIG.structure.vector_color_mode.description,
786
+ })}
787
+ >
788
+ Color Mode
789
+ <select bind:value={scene_props.vector_color_mode}>
790
+ {#each VECTOR_COLOR_MODES as mode (mode)}
791
+ <option value={mode}>{mode.replaceAll(`_`, ` `)}</option>
792
+ {/each}
793
+ </select>
794
+ </label>
795
+ {#if scene_props.vector_color_mode === `magnitude`}
796
+ <label>
797
+ Scale
798
+ <ColorScaleSelect
799
+ bind:value={scene_props.vector_color_scale}
800
+ style="max-width: 180px"
801
+ />
802
+ </label>
803
+ {/if}
804
+ {#if scene_props.vector_color_mode === `uniform`}
805
+ <label>
806
+ Color
807
+ <input type="color" bind:value={scene_props.vector_color} />
808
+ </label>
809
+ {/if}
810
+ {#if available_vector_keys.length > 1}
811
+ <label
812
+ {@attach tooltip({
813
+ content: SETTINGS_CONFIG.structure.vector_origin_gap.description,
814
+ })}
815
+ >
816
+ Origin Gap
817
+ <input
818
+ type="number"
819
+ min={0}
820
+ max={0.5}
821
+ step={0.02}
822
+ bind:value={scene_props.vector_origin_gap}
823
+ />
824
+ <input
825
+ type="range"
826
+ min={0}
827
+ max={0.5}
828
+ step={0.02}
829
+ bind:value={scene_props.vector_origin_gap}
830
+ />
831
+ </label>
832
+ {#each available_vector_keys as key (key)}
833
+ {#if is_key_visible(key)}
834
+ {@const on_scale = (evt: Event) => {
835
+ const parsed = parseFloat((evt.target as HTMLInputElement).value)
836
+ update_vector_config(key, { scale: Number.isNaN(parsed) ? 1.0 : parsed })
837
+ }}
838
+ <label
839
+ {@attach tooltip({
840
+ content:
841
+ `Scale multiplier for ${key} arrows (applied on top of global scale)`,
842
+ })}
843
+ >
844
+ {key} scale
845
+ <input
846
+ type="number"
847
+ min={0.1}
848
+ max={5}
849
+ step={0.1}
850
+ value={scene_props.vector_configs?.[key]?.scale ?? 1.0}
851
+ onchange={on_scale}
852
+ />
853
+ <input
854
+ type="range"
855
+ min={0.1}
856
+ max={5}
857
+ step={0.1}
858
+ value={scene_props.vector_configs?.[key]?.scale ?? 1.0}
859
+ oninput={on_scale}
860
+ />
861
+ </label>
862
+ {/if}
863
+ {/each}
864
+ {/if}
634
865
  </SettingsSection>
635
866
  {/if}
636
867