matterviz 0.3.0 → 0.3.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.
Files changed (286) hide show
  1. package/dist/FilePicker.svelte +37 -20
  2. package/dist/Icon.svelte +2 -2
  3. package/dist/MillerIndexInput.svelte +60 -0
  4. package/dist/MillerIndexInput.svelte.d.ts +7 -0
  5. package/dist/app.css +38 -2
  6. package/dist/brillouin/BrillouinZone.svelte +20 -62
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  8. package/dist/brillouin/BrillouinZoneExportPane.svelte +12 -20
  9. package/dist/brillouin/BrillouinZoneScene.svelte +2 -2
  10. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  11. package/dist/chempot-diagram/ChemPotDiagram.svelte +192 -0
  12. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  13. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +677 -0
  14. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  15. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2688 -0
  16. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  17. package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -0
  18. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  19. package/dist/chempot-diagram/color.d.ts +10 -0
  20. package/dist/chempot-diagram/color.js +33 -0
  21. package/dist/chempot-diagram/compute.d.ts +38 -0
  22. package/dist/chempot-diagram/compute.js +650 -0
  23. package/dist/chempot-diagram/index.d.ts +5 -0
  24. package/dist/chempot-diagram/index.js +5 -0
  25. package/dist/chempot-diagram/pointer.d.ts +16 -0
  26. package/dist/chempot-diagram/pointer.js +40 -0
  27. package/dist/chempot-diagram/temperature.d.ts +15 -0
  28. package/dist/chempot-diagram/temperature.js +37 -0
  29. package/dist/chempot-diagram/types.d.ts +83 -0
  30. package/dist/chempot-diagram/types.js +27 -0
  31. package/dist/colors/index.d.ts +3 -1
  32. package/dist/colors/index.js +4 -0
  33. package/dist/composition/BarChart.svelte +13 -22
  34. package/dist/composition/BubbleChart.svelte +5 -3
  35. package/dist/composition/FormulaFilter.svelte +770 -90
  36. package/dist/composition/FormulaFilter.svelte.d.ts +37 -1
  37. package/dist/composition/PieChart.svelte +43 -18
  38. package/dist/composition/PieChart.svelte.d.ts +1 -1
  39. package/dist/constants.d.ts +1 -0
  40. package/dist/constants.js +2 -0
  41. package/dist/convex-hull/ConvexHull.svelte +14 -1
  42. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  43. package/dist/convex-hull/ConvexHull2D.svelte +14 -45
  44. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  45. package/dist/convex-hull/ConvexHull3D.svelte +396 -134
  46. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  47. package/dist/convex-hull/ConvexHull4D.svelte +93 -42
  48. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  49. package/dist/convex-hull/ConvexHullControls.svelte +94 -31
  50. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +4 -2
  51. package/dist/convex-hull/ConvexHullStats.svelte +697 -128
  52. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +6 -1
  53. package/dist/convex-hull/ConvexHullTooltip.svelte +1 -0
  54. package/dist/convex-hull/GasPressureControls.svelte +72 -38
  55. package/dist/convex-hull/GasPressureControls.svelte.d.ts +2 -1
  56. package/dist/convex-hull/TemperatureSlider.svelte +46 -19
  57. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +2 -1
  58. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  59. package/dist/convex-hull/demo-temperature.js +36 -0
  60. package/dist/convex-hull/gas-thermodynamics.js +16 -5
  61. package/dist/convex-hull/helpers.d.ts +7 -1
  62. package/dist/convex-hull/helpers.js +45 -15
  63. package/dist/convex-hull/index.d.ts +15 -1
  64. package/dist/convex-hull/index.js +1 -0
  65. package/dist/convex-hull/thermodynamics.d.ts +8 -21
  66. package/dist/convex-hull/thermodynamics.js +106 -17
  67. package/dist/convex-hull/types.d.ts +7 -0
  68. package/dist/convex-hull/types.js +11 -0
  69. package/dist/coordination/CoordinationBarPlot.svelte +29 -46
  70. package/dist/element/BohrAtom.svelte +1 -1
  71. package/dist/element/data.js +2 -14
  72. package/dist/element/data.json.gz +0 -0
  73. package/dist/element/index.d.ts +1 -1
  74. package/dist/element/index.js +1 -0
  75. package/dist/element/types.d.ts +1 -0
  76. package/dist/fermi-surface/FermiSurface.svelte +21 -65
  77. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  78. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  79. package/dist/fermi-surface/FermiSurfaceScene.svelte +1 -1
  80. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  81. package/dist/fermi-surface/compute.js +1 -21
  82. package/dist/fermi-surface/marching-cubes.d.ts +2 -13
  83. package/dist/fermi-surface/marching-cubes.js +2 -519
  84. package/dist/fermi-surface/parse.js +17 -23
  85. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1273 -0
  86. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  87. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +171 -0
  88. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +31 -0
  89. package/dist/heatmap-matrix/index.d.ts +53 -0
  90. package/dist/heatmap-matrix/index.js +100 -0
  91. package/dist/heatmap-matrix/shared.d.ts +2 -0
  92. package/dist/heatmap-matrix/shared.js +4 -0
  93. package/dist/icons.d.ts +119 -0
  94. package/dist/icons.js +119 -0
  95. package/dist/index.d.ts +6 -1
  96. package/dist/index.js +6 -1
  97. package/dist/io/export.js +15 -3
  98. package/dist/io/file-drop.d.ts +7 -0
  99. package/dist/io/file-drop.js +43 -0
  100. package/dist/io/index.d.ts +2 -2
  101. package/dist/io/index.js +2 -112
  102. package/dist/io/types.d.ts +1 -0
  103. package/dist/io/url-drop.d.ts +2 -0
  104. package/dist/io/url-drop.js +118 -0
  105. package/dist/isosurface/Isosurface.svelte +231 -0
  106. package/dist/isosurface/Isosurface.svelte.d.ts +8 -0
  107. package/dist/isosurface/IsosurfaceControls.svelte +273 -0
  108. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +9 -0
  109. package/dist/isosurface/index.d.ts +5 -0
  110. package/dist/isosurface/index.js +6 -0
  111. package/dist/isosurface/parse.d.ts +6 -0
  112. package/dist/isosurface/parse.js +548 -0
  113. package/dist/isosurface/slice.d.ts +11 -0
  114. package/dist/isosurface/slice.js +145 -0
  115. package/dist/isosurface/types.d.ts +55 -0
  116. package/dist/isosurface/types.js +178 -0
  117. package/dist/labels.d.ts +2 -1
  118. package/dist/labels.js +1 -0
  119. package/dist/layout/InfoTag.svelte +62 -62
  120. package/dist/layout/SubpageGrid.svelte +74 -0
  121. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  122. package/dist/layout/index.d.ts +1 -0
  123. package/dist/layout/index.js +1 -0
  124. package/dist/layout/json-tree/JsonNode.svelte +226 -53
  125. package/dist/layout/json-tree/JsonTree.svelte +425 -51
  126. package/dist/layout/json-tree/JsonTree.svelte.d.ts +1 -1
  127. package/dist/layout/json-tree/JsonValue.svelte +218 -97
  128. package/dist/layout/json-tree/types.d.ts +27 -2
  129. package/dist/layout/json-tree/utils.d.ts +14 -1
  130. package/dist/layout/json-tree/utils.js +254 -0
  131. package/dist/marching-cubes.d.ts +14 -0
  132. package/dist/marching-cubes.js +519 -0
  133. package/dist/math.d.ts +8 -0
  134. package/dist/math.js +374 -7
  135. package/dist/overlays/ContextMenu.svelte +3 -2
  136. package/dist/overlays/DraggablePane.svelte +163 -58
  137. package/dist/overlays/DraggablePane.svelte.d.ts +2 -0
  138. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +232 -77
  139. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -2
  140. package/dist/phase-diagram/PhaseDiagramControls.svelte +32 -11
  141. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +3 -2
  142. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +103 -0
  143. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  144. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +102 -95
  145. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +7 -0
  146. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +100 -26
  147. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +6 -3
  148. package/dist/phase-diagram/index.d.ts +2 -0
  149. package/dist/phase-diagram/index.js +2 -0
  150. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  151. package/dist/phase-diagram/svg-to-diagram.js +865 -0
  152. package/dist/phase-diagram/types.d.ts +10 -0
  153. package/dist/phase-diagram/utils.d.ts +7 -4
  154. package/dist/phase-diagram/utils.js +149 -59
  155. package/dist/plot/AxisLabel.svelte +26 -0
  156. package/dist/plot/AxisLabel.svelte.d.ts +16 -0
  157. package/dist/plot/BarPlot.svelte +473 -228
  158. package/dist/plot/BarPlot.svelte.d.ts +3 -3
  159. package/dist/plot/BarPlotControls.svelte +3 -2
  160. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  161. package/dist/plot/ColorBar.svelte +54 -54
  162. package/dist/plot/ColorBar.svelte.d.ts +1 -1
  163. package/dist/plot/ElementScatter.svelte +4 -3
  164. package/dist/plot/FillArea.svelte +4 -1
  165. package/dist/plot/Histogram.svelte +320 -230
  166. package/dist/plot/Histogram.svelte.d.ts +2 -2
  167. package/dist/plot/HistogramControls.svelte +29 -10
  168. package/dist/plot/HistogramControls.svelte.d.ts +6 -2
  169. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +2 -2
  170. package/dist/plot/PlotControls.svelte +109 -27
  171. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  172. package/dist/plot/PlotLegend.svelte +1 -1
  173. package/dist/plot/PortalSelect.svelte +2 -1
  174. package/dist/plot/ReferenceLine.svelte +2 -1
  175. package/dist/plot/ReferenceLine.svelte.d.ts +1 -0
  176. package/dist/plot/ReferencePlane.svelte +1 -3
  177. package/dist/plot/ScatterPlot.svelte +343 -209
  178. package/dist/plot/ScatterPlot.svelte.d.ts +3 -3
  179. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  180. package/dist/plot/ScatterPlot3DControls.svelte +203 -250
  181. package/dist/plot/ScatterPlot3DScene.svelte +4 -7
  182. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  183. package/dist/plot/ScatterPlotControls.svelte +95 -55
  184. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  185. package/dist/plot/ZeroLines.svelte +44 -0
  186. package/dist/plot/ZeroLines.svelte.d.ts +32 -0
  187. package/dist/plot/ZoomRect.svelte +21 -0
  188. package/dist/plot/ZoomRect.svelte.d.ts +8 -0
  189. package/dist/plot/axis-utils.d.ts +1 -1
  190. package/dist/plot/data-cleaning.js +1 -5
  191. package/dist/plot/index.d.ts +6 -2
  192. package/dist/plot/index.js +6 -2
  193. package/dist/plot/interactions.d.ts +8 -10
  194. package/dist/plot/interactions.js +10 -19
  195. package/dist/plot/layout.d.ts +7 -1
  196. package/dist/plot/layout.js +12 -4
  197. package/dist/plot/reference-line.d.ts +4 -21
  198. package/dist/plot/reference-line.js +7 -81
  199. package/dist/plot/types.d.ts +42 -17
  200. package/dist/plot/types.js +10 -0
  201. package/dist/plot/utils/label-placement.js +14 -11
  202. package/dist/plot/utils.d.ts +1 -0
  203. package/dist/plot/utils.js +14 -0
  204. package/dist/rdf/RdfPlot.svelte +55 -66
  205. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  206. package/dist/rdf/index.d.ts +1 -1
  207. package/dist/rdf/index.js +1 -1
  208. package/dist/settings.d.ts +5 -0
  209. package/dist/settings.js +37 -3
  210. package/dist/spectral/Bands.svelte +515 -143
  211. package/dist/spectral/Bands.svelte.d.ts +22 -2
  212. package/dist/spectral/helpers.d.ts +23 -1
  213. package/dist/spectral/helpers.js +65 -9
  214. package/dist/spectral/types.d.ts +2 -0
  215. package/dist/structure/AtomLegend.svelte +31 -10
  216. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  217. package/dist/structure/CellSelect.svelte +92 -22
  218. package/dist/structure/Lattice.svelte +2 -0
  219. package/dist/structure/Structure.svelte +716 -173
  220. package/dist/structure/Structure.svelte.d.ts +7 -2
  221. package/dist/structure/StructureControls.svelte +26 -14
  222. package/dist/structure/StructureControls.svelte.d.ts +5 -1
  223. package/dist/structure/StructureInfoPane.svelte +7 -1
  224. package/dist/structure/StructureScene.svelte +386 -95
  225. package/dist/structure/StructureScene.svelte.d.ts +15 -4
  226. package/dist/structure/atom-properties.d.ts +6 -2
  227. package/dist/structure/atom-properties.js +38 -25
  228. package/dist/structure/export.js +10 -7
  229. package/dist/structure/ferrox-wasm-types.d.ts +3 -2
  230. package/dist/structure/ferrox-wasm-types.js +0 -3
  231. package/dist/structure/ferrox-wasm.d.ts +3 -2
  232. package/dist/structure/ferrox-wasm.js +1 -2
  233. package/dist/structure/index.d.ts +7 -0
  234. package/dist/structure/index.js +22 -0
  235. package/dist/structure/parse.js +19 -16
  236. package/dist/structure/partial-occupancy.d.ts +25 -0
  237. package/dist/structure/partial-occupancy.js +102 -0
  238. package/dist/structure/validation.js +6 -3
  239. package/dist/symmetry/SymmetryStats.svelte +18 -4
  240. package/dist/symmetry/WyckoffTable.svelte +18 -10
  241. package/dist/symmetry/index.d.ts +7 -4
  242. package/dist/symmetry/index.js +83 -18
  243. package/dist/table/HeatmapTable.svelte +468 -69
  244. package/dist/table/HeatmapTable.svelte.d.ts +13 -1
  245. package/dist/table/ToggleMenu.svelte +291 -44
  246. package/dist/table/ToggleMenu.svelte.d.ts +4 -1
  247. package/dist/table/index.d.ts +3 -0
  248. package/dist/tooltip/index.d.ts +1 -1
  249. package/dist/tooltip/index.js +1 -0
  250. package/dist/trajectory/Trajectory.svelte +147 -145
  251. package/dist/trajectory/TrajectoryExportPane.svelte +13 -9
  252. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +1 -1
  253. package/dist/trajectory/constants.d.ts +6 -0
  254. package/dist/trajectory/constants.js +7 -0
  255. package/dist/trajectory/extract.js +3 -5
  256. package/dist/trajectory/format-detect.d.ts +9 -0
  257. package/dist/trajectory/format-detect.js +76 -0
  258. package/dist/trajectory/frame-reader.d.ts +17 -0
  259. package/dist/trajectory/frame-reader.js +339 -0
  260. package/dist/trajectory/helpers.d.ts +15 -0
  261. package/dist/trajectory/helpers.js +187 -0
  262. package/dist/trajectory/index.d.ts +1 -0
  263. package/dist/trajectory/index.js +11 -4
  264. package/dist/trajectory/parse/ase.d.ts +2 -0
  265. package/dist/trajectory/parse/ase.js +76 -0
  266. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  267. package/dist/trajectory/parse/hdf5.js +121 -0
  268. package/dist/trajectory/parse/index.d.ts +12 -0
  269. package/dist/trajectory/parse/index.js +304 -0
  270. package/dist/trajectory/parse/lammps.d.ts +5 -0
  271. package/dist/trajectory/parse/lammps.js +169 -0
  272. package/dist/trajectory/parse/vasp.d.ts +2 -0
  273. package/dist/trajectory/parse/vasp.js +65 -0
  274. package/dist/trajectory/parse/xyz.d.ts +2 -0
  275. package/dist/trajectory/parse/xyz.js +109 -0
  276. package/dist/trajectory/types.d.ts +11 -0
  277. package/dist/trajectory/types.js +1 -0
  278. package/dist/utils.d.ts +2 -0
  279. package/dist/utils.js +4 -0
  280. package/dist/xrd/XrdPlot.svelte +6 -4
  281. package/dist/xrd/calc-xrd.js +0 -1
  282. package/package.json +33 -23
  283. package/readme.md +4 -4
  284. package/dist/trajectory/parse.d.ts +0 -42
  285. package/dist/trajectory/parse.js +0 -1267
  286. /package/dist/element/{data.json.d.ts → data.json.gz.d.ts} +0 -0
