matterviz 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/EmptyState.svelte +10 -4
- package/dist/FilePicker.svelte +48 -60
- package/dist/Icon.svelte +7 -4
- package/dist/MillerIndexInput.svelte +2 -2
- package/dist/api/optimade.js +10 -7
- package/dist/app.css +68 -0
- package/dist/brillouin/BrillouinZone.svelte +90 -91
- package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
- package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
- package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
- package/dist/brillouin/BrillouinZoneScene.svelte +46 -68
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
- package/dist/brillouin/compute.js +10 -16
- package/dist/brillouin/geometry.js +2 -2
- package/dist/chempot-diagram/ChemPotDiagram.svelte +48 -50
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +61 -169
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +559 -755
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
- package/dist/chempot-diagram/async-compute.svelte.js +13 -14
- package/dist/chempot-diagram/color.d.ts +21 -1
- package/dist/chempot-diagram/color.js +70 -1
- package/dist/chempot-diagram/compute.d.ts +7 -0
- package/dist/chempot-diagram/compute.js +85 -26
- package/dist/chempot-diagram/controls-state.svelte.js +1 -1
- package/dist/chempot-diagram/export.js +1 -6
- package/dist/chempot-diagram/temperature.js +9 -10
- package/dist/colors/index.d.ts +0 -4
- package/dist/colors/index.js +19 -20
- package/dist/composition/BarChart.svelte +30 -26
- package/dist/composition/BubbleChart.svelte +17 -17
- package/dist/composition/Composition.svelte +10 -19
- package/dist/composition/Formula.svelte +20 -27
- package/dist/composition/FormulaFilter.svelte +115 -184
- package/dist/composition/PieChart.svelte +55 -41
- package/dist/composition/format.js +7 -9
- package/dist/composition/index.d.ts +2 -0
- package/dist/composition/index.js +14 -0
- package/dist/composition/parse.d.ts +2 -2
- package/dist/composition/parse.js +61 -115
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +17 -26
- package/dist/convex-hull/ConvexHull.svelte +12 -15
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull2D.svelte +93 -94
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +127 -186
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +131 -180
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
- package/dist/convex-hull/ConvexHullControls.svelte +46 -48
- package/dist/convex-hull/ConvexHullStats.svelte +193 -195
- package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
- package/dist/convex-hull/GasPressureControls.svelte +5 -12
- package/dist/convex-hull/StructurePopup.svelte +18 -22
- package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
- package/dist/convex-hull/TemperatureSlider.svelte +4 -10
- package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
- package/dist/convex-hull/gas-thermodynamics.js +21 -53
- package/dist/convex-hull/helpers.d.ts +8 -10
- package/dist/convex-hull/helpers.js +37 -43
- package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
- package/dist/convex-hull/thermodynamics.js +37 -44
- package/dist/coordination/CoordinationBarPlot.svelte +49 -53
- package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
- package/dist/coordination/calc-coordination.d.ts +1 -1
- package/dist/coordination/calc-coordination.js +28 -25
- package/dist/element/BohrAtom.svelte +5 -9
- package/dist/element/ElementHeading.svelte +4 -1
- package/dist/element/ElementPhoto.svelte +11 -9
- package/dist/element/ElementStats.svelte +12 -10
- package/dist/element/ElementTile.svelte +44 -67
- package/dist/element/Nucleus.svelte +4 -2
- package/dist/element/data.d.ts +3 -2
- package/dist/element/data.js +5 -1
- package/dist/element/helpers.d.ts +4 -0
- package/dist/element/helpers.js +18 -0
- package/dist/element/index.d.ts +2 -5
- package/dist/element/index.js +4 -19
- package/dist/feedback/DragOverlay.svelte +5 -5
- package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
- package/dist/feedback/StatusMessage.svelte +7 -4
- package/dist/fermi-surface/FermiSlice.svelte +21 -18
- package/dist/fermi-surface/FermiSurface.svelte +35 -44
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +7 -13
- package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +64 -136
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
- package/dist/fermi-surface/compute.js +25 -58
- package/dist/fermi-surface/parse.js +54 -88
- package/dist/file-viewer/JsonBrowser.svelte +1043 -0
- package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
- package/dist/file-viewer/PlotPanel.svelte +350 -0
- package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
- package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
- package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
- package/dist/file-viewer/detect.d.ts +11 -0
- package/dist/file-viewer/detect.js +381 -0
- package/dist/file-viewer/eligibility.d.ts +4 -0
- package/dist/file-viewer/eligibility.js +53 -0
- package/dist/file-viewer/host-protocol.d.ts +50 -0
- package/dist/file-viewer/host-transfer.d.ts +25 -0
- package/dist/file-viewer/host-transfer.js +42 -0
- package/dist/file-viewer/index.d.ts +5 -0
- package/dist/file-viewer/index.js +5 -0
- package/dist/file-viewer/main.d.ts +44 -0
- package/dist/file-viewer/main.js +535 -0
- package/dist/file-viewer/parse.d.ts +9 -0
- package/dist/file-viewer/parse.js +170 -0
- package/dist/file-viewer/plot-utils.d.ts +24 -0
- package/dist/file-viewer/plot-utils.js +191 -0
- package/dist/file-viewer/types.d.ts +4 -0
- package/dist/file-viewer/types.js +5 -0
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +153 -219
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
- package/dist/heatmap-matrix/index.d.ts +5 -0
- package/dist/icons.d.ts +4 -0
- package/dist/icons.js +4 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/io/ExportPane.svelte +11 -7
- package/dist/io/decompress.d.ts +4 -1
- package/dist/io/decompress.js +24 -36
- package/dist/io/export.d.ts +11 -4
- package/dist/io/export.js +75 -19
- package/dist/io/fetch.d.ts +0 -3
- package/dist/io/fetch.js +0 -11
- package/dist/io/file-drop.js +60 -35
- package/dist/io/index.d.ts +0 -1
- package/dist/io/index.js +2 -9
- package/dist/io/is-binary.d.ts +9 -0
- package/dist/io/is-binary.js +45 -1
- package/dist/io/url-drop.d.ts +2 -0
- package/dist/io/url-drop.js +40 -40
- package/dist/isosurface/Isosurface.svelte +700 -215
- package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
- package/dist/isosurface/IsosurfaceControls.svelte +590 -116
- package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
- package/dist/isosurface/VolumeSlice.svelte +224 -0
- package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
- package/dist/isosurface/coloring.d.ts +20 -0
- package/dist/isosurface/coloring.js +118 -0
- package/dist/isosurface/geometry-worker-types.d.ts +38 -0
- package/dist/isosurface/geometry.worker.d.ts +1 -0
- package/dist/isosurface/geometry.worker.js +59 -0
- package/dist/isosurface/grid.d.ts +10 -0
- package/dist/isosurface/grid.js +31 -0
- package/dist/isosurface/index.d.ts +4 -0
- package/dist/isosurface/index.js +4 -0
- package/dist/isosurface/parse-vaspwave.d.ts +3 -0
- package/dist/isosurface/parse-vaspwave.js +138 -0
- package/dist/isosurface/parse.js +6 -6
- package/dist/isosurface/profile.d.ts +12 -0
- package/dist/isosurface/profile.js +19 -0
- package/dist/isosurface/sampling.d.ts +34 -0
- package/dist/isosurface/sampling.js +408 -0
- package/dist/isosurface/slice-rendering.d.ts +13 -0
- package/dist/isosurface/slice-rendering.js +79 -0
- package/dist/isosurface/slice.d.ts +22 -2
- package/dist/isosurface/slice.js +200 -116
- package/dist/isosurface/types.d.ts +24 -1
- package/dist/isosurface/types.js +120 -8
- package/dist/json-path.d.ts +4 -0
- package/dist/json-path.js +89 -0
- package/dist/labels.d.ts +6 -2
- package/dist/labels.js +44 -14
- package/dist/layout/FullscreenButton.svelte +2 -1
- package/dist/layout/FullscreenToggle.svelte +10 -4
- package/dist/layout/InfoCard.svelte +8 -21
- package/dist/layout/InfoTag.svelte +1 -3
- package/dist/layout/NumberRangeInput.svelte +46 -0
- package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
- package/dist/layout/PropertyFilter.svelte +2 -6
- package/dist/layout/SettingsSection.svelte +57 -62
- package/dist/layout/SettingsSection.svelte.d.ts +6 -7
- package/dist/layout/SubpageGrid.svelte +3 -1
- package/dist/layout/ViewerChrome.svelte +16 -11
- package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
- package/dist/layout/fullscreen.js +3 -5
- package/dist/layout/fullscreen.svelte.js +1 -2
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.js +1 -0
- package/dist/layout/json-tree/JsonNode.svelte +22 -59
- package/dist/layout/json-tree/JsonTree.svelte +101 -172
- package/dist/layout/json-tree/JsonValue.svelte +9 -32
- package/dist/layout/json-tree/utils.d.ts +0 -3
- package/dist/layout/json-tree/utils.js +50 -188
- package/dist/marching-cubes.d.ts +8 -1
- package/dist/marching-cubes.js +115 -48
- package/dist/math.d.ts +5 -2
- package/dist/math.js +48 -38
- package/dist/overlays/ContextMenu.svelte +19 -34
- package/dist/overlays/CopyButton.svelte +11 -5
- package/dist/overlays/DragControlTab.svelte +6 -1
- package/dist/overlays/DraggablePane.svelte +110 -74
- package/dist/overlays/DraggablePane.svelte.d.ts +2 -1
- package/dist/overlays/GlassChip.svelte +32 -0
- package/dist/overlays/GlassChip.svelte.d.ts +8 -0
- package/dist/overlays/InfoPaneCards.svelte +11 -23
- package/dist/overlays/index.d.ts +7 -0
- package/dist/overlays/index.js +26 -0
- package/dist/overlays/portal.d.ts +2 -0
- package/dist/overlays/portal.js +14 -0
- package/dist/periodic-table/PeriodicTable.svelte +113 -145
- package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
- package/dist/periodic-table/PeriodicTableControls.svelte +37 -115
- package/dist/periodic-table/TableInset.svelte +9 -4
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +68 -105
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
- package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
- package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
- package/dist/phase-diagram/build-diagram.js +4 -9
- package/dist/phase-diagram/diagram-input.d.ts +1 -2
- package/dist/phase-diagram/parse.js +15 -15
- package/dist/phase-diagram/svg-to-diagram.js +28 -27
- package/dist/phase-diagram/utils.js +2 -3
- package/dist/plot/bar/BarPlot.svelte +461 -426
- package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
- package/dist/plot/bar/BarPlotControls.svelte +1 -3
- package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
- package/dist/plot/bar/SpacegroupBarPlot.svelte +46 -77
- package/dist/plot/bar/data.d.ts +5 -4
- package/dist/plot/bar/data.js +2 -1
- package/dist/plot/box/BoxPlot.svelte +322 -226
- package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
- package/dist/plot/box/Violin.svelte.d.ts +1 -0
- package/dist/plot/box/box-plot.js +1 -1
- package/dist/plot/core/auto-place.d.ts +1 -1
- package/dist/plot/core/auto-place.js +2 -2
- package/dist/plot/core/axis-utils.d.ts +12 -7
- package/dist/plot/core/axis-utils.js +48 -48
- package/dist/plot/core/components/AxisLabel.svelte +82 -20
- package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
- package/dist/plot/core/components/ColorBar.svelte +101 -106
- package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
- package/dist/plot/core/components/FillArea.svelte +10 -17
- package/dist/plot/core/components/HierarchyControls.svelte +249 -0
- package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
- package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
- package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
- package/dist/plot/core/components/Line.svelte +18 -9
- package/dist/plot/core/components/Line.svelte.d.ts +2 -0
- package/dist/plot/core/components/PlotAxis.svelte +40 -17
- package/dist/plot/core/components/PlotControls.svelte +65 -41
- package/dist/plot/core/components/PlotLegend.svelte +31 -35
- package/dist/plot/core/components/PlotMarginals.svelte +616 -0
- package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
- package/dist/plot/core/components/PlotTooltip.svelte +1 -1
- package/dist/plot/core/components/PortalSelect.svelte +4 -8
- package/dist/plot/core/components/ReferenceLine.svelte +27 -24
- package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
- package/dist/plot/core/components/ReferencePlane.svelte +7 -8
- package/dist/plot/core/components/ZeroLines.svelte +4 -8
- package/dist/plot/core/components/ZoomRect.svelte +1 -2
- package/dist/plot/core/components/index.d.ts +1 -0
- package/dist/plot/core/components/index.js +1 -0
- package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
- package/dist/plot/core/data-cleaning-signal.js +467 -0
- package/dist/plot/core/data-cleaning.d.ts +2 -42
- package/dist/plot/core/data-cleaning.js +27 -474
- package/dist/plot/core/data-transform.d.ts +1 -2
- package/dist/plot/core/data-transform.js +9 -15
- package/dist/plot/core/fill-utils.d.ts +3 -1
- package/dist/plot/core/fill-utils.js +28 -6
- package/dist/plot/core/index.d.ts +1 -0
- package/dist/plot/core/index.js +1 -0
- package/dist/plot/core/interactions.js +0 -2
- package/dist/plot/core/layout.d.ts +15 -6
- package/dist/plot/core/layout.js +57 -38
- package/dist/plot/core/marginals.d.ts +170 -0
- package/dist/plot/core/marginals.js +436 -0
- package/dist/plot/core/pan-zoom.svelte.d.ts +2 -4
- package/dist/plot/core/pan-zoom.svelte.js +34 -17
- package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
- package/dist/plot/core/placed-tween.svelte.js +68 -21
- package/dist/plot/core/reference-line.js +1 -1
- package/dist/plot/core/scales.d.ts +23 -0
- package/dist/plot/core/scales.js +39 -13
- package/dist/plot/core/svg.js +0 -1
- package/dist/plot/core/types/fills.d.ts +101 -0
- package/dist/plot/core/types/fills.js +15 -0
- package/dist/plot/core/types/plot-3d.d.ts +87 -0
- package/dist/plot/core/types/plot-3d.js +4 -0
- package/dist/plot/core/types/reference-lines.d.ts +140 -0
- package/dist/plot/core/types/reference-lines.js +9 -0
- package/dist/plot/core/types.d.ts +29 -324
- package/dist/plot/core/types.js +23 -20
- package/dist/plot/core/utils/hierarchy-chart.d.ts +52 -0
- package/dist/plot/core/utils/hierarchy-chart.js +191 -0
- package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
- package/dist/plot/core/utils/hierarchy-labels.js +100 -0
- package/dist/plot/core/utils/label-placement.js +2 -2
- package/dist/plot/histogram/Histogram.svelte +314 -340
- package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
- package/dist/plot/histogram/HistogramControls.svelte +30 -28
- package/dist/plot/histogram/histogram.d.ts +31 -0
- package/dist/plot/histogram/histogram.js +70 -0
- package/dist/plot/histogram/index.d.ts +1 -0
- package/dist/plot/histogram/index.js +1 -0
- package/dist/plot/index.d.ts +1 -0
- package/dist/plot/index.js +1 -0
- package/dist/plot/sankey/Sankey.svelte +78 -69
- package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
- package/dist/plot/sankey/SankeyControls.svelte +22 -16
- package/dist/plot/sankey/sankey.js +13 -9
- package/dist/plot/scatter/BinnedScatterPlot.svelte +311 -141
- package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
- package/dist/plot/scatter/ElementScatter.svelte +4 -1
- package/dist/plot/scatter/ScatterPlot.svelte +517 -410
- package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
- package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
- package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
- package/dist/plot/scatter/ScatterPoint.svelte +16 -9
- package/dist/plot/scatter/adaptive-density.d.ts +1 -1
- package/dist/plot/scatter/adaptive-density.js +36 -20
- package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
- package/dist/plot/scatter/binned-scatter-types.js +6 -1
- package/dist/plot/scatter/scatter-data.d.ts +1 -1
- package/dist/plot/scatter/scatter-data.js +8 -7
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
- package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
- package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
- package/dist/plot/sunburst/Sunburst.svelte +269 -347
- package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
- package/dist/plot/sunburst/index.d.ts +1 -1
- package/dist/plot/sunburst/index.js +2 -1
- package/dist/plot/sunburst/render.d.ts +2 -2
- package/dist/plot/sunburst/render.js +47 -22
- package/dist/plot/sunburst/sunburst.d.ts +5 -1
- package/dist/plot/sunburst/sunburst.js +10 -3
- package/dist/plot/treemap/Treemap.svelte +1022 -0
- package/dist/plot/treemap/Treemap.svelte.d.ts +90 -0
- package/dist/plot/treemap/index.d.ts +4 -0
- package/dist/plot/treemap/index.js +4 -0
- package/dist/plot/treemap/labels.d.ts +38 -0
- package/dist/plot/treemap/labels.js +80 -0
- package/dist/plot/treemap/treemap.d.ts +28 -0
- package/dist/plot/treemap/treemap.js +102 -0
- package/dist/rdf/RdfPlot.svelte +37 -59
- package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
- package/dist/rdf/calc-rdf.js +63 -52
- package/dist/rdf/index.d.ts +0 -1
- package/dist/sanitize.js +85 -27
- package/dist/scene/SceneCamera.svelte +1 -1
- package/dist/scene/SceneCamera.svelte.d.ts +1 -1
- package/dist/scene/bind-renderer.svelte.js +14 -6
- package/dist/scene/index.d.ts +1 -2
- package/dist/scene/index.js +1 -1
- package/dist/scene/{props.js → props.svelte.js} +15 -1
- package/dist/settings.d.ts +19 -9
- package/dist/settings.js +229 -525
- package/dist/spectral/Bands.svelte +207 -221
- package/dist/spectral/BandsAndDos.svelte +11 -9
- package/dist/spectral/BrillouinBandsDos.svelte +19 -42
- package/dist/spectral/Dos.svelte +92 -93
- package/dist/spectral/helpers.d.ts +3 -3
- package/dist/spectral/helpers.js +65 -140
- package/dist/state.svelte.js +5 -18
- package/dist/structure/Arrow.svelte +5 -18
- package/dist/structure/ArrowInstances.svelte +160 -0
- package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
- package/dist/structure/AtomLegend.svelte +120 -85
- package/dist/structure/AtomLegend.svelte.d.ts +2 -3
- package/dist/structure/Bond.svelte +31 -23
- package/dist/structure/CanvasTooltip.svelte +15 -3
- package/dist/structure/CellSelect.svelte +45 -35
- package/dist/structure/Cylinder.svelte +24 -40
- package/dist/structure/InstancedAtoms.svelte +114 -0
- package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
- package/dist/structure/Lattice.svelte +85 -149
- package/dist/structure/SiteLabels.svelte +122 -0
- package/dist/structure/SiteLabels.svelte.d.ts +18 -0
- package/dist/structure/Structure.svelte +636 -504
- package/dist/structure/Structure.svelte.d.ts +4 -2
- package/dist/structure/StructureCarousel.svelte +637 -0
- package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
- package/dist/structure/StructureControls.svelte +165 -425
- package/dist/structure/StructureControls.svelte.d.ts +1 -1
- package/dist/structure/StructureExportPane.svelte +17 -21
- package/dist/structure/StructureInfoPane.svelte +128 -133
- package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
- package/dist/structure/StructureScene.svelte +535 -578
- package/dist/structure/StructureScene.svelte.d.ts +6 -2
- package/dist/structure/StructureViewport.svelte +451 -0
- package/dist/structure/StructureViewport.svelte.d.ts +65 -0
- package/dist/structure/atom-label-placement.d.ts +16 -12
- package/dist/structure/atom-label-placement.js +70 -37
- package/dist/structure/atom-properties.d.ts +2 -0
- package/dist/structure/atom-properties.js +105 -38
- package/dist/structure/bond-order-perception.js +3 -8
- package/dist/structure/bonding.d.ts +9 -3
- package/dist/structure/bonding.js +95 -46
- package/dist/structure/edit-history.d.ts +6 -0
- package/dist/structure/edit-history.js +27 -0
- package/dist/structure/export.d.ts +1 -0
- package/dist/structure/export.js +89 -105
- package/dist/structure/format-detect.d.ts +1 -0
- package/dist/structure/format-detect.js +20 -0
- package/dist/structure/geometry.d.ts +9 -0
- package/dist/structure/geometry.js +27 -0
- package/dist/structure/index.d.ts +16 -1
- package/dist/structure/index.js +15 -10
- package/dist/structure/measure.d.ts +1 -1
- package/dist/structure/measure.js +6 -12
- package/dist/structure/parse.d.ts +2 -1
- package/dist/structure/parse.js +272 -313
- package/dist/structure/partial-occupancy.js +10 -5
- package/dist/structure/pbc.js +85 -107
- package/dist/structure/polyhedra.d.ts +0 -1
- package/dist/structure/polyhedra.js +7 -21
- package/dist/structure/prop-groups.d.ts +85 -0
- package/dist/structure/prop-groups.js +18 -0
- package/dist/structure/supercell.d.ts +1 -2
- package/dist/structure/supercell.js +7 -13
- package/dist/symmetry/SymmetryElements.svelte +11 -15
- package/dist/symmetry/SymmetryStats.svelte +55 -71
- package/dist/symmetry/WyckoffTable.svelte +10 -28
- package/dist/symmetry/cell-transform.js +6 -14
- package/dist/symmetry/index.d.ts +1 -0
- package/dist/symmetry/index.js +13 -10
- package/dist/symmetry/spacegroups.js +3 -2
- package/dist/table/HeatmapTable.svelte +1142 -447
- package/dist/table/HeatmapTable.svelte.d.ts +12 -2
- package/dist/table/ToggleMenu.svelte +168 -53
- package/dist/table/ToggleMenu.svelte.d.ts +1 -1
- package/dist/table/index.d.ts +21 -6
- package/dist/table/index.js +34 -21
- package/dist/theme/ThemeControl.svelte +16 -8
- package/dist/theme/embedded.d.ts +18 -0
- package/dist/theme/embedded.js +206 -0
- package/dist/theme/index.d.ts +5 -5
- package/dist/theme/index.js +5 -12
- package/dist/theme/themes.mjs +44 -66
- package/dist/tooltip/KCoords.svelte +4 -1
- package/dist/tooltip/TooltipContent.svelte +3 -6
- package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
- package/dist/tooltip/index.d.ts +8 -1
- package/dist/trajectory/Trajectory.svelte +613 -386
- package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
- package/dist/trajectory/TrajectoryError.svelte +12 -74
- package/dist/trajectory/TrajectoryExportPane.svelte +14 -32
- package/dist/trajectory/TrajectoryInfoPane.svelte +127 -164
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
- package/dist/trajectory/extract.js +61 -49
- package/dist/trajectory/format-detect.d.ts +2 -0
- package/dist/trajectory/format-detect.js +17 -13
- package/dist/trajectory/frame-reader.d.ts +2 -0
- package/dist/trajectory/frame-reader.js +35 -32
- package/dist/trajectory/helpers.d.ts +2 -0
- package/dist/trajectory/helpers.js +34 -56
- package/dist/trajectory/index.d.ts +1 -0
- package/dist/trajectory/index.js +5 -8
- package/dist/trajectory/parse/ase.js +1 -1
- package/dist/trajectory/parse/h5-utils.d.ts +13 -0
- package/dist/trajectory/parse/h5-utils.js +109 -0
- package/dist/trajectory/parse/hdf5.d.ts +1 -1
- package/dist/trajectory/parse/hdf5.js +116 -106
- package/dist/trajectory/parse/index.d.ts +6 -6
- package/dist/trajectory/parse/index.js +25 -33
- package/dist/trajectory/parse/lammps.js +8 -12
- package/dist/trajectory/parse/vasp.js +10 -7
- package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
- package/dist/trajectory/parse/vaspout-electronic.js +207 -0
- package/dist/trajectory/parse/vaspout-h5.d.ts +4 -0
- package/dist/trajectory/parse/vaspout-h5.js +281 -0
- package/dist/trajectory/parse/xyz.js +59 -9
- package/dist/trajectory/plotting.d.ts +8 -9
- package/dist/trajectory/plotting.js +113 -64
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +7 -0
- package/dist/xrd/XrdPlot.svelte +79 -118
- package/dist/xrd/broadening.js +2 -1
- package/dist/xrd/calc-xrd.js +24 -62
- package/dist/xrd/parse.d.ts +0 -1
- package/dist/xrd/parse.js +69 -95
- package/package.json +94 -34
- package/readme.md +6 -5
- package/dist/api/mp.d.ts +0 -6
- package/dist/api/mp.js +0 -22
- package/dist/plot/sunburst/SunburstControls.svelte +0 -200
- package/dist/scene/types.d.ts +0 -26
- package/dist/tooltip/types.d.ts +0 -8
- package/dist/trajectory/constants.d.ts +0 -6
- package/dist/trajectory/constants.js +0 -11
- /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
- /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
// Shared marginal-distribution model for all 2D plots. Pure and unit-tested: types,
|
|
2
|
+
// shorthand resolution, pad reservation, strip geometry, and the curve math (histogram /
|
|
3
|
+
// kde / cdf / rug). The PlotMarginals.svelte renderer consumes these; each plot only adapts
|
|
4
|
+
// its data to MarginalSeriesInput and folds reserve_marginal_pad into its `pad`.
|
|
5
|
+
import { sorted_range } from './interactions';
|
|
6
|
+
import { get_scale_type_name } from './types';
|
|
7
|
+
import { gaussian_kde } from '../box/kde';
|
|
8
|
+
import { bin } from 'd3-array';
|
|
9
|
+
export const MARGINAL_SIDES = [`top`, `bottom`, `left`, `right`];
|
|
10
|
+
// Top/bottom strips run along the x (horizontal) positional axis; left/right run along y
|
|
11
|
+
const is_x_side = (side) => side === `top` || side === `bottom`;
|
|
12
|
+
// Build a MarginalAxis from a host plot's scale fn + current range, reading scale_type/format/label
|
|
13
|
+
// off the plot's AxisConfig (DRYs the per-axis object every host plot passes to PlotMarginals; the
|
|
14
|
+
// renderer defaults a missing scale_type to `linear`). `tick_label` maps a position to a label.
|
|
15
|
+
export const marginal_axis = (scale, range, axis, tick_label) => ({
|
|
16
|
+
scale,
|
|
17
|
+
range,
|
|
18
|
+
scale_type: axis.scale_type,
|
|
19
|
+
format: axis.format,
|
|
20
|
+
label: axis.label,
|
|
21
|
+
tick_label,
|
|
22
|
+
});
|
|
23
|
+
// Pixel tolerance for rug-tick hit-testing (a tick farther than this from the pointer is a miss)
|
|
24
|
+
export const MARGINAL_HIT_TOLERANCE_PX = 10;
|
|
25
|
+
// Pure hit-test: given a strip's render context and a pointer position in wrapper px, return the
|
|
26
|
+
// nearest datum as a MarginalHover (or null for a miss). ctx.curves is kind-homogeneous, so we
|
|
27
|
+
// branch once on the first curve's kind, matching only along the shared positional axis. Non-finite
|
|
28
|
+
// data is skipped (consistent with the renderer) so custom reduce/data curves can't yield ghost hits.
|
|
29
|
+
export function marginal_hit(ctx, px, py) {
|
|
30
|
+
const { side, curves, positional_scale, value_scale, baseline, config, scale_type } = ctx;
|
|
31
|
+
const is_x = is_x_side(side);
|
|
32
|
+
const pointer_pos = is_x ? px : py; // along the shared positional axis
|
|
33
|
+
const pointer_cross = is_x ? py : px; // across the strip thickness (the value direction)
|
|
34
|
+
const kind = curves[0]?.curve.kind;
|
|
35
|
+
if (!kind)
|
|
36
|
+
return null;
|
|
37
|
+
const contains_cross = (value_px) => Number.isFinite(value_px) &&
|
|
38
|
+
pointer_cross >= Math.min(baseline, value_px) &&
|
|
39
|
+
pointer_cross <= Math.max(baseline, value_px);
|
|
40
|
+
const hover = (curve, extra) => ({
|
|
41
|
+
side,
|
|
42
|
+
x: px,
|
|
43
|
+
y: py,
|
|
44
|
+
color: config.color ?? curve.color,
|
|
45
|
+
label: curve.label,
|
|
46
|
+
kind,
|
|
47
|
+
config,
|
|
48
|
+
scale_type,
|
|
49
|
+
format: ctx.format,
|
|
50
|
+
pos_label: ctx.tick_label?.(extra.pos),
|
|
51
|
+
axis_title: ctx.axis_title,
|
|
52
|
+
...extra,
|
|
53
|
+
});
|
|
54
|
+
if (kind === `bars`) {
|
|
55
|
+
// Among bins whose rendered rect contains the pointer, pick the largest-value (tallest) bar.
|
|
56
|
+
// Baseline-anchored bars nest, so the tallest containing bar wins render-order independently.
|
|
57
|
+
let best = null;
|
|
58
|
+
for (const series_curve of curves) {
|
|
59
|
+
if (series_curve.curve.kind !== `bars`)
|
|
60
|
+
continue;
|
|
61
|
+
for (const bar of series_curve.curve.bins) {
|
|
62
|
+
if (!Number.isFinite(bar.value) || bar.value <= 0)
|
|
63
|
+
continue; // finite positive only (matches renderer)
|
|
64
|
+
const edge_a = positional_scale(bar.pos0);
|
|
65
|
+
const edge_b = positional_scale(bar.pos1);
|
|
66
|
+
if (!Number.isFinite(edge_a) || !Number.isFinite(edge_b))
|
|
67
|
+
continue;
|
|
68
|
+
if (pointer_pos < Math.min(edge_a, edge_b) || pointer_pos > Math.max(edge_a, edge_b)) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (!contains_cross(value_scale(bar.value)))
|
|
72
|
+
continue;
|
|
73
|
+
if (!best || bar.value > best.bar.value)
|
|
74
|
+
best = { curve: series_curve, bar };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!best)
|
|
78
|
+
return null;
|
|
79
|
+
const { bar } = best;
|
|
80
|
+
return hover(best.curve, {
|
|
81
|
+
pos: (bar.pos0 + bar.pos1) / 2,
|
|
82
|
+
pos0: bar.pos0,
|
|
83
|
+
pos1: bar.pos1,
|
|
84
|
+
value: bar.value,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (kind === `line`) {
|
|
88
|
+
let chosen = null;
|
|
89
|
+
let best_extent = -1;
|
|
90
|
+
for (const series_curve of curves) {
|
|
91
|
+
if (series_curve.curve.kind !== `line`)
|
|
92
|
+
continue;
|
|
93
|
+
const pts = [];
|
|
94
|
+
let min_pos = Infinity;
|
|
95
|
+
let max_pos = -Infinity;
|
|
96
|
+
for (const pt of series_curve.curve.points) {
|
|
97
|
+
const px_pos = positional_scale(pt.pos);
|
|
98
|
+
const px_val = value_scale(pt.value);
|
|
99
|
+
if (!Number.isFinite(px_pos) || !Number.isFinite(px_val))
|
|
100
|
+
continue;
|
|
101
|
+
pts.push({ curve: series_curve, pos: pt.pos, value: pt.value, px_pos, px_val });
|
|
102
|
+
min_pos = Math.min(min_pos, px_pos);
|
|
103
|
+
max_pos = Math.max(max_pos, px_pos);
|
|
104
|
+
}
|
|
105
|
+
if (pts.length < 2)
|
|
106
|
+
continue; // renderer skips line/area paths without two finite points
|
|
107
|
+
if (pointer_pos < min_pos || pointer_pos > max_pos)
|
|
108
|
+
continue;
|
|
109
|
+
let near = null;
|
|
110
|
+
let near_dist = Infinity;
|
|
111
|
+
for (const pt of pts) {
|
|
112
|
+
const pos_dist = Math.abs(pt.px_pos - pointer_pos);
|
|
113
|
+
if (pos_dist < near_dist) {
|
|
114
|
+
near_dist = pos_dist;
|
|
115
|
+
near = pt;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (!near || !contains_cross(near.px_val))
|
|
119
|
+
continue;
|
|
120
|
+
const extent = Math.abs(near.px_val - baseline);
|
|
121
|
+
if (extent > best_extent)
|
|
122
|
+
[best_extent, chosen] = [extent, near];
|
|
123
|
+
}
|
|
124
|
+
return chosen ? hover(chosen.curve, { pos: chosen.pos, value: chosen.value }) : null;
|
|
125
|
+
}
|
|
126
|
+
// rug: nearest tick along the positional axis, within a pixel tolerance (no value/cross axis)
|
|
127
|
+
let best = null;
|
|
128
|
+
for (const series_curve of curves) {
|
|
129
|
+
if (series_curve.curve.kind !== `rug`)
|
|
130
|
+
continue;
|
|
131
|
+
for (const pos of series_curve.curve.positions) {
|
|
132
|
+
const px_pos = positional_scale(pos);
|
|
133
|
+
if (!Number.isFinite(px_pos))
|
|
134
|
+
continue;
|
|
135
|
+
const dist = Math.abs(px_pos - pointer_pos);
|
|
136
|
+
if (dist < (best?.dist ?? Infinity))
|
|
137
|
+
best = { curve: series_curve, pos, dist };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (!best || best.dist > MARGINAL_HIT_TOLERANCE_PX)
|
|
141
|
+
return null;
|
|
142
|
+
return hover(best.curve, { pos: best.pos });
|
|
143
|
+
}
|
|
144
|
+
// Co-located defaults (mirrors REF_LINE_STYLE_DEFAULTS in types.ts). Deliberately NOT part of
|
|
145
|
+
// settings.ts DEFAULTS to avoid pulling marginals into the settings-UI JSON schema.
|
|
146
|
+
export const MARGINAL_DEFAULTS = {
|
|
147
|
+
type: `histogram`,
|
|
148
|
+
size: 64,
|
|
149
|
+
gap: 6,
|
|
150
|
+
placement: `auto`,
|
|
151
|
+
per_series: true,
|
|
152
|
+
bins: 60,
|
|
153
|
+
bandwidth: `silverman`,
|
|
154
|
+
stroke_width: 1.5,
|
|
155
|
+
opacity: 1,
|
|
156
|
+
value_axis: true,
|
|
157
|
+
};
|
|
158
|
+
// Normalize a single side's shorthand to a MarginalConfig, `false` (explicit disable), or
|
|
159
|
+
// undefined (not specified -> fall back to default)
|
|
160
|
+
const to_config = (input) => {
|
|
161
|
+
if (input === undefined)
|
|
162
|
+
return undefined;
|
|
163
|
+
if (input === false)
|
|
164
|
+
return false;
|
|
165
|
+
if (input === true)
|
|
166
|
+
return {};
|
|
167
|
+
if (typeof input === `string`)
|
|
168
|
+
return { type: input };
|
|
169
|
+
return input;
|
|
170
|
+
};
|
|
171
|
+
// Merge a user side-input over the plot's default side-input into a resolved config (or null)
|
|
172
|
+
const resolve_side = (user_input, default_input) => {
|
|
173
|
+
const user = to_config(user_input);
|
|
174
|
+
if (user === false)
|
|
175
|
+
return null; // explicit disable wins over any default
|
|
176
|
+
const base = to_config(default_input);
|
|
177
|
+
const base_cfg = base === false ? undefined : base;
|
|
178
|
+
if (user === undefined && base_cfg === undefined)
|
|
179
|
+
return null; // side inactive
|
|
180
|
+
return { ...MARGINAL_DEFAULTS, ...base_cfg, ...user };
|
|
181
|
+
};
|
|
182
|
+
// Expand the `marginals` prop into a per-side resolved config, merging with the plot's
|
|
183
|
+
// `default_sides` (the sensible defaults a given plot enables when `marginals` is `true`).
|
|
184
|
+
// - `true`: enable exactly the plot's default sides
|
|
185
|
+
// - a type string: that type on the plot's default sides (or top+right if none), inheriting
|
|
186
|
+
// each default side's config (e.g. shared bins)
|
|
187
|
+
// - a per-side map: enable ONLY the sides the user lists (default sides do not auto-activate),
|
|
188
|
+
// merging the plot's per-side default config under the user's
|
|
189
|
+
export function normalize_marginals(prop, default_sides = {}) {
|
|
190
|
+
const result = { top: null, bottom: null, left: null, right: null };
|
|
191
|
+
if (prop == null || prop === false)
|
|
192
|
+
return result;
|
|
193
|
+
if (prop === true) {
|
|
194
|
+
for (const side of MARGINAL_SIDES)
|
|
195
|
+
result[side] = resolve_side(undefined, default_sides[side]);
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
if (typeof prop === `string`) {
|
|
199
|
+
const sides = Object.keys(default_sides).length > 0 ? default_sides : { top: true, right: true };
|
|
200
|
+
for (const side of MARGINAL_SIDES) {
|
|
201
|
+
if (!(side in sides))
|
|
202
|
+
continue;
|
|
203
|
+
result[side] = resolve_side(prop, default_sides[side]);
|
|
204
|
+
}
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
// Explicit per-side map: only sides the user names become active
|
|
208
|
+
for (const side of MARGINAL_SIDES) {
|
|
209
|
+
if (prop[side] === undefined)
|
|
210
|
+
continue;
|
|
211
|
+
result[side] = resolve_side(prop[side], default_sides[side]);
|
|
212
|
+
}
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
215
|
+
// Padding (px) each plot must add to its `pad` to make room for active marginal strips
|
|
216
|
+
export function reserve_marginal_pad(resolved) {
|
|
217
|
+
const reserve = (cfg) => (cfg ? cfg.size + cfg.gap : 0);
|
|
218
|
+
return {
|
|
219
|
+
t: reserve(resolved.top),
|
|
220
|
+
b: reserve(resolved.bottom),
|
|
221
|
+
l: reserve(resolved.left),
|
|
222
|
+
r: reserve(resolved.right),
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
// Sum two padding objects (used to fold marginal reservation into the decoration pad)
|
|
226
|
+
export const add_sides = (a, b) => ({
|
|
227
|
+
t: a.t + b.t,
|
|
228
|
+
b: a.b + b.b,
|
|
229
|
+
l: a.l + b.l,
|
|
230
|
+
r: a.r + b.r,
|
|
231
|
+
});
|
|
232
|
+
// Default axis a side binds to when `config.axis` is unset
|
|
233
|
+
export const default_axis_for_side = (side) => is_x_side(side) ? `x1` : `y1`;
|
|
234
|
+
// Which sides carry an axis (drives `auto` placement). Bottom/left hold the primary x/y axes and
|
|
235
|
+
// are always present; top/right only when the plot shows a secondary axis there.
|
|
236
|
+
export const marginal_axis_presence = (top, right) => ({ top, bottom: true, left: true, right });
|
|
237
|
+
// Whether the strip should hug the plot edge (`flush`) vs sit beyond the ticks (`outer`)
|
|
238
|
+
const is_flush = (placement, has_axis) => placement === `flush` || (placement === `auto` && !has_axis);
|
|
239
|
+
// Pixel rect of a marginal strip. The cross dimension spans the plot area (so it aligns with
|
|
240
|
+
// the shared positional scale); the thickness is `config.size`, positioned per placement.
|
|
241
|
+
export function marginal_strip_rect(side, pad, width, height, config, has_axis) {
|
|
242
|
+
const { size, gap } = config;
|
|
243
|
+
const flush = is_flush(config.placement, has_axis);
|
|
244
|
+
const is_x = is_x_side(side);
|
|
245
|
+
const grows_negative = side === `top` || side === `left`;
|
|
246
|
+
// thickness-axis position of the strip's near edge: flush sits a gap from the plot, outer at
|
|
247
|
+
// the container edge (top/left strips go before the plot, bottom/right strips after it)
|
|
248
|
+
const plot_near = is_x ? pad.t : pad.l;
|
|
249
|
+
const plot_far = is_x ? height - pad.b : width - pad.r;
|
|
250
|
+
const container_far = is_x ? height : width;
|
|
251
|
+
const thick = flush
|
|
252
|
+
? grows_negative
|
|
253
|
+
? plot_near - gap - size
|
|
254
|
+
: plot_far + gap
|
|
255
|
+
: grows_negative
|
|
256
|
+
? 0
|
|
257
|
+
: container_far - size;
|
|
258
|
+
// cross axis spans the plot area so the strip aligns with the shared positional scale
|
|
259
|
+
const cross_min = is_x ? pad.l : pad.t;
|
|
260
|
+
const cross = Math.max(0, (is_x ? width - pad.r : height - pad.b) - cross_min);
|
|
261
|
+
return is_x
|
|
262
|
+
? { x: cross_min, y: thick, width: cross, height: size }
|
|
263
|
+
: { x: thick, y: cross_min, width: size, height: cross };
|
|
264
|
+
}
|
|
265
|
+
// Linear value scale across a strip's thickness, growing away from the plot. `domain` is the
|
|
266
|
+
// marginal value range (typically [0, max]); `baseline` is the plot-facing value=domain[0] edge.
|
|
267
|
+
export function marginal_value_scale(side, rect, domain) {
|
|
268
|
+
const [lo, hi] = domain;
|
|
269
|
+
const span = hi - lo || 1;
|
|
270
|
+
const is_x = is_x_side(side);
|
|
271
|
+
const thickness = is_x ? rect.height : rect.width;
|
|
272
|
+
const near = is_x ? rect.y : rect.x; // strip edge at the smaller pixel coordinate
|
|
273
|
+
// top/left strips grow toward smaller pixel coords; their baseline (value=lo, plot-facing) sits
|
|
274
|
+
// at the far edge, and value increases in the negative pixel direction
|
|
275
|
+
const grows_negative = side === `top` || side === `left`;
|
|
276
|
+
const baseline = grows_negative ? near + thickness : near;
|
|
277
|
+
const sign = grows_negative ? -1 : 1;
|
|
278
|
+
return { scale: (val) => baseline + sign * ((val - lo) / span) * thickness, baseline };
|
|
279
|
+
}
|
|
280
|
+
// Drop non-finite positions (and matching weights), restrict to the current positional range
|
|
281
|
+
// so every marginal type tracks zoom/pan consistently (histogram already clips via bin domain),
|
|
282
|
+
// and drop non-positive positions on a log axis.
|
|
283
|
+
const clean_pairs = (positions, weights, positional_range, scale_type) => {
|
|
284
|
+
const [lo, hi] = positional_range; // ascending (canonicalized by compute_marginal_curve)
|
|
285
|
+
const require_positive = get_scale_type_name(scale_type) === `log`;
|
|
286
|
+
const out_pos = [];
|
|
287
|
+
const out_wts = weights ? [] : undefined;
|
|
288
|
+
for (let idx = 0; idx < positions.length; idx++) {
|
|
289
|
+
const pos = positions[idx];
|
|
290
|
+
if (!Number.isFinite(pos) || pos < lo || pos > hi)
|
|
291
|
+
continue;
|
|
292
|
+
if (require_positive && pos <= 0)
|
|
293
|
+
continue;
|
|
294
|
+
if (weights && out_wts) {
|
|
295
|
+
const weight = weights[idx];
|
|
296
|
+
// skip non-finite and negative weights: a negative makes a weighted CDF non-monotone and
|
|
297
|
+
// skews histogram normalization. zero is kept (it contributes nothing and the renderer
|
|
298
|
+
// already drops zero-value bars, so skipping it would only needlessly drop rug/kde positions)
|
|
299
|
+
if (!Number.isFinite(weight) || weight < 0)
|
|
300
|
+
continue;
|
|
301
|
+
out_wts.push(weight);
|
|
302
|
+
}
|
|
303
|
+
out_pos.push(pos);
|
|
304
|
+
}
|
|
305
|
+
return { positions: out_pos, weights: out_wts };
|
|
306
|
+
};
|
|
307
|
+
function compute_histogram(positions, weights, config, positional_range) {
|
|
308
|
+
const indices = positions.map((_, idx) => idx);
|
|
309
|
+
const binner = bin()
|
|
310
|
+
.domain(positional_range)
|
|
311
|
+
.thresholds(config.bins)
|
|
312
|
+
.value((idx) => positions[idx]);
|
|
313
|
+
const binned = binner(indices);
|
|
314
|
+
let max = 0;
|
|
315
|
+
const bins = binned.map((items) => {
|
|
316
|
+
const value = weights ? items.reduce((sum, idx) => sum + weights[idx], 0) : items.length;
|
|
317
|
+
if (value > max)
|
|
318
|
+
max = value;
|
|
319
|
+
return { pos0: items.x0 ?? 0, pos1: items.x1 ?? 0, value };
|
|
320
|
+
});
|
|
321
|
+
// count: raw; probability: value/total; density: value/(total*bin_width)
|
|
322
|
+
if (config.normalize && config.normalize !== `count`) {
|
|
323
|
+
const grand = bins.reduce((sum, item) => sum + item.value, 0) || 1;
|
|
324
|
+
max = 0;
|
|
325
|
+
for (const item of bins) {
|
|
326
|
+
const width = item.pos1 - item.pos0;
|
|
327
|
+
item.value =
|
|
328
|
+
config.normalize === `density`
|
|
329
|
+
? item.value / (grand * (width || 1))
|
|
330
|
+
: item.value / grand;
|
|
331
|
+
if (item.value > max)
|
|
332
|
+
max = item.value;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return { kind: `bars`, bins, max };
|
|
336
|
+
}
|
|
337
|
+
function compute_cdf(positions, weights) {
|
|
338
|
+
const order = positions.map((_, idx) => idx).sort((a, b) => positions[a] - positions[b]);
|
|
339
|
+
const total = weights ? weights.reduce((sum, weight) => sum + weight, 0) : positions.length;
|
|
340
|
+
const points = [];
|
|
341
|
+
let cum = 0;
|
|
342
|
+
for (const idx of order) {
|
|
343
|
+
cum += weights ? weights[idx] : 1;
|
|
344
|
+
const pos = positions[idx];
|
|
345
|
+
const value = total > 0 ? cum / total : 0;
|
|
346
|
+
// collapse ties so positions stay strictly increasing (keeps monotone curves well-behaved)
|
|
347
|
+
const last = points[points.length - 1];
|
|
348
|
+
if (last?.pos === pos)
|
|
349
|
+
last.value = value;
|
|
350
|
+
else
|
|
351
|
+
points.push({ pos, value });
|
|
352
|
+
}
|
|
353
|
+
return { kind: `line`, points, max: 1 };
|
|
354
|
+
}
|
|
355
|
+
// Smallest strictly-positive value (Infinity if none): repairs a degenerate log lower bound (<= 0)
|
|
356
|
+
// so kde grids / histogram bins don't dip to non-renderable positions
|
|
357
|
+
const smallest_positive = (vals) => vals.reduce((min, val) => (val > 0 && val < min ? val : min), Infinity);
|
|
358
|
+
function compute_kde(positions, config, positional_range, scale_type) {
|
|
359
|
+
// The grid spans the current positional range, so on a normal log axis (range[0] > 0) no
|
|
360
|
+
// clamping is needed. Only repair a degenerate log range whose lower bound is <= 0 (would
|
|
361
|
+
// otherwise emit grid points at <= 0 -> NaN pixels) by clamping to the smallest positive sample.
|
|
362
|
+
let clip;
|
|
363
|
+
if (get_scale_type_name(scale_type) === `log` && positional_range[0] <= 0) {
|
|
364
|
+
const min_pos = smallest_positive(positions);
|
|
365
|
+
if (Number.isFinite(min_pos))
|
|
366
|
+
clip = [min_pos, null];
|
|
367
|
+
}
|
|
368
|
+
const kde = gaussian_kde(positions, {
|
|
369
|
+
bandwidth: config.bandwidth,
|
|
370
|
+
n_points: 100,
|
|
371
|
+
range: positional_range,
|
|
372
|
+
clip,
|
|
373
|
+
max_samples: 5000,
|
|
374
|
+
});
|
|
375
|
+
let max = 0;
|
|
376
|
+
for (const density of kde.density)
|
|
377
|
+
if (density > max)
|
|
378
|
+
max = density;
|
|
379
|
+
const points = kde.grid.map((pos, idx) => ({ pos, value: kde.density[idx] }));
|
|
380
|
+
return { kind: `line`, points, max };
|
|
381
|
+
}
|
|
382
|
+
// Summarize 1-D values into a renderable curve per the marginal type. Filters non-finite
|
|
383
|
+
// inputs and returns an empty curve for empty input (so nothing renders).
|
|
384
|
+
export function compute_marginal_curve(positions, weights, config, positional_range, scale_type) {
|
|
385
|
+
// Canonicalize to an ascending range so a reversed (inverted-axis) range doesn't crash
|
|
386
|
+
// d3.bin (negative-length bin array) or empty the kde grid
|
|
387
|
+
const range = sorted_range(positional_range[0], positional_range[1]);
|
|
388
|
+
const { positions: pos, weights: wts } = clean_pairs(positions, weights, range, scale_type);
|
|
389
|
+
// rug returns the raw positions (empty or not); other types short-circuit on empty input
|
|
390
|
+
if (config.type === `rug`)
|
|
391
|
+
return { kind: `rug`, positions: pos };
|
|
392
|
+
if (pos.length === 0) {
|
|
393
|
+
return config.type === `histogram`
|
|
394
|
+
? { kind: `bars`, bins: [], max: 0 }
|
|
395
|
+
: { kind: `line`, points: [], max: 0 };
|
|
396
|
+
}
|
|
397
|
+
if (config.type === `histogram`) {
|
|
398
|
+
// on a degenerate log axis (lower bound <= 0) bin over the smallest positive sample instead, so
|
|
399
|
+
// bins aren't spread below the smallest renderable position (mirrors compute_kde's clip)
|
|
400
|
+
const hist_range = get_scale_type_name(scale_type) === `log` && range[0] <= 0
|
|
401
|
+
? [smallest_positive(pos), range[1]]
|
|
402
|
+
: range;
|
|
403
|
+
return compute_histogram(pos, wts, config, hist_range);
|
|
404
|
+
}
|
|
405
|
+
if (config.type === `cdf`)
|
|
406
|
+
return compute_cdf(pos, wts);
|
|
407
|
+
return compute_kde(pos, config, range, scale_type);
|
|
408
|
+
}
|
|
409
|
+
// Max value across a set of curves (for a shared per-side value scale)
|
|
410
|
+
export const curves_max = (curves) => curves.reduce((max, curve) => (curve.kind === `rug` ? max : Math.max(max, curve.max)), 0);
|
|
411
|
+
// Value-axis title for a strip: explicit `config.label` wins, else auto per type (histogram uses
|
|
412
|
+
// its normalization). `rug` has no value axis so returns an empty string.
|
|
413
|
+
export const default_marginal_label = (config) => {
|
|
414
|
+
if (config.label != null)
|
|
415
|
+
return config.label;
|
|
416
|
+
if (config.type === `cdf`)
|
|
417
|
+
return `CDF`;
|
|
418
|
+
if (config.type === `kde`)
|
|
419
|
+
return `density`;
|
|
420
|
+
if (config.type === `histogram`)
|
|
421
|
+
return config.normalize ?? `count`;
|
|
422
|
+
return ``;
|
|
423
|
+
};
|
|
424
|
+
// d3-format spec for the strip's value-axis tick labels, picked to suit each type's value units
|
|
425
|
+
export const marginal_value_format = (config) => {
|
|
426
|
+
if (config.type === `cdf`)
|
|
427
|
+
return `.0%`;
|
|
428
|
+
if (config.type === `histogram`) {
|
|
429
|
+
if (config.normalize === `probability`)
|
|
430
|
+
return `.0%`;
|
|
431
|
+
if (config.normalize === `density`)
|
|
432
|
+
return `.2~g`;
|
|
433
|
+
return `.3~s`;
|
|
434
|
+
}
|
|
435
|
+
return `.2~g`; // kde density
|
|
436
|
+
};
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import type { Point2D, Vec2 } from '../../math';
|
|
2
|
+
import { type Rect } from './layout';
|
|
2
3
|
import type { AxisRanges, PanConfig, ScaleType } from './types';
|
|
3
4
|
type Axis = `x` | `x2` | `y` | `y2`;
|
|
4
5
|
export interface PanZoomOptions {
|
|
5
6
|
ranges: () => AxisRanges;
|
|
6
7
|
scale_type: (axis: Axis) => ScaleType | undefined;
|
|
7
|
-
|
|
8
|
-
width: number;
|
|
9
|
-
height: number;
|
|
10
|
-
};
|
|
8
|
+
plot_bounds: () => Rect;
|
|
11
9
|
pan: () => PanConfig | undefined;
|
|
12
10
|
set_range: (axis: Axis, range: Vec2) => void;
|
|
13
11
|
svg: () => SVGElement | null;
|
|
@@ -3,17 +3,18 @@
|
|
|
3
3
|
// per-component policy (which axis props to write on rect-zoom, reset semantics)
|
|
4
4
|
// stays in the component via the on_rect_zoom/on_reset/set_range callbacks.
|
|
5
5
|
import { MIN_TOUCH_DISTANCE_PIXELS, pan_range_by_pixels, PINCH_ZOOM_THRESHOLD, remove_drag_listeners, snapshot_ranges, zoom_range_by_factor, } from './interactions';
|
|
6
|
+
import { point_in_rect } from './layout';
|
|
6
7
|
const AXES = [`x`, `x2`, `y`, `y2`];
|
|
7
8
|
export function create_pan_zoom(opts) {
|
|
8
9
|
// Rect-zoom drag state
|
|
9
|
-
let drag_state = $state(
|
|
10
|
+
let drag_state = $state(null);
|
|
10
11
|
// Pan state
|
|
11
12
|
let is_focused = $state(false);
|
|
12
13
|
let shift_held = $state(false);
|
|
13
14
|
let pan_drag_state = $state(null);
|
|
14
15
|
let touch_state = $state(null);
|
|
15
16
|
const cancel_rect_drag = () => {
|
|
16
|
-
drag_state =
|
|
17
|
+
drag_state = null;
|
|
17
18
|
if (typeof window !== `undefined`) {
|
|
18
19
|
window.removeEventListener(`mousemove`, on_window_mouse_move);
|
|
19
20
|
window.removeEventListener(`mouseup`, on_window_mouse_up);
|
|
@@ -21,7 +22,7 @@ export function create_pan_zoom(opts) {
|
|
|
21
22
|
}
|
|
22
23
|
};
|
|
23
24
|
const on_window_mouse_move = (evt) => {
|
|
24
|
-
if (!drag_state
|
|
25
|
+
if (!drag_state)
|
|
25
26
|
return;
|
|
26
27
|
const coords = {
|
|
27
28
|
x: evt.clientX - drag_state.bounds.left,
|
|
@@ -35,7 +36,7 @@ export function create_pan_zoom(opts) {
|
|
|
35
36
|
opts.on_drag_move?.(coords, inside_svg);
|
|
36
37
|
};
|
|
37
38
|
const on_window_mouse_up = () => {
|
|
38
|
-
if (drag_state
|
|
39
|
+
if (drag_state) {
|
|
39
40
|
// Ignore minuscule drag rects (e.g. accidental clicks)
|
|
40
41
|
const dx = Math.abs(drag_state.start.x - drag_state.current.x);
|
|
41
42
|
const dy = Math.abs(drag_state.start.y - drag_state.current.y);
|
|
@@ -47,7 +48,7 @@ export function create_pan_zoom(opts) {
|
|
|
47
48
|
// Pan/zoom all four axes from an interaction-start snapshot, each in its own
|
|
48
49
|
// scale's transform space (log axes pan by a constant factor, linear by a shift)
|
|
49
50
|
const pan_all_axes = (init, dx_px, dy_px) => {
|
|
50
|
-
const dims = opts.
|
|
51
|
+
const dims = opts.plot_bounds();
|
|
51
52
|
for (const axis of AXES) {
|
|
52
53
|
const horizontal = axis === `x` || axis === `x2`;
|
|
53
54
|
opts.set_range(axis, pan_range_by_pixels(init[`initial_${axis}_range`], horizontal ? dx_px : dy_px, horizontal ? dims.width : dims.height, opts.scale_type(axis)));
|
|
@@ -72,9 +73,17 @@ export function create_pan_zoom(opts) {
|
|
|
72
73
|
window.removeEventListener(`mouseup`, on_pan_end);
|
|
73
74
|
};
|
|
74
75
|
const on_mouse_down = (evt) => {
|
|
76
|
+
if (evt.button !== 0)
|
|
77
|
+
return;
|
|
75
78
|
const svg = opts.svg();
|
|
76
79
|
if (!svg)
|
|
77
80
|
return;
|
|
81
|
+
// The SVG also contains axes, tick labels, and titles. Only the padded data
|
|
82
|
+
// rectangle may start a drag interaction.
|
|
83
|
+
const svg_bounds = svg.getBoundingClientRect();
|
|
84
|
+
const coords = { x: evt.clientX - svg_bounds.left, y: evt.clientY - svg_bounds.top };
|
|
85
|
+
if (!point_in_rect(coords, opts.plot_bounds()))
|
|
86
|
+
return;
|
|
78
87
|
// Shift+drag pans (when enabled); plain drag draws the zoom rect
|
|
79
88
|
const pan_enabled = opts.pan()?.enabled !== false;
|
|
80
89
|
if (pan_enabled && evt.shiftKey) {
|
|
@@ -89,9 +98,7 @@ export function create_pan_zoom(opts) {
|
|
|
89
98
|
return;
|
|
90
99
|
}
|
|
91
100
|
// Cache bounds at drag start so window mousemove can compute relative coords
|
|
92
|
-
|
|
93
|
-
const coords = { x: evt.clientX - bounds.left, y: evt.clientY - bounds.top };
|
|
94
|
-
drag_state = { start: coords, current: coords, bounds };
|
|
101
|
+
drag_state = { start: coords, current: coords, bounds: svg_bounds };
|
|
95
102
|
window.addEventListener(`mousemove`, on_window_mouse_move);
|
|
96
103
|
window.addEventListener(`mouseup`, on_window_mouse_up);
|
|
97
104
|
document.body.style.cursor = `crosshair`;
|
|
@@ -104,7 +111,7 @@ export function create_pan_zoom(opts) {
|
|
|
104
111
|
if (pan_cfg?.enabled === false || !is_focused || !shift_held)
|
|
105
112
|
return;
|
|
106
113
|
evt.preventDefault();
|
|
107
|
-
const dims = opts.
|
|
114
|
+
const dims = opts.plot_bounds();
|
|
108
115
|
const sensitivity = pan_cfg?.wheel_sensitivity ?? 1;
|
|
109
116
|
const ranges = opts.ranges();
|
|
110
117
|
// Pan along the dominant wheel direction
|
|
@@ -125,12 +132,22 @@ export function create_pan_zoom(opts) {
|
|
|
125
132
|
const touch_enabled = pan_cfg?.enabled !== false && pan_cfg?.touch_enabled !== false;
|
|
126
133
|
if (!touch_enabled || evt.touches.length !== 2)
|
|
127
134
|
return;
|
|
135
|
+
const svg_bounds = opts.svg()?.getBoundingClientRect();
|
|
136
|
+
if (!svg_bounds)
|
|
137
|
+
return;
|
|
138
|
+
const plot_bounds = opts.plot_bounds();
|
|
139
|
+
const start_touches = Array.from(evt.touches).map((touch) => ({
|
|
140
|
+
x: touch.clientX,
|
|
141
|
+
y: touch.clientY,
|
|
142
|
+
}));
|
|
143
|
+
// Every contact must start in the data rectangle; touching an axis or label
|
|
144
|
+
// must not arm a gesture that later moves into the plot.
|
|
145
|
+
const starts_outside_plot = start_touches.some((touch) => !point_in_rect({ x: touch.x - svg_bounds.left, y: touch.y - svg_bounds.top }, plot_bounds));
|
|
146
|
+
if (starts_outside_plot)
|
|
147
|
+
return;
|
|
128
148
|
evt.preventDefault();
|
|
129
149
|
touch_state = {
|
|
130
|
-
start_touches
|
|
131
|
-
x: touch.clientX,
|
|
132
|
-
y: touch.clientY,
|
|
133
|
-
})),
|
|
150
|
+
start_touches,
|
|
134
151
|
...snapshot_ranges(opts.ranges()),
|
|
135
152
|
};
|
|
136
153
|
};
|
|
@@ -168,7 +185,7 @@ export function create_pan_zoom(opts) {
|
|
|
168
185
|
const on_key_down = (evt) => {
|
|
169
186
|
if (evt.target !== evt.currentTarget)
|
|
170
187
|
return;
|
|
171
|
-
if (evt.key === `Escape` && drag_state
|
|
188
|
+
if (evt.key === `Escape` && drag_state)
|
|
172
189
|
cancel_rect_drag();
|
|
173
190
|
if ([`Enter`, ` `].includes(evt.key)) {
|
|
174
191
|
evt.preventDefault();
|
|
@@ -177,10 +194,10 @@ export function create_pan_zoom(opts) {
|
|
|
177
194
|
};
|
|
178
195
|
return {
|
|
179
196
|
get drag_start() {
|
|
180
|
-
return drag_state
|
|
197
|
+
return drag_state?.start ?? null;
|
|
181
198
|
},
|
|
182
199
|
get drag_current() {
|
|
183
|
-
return drag_state
|
|
200
|
+
return drag_state?.current ?? null;
|
|
184
201
|
},
|
|
185
202
|
get is_pan_dragging() {
|
|
186
203
|
return pan_drag_state !== null;
|
|
@@ -213,7 +230,7 @@ export function create_pan_zoom(opts) {
|
|
|
213
230
|
// stuck cursor). Safe during SSR teardown, where window/document don't exist.
|
|
214
231
|
destroy: () => {
|
|
215
232
|
remove_drag_listeners([on_window_mouse_move, on_pan_move], [on_window_mouse_up, on_pan_end]);
|
|
216
|
-
drag_state =
|
|
233
|
+
drag_state = null;
|
|
217
234
|
pan_drag_state = null;
|
|
218
235
|
touch_state = null;
|
|
219
236
|
},
|
|
@@ -14,8 +14,11 @@ export declare function create_placed_tween(opts: {
|
|
|
14
14
|
tween?: () => TweenOptions<Point> | undefined;
|
|
15
15
|
suspended?: () => boolean;
|
|
16
16
|
manual_position?: () => Point | null;
|
|
17
|
+
on_element_resize?: () => void;
|
|
18
|
+
placement_revision?: () => unknown;
|
|
17
19
|
}): {
|
|
18
20
|
coords: Tween<Point>;
|
|
21
|
+
placed: () => boolean;
|
|
19
22
|
set_locked: (locked: boolean) => void;
|
|
20
23
|
};
|
|
21
24
|
export {};
|