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
@@ -41,10 +41,10 @@ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & BasePlotProps & PlotCon
41
41
  on_ref_line_hover?: (event: RefLineEvent | null) => void;
42
42
  on_series_toggle?: (series_idx: number) => void;
43
43
  data_loader?: DataLoaderFn;
44
- on_axis_change?: (axis: `x` | `y` | `y2`, key: string, new_series: DataSeries[]) => void;
44
+ on_axis_change?: (axis: `x` | `x2` | `y` | `y2`, key: string, new_series: DataSeries[]) => void;
45
45
  on_error?: (error: AxisLoadError) => void;
46
46
  pan?: PanConfig;
47
47
  };
48
- declare const Histogram: import("svelte").Component<$$ComponentProps, {}, "mode" | "fullscreen" | "series" | "bins" | "show_legend" | "selected_property" | "hovered" | "ref_lines" | "show_controls" | "controls_open">;
48
+ declare const Histogram: import("svelte").Component<$$ComponentProps, {}, "mode" | "series" | "show_controls" | "controls_open" | "fullscreen" | "bins" | "show_legend" | "selected_property" | "hovered" | "ref_lines">;
49
49
  type Histogram = ReturnType<typeof Histogram>;
50
50
  export default Histogram;
@@ -2,7 +2,7 @@
2
2
  import { SettingsSection } from '../layout';
3
3
  import { PlotControls } from './';
4
4
  import { DEFAULTS } from '../settings';
5
- let { series = [], bins = $bindable(DEFAULTS.histogram.bin_count), mode = $bindable(DEFAULTS.histogram.mode), bar = $bindable({}), show_legend = $bindable(DEFAULTS.histogram.show_legend), selected_property = $bindable(``), x_axis = $bindable({}), y_axis = $bindable({}), y2_axis = $bindable({}), display = $bindable({}), show_controls = $bindable(false), controls_open = $bindable(false), auto_y2_range = undefined, children, ...rest } = $props();
5
+ let { series = [], bins = $bindable(DEFAULTS.histogram.bin_count), mode = $bindable(DEFAULTS.histogram.mode), bar = $bindable({}), show_legend = $bindable(DEFAULTS.histogram.show_legend), selected_property = $bindable(``), x_axis = $bindable({}), x2_axis = $bindable({}), y_axis = $bindable({}), y2_axis = $bindable({}), display = $bindable({}), show_controls = $bindable(false), controls_open = $bindable(false), auto_x2_range = undefined, auto_y2_range = undefined, has_x2_points = false, has_y2_points = false, children, ...rest } = $props();
6
6
  bar = { ...DEFAULTS.histogram.bar, ...bar }; // Initialize bar styles with defaults (runs once)
7
7
  let has_multiple_series = $derived(series.filter(Boolean).length > 1);
8
8
  let visible_series = $derived(series.filter((srs) => srs && (srs.visible ?? true)));