@@ -64,12 +64,12 @@ declare function $$render<Metadata extends Record<string, unknown> = Record<stri
64
64
  selected_series_idx?: number;
65
65
  wrapper?: HTMLDivElement;
66
66
  data_loader?: DataLoaderFn<Metadata>;
67
- on_axis_change?: (axis: `x` | `y` | `y2`, key: string, new_series: DataSeries<Metadata>[]) => void;
67
+ on_axis_change?: (axis: `x` | `x2` | `y` | `y2`, key: string, new_series: DataSeries<Metadata>[]) => void;
68
68
  on_error?: (error: AxisLoadError) => void;
69
69
  pan?: PanConfig;
70
70
  };
71
71
  exports: {};
72
- bindings: "display" | "fullscreen" | "series" | "hovered" | "ref_lines" | "x_axis" | "y_axis" | "y2_axis" | "wrapper" | "tooltip_point" | "fill_regions" | "selected_series_idx";
72
+ bindings: "display" | "series" | "x_axis" | "x2_axis" | "y_axis" | "y2_axis" | "fullscreen" | "hovered" | "ref_lines" | "wrapper" | "tooltip_point" | "fill_regions" | "selected_series_idx";
73
73
  slots: {};
74
74
  events: {};
75
75
  };
@@ -77,7 +77,7 @@ declare class __sveltets_Render<Metadata extends Record<string, unknown> = Recor
77
77
  props(): ReturnType<typeof $$render<Metadata>>['props'];