@@ -14,12 +14,14 @@ let series_options = $derived(visible_series.map((srs) => srs.label || `Series`)
14
14
  bind:controls_open
15
15
  bind:display
16
16
  bind:x_axis
17
+ bind:x2_axis
17
18
  bind:y_axis
18
19
  bind:y2_axis
20
+ {auto_x2_range}
19
21
  {auto_y2_range}
20
22
  {...rest}
21
23
  >
22
- {@render children?.({ x_axis, y_axis, y2_axis, display })}
24
+ {@render children?.({ x_axis, x2_axis, y_axis, y2_axis, display })}
23
25
  <SettingsSection
24
26
  title="Histogram"
25
27
  current_values={{ bins, mode, show_legend }}
@@ -113,8 +115,9 @@ let series_options = $derived(visible_series.map((srs) => srs.label || `Series`)
113
115
  data-testid="scale-type-section"
114
116
  current_values={{
115
117
  x_scale_type: x_axis.scale_type,
118
+ ...(has_x2_points ? { x2_scale_type: x2_axis.scale_type } : {}),
116
119
  y_scale_type: y_axis.scale_type,
117
- y2_scale_type: y2_axis.scale_type,
120
+ ...(has_y2_points ? { y2_scale_type: y2_axis.scale_type } : {}),
118
121
  }}
119
122
  on_reset={() => {
120
123
  x_axis = {
@@ -125,9 +128,17 @@ let series_options = $derived(visible_series.map((srs) => srs.label || `Series`)
125
128
  ...y_axis,
126
129
  scale_type: DEFAULTS.plot.y_scale_type as `linear` | `log`,
127
130
  }
128
- y2_axis = {
129
- ...y2_axis,
130
- scale_type: DEFAULTS.plot.y_scale_type as `linear` | `log`,
131
+ if (has_x2_points) {
132
+ x2_axis = {
133
+ ...x2_axis,
134
+ scale_type: DEFAULTS.plot.x_scale_type as `linear` | `log`,
135
+ }
136
+ }
137
+ if (has_y2_points) {
138
+ y2_axis = {
139
+ ...y2_axis,
140
+ scale_type: DEFAULTS.plot.y_scale_type as `linear` | `log`,
141
+ }
131
142
  }
132
143
  }}
133
144
  class="pane-grid"
@@ -137,13 +148,21 @@ let series_options = $derived(visible_series.map((srs) => srs.label || `Series`)
137
148
  <option value="linear">Linear</option>
138
149
  <option value="log">Log</option>
139
150
  </select></label>
151
+ {#if has_x2_points}
152
+ <label>X2: <select bind:value={x2_axis.scale_type}>
153
+ <option value="linear">Linear</option>
154
+ <option value="log">Log</option>
155
+ </select></label>
156
+ {/if}
140
157
  <label>Y: <select bind:value={y_axis.scale_type}>
141
158
  <option value="linear">Linear</option>
142
159
  <option value="log">Log</option>
143
160
  </select></label>
144
- <label>Y2: <select bind:value={y2_axis.scale_type}>
145
- <option value="linear">Linear</option>
146
- <option value="log">Log</option>
147
- </select></label>
161
+ {#if has_y2_points}
162
+ <label>Y2: <select bind:value={y2_axis.scale_type}>
163
+ <option value="linear">Linear</option>
164
+ <option value="log">Log</option>
165
+ </select></label>
166
+ {/if}
148
167
  </SettingsSection>
149
168
  </PlotControls>
@@ -1,3 +1,4 @@
1
+ import type { Vec2 } from '../math';
1
2
  import type { BarStyle, DataSeries, PlotConfig } from './';
2
3
  import type { PlotControlsProps } from './types';
3
4
  import type { Snippet } from 'svelte';
@@ -10,9 +11,12 @@ type $$ComponentProps = Omit<PlotControlsProps, `children` | `post_children`> &
10
11
  selected_property?: string;
11
12
  show_controls?: boolean;
12
13
  controls_open?: boolean;
13
- auto_y2_range?: [number, number];
14
+ auto_x2_range?: Vec2;
15
+ auto_y2_range?: Vec2;
16
+ has_x2_points?: boolean;
17
+ has_y2_points?: boolean;
14
18
  children?: Snippet<[Required<PlotConfig>]>;
15
19
  };
16
- declare const HistogramControls: import("svelte").Component<$$ComponentProps, {}, "display" | "mode" | "bins" | "show_legend" | "selected_property" | "show_controls" | "controls_open" | "x_axis" | "y_axis" | "bar" | "y2_axis">;
20
+ declare const HistogramControls: import("svelte").Component<$$ComponentProps, {}, "display" | "mode" | "bar" | "show_controls" | "controls_open" | "x_axis" | "x2_axis" | "y_axis" | "y2_axis" | "bins" | "show_legend" | "selected_property">;
17
21
  type HistogramControls = ReturnType<typeof HistogramControls>;
18
22
  export default HistogramControls;
@@ -4,11 +4,11 @@ type $$ComponentProps = {
4
4
  options?: AxisOption[];
5
5
  selected_key?: string;
6
6
  loading?: boolean;
7
- axis_type?: `x` | `y` | `y2`;
7
+ axis_type?: `x` | `x2` | `y` | `y2`;
8
8
  color?: string | null;
9
9
  on_select?: (key: string) => void;
10
10
  [key: string]: unknown;
11
11
  };
12
- declare const InteractiveAxisLabel: import("svelte").Component<$$ComponentProps, {}, "color" | "loading" | "selected_key">;
12
+ declare const InteractiveAxisLabel: import("svelte").Component<$$ComponentProps, {}, "color" | "selected_key" | "loading">;
13
13
  type InteractiveAxisLabel = ReturnType<typeof InteractiveAxisLabel>;
14
14
  export default InteractiveAxisLabel;
@@ -1,4 +1,4 @@
1
- <script lang="ts">// NOTE: Axis config objects (x_axis, y_axis, y2_axis) must be reassigned (not mutated)
1
+ <script lang="ts">// NOTE: Axis config objects (x_axis, x2_axis, y_axis, y2_axis) must be reassigned (not mutated)
2
2
  // to trigger $bindable reactivity propagation to parent components.
3
3
  // Pattern: `x_axis = { ...x_axis, prop: value }` instead of `x_axis.prop = value`
4
4
  import SettingsSection from '../layout/SettingsSection.svelte';
@@ -8,15 +8,19 @@ import { format } from 'd3-format';
8
8
  import { timeFormat } from 'd3-time-format';
9
9
  import { tooltip } from 'svelte-multiselect/attachments';
10
10
  import { normalize_y2_sync } from './interactions';
11
- import { get_scale_type_name } from './types';
12
- let { show_controls = $bindable(false), controls_open = $bindable(false), children, post_children, x_axis = $bindable({}), y_axis = $bindable({}), y2_axis = $bindable({}), display = $bindable({}), auto_x_range = [0, 1], auto_y_range = [0, 1], auto_y2_range = undefined, has_y2_points = false, show_ticks = false, controls_title = `plot`, controls_class = ``, toggle_props = {}, pane_props = {}, } = $props();
11
+ import { get_scale_type_name, is_scale_type_name, is_y2_sync_mode } from './types';
12
+ let { show_controls = $bindable(false), controls_open = $bindable(false), children, post_children, x_axis = $bindable({}), x2_axis = $bindable({}), y_axis = $bindable({}), y2_axis = $bindable({}), display = $bindable({}), auto_x_range = [0, 1], auto_x2_range = undefined, auto_y_range = [0, 1], auto_y2_range = undefined, has_x2_points = false, has_y2_points = false, show_ticks = false, controls_title = `plot`, controls_class = ``, toggle_props = {}, pane_props = {}, } = $props();
13
13
  // Range input state
14
- let range_inputs = $state({ x: [null, null], y: [null, null], y2: [null, null] });
14
+ let range_inputs = $state({ x: [null, null], x2: [null, null], y: [null, null], y2: [null, null] });
15
15
  let range_els = $state({});
16
- let x_includes_zero = $derived(((x_axis.range?.[0] ?? auto_x_range[0]) <= 0) &&
17
- ((x_axis.range?.[1] ?? auto_x_range[1]) >= 0));
18
- let y_includes_zero = $derived(((y_axis.range?.[0] ?? auto_y_range[0]) <= 0) &&
19
- ((y_axis.range?.[1] ?? auto_y_range[1]) >= 0));
16
+ // Check if an axis range spans zero (handles inverted ranges like [3.5, 1.4])
17
+ const range_spans_zero = (lo, hi) => Math.min(lo, hi) <= 0 && Math.max(lo, hi) >= 0;
18
+ let x_includes_zero = $derived(range_spans_zero(x_axis.range?.[0] ?? auto_x_range[0], x_axis.range?.[1] ?? auto_x_range[1]));
19
+ let x2_includes_zero = $derived(has_x2_points && auto_x2_range != null &&
20
+ range_spans_zero(x2_axis.range?.[0] ?? auto_x2_range[0], x2_axis.range?.[1] ?? auto_x2_range[1]));
21
+ let y_includes_zero = $derived(range_spans_zero(y_axis.range?.[0] ?? auto_y_range[0], y_axis.range?.[1] ?? auto_y_range[1]));
22
+ let y2_includes_zero = $derived(has_y2_points && auto_y2_range != null &&
23
+ range_spans_zero(y2_axis.range?.[0] ?? auto_y2_range[0], y2_axis.range?.[1] ?? auto_y2_range[1]));
20
24
  // Validation function for format specifiers
21
25
  function is_valid_format(format_string) {
22
26
  if (!format_string)
@@ -38,37 +42,53 @@ function is_valid_format(format_string) {
38
42
  // Handle format input changes
39
43
  const format_input_handler = (format_type) => (event) => {
40
44
  const input = event.target;
41
- const axes = { x: x_axis, y: y_axis, y2: y2_axis };
42
- const axis = axes[format_type];
43
- if (is_valid_format(input.value)) {
44
- input.classList.remove(`invalid`);
45
- axis.format = input.value;
45
+ if (!(input instanceof HTMLInputElement))
46
+ return;
47
+ if (!is_valid_format(input.value)) {
48
+ input.classList.add(`invalid`);
49
+ return;
46
50
  }
51
+ input.classList.remove(`invalid`);
52
+ if (format_type === `x`)
53
+ x_axis = { ...x_axis, format: input.value };
54
+ else if (format_type === `x2`)
55
+ x2_axis = { ...x2_axis, format: input.value };
56
+ else if (format_type === `y`)
57
+ y_axis = { ...y_axis, format: input.value };
47
58
  else
48
- input.classList.add(`invalid`);
59
+ y2_axis = { ...y2_axis, format: input.value };
49
60
  };
50
61
  // Handle range input changes
51
62
  const update_range = (axis, bound, value) => {
52
63
  const parsed = value === `` ? null : Number(value);
53
64
  range_inputs[axis][bound] = Number.isFinite(parsed) ? parsed : null;
54
65
  const [min, max] = range_inputs[axis];
55
- const auto = { x: auto_x_range, y: auto_y_range, y2: auto_y2_range }[axis];
66
+ const auto = { x: auto_x_range, x2: auto_x2_range, y: auto_y_range, y2: auto_y2_range }[axis];
56
67
  const invalid = min !== null && max !== null && min >= max;
57
68
  range_els[`${axis}-min`]?.classList.toggle(`invalid`, invalid);
58
69
  range_els[`${axis}-max`]?.classList.toggle(`invalid`, invalid);
59
70
  if (invalid)
60
71
  return;
61
- const axis_config = { x: x_axis, y: y_axis, y2: y2_axis }[axis];
72
+ const axis_config = { x: x_axis, x2: x2_axis, y: y_axis, y2: y2_axis }[axis];
73
+ const next_range = min === null && max === null
74
+ ? undefined
75
+ : [min ?? auto?.[0] ?? 0, max ?? auto?.[1] ?? 1];
62
76
  // If auto range is undefined, only set if both min and max are provided
63
77
  if (!auto && (min === null || max === null))
64
78
  return;
65
- axis_config.range = min === null && max === null
66
- ? undefined
67
- : [min ?? auto?.[0] ?? 0, max ?? auto?.[1] ?? 1];
79
+ if (axis === `x`)
80
+ x_axis = { ...axis_config, range: next_range };
81
+ else if (axis === `x2`)
82
+ x2_axis = { ...axis_config, range: next_range };
83
+ else if (axis === `y`)
84
+ y_axis = { ...axis_config, range: next_range };
85
+ else
86
+ y2_axis = { ...axis_config, range: next_range };
68
87
  };
69
88
  // Sync range inputs from props
70
89
  $effect(() => {
71
90
  range_inputs.x = [x_axis.range?.[0] ?? null, x_axis.range?.[1] ?? null];
91
+ range_inputs.x2 = [x2_axis.range?.[0] ?? null, x2_axis.range?.[1] ?? null];
72
92
  range_inputs.y = [y_axis.range?.[0] ?? null, y_axis.range?.[1] ?? null];
73
93
  range_inputs.y2 = [y2_axis.range?.[0] ?? null, y2_axis.range?.[1] ?? null];
74
94
  });
@@ -76,6 +96,7 @@ let ctrl_state = $derived({
76
96
  show_controls,
77
97
  controls_open,
78
98
  x_axis,
99
+ x2_axis,
79
100
  y_axis,
80
101
  y2_axis,
81
102
  display,
@@ -109,32 +130,49 @@ let ctrl_state = $derived({
109
130
  title="Display"
110
131
  current_values={{
111
132
  x_zero_line: display.x_zero_line,
133
+ x2_zero_line: display.x2_zero_line,
112
134
  y_zero_line: display.y_zero_line,
135
+ y2_zero_line: display.y2_zero_line,
113
136
  x_grid: display.x_grid,
137
+ x2_grid: display.x2_grid,
114
138
  y_grid: display.y_grid,
115
139
  y2_grid: display.y2_grid,
116
140
  }}
117
141
  on_reset={() => {
118
142
  display.x_zero_line = false
143
+ display.x2_zero_line = false
119
144
  display.y_zero_line = false
145
+ display.y2_zero_line = false
120
146
  display.x_grid = DEFAULTS.plot.show_x_grid
147
+ display.x2_grid = DEFAULTS.plot.show_x2_grid
121
148
  display.y_grid = DEFAULTS.plot.show_y_grid
122
149
  display.y2_grid = DEFAULTS.plot.show_y2_grid
123
150
  }}
124
151
  style="display: flex; flex-wrap: wrap; gap: 1ex; align-items: center"
125
152
  >
126
- {#if x_includes_zero || y_includes_zero}
153
+ {#if x_includes_zero || x2_includes_zero || y_includes_zero || y2_includes_zero}
127
154
  <span class="control-group" data-label="zero line">Zero line:
128
155
  {#if x_includes_zero}
129
156
  <label><input type="checkbox" bind:checked={display.x_zero_line} /> X</label>
130
157
  {/if}
158
+ {#if x2_includes_zero}
159
+ <label><input type="checkbox" bind:checked={display.x2_zero_line} />
160
+ X2</label>
161
+ {/if}
131
162
  {#if y_includes_zero}
132
163
  <label><input type="checkbox" bind:checked={display.y_zero_line} /> Y</label>
133
164
  {/if}
165
+ {#if y2_includes_zero}
166
+ <label><input type="checkbox" bind:checked={display.y2_zero_line} />
167
+ Y2</label>
168
+ {/if}
134
169
  </span>
135
170
  {/if}
136
171
  <span class="control-group" data-label="grid">Grid:
137
172
  <label><input type="checkbox" bind:checked={display.x_grid} /> X</label>
173
+ {#if has_x2_points}
174
+ <label><input type="checkbox" bind:checked={display.x2_grid} /> X2</label>
175
+ {/if}
138
176
  <label><input type="checkbox" bind:checked={display.y_grid} /> Y</label>
139
177
  {#if has_y2_points}
140
178
  <label><input type="checkbox" bind:checked={display.y2_grid} /> Y2</label>
@@ -145,9 +183,15 @@ let ctrl_state = $derived({
145
183
  <!-- Base Axis Range controls -->
146
184
  <SettingsSection
147
185
  title="Axis Range"
148
- current_values={{ x_range: x_axis.range, y_range: y_axis.range, y2_range: y2_axis.range }}
186
+ current_values={{
187
+ x_range: x_axis.range,
188
+ x2_range: x2_axis.range,
189
+ y_range: y_axis.range,
190
+ y2_range: y2_axis.range,
191
+ }}
149
192
  on_reset={() => {
150
193
  x_axis = { ...x_axis, range: [null, null] }
194
+ x2_axis = { ...x2_axis, range: [null, null] }
151
195
  y_axis = { ...y_axis, range: [null, null] }
152
196
  y2_axis = { ...y2_axis, range: [null, null] }
153
197
  Object.values(range_els).forEach((el) => el.classList.remove(`invalid`))
@@ -156,6 +200,7 @@ let ctrl_state = $derived({
156
200
  >
157
201
  {#each [
158
202
  [`x`, `X`],
203
+ ...(has_x2_points ? [[`x2`, `X2`]] : []),
159
204
  [`y`, `Y`],
160
205
  ...(has_y2_points ? [[`y2`, `Y2`]] : []),
161
206
  ] as
@@ -171,7 +216,7 @@ let ctrl_state = $derived({
171
216
  placeholder="auto"
172
217
  class="range-input"
173
218
  oninput={(e) => update_range(axis, 0, e.currentTarget.value)}
174
- onkeydown={(e) => e.key === `Enter` && e.currentTarget.blur()}
219
+ onkeydown={(e) => e.key === `Enter` && e.currentTarget?.blur()}
175
220
  /> to <input
176
221
  type="number"
177
222
  value={range_inputs[axis][1] ?? ``}
@@ -179,7 +224,7 @@ let ctrl_state = $derived({
179
224
  placeholder="auto"
180
225
  class="range-input"
181
226
  oninput={(e) => update_range(axis, 1, e.currentTarget.value)}
182
- onkeydown={(e) => e.key === `Enter` && e.currentTarget.blur()}
227
+ onkeydown={(e) => e.key === `Enter` && e.currentTarget?.blur()}
183
228
  />
184
229
  </label>
185
230
  {/each}
@@ -239,11 +284,13 @@ let ctrl_state = $derived({
239
284
  title="Scale Type"
240
285
  current_values={{
241
286
  x_scale: get_scale_type_name(x_axis.scale_type),
287
+ x2_scale: get_scale_type_name(x2_axis.scale_type),
242
288
  y_scale: get_scale_type_name(y_axis.scale_type),
243
289
  y2_scale: get_scale_type_name(y2_axis.scale_type),
244
290
  }}
245
291
  on_reset={() => {
246
292
  x_axis = { ...x_axis, scale_type: `linear` }
293
+ x2_axis = { ...x2_axis, scale_type: `linear` }
247
294
  y_axis = { ...y_axis, scale_type: `linear` }
248
295
  y2_axis = { ...y2_axis, scale_type: `linear` }
249
296
  }}
@@ -253,9 +300,10 @@ let ctrl_state = $derived({
253
300
  <select
254
301
  value={get_scale_type_name(x_axis.scale_type)}
255
302
  onchange={(e) => {
303
+ const val = e.currentTarget.value
256
304
  x_axis = {
257
305
  ...x_axis,
258
- scale_type: e.currentTarget.value as ScaleTypeName,
306
+ scale_type: is_scale_type_name(val) ? val : `linear`,
259
307
  }
260
308
  }}
261
309
  >
@@ -264,13 +312,32 @@ let ctrl_state = $derived({
264
312
  <option value="arcsinh">Arcsinh</option>
265
313
  </select>
266
314
  </label>
315
+ {#if has_x2_points}
316
+ <label>X2:
317
+ <select
318
+ value={get_scale_type_name(x2_axis.scale_type)}
319
+ onchange={(e) => {
320
+ const val = e.currentTarget.value
321
+ x2_axis = {
322
+ ...x2_axis,
323
+ scale_type: is_scale_type_name(val) ? val : `linear`,
324
+ }
325
+ }}
326
+ >
327
+ <option value="linear">Linear</option>
328
+ <option value="log">Log</option>
329
+ <option value="arcsinh">Arcsinh</option>
330
+ </select>
331
+ </label>
332
+ {/if}
267
333
  <label>Y:
268
334
  <select
269
335
  value={get_scale_type_name(y_axis.scale_type)}
270
336
  onchange={(e) => {
337
+ const val = e.currentTarget.value
271
338
  y_axis = {
272
339
  ...y_axis,
273
- scale_type: e.currentTarget.value as ScaleTypeName,
340
+ scale_type: is_scale_type_name(val) ? val : `linear`,
274
341
  }
275
342
  }}
276
343
  >
@@ -284,9 +351,10 @@ let ctrl_state = $derived({
284
351
  <select
285
352
  value={get_scale_type_name(y2_axis.scale_type)}
286
353
  onchange={(e) => {
354
+ const val = e.currentTarget.value
287
355
  y2_axis = {
288
356
  ...y2_axis,
289
- scale_type: e.currentTarget.value as ScaleTypeName,
357
+ scale_type: is_scale_type_name(val) ? val : `linear`,
290
358
  }
291
359
  }}
292
360
  >
@@ -318,7 +386,8 @@ let ctrl_state = $derived({
318
386
  value={current_sync.mode}
319
387
  aria-label="Y2 axis synchronization mode"
320
388
  onchange={(e) => {
321
- const mode = e.currentTarget.value as Y2SyncMode
389
+ const val = e.currentTarget.value
390
+ const mode = is_y2_sync_mode(val) ? val : `none`
322
391
  if (mode === `none`) {
323
392
  y2_axis = { ...y2_axis, sync: undefined }
324
393
  } else if (mode === `align`) {
@@ -365,11 +434,13 @@ let ctrl_state = $derived({
365
434
  data-testid="tick-format-section"
366
435
  current_values={{
367
436
  x_format: x_axis.format,
437
+ x2_format: x2_axis.format,
368
438
  y_format: y_axis.format,
369
439
  y2_format: y2_axis.format,
370
440
  }}
371
441
  on_reset={() => {
372
442
  x_axis = { ...x_axis, format: DEFAULTS.plot.x_format }
443
+ x2_axis = { ...x2_axis, format: DEFAULTS.plot.x2_format }
373
444
  y_axis = { ...y_axis, format: DEFAULTS.plot.y_format }
374
445
  y2_axis = { ...y2_axis, format: DEFAULTS.plot.y2_format }
375
446
  }}
@@ -384,6 +455,17 @@ let ctrl_state = $derived({
384
455
  oninput={format_input_handler(`x`)}
385
456
  />
386
457
  </label>
458
+ {#if has_x2_points}
459
+ <label style="white-space: nowrap">X2-axis:
460
+ <input
461
+ type="text"
462
+ value={x2_axis.format ?? DEFAULTS.plot.x2_format}
463
+ placeholder=".2~s / .0% / %Y-%m-%d"
464
+ oninput={format_input_handler(`x2`)}
465
+ style="width: 100%"
466
+ />
467
+ </label>
468
+ {/if}
387
469
  <label style="white-space: nowrap">Y-axis:
388
470
  <input
389
471
  type="text"
@@ -1,4 +1,4 @@
1
1
  import type { PlotControlsProps } from './index';
2
- declare const PlotControls: import("svelte").Component<PlotControlsProps, {}, "display" | "show_controls" | "controls_open" | "x_axis" | "y_axis" | "y2_axis">;
2
+ declare const PlotControls: import("svelte").Component<PlotControlsProps, {}, "display" | "show_controls" | "controls_open" | "x_axis" | "x2_axis" | "y_axis" | "y2_axis">;
3
3
  type PlotControls = ReturnType<typeof PlotControls>;
4
4
  export default PlotControls;
@@ -47,7 +47,7 @@ function handle_legend_mouse_down(event) {
47
47
  return;
48
48
  // Only start drag if clicking on empty areas (not on legend items)
49
49
  const target = event.target;
50
- if (target.closest(`.legend-item`))
50
+ if (target instanceof Element && target.closest(`.legend-item`))
51
51
  return;
52
52
  event.preventDefault();
53
53
  event.stopPropagation();
@@ -130,7 +130,8 @@ function handle_click_outside(evt) {
130
130
  if (!dropdown_open)
131
131
  return;
132
132
  const target = evt.target;
133
- if (!trigger_el?.contains(target) && !portal_el?.contains(target)) {
133
+ if (!(target instanceof Node) ||
134
+ (!trigger_el?.contains(target) && !portal_el?.contains(target))) {
134
135
  close_dropdown();
135
136
  }
136
137
  }
@@ -1,9 +1,10 @@
1
1
  <script lang="ts">// ReferenceLine: 2D reference lines with annotations (horizontal, vertical, diagonal, segment, line)
2
2
  import { calculate_annotation_position, resolve_line_endpoints, } from './reference-line';
3
3
  import { REF_LINE_STYLE_DEFAULTS } from './types';
4
- let { ref_line, line_idx, x_min, x_max, y_min, y_max, x_scale, y_scale, y2_scale, clip_path_id, hovered_line_idx = null, on_click, on_hover, } = $props();
4
+ let { ref_line, line_idx, x_min, x_max, y_min, y_max, x_scale, x2_scale, y_scale, y2_scale, clip_path_id, hovered_line_idx = null, on_click, on_hover, } = $props();
5
5
  let endpoints = $derived(resolve_line_endpoints(ref_line, { x_min, x_max, y_min, y_max }, {
6
6
  x_scale,
7
+ x2_scale,
7
8
  y_scale,
8
9
  y2_scale,
9
10
  }));
@@ -7,6 +7,7 @@ type $$ComponentProps = {
7
7
  y_min: number;
8
8
  y_max: number;
9
9
  x_scale: (val: number) => number;
10
+ x2_scale?: (val: number) => number;
10
11
  y_scale: (val: number) => number;
11
12
  y2_scale?: (val: number) => number;
12
13
  clip_path_id: string;
@@ -25,9 +25,7 @@ let [x_min, x_max] = $derived(span_or(ref_plane.x_span, x_range));
25
25
  let [y_min, y_max] = $derived(span_or(ref_plane.y_span, y_range));
26
26
  let [z_min, z_max] = $derived(span_or(ref_plane.z_span, z_range));
27
27
  // Helper to create quad from 4 corner coords
28
- function quad(coords) {
29
- return create_quad_geometry(coords.map(([ux, uy, uz]) => to_vec3(ux, uy, uz)));
30
- }
28
+ const quad = (coords) => create_quad_geometry(coords.map(([ux, uy, uz]) => to_vec3(ux, uy, uz)));
31
29
  // Compute plane geometry based on type - returns result to use in $effect
32
30
  function compute_geometry() {
33
31
  if (ref_plane.visible === false)