78
78
  events(): ReturnType<typeof $$render<Metadata>>['events'];
79
79
  slots(): ReturnType<typeof $$render<Metadata>>['slots'];
80
- bindings(): "display" | "fullscreen" | "series" | "hovered" | "ref_lines" | "x_axis" | "y_axis" | "y2_axis" | "wrapper" | "tooltip_point" | "fill_regions" | "selected_series_idx";
80
+ bindings(): "display" | "series" | "x_axis" | "x2_axis" | "y_axis" | "y2_axis" | "fullscreen" | "hovered" | "ref_lines" | "wrapper" | "tooltip_point" | "fill_regions" | "selected_series_idx";
81
81
  exports(): {};
82
82
  }
83
83
  interface $$IsomorphicComponent {
@@ -71,7 +71,7 @@ declare function $$render<Metadata extends Record<string, unknown> = Record<stri
71
71
  controls_extra?: Snippet;
72
72
  };
73
73
  exports: {};
74
- bindings: "fullscreen" | "hovered" | "camera_position" | "scene" | "camera" | "orbit_controls" | "wrapper" | "tooltip_point";
74
+ bindings: "fullscreen" | "hovered" | "camera_position" | "wrapper" | "tooltip_point" | "scene" | "camera" | "orbit_controls";
75
75
  slots: {};
76
76
  events: {};
77
77
  };
@@ -79,7 +79,7 @@ declare class __sveltets_Render<Metadata extends Record<string, unknown> = Recor
79
79
  props(): ReturnType<typeof $$render<Metadata>>['props'];
80
80
  events(): ReturnType<typeof $$render<Metadata>>['events'];
81
81
  slots(): ReturnType<typeof $$render<Metadata>>['slots'];
82
- bindings(): "fullscreen" | "hovered" | "camera_position" | "scene" | "camera" | "orbit_controls" | "wrapper" | "tooltip_point";
82
+ bindings(): "fullscreen" | "hovered" | "camera_position" | "wrapper" | "tooltip_point" | "scene" | "camera" | "orbit_controls";
83
83
  exports(): {};
84
84
  }
85
85
  interface $$IsomorphicComponent {
@@ -44,10 +44,32 @@ const toggle_projection = (plane) => () => {
44
44
  projections: { ...display.projections, [plane]: !display.projections?.[plane] },
45
45
  };
46
46
  };
47
+ // Round to 4 decimal places for display
48
+ const round4 = (val) => Math.round(val * 1e4) / 1e4;
47
49
  // Helper for axis label updates
48
50
  const update_axis_label = (axis, setter) => (event) => {
49
51
  setter({ ...axis, label: get_input_value(event) });
50
52
  };
53
+ const axes = $derived([
54
+ {
55
+ name: `X`,
56
+ axis: x_axis,
57
+ auto_range: auto_x_range,
58
+ set: (val) => (x_axis = val),
59
+ },
60
+ {
61
+ name: `Y`,
62
+ axis: y_axis,
63
+ auto_range: auto_y_range,
64
+ set: (val) => (y_axis = val),
65
+ },
66
+ {
67
+ name: `Z`,
68
+ axis: z_axis,
69
+ auto_range: auto_z_range,
70
+ set: (val) => (z_axis = val),
71
+ },
72
+ ]);
51
73
  </script>
52
74
 
53
75
  <DraggablePane
@@ -138,263 +160,160 @@ const update_axis_label = (axis, setter) => (event) => {
138
160
  </label>
139
161
  </SettingsSection>
140
162
 
141
- <!-- Projections -->
163
+ <!-- Projections: only when there's data to project -->
164
+ {#if series.length > 0}
165
+ <SettingsSection
166
+ title="Projections"
167
+ current_values={{
168
+ xy: display.projections?.xy,
169
+ xz: display.projections?.xz,
170
+ yz: display.projections?.yz,
171
+ opacity: display.projection_opacity,
172
+ scale: display.projection_scale,
173
+ }}
174
+ on_reset={() => {
175
+ display = {
176
+ ...display,
177
+ projections: { xy: false, xz: false, yz: false },
178
+ projection_opacity: 0.3,
179
+ projection_scale: 0.5,
180
+ }
181
+ }}
182
+ >
183
+ <div style="display: flex; flex-wrap: wrap; gap: 1ex">
184
+ <label>
185
+ <input
186
+ type="checkbox"
187
+ checked={display.projections?.xy}
188
+ onchange={toggle_projection(`xy`)}
189
+ /> XY
190
+ </label>
191
+ <label>
192
+ <input
193
+ type="checkbox"
194
+ checked={display.projections?.xz}
195
+ onchange={toggle_projection(`xz`)}
196
+ /> XZ
197
+ </label>
198
+ <label>
199
+ <input
200
+ type="checkbox"
201
+ checked={display.projections?.yz}
202
+ onchange={toggle_projection(`yz`)}
203
+ /> YZ
204
+ </label>
205
+ </div>
206
+ <div class="pane-row">
207
+ <label for="{uid}-proj-opacity">Opacity:</label>
208
+ <input
209
+ id="{uid}-proj-opacity"
210
+ type="range"
211
+ min="0"
212
+ max="1"
213
+ step="0.05"
214
+ value={display.projection_opacity ?? 0.3}
215
+ oninput={update_display(`projection_opacity`)}
216
+ />
217
+ <input
218
+ type="number"
219
+ min="0"
220
+ max="1"
221
+ step="0.05"
222
+ value={display.projection_opacity ?? 0.3}
223
+ oninput={update_display(`projection_opacity`)}
224
+ style="width: 3.5em"
225
+ />
226
+ </div>
227
+ <div class="pane-row">
228
+ <label for="{uid}-proj-scale">Size:</label>
229
+ <input
230
+ id="{uid}-proj-scale"
231
+ type="range"
232
+ min="0.1"
233
+ max="1"
234
+ step="0.05"
235
+ value={display.projection_scale ?? 0.5}
236
+ oninput={update_display(`projection_scale`)}
237
+ />
238
+ <input
239
+ type="number"
240
+ min="0.1"
241
+ max="1"
242
+ step="0.05"
243
+ value={display.projection_scale ?? 0.5}
244
+ oninput={update_display(`projection_scale`)}
245
+ style="width: 3.5em"
246
+ />
247
+ </div>
248
+ </SettingsSection>
249
+ {/if}
250
+
251
+ <!-- Axes (merged X/Y/Z) -->
142
252
  <SettingsSection
143
- title="Projections"
253
+ title="Axes"
144
254
  current_values={{
145
- xy: display.projections?.xy,
146
- xz: display.projections?.xz,
147
- yz: display.projections?.yz,
148
- opacity: display.projection_opacity,
149
- scale: display.projection_scale,
255
+ x_range: x_axis.range,
256
+ y_range: y_axis.range,
257
+ z_range: z_axis.range,
150
258
  }}
151
259
  on_reset={() => {
152
- display = {
153
- ...display,
154
- projections: { xy: false, xz: false, yz: false },
155
- projection_opacity: 0.3,
156
- projection_scale: 0.5,
157
- }
260
+ x_axis = { ...x_axis, range: [null, null] }
261
+ y_axis = { ...y_axis, range: [null, null] }
262
+ z_axis = { ...z_axis, range: [null, null] }
158
263
  }}
159
264
  >
160
- <div style="display: flex; flex-wrap: wrap; gap: 1ex">
161
- <label>
265
+ {#each axes as { name, axis, auto_range, set } (name)}
266
+ <div class="axis-row">
267
+ <span class="axis-name">{name}</span>
162
268
  <input
163
- type="checkbox"
164
- checked={display.projections?.xy}
165
- onchange={toggle_projection(`xy`)}
166
- /> XY
167
- </label>
168
- <label>
269
+ type="text"
270
+ value={axis.label}
271
+ oninput={update_axis_label(axis, set)}
272
+ placeholder="{name} label"
273
+ aria-label="{name} label"
274
+ class="axis-label-input"
275
+ />
169
276
  <input
170
- type="checkbox"
171
- checked={display.projections?.xz}
172
- onchange={toggle_projection(`xz`)}
173
- /> XZ
174
- </label>
175
- <label>
277
+ type="number"
278
+ step="any"
279
+ value={round4(axis.range?.[0] ?? auto_range[0])}
280
+ oninput={(event) => {
281
+ const val = parseFloat((event.target as HTMLInputElement).value)
282
+ if (Number.isNaN(val)) return
283
+ set({ ...axis, range: [val, axis.range?.[1] ?? auto_range[1]] })
284
+ }}
285
+ aria-label="{name} min"
286
+ class="axis-range-input"
287
+ />
288
+ <span class="axis-to">–</span>
176
289
  <input
177
- type="checkbox"
178
- checked={display.projections?.yz}
179
- onchange={toggle_projection(`yz`)}
180
- /> YZ
181
- </label>
182
- </div>
183
- <div class="pane-row">
184
- <label for="{uid}-proj-opacity">Opacity:</label>
185
- <input
186
- id="{uid}-proj-opacity"
187
- type="range"
188
- min="0"
189
- max="1"
190
- step="0.05"
191
- value={display.projection_opacity ?? 0.3}
192
- oninput={update_display(`projection_opacity`)}
193
- />
194
- <input
195
- type="number"
196
- min="0"
197
- max="1"
198
- step="0.05"
199
- value={display.projection_opacity ?? 0.3}
200
- oninput={update_display(`projection_opacity`)}
201
- style="width: 3.5em"
202
- />
203
- </div>
204
- <div class="pane-row">
205
- <label for="{uid}-proj-scale">Size:</label>
206
- <input
207
- id="{uid}-proj-scale"
208
- type="range"
209
- min="0.1"
210
- max="1"
211
- step="0.05"
212
- value={display.projection_scale ?? 0.5}
213
- oninput={update_display(`projection_scale`)}
214
- />
215
- <input
216
- type="number"
217
- min="0.1"
218
- max="1"
219
- step="0.05"
220
- value={display.projection_scale ?? 0.5}
221
- oninput={update_display(`projection_scale`)}
222
- style="width: 3.5em"
223
- />
224
- </div>
225
- </SettingsSection>
226
-
227
- <!-- X Axis Range -->
228
- <SettingsSection
229
- title="X Axis"
230
- current_values={{ range: x_axis.range }}
231
- on_reset={() => (x_axis = { ...x_axis, range: [null, null] })}
232
- >
233
- <div class="pane-row">
234
- <label for="{uid}-x-label">Label:</label>
235
- <input
236
- id="{uid}-x-label"
237
- type="text"
238
- value={x_axis.label}
239
- oninput={update_axis_label(x_axis, (val) => (x_axis = val))}
240
- placeholder="X"
241
- />
242
- </div>
243
- <div class="pane-row">
244
- <label for="{uid}-x-range-min">Range:</label>
245
- <input
246
- id="{uid}-x-range-min"
247
- type="number"
248
- step="any"
249
- value={x_axis.range?.[0] ?? auto_x_range[0]}
250
- oninput={(event) => {
251
- const val = parseFloat((event.target as HTMLInputElement).value)
252
- if (Number.isNaN(val)) return
253
- x_axis = {
254
- ...x_axis,
255
- range: [val, x_axis.range?.[1] ?? auto_x_range[1]],
256
- }
257
- }}
258
- />
259
- <span>to</span>
260
- <input
261
- id="{uid}-x-range-max"
262
- type="number"
263
- step="any"
264
- value={x_axis.range?.[1] ?? auto_x_range[1]}
265
- oninput={(event) => {
266
- const val = parseFloat((event.target as HTMLInputElement).value)
267
- if (Number.isNaN(val)) return
268
- x_axis = {
269
- ...x_axis,
270
- range: [x_axis.range?.[0] ?? auto_x_range[0], val],
271
- }
272
- }}
273
- />
274
- </div>
275
- </SettingsSection>
276
-
277
- <!-- Y Axis Range -->
278
- <SettingsSection
279
- title="Y Axis"
280
- current_values={{ range: y_axis.range }}
281
- on_reset={() => (y_axis = { ...y_axis, range: [null, null] })}
282
- >
283
- <div class="pane-row">
284
- <label for="{uid}-y-label">Label:</label>
285
- <input
286
- id="{uid}-y-label"
287
- type="text"
288
- value={y_axis.label}
289
- oninput={update_axis_label(y_axis, (val) => (y_axis = val))}
290
- placeholder="Y"
291
- />
292
- </div>
293
- <div class="pane-row">
294
- <label for="{uid}-y-range-min">Range:</label>
295
- <input
296
- id="{uid}-y-range-min"
297
- type="number"
298
- step="any"
299
- value={y_axis.range?.[0] ?? auto_y_range[0]}
300
- oninput={(event) => {
301
- const val = parseFloat((event.target as HTMLInputElement).value)
302
- if (Number.isNaN(val)) return
303
- y_axis = {
304
- ...y_axis,
305
- range: [val, y_axis.range?.[1] ?? auto_y_range[1]],
306
- }
307
- }}
308
- />
309
- <span>to</span>
310
- <input
311
- id="{uid}-y-range-max"
312
- type="number"
313
- step="any"
314
- value={y_axis.range?.[1] ?? auto_y_range[1]}
315
- oninput={(event) => {
316
- const val = parseFloat((event.target as HTMLInputElement).value)
317
- if (Number.isNaN(val)) return
318
- y_axis = {
319
- ...y_axis,
320
- range: [y_axis.range?.[0] ?? auto_y_range[0], val],
321
- }
322
- }}
323
- />
324
- </div>
290
+ type="number"
291
+ step="any"
292
+ value={round4(axis.range?.[1] ?? auto_range[1])}
293
+ oninput={(event) => {
294
+ const val = parseFloat((event.target as HTMLInputElement).value)
295
+ if (Number.isNaN(val)) return
296
+ set({ ...axis, range: [axis.range?.[0] ?? auto_range[0], val] })
297
+ }}
298
+ aria-label="{name} max"
299
+ class="axis-range-input"
300
+ />
301
+ </div>
302
+ {/each}
325
303
  </SettingsSection>
326
304
 
327
- <!-- Z Axis Range -->
328
- <SettingsSection
329
- title="Z Axis"
330
- current_values={{ range: z_axis.range }}
331
- on_reset={() => (z_axis = { ...z_axis, range: [null, null] })}
332
- >
333
- <div class="pane-row">
334
- <label for="{uid}-z-label">Label:</label>
335
- <input
336
- id="{uid}-z-label"
337
- type="text"
338
- value={z_axis.label}
339
- oninput={update_axis_label(z_axis, (val) => (z_axis = val))}
340
- placeholder="Z"
341
- />
305
+ <!-- Data summary: only when there's data -->
306
+ {#if series.length > 0 || surfaces.length > 0}
307
+ <div class="data-summary">
308
+ {#if series.length > 0}
309
+ <span>{series.length} series · {
310
+ series.reduce((sum, srs) => sum + srs.x.length, 0).toLocaleString()
311
+ } points</span>
312
+ {/if}
313
+ {#if surfaces.length > 0}
314
+ <span>{surfaces.length} {surfaces.length === 1 ? `surface` : `surfaces`}</span>
315
+ {/if}
342
316
  </div>
343
- <div class="pane-row">
344
- <label for="{uid}-z-range-min">Range:</label>
345
- <input
346
- id="{uid}-z-range-min"
347
- type="number"
348
- step="any"
349
- value={z_axis.range?.[0] ?? auto_z_range[0]}
350
- oninput={(event) => {
351
- const val = parseFloat((event.target as HTMLInputElement).value)
352
- if (Number.isNaN(val)) return
353
- z_axis = {
354
- ...z_axis,
355
- range: [val, z_axis.range?.[1] ?? auto_z_range[1]],
356
- }
357
- }}
358
- />
359
- <span>to</span>
360
- <input
361
- id="{uid}-z-range-max"
362
- type="number"
363
- step="any"
364
- value={z_axis.range?.[1] ?? auto_z_range[1]}
365
- oninput={(event) => {
366
- const val = parseFloat((event.target as HTMLInputElement).value)
367
- if (Number.isNaN(val)) return
368
- z_axis = {
369
- ...z_axis,
370
- range: [z_axis.range?.[0] ?? auto_z_range[0], val],
371
- }
372
- }}
373
- />
374
- </div>
375
- </SettingsSection>
376
-
377
- <!-- Series Info -->
378
- {#if series.length > 0}
379
- <SettingsSection title="Data" current_values={{ series_count: series.length }}>
380
- <div class="pane-row">
381
- <span>Series: {series.length}</span>
382
- </div>
383
- <div class="pane-row">
384
- <span>
385
- Points: {series.reduce((sum, srs) => sum + srs.x.length, 0).toLocaleString()}
386
- </span>
387
- </div>
388
- </SettingsSection>
389
- {/if}
390
-
391
- <!-- Surfaces Info -->
392
- {#if surfaces.length > 0}
393
- <SettingsSection title="Surfaces" current_values={{ surface_count: surfaces.length }}>
394
- <div class="pane-row">
395
- <span>Surfaces: {surfaces.length}</span>
396
- </div>
397
- </SettingsSection>
398
317
  {/if}
399
318
 
400
319
  <!-- User-provided children -->
@@ -416,10 +335,6 @@ const update_axis_label = (axis, setter) => (event) => {
416
335
  .pane-row input[type='number'] {
417
336
  width: 5em;
418
337
  }
419
- .pane-row input[type='text'] {
420
- flex: 1;
421
- min-width: 0;
422
- }
423
338
  .pane-row input[type='range'] {
424
339
  flex: 1;
425
340
  min-width: 4em;
@@ -428,7 +343,45 @@ const update_axis_label = (axis, setter) => (event) => {
428
343
  flex: 1;
429
344
  min-width: 0;
430
345
  }
431
- .pane-row span {
346
+ .axis-row {
347
+ display: flex;
348
+ align-items: center;
349
+ gap: 4px;
350
+ margin: 2px 0;
351
+ font-size: 0.9em;
352
+ }
353
+ .axis-row input {
354
+ box-sizing: border-box;
355
+ height: 1.4em;
356
+ padding: 0 3px;
357
+ font-size: inherit;
358
+ line-height: 1;
359
+ }
360
+ .axis-name {
361
+ font-weight: 600;
362
+ width: 1.2em;
363
+ flex-shrink: 0;
364
+ }
365
+ .axis-label-input {
366
+ width: 6em;
367
+ min-width: 0;
368
+ flex-shrink: 1;
369
+ }
370
+ .axis-range-input {
371
+ width: 7em;
372
+ flex: 1;
373
+ min-width: 5em;
374
+ }
375
+ .axis-to {
432
376
  flex-shrink: 0;
377
+ opacity: 0.5;
378
+ }
379
+ .data-summary {
380
+ display: flex;
381
+ flex-wrap: wrap;
382
+ gap: 1ex;
383
+ font-size: 0.85em;
384
+ opacity: 0.7;
385
+ margin-top: 4px;
433
386
  }
434
387
  </style>
@@ -11,6 +11,7 @@ import { Line2 } from 'three/examples/jsm/lines/Line2.js';
11
11
  import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js';
12
12
  import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js';
13
13
  import { get_series_color } from './data-transform';
14
+ import { normalize_to_scene } from './reference-line';
14
15
  import ReferenceLine3D from './ReferenceLine3D.svelte';
15
16
  import ReferencePlane from './ReferencePlane.svelte';
16
17
  import { create_color_scale, create_size_scale } from './scales';
@@ -131,13 +132,9 @@ let z_range = $derived(compute_range([
131
132
  ...all_points.map((p) => p.z),
132
133
  ...surface_samples.map((p) => p.z),
133
134
  ], z_axis.range));
134
- // Normalize value to scene coordinates (centered around 0)
135
- function normalize(value, [min_val, max_val], scene_size) {
136
- return ((value - min_val) / (max_val - min_val || 1) - 0.5) * scene_size;
137
- }
138
- const normalize_x = (v) => normalize(v, x_range, scene_x);
139
- const normalize_y = (v) => normalize(v, y_range, scene_y);
140
- const normalize_z = (v) => normalize(v, z_range, scene_z);
135
+ const normalize_x = (value) => normalize_to_scene(value, x_range, scene_x);
136
+ const normalize_y = (value) => normalize_to_scene(value, y_range, scene_y);
137
+ const normalize_z = (value) => normalize_to_scene(value, z_range, scene_z);
141
138
  // Color/size scales
142
139
  let all_color_values = $derived(all_points.map((pt) => pt.color_value).filter((v) => v != null));
143
140
  let auto_color_range = $derived.by(() => {
@@ -51,7 +51,7 @@ declare function $$render<Metadata extends Record<string, unknown> = Record<stri
51
51
  height?: number;
52
52
  };
53
53
  exports: {};
54
- bindings: "scene" | "camera" | "orbit_controls" | "hovered_point";
54
+ bindings: "hovered_point" | "scene" | "camera" | "orbit_controls";
55
55
  slots: {};
56
56
  events: {};
57
57
  };
@@ -59,7 +59,7 @@ declare class __sveltets_Render<Metadata extends Record<string, unknown> = Recor
59
59
  props(): ReturnType<typeof $$render<Metadata>>['props'];
60
60
  events(): ReturnType<typeof $$render<Metadata>>['events'];
61
61
  slots(): ReturnType<typeof $$render<Metadata>>['slots'];
62
- bindings(): "scene" | "camera" | "orbit_controls" | "hovered_point";
62
+ bindings(): "hovered_point" | "scene" | "camera" | "orbit_controls";
63
63
  exports(): {};
64
64
  }
65
65
  interface $$IsomorphicComponent {