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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { format_value_or_num } from '../../labels'
|
|
3
3
|
import { FullscreenToggle, set_fullscreen_bg } from '../../layout'
|
|
4
4
|
import type {
|
|
5
5
|
AxisLoadError,
|
|
@@ -15,10 +15,22 @@
|
|
|
15
15
|
HistogramControls,
|
|
16
16
|
PlotAxis,
|
|
17
17
|
PlotLegend,
|
|
18
|
+
PlotMarginals,
|
|
18
19
|
ReferenceLine,
|
|
19
20
|
} from '..'
|
|
20
|
-
import type {
|
|
21
|
-
import {
|
|
21
|
+
import type { MarginalSeriesInput, MarginalsProp } from '../core/marginals'
|
|
22
|
+
import {
|
|
23
|
+
add_sides,
|
|
24
|
+
marginal_axis,
|
|
25
|
+
marginal_axis_presence,
|
|
26
|
+
normalize_marginals,
|
|
27
|
+
reserve_marginal_pad,
|
|
28
|
+
} from '../core/marginals'
|
|
29
|
+
import {
|
|
30
|
+
AXIS_DEFAULTS,
|
|
31
|
+
type AxisChangeState,
|
|
32
|
+
create_axis_loader,
|
|
33
|
+
} from '../core/axis-utils'
|
|
22
34
|
import { extract_series_color, prepare_legend_data } from '../core/data-transform'
|
|
23
35
|
import { create_placed_tween } from '../core/placed-tween.svelte'
|
|
24
36
|
import { create_pan_zoom } from '../core/pan-zoom.svelte'
|
|
@@ -29,7 +41,9 @@
|
|
|
29
41
|
vec2_equal,
|
|
30
42
|
} from '../core/interactions'
|
|
31
43
|
import {
|
|
44
|
+
AXIS_TITLE_OFFSET,
|
|
32
45
|
calc_auto_padding,
|
|
46
|
+
DEFAULT_PLOT_PADDING,
|
|
33
47
|
filter_padding,
|
|
34
48
|
LABEL_GAP_DEFAULT,
|
|
35
49
|
y2_axis_label_x,
|
|
@@ -46,7 +60,7 @@
|
|
|
46
60
|
import type { IndexedRefLine } from '../core/reference-line'
|
|
47
61
|
import { group_ref_lines_by_z, index_ref_lines } from '../core/reference-line'
|
|
48
62
|
import {
|
|
49
|
-
|
|
63
|
+
create_axis_scales,
|
|
50
64
|
generate_ticks,
|
|
51
65
|
get_nice_data_range,
|
|
52
66
|
get_tick_label,
|
|
@@ -56,13 +70,15 @@
|
|
|
56
70
|
DataSeries,
|
|
57
71
|
LegendConfig,
|
|
58
72
|
PlotConfig,
|
|
59
|
-
ScaleType,
|
|
60
73
|
} from '../core/types'
|
|
61
|
-
import {
|
|
74
|
+
import {
|
|
75
|
+
compute_count_range,
|
|
76
|
+
compute_histogram_bins,
|
|
77
|
+
log_safe_range,
|
|
78
|
+
} from './histogram'
|
|
62
79
|
import ZeroLines from '../core/components/ZeroLines.svelte'
|
|
63
80
|
import ZoomRect from '../core/components/ZoomRect.svelte'
|
|
64
81
|
import { DEFAULTS } from '../../settings'
|
|
65
|
-
import { bin, max } from 'd3-array'
|
|
66
82
|
import type { Snippet } from 'svelte'
|
|
67
83
|
import { onDestroy, untrack } from 'svelte'
|
|
68
84
|
import type { HTMLAttributes } from 'svelte/elements'
|
|
@@ -78,8 +94,8 @@
|
|
|
78
94
|
y_axis: y_axis_init = {},
|
|
79
95
|
y2_axis: y2_axis_init = {},
|
|
80
96
|
display: display_init = DEFAULTS.histogram.display,
|
|
81
|
-
range_padding = 0
|
|
82
|
-
padding =
|
|
97
|
+
range_padding = 0,
|
|
98
|
+
padding = DEFAULT_PLOT_PADDING,
|
|
83
99
|
bins = $bindable(100),
|
|
84
100
|
show_legend = $bindable(true),
|
|
85
101
|
legend = {},
|
|
@@ -108,49 +124,47 @@
|
|
|
108
124
|
on_axis_change,
|
|
109
125
|
on_error,
|
|
110
126
|
pan = {},
|
|
127
|
+
marginals = false,
|
|
111
128
|
...rest
|
|
112
|
-
}: HTMLAttributes<HTMLDivElement> &
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
[
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
data: {
|
|
129
|
+
}: HTMLAttributes<HTMLDivElement> &
|
|
130
|
+
BasePlotProps &
|
|
131
|
+
PlotConfig & {
|
|
132
|
+
series: DataSeries[]
|
|
133
|
+
// Component-specific props
|
|
134
|
+
bins?: number
|
|
135
|
+
show_legend?: boolean
|
|
136
|
+
legend?: LegendConfig | null
|
|
137
|
+
bar?: BarStyle
|
|
138
|
+
selected_property?: string
|
|
139
|
+
mode?: `single` | `overlay`
|
|
140
|
+
tooltip?: Snippet<[HistogramHandlerProps]>
|
|
141
|
+
header_controls?: Snippet<[{ height: number; width: number; fullscreen: boolean }]>
|
|
142
|
+
controls_extra?: Snippet<[Required<PlotConfig>]>
|
|
143
|
+
change?: (data: { value: number; count: number; property: string } | null) => void
|
|
144
|
+
on_bar_click?: (data: {
|
|
129
145
|
value: number
|
|
130
146
|
count: number
|
|
131
147
|
property: string
|
|
132
148
|
event: MouseEvent | KeyboardEvent
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
pan?: PanConfig
|
|
153
|
-
} = $props()
|
|
149
|
+
}) => void
|
|
150
|
+
on_bar_hover?: (
|
|
151
|
+
data: { value: number; count: number; property: string; event: MouseEvent } | null,
|
|
152
|
+
) => void
|
|
153
|
+
ref_lines?: RefLine[]
|
|
154
|
+
on_ref_line_click?: (event: RefLineEvent) => void
|
|
155
|
+
on_ref_line_hover?: (event: RefLineEvent | null) => void
|
|
156
|
+
on_series_toggle?: (series_idx: number) => void
|
|
157
|
+
// Interactive axis props
|
|
158
|
+
data_loader?: DataLoaderFn
|
|
159
|
+
on_axis_change?: (
|
|
160
|
+
axis: `x` | `x2` | `y` | `y2`,
|
|
161
|
+
key: string,
|
|
162
|
+
new_series: DataSeries[],
|
|
163
|
+
) => void
|
|
164
|
+
on_error?: (error: AxisLoadError) => void
|
|
165
|
+
pan?: PanConfig
|
|
166
|
+
marginals?: MarginalsProp
|
|
167
|
+
} = $props()
|
|
154
168
|
|
|
155
169
|
// Local state for controls (initialized from props, owned by this component)
|
|
156
170
|
// Include key AXIS_DEFAULTS props (range, ticks, scale_type) that PlotControls needs
|
|
@@ -160,25 +174,29 @@
|
|
|
160
174
|
let bar = $state(untrack(() => ({ ...DEFAULTS.histogram.bar, ...bar_init })))
|
|
161
175
|
let x_axis = $state(untrack(() => ({ ...axis_state_defaults, ...x_axis_init })))
|
|
162
176
|
// x2-axis needs different default label_shift for top-side positioning
|
|
163
|
-
let x2_axis = $state(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
177
|
+
let x2_axis = $state(
|
|
178
|
+
untrack(() => ({
|
|
179
|
+
...axis_state_defaults,
|
|
180
|
+
label_shift: { x: 0, y: AXIS_TITLE_OFFSET },
|
|
181
|
+
...x2_axis_init,
|
|
182
|
+
})),
|
|
183
|
+
)
|
|
168
184
|
let y_axis = $state(untrack(() => ({ ...axis_state_defaults, ...y_axis_init })))
|
|
169
185
|
// y2 title stays vertically centered; its x position is computed by y2_axis_label_x
|
|
170
|
-
let y2_axis = $state(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
untrack(() => ({ ...DEFAULTS.histogram.display, ...display_init })),
|
|
186
|
+
let y2_axis = $state(
|
|
187
|
+
untrack(() => ({
|
|
188
|
+
...axis_state_defaults,
|
|
189
|
+
label_shift: { x: 0, y: 0 },
|
|
190
|
+
...y2_axis_init,
|
|
191
|
+
})),
|
|
177
192
|
)
|
|
193
|
+
let display = $state(untrack(() => ({ ...DEFAULTS.histogram.display, ...display_init })))
|
|
178
194
|
|
|
179
195
|
// Merge component-specific defaults with local state (format comes from here, not AXIS_DEFAULTS)
|
|
180
|
-
|
|
181
|
-
|
|
196
|
+
// No default tick format: PlotAxis falls back to format_num, which uses SI
|
|
197
|
+
// prefixes above 1 but plain decimals below (0.2 must not render as 200m)
|
|
198
|
+
const final_x_axis = $derived({ label: `Value`, ...x_axis })
|
|
199
|
+
const final_x2_axis = $derived({ label: `Value`, ...x2_axis })
|
|
182
200
|
const final_y_axis = $derived({ label: `Count`, format: `d`, ...y_axis })
|
|
183
201
|
const final_bar = $derived({ ...DEFAULTS.histogram.bar, ...bar })
|
|
184
202
|
const final_y2_axis = $derived({ label: `Count`, format: `d`, ...y2_axis })
|
|
@@ -197,8 +215,7 @@
|
|
|
197
215
|
let axis_loading = $state<`x` | `x2` | `y` | `y2` | null>(null)
|
|
198
216
|
|
|
199
217
|
// Compute ref_lines with index and group by z-index (using shared utilities)
|
|
200
|
-
let
|
|
201
|
-
let ref_lines_by_z = $derived(group_ref_lines_by_z(indexed_ref_lines))
|
|
218
|
+
let ref_lines_by_z = $derived(group_ref_lines_by_z(index_ref_lines(ref_lines)))
|
|
202
219
|
|
|
203
220
|
// Legend placement stability state
|
|
204
221
|
let legend_element = $state<HTMLDivElement | undefined>()
|
|
@@ -220,29 +237,24 @@
|
|
|
220
237
|
let selected_series_entries = $derived<IndexedSeries[]>(
|
|
221
238
|
series
|
|
222
239
|
.map((series_data: DataSeries, series_idx: number) => ({ series_data, series_idx }))
|
|
223
|
-
.filter(
|
|
224
|
-
(series_data
|
|
225
|
-
|
|
240
|
+
.filter(
|
|
241
|
+
({ series_data }) =>
|
|
242
|
+
(series_data.visible ?? true) &&
|
|
243
|
+
(mode !== `single` || !selected_property || series_data.label === selected_property),
|
|
226
244
|
),
|
|
227
245
|
)
|
|
228
|
-
let selected_series = $derived(
|
|
229
|
-
selected_series_entries.map(({ series_data }) => series_data),
|
|
230
|
-
)
|
|
246
|
+
let selected_series = $derived(selected_series_entries.map(({ series_data }) => series_data))
|
|
231
247
|
|
|
232
248
|
// Separate series by y-axis
|
|
233
249
|
let y1_series = $derived(
|
|
234
250
|
selected_series.filter((srs: DataSeries) => (srs.y_axis ?? `y1`) === `y1`),
|
|
235
251
|
)
|
|
236
|
-
let y2_series = $derived(
|
|
237
|
-
|
|
238
|
-
)
|
|
239
|
-
let x2_series = $derived(
|
|
240
|
-
selected_series.filter((srs: DataSeries) => srs.x_axis === `x2`),
|
|
241
|
-
)
|
|
252
|
+
let y2_series = $derived(selected_series.filter((srs: DataSeries) => srs.y_axis === `y2`))
|
|
253
|
+
let x2_series = $derived(selected_series.filter((srs: DataSeries) => srs.x_axis === `x2`))
|
|
242
254
|
|
|
243
255
|
let auto_ranges = $derived.by(() => {
|
|
244
256
|
// Only x1 series contribute to the x1 auto-range (x2 series get their own domain below)
|
|
245
|
-
const x1_values = selected_series.flatMap((srs) => srs.x_axis === `x2` ? [] : srs.y)
|
|
257
|
+
const x1_values = selected_series.flatMap((srs) => (srs.x_axis === `x2` ? [] : srs.y))
|
|
246
258
|
const auto_x = get_nice_data_range(
|
|
247
259
|
x1_values.map((val) => ({ x: val, y: 0 })),
|
|
248
260
|
({ x }) => x,
|
|
@@ -253,68 +265,29 @@
|
|
|
253
265
|
)
|
|
254
266
|
|
|
255
267
|
const x2_values = x2_series.flatMap((srs: DataSeries) => srs.y)
|
|
256
|
-
const auto_x2 =
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
scale_type:
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
// out-of-domain values, so binning x2 series over the x1 domain skews max_count)
|
|
280
|
-
const max_count = Math.max(
|
|
281
|
-
0,
|
|
282
|
-
...series_list.map((srs: DataSeries) => {
|
|
283
|
-
const hist = bin().domain(srs.x_axis === `x2` ? auto_x2 : auto_x).thresholds(bins)
|
|
284
|
-
return max(hist(srs.y), (data) => data.length) || 0
|
|
285
|
-
}),
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
// If there's effectively no data, avoid log-range issues (counts can't be <= 0 on log)
|
|
289
|
-
if (max_count <= 0) {
|
|
290
|
-
const fallback = type_name === `log` ? 1 : 0
|
|
291
|
-
return [fallback, 1]
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const [y0, y1] = get_nice_data_range(
|
|
295
|
-
[{ x: 0, y: 0 }, { x: max_count, y: 0 }],
|
|
296
|
-
({ x }) => x,
|
|
297
|
-
y_limit,
|
|
298
|
-
scale_type,
|
|
299
|
-
range_padding,
|
|
300
|
-
false,
|
|
301
|
-
)
|
|
302
|
-
// For log scale, minimum must be >= 1 (count can't be 0 on log)
|
|
303
|
-
// For linear/arcsinh, start from 0
|
|
304
|
-
const y_min = type_name === `log` ? Math.max(1, y0) : Math.max(0, y0)
|
|
305
|
-
return [y_min, y1]
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const y1_range = calc_y_range(
|
|
309
|
-
y1_series,
|
|
310
|
-
final_y_axis.range ?? [null, null],
|
|
311
|
-
final_y_axis.scale_type ?? `linear`,
|
|
312
|
-
)
|
|
313
|
-
const y2_auto_range = calc_y_range(
|
|
314
|
-
y2_series,
|
|
315
|
-
final_y2_axis.range ?? [null, null],
|
|
316
|
-
final_y2_axis.scale_type ?? `linear`,
|
|
317
|
-
)
|
|
268
|
+
const auto_x2 =
|
|
269
|
+
x2_values.length > 0
|
|
270
|
+
? get_nice_data_range(
|
|
271
|
+
x2_values.map((val) => ({ x: val, y: 0 })),
|
|
272
|
+
({ x }) => x,
|
|
273
|
+
final_x2_axis.range ?? [null, null],
|
|
274
|
+
final_x2_axis.scale_type ?? `linear`,
|
|
275
|
+
range_padding,
|
|
276
|
+
false,
|
|
277
|
+
)
|
|
278
|
+
: ([0, 1] as Vec2)
|
|
279
|
+
|
|
280
|
+
const count_cfg = { x_domain: auto_x, x2_domain: auto_x2, bin_count: bins, range_padding }
|
|
281
|
+
const y1_range = compute_count_range(y1_series, {
|
|
282
|
+
...count_cfg,
|
|
283
|
+
scale_type: final_y_axis.scale_type ?? `linear`,
|
|
284
|
+
y_limit: log_safe_range(final_y_axis),
|
|
285
|
+
})
|
|
286
|
+
const y2_auto_range = compute_count_range(y2_series, {
|
|
287
|
+
...count_cfg,
|
|
288
|
+
scale_type: final_y2_axis.scale_type ?? `linear`,
|
|
289
|
+
y_limit: log_safe_range(final_y2_axis),
|
|
290
|
+
})
|
|
318
291
|
|
|
319
292
|
return { x: auto_x, x2: auto_x2, y: y1_range, y2: y2_auto_range }
|
|
320
293
|
})
|
|
@@ -336,10 +309,16 @@
|
|
|
336
309
|
})
|
|
337
310
|
|
|
338
311
|
$effect(() => {
|
|
339
|
-
// Supports one-sided range pinning (null bounds fall back to auto); returns null
|
|
340
|
-
//
|
|
312
|
+
// Supports one-sided range pinning (null bounds fall back to auto); returns null for transient
|
|
313
|
+
// non-finite bounds (skip: writing NaN breaks scales and loops here). y/y2 ranges are
|
|
314
|
+
// log-sanitized so an invalid (<= 0) log lower falls back to the auto count minimum.
|
|
341
315
|
const next = resolve_axis_ranges(
|
|
342
|
-
{
|
|
316
|
+
{
|
|
317
|
+
x: final_x_axis,
|
|
318
|
+
x2: final_x2_axis,
|
|
319
|
+
y: { range: log_safe_range(final_y_axis) },
|
|
320
|
+
y2: { range: log_safe_range(final_y2_axis) },
|
|
321
|
+
},
|
|
343
322
|
auto_ranges,
|
|
344
323
|
)
|
|
345
324
|
if (!next) return
|
|
@@ -348,15 +327,16 @@
|
|
|
348
327
|
// (reading + writing the same state otherwise causes effect_update_depth_exceeded).
|
|
349
328
|
const init = untrack(() => ranges.initial)
|
|
350
329
|
if (!vec2_equal(init.x, next.x)) [ranges.initial.x, ranges.current.x] = [next.x, next.x]
|
|
351
|
-
if (!vec2_equal(init.x2, next.x2))
|
|
330
|
+
if (!vec2_equal(init.x2, next.x2))
|
|
331
|
+
[ranges.initial.x2, ranges.current.x2] = [next.x2, next.x2]
|
|
352
332
|
if (!vec2_equal(init.y, next.y)) [ranges.initial.y, ranges.current.y] = [next.y, next.y]
|
|
353
|
-
if (!vec2_equal(init.y2, next.y2))
|
|
333
|
+
if (!vec2_equal(init.y2, next.y2))
|
|
334
|
+
[ranges.initial.y2, ranges.current.y2] = [next.y2, next.y2]
|
|
354
335
|
})
|
|
355
336
|
|
|
356
337
|
// Layout: dynamic padding based on tick label widths
|
|
357
|
-
const default_padding = { t: 20, b: 60, l: 60, r: 20 }
|
|
358
338
|
// base_pad reserves space for tick labels/axis titles; pad (below) adds decoration reservations
|
|
359
|
-
let base_pad = $derived(filter_padding(padding,
|
|
339
|
+
let base_pad = $derived(filter_padding(padding, DEFAULT_PLOT_PADDING))
|
|
360
340
|
|
|
361
341
|
// Update padding based on tick label widths (untrack breaks circular dependency)
|
|
362
342
|
$effect(() => {
|
|
@@ -364,19 +344,23 @@
|
|
|
364
344
|
const current_ticks_y = untrack(() => ticks.y)
|
|
365
345
|
const current_ticks_y2 = untrack(() => ticks.y2)
|
|
366
346
|
|
|
367
|
-
const new_pad =
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
347
|
+
const new_pad =
|
|
348
|
+
width && height && current_ticks_y.length > 0
|
|
349
|
+
? calc_auto_padding({
|
|
350
|
+
padding,
|
|
351
|
+
default_padding: DEFAULT_PLOT_PADDING,
|
|
352
|
+
x2_axis: { ...final_x2_axis, tick_values: current_ticks_x2 },
|
|
353
|
+
y_axis: { ...final_y_axis, tick_values: current_ticks_y },
|
|
354
|
+
y2_axis: { ...final_y2_axis, tick_values: current_ticks_y2 },
|
|
355
|
+
})
|
|
356
|
+
: filter_padding(padding, DEFAULT_PLOT_PADDING)
|
|
376
357
|
|
|
377
358
|
// Add y2 axis label space (calc_auto_padding only accounts for tick labels)
|
|
378
359
|
if (
|
|
379
|
-
width &&
|
|
360
|
+
width &&
|
|
361
|
+
height &&
|
|
362
|
+
y2_series.length > 0 &&
|
|
363
|
+
current_ticks_y2.length > 0 &&
|
|
380
364
|
final_y2_axis.label
|
|
381
365
|
) {
|
|
382
366
|
const inside = final_y2_axis.tick?.label?.inside ?? false
|
|
@@ -392,29 +376,35 @@
|
|
|
392
376
|
|
|
393
377
|
// Add x2 axis label space (mirroring y2 logic for top padding)
|
|
394
378
|
if (
|
|
395
|
-
width &&
|
|
379
|
+
width &&
|
|
380
|
+
height &&
|
|
381
|
+
x2_series.length > 0 &&
|
|
382
|
+
current_ticks_x2.length > 0 &&
|
|
396
383
|
final_x2_axis.label
|
|
397
384
|
) {
|
|
398
385
|
const inside = final_x2_axis.tick?.label?.inside ?? false
|
|
399
|
-
const tick_shift = inside
|
|
400
|
-
? 0
|
|
401
|
-
: Math.abs(final_x2_axis.tick?.label?.shift?.y ?? 0) + 8
|
|
386
|
+
const tick_shift = inside ? 0 : Math.abs(final_x2_axis.tick?.label?.shift?.y ?? 0) + 8
|
|
402
387
|
const label_thickness = Math.round(12 * 1.2)
|
|
403
|
-
new_pad.t = Math.max(
|
|
404
|
-
new_pad.t,
|
|
405
|
-
tick_shift + LABEL_GAP_DEFAULT + label_thickness,
|
|
406
|
-
)
|
|
388
|
+
new_pad.t = Math.max(new_pad.t, tick_shift + LABEL_GAP_DEFAULT + label_thickness)
|
|
407
389
|
}
|
|
408
390
|
|
|
409
391
|
// Only update if padding actually changed
|
|
410
392
|
if (
|
|
411
|
-
base_pad.t !== new_pad.t ||
|
|
412
|
-
base_pad.
|
|
413
|
-
|
|
393
|
+
base_pad.t !== new_pad.t ||
|
|
394
|
+
base_pad.b !== new_pad.b ||
|
|
395
|
+
base_pad.l !== new_pad.l ||
|
|
396
|
+
base_pad.r !== new_pad.r
|
|
397
|
+
)
|
|
398
|
+
base_pad = new_pad
|
|
414
399
|
})
|
|
415
400
|
|
|
416
|
-
|
|
401
|
+
let legend_size_revision = $state(0)
|
|
402
|
+
const legend_footprint = $derived.by(() => {
|
|
403
|
+
void legend_size_revision
|
|
404
|
+
return measured_footprint(legend_element, { width: 120, height: 60 })
|
|
405
|
+
})
|
|
417
406
|
const legend_has_explicit_pos = $derived(has_explicit_position(legend?.style))
|
|
407
|
+
const should_show_legend = $derived(show_legend && legend != null && series.length > 1)
|
|
418
408
|
|
|
419
409
|
// Obstacle field in normalized [0,1] plot coords (y=0 at top). Each filled bar is modeled as a
|
|
420
410
|
// vertical segment (top -> baseline) so the legend can't hide inside a tall bar. Built from
|
|
@@ -444,73 +434,64 @@
|
|
|
444
434
|
})
|
|
445
435
|
|
|
446
436
|
// Move the legend to the bottom margin when no interior spot avoids the bars
|
|
447
|
-
const decor = $derived
|
|
437
|
+
const decor = $derived(
|
|
448
438
|
place_decorations({
|
|
449
439
|
base_pad,
|
|
450
440
|
width,
|
|
451
441
|
height,
|
|
452
442
|
obstacles_norm,
|
|
453
443
|
// gate on legend_element (the render signal) not legend_data, whose entries can read pad
|
|
454
|
-
legend:
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
})
|
|
444
|
+
legend:
|
|
445
|
+
should_show_legend && legend_element != null && !legend_has_explicit_pos
|
|
446
|
+
? { footprint: legend_footprint, clearance: legend?.axis_clearance }
|
|
447
|
+
: null,
|
|
448
|
+
}),
|
|
449
|
+
)
|
|
450
|
+
// Resolve marginals (default: CDF strip on top) and reserve outer-band padding. Pass the
|
|
451
|
+
// histogram's `bins` as the marginal's histogram bin count (NOT `size`/thickness) so a
|
|
452
|
+
// `histogram` marginal inherits the main binning via normalize_marginals' merge; `cdf`
|
|
453
|
+
// ignores `bins`. Samples lie along x and equal series.y, so the adapter maps y -> x.
|
|
454
|
+
const resolved_marginals = $derived(
|
|
455
|
+
normalize_marginals(marginals, { top: { type: `cdf`, bins } }),
|
|
456
|
+
)
|
|
457
|
+
const pad = $derived(add_sides(decor.pad, reserve_marginal_pad(resolved_marginals)))
|
|
458
|
+
// a lone series uses the configured bar color; with multiple, each gets its own
|
|
459
|
+
const series_color = (series_data: DataSeries) =>
|
|
460
|
+
selected_series.length === 1 ? final_bar.color : extract_series_color(series_data)
|
|
461
|
+
const marginal_series = $derived<MarginalSeriesInput[]>(
|
|
462
|
+
selected_series_entries.map(({ series_data }) => ({
|
|
463
|
+
x: series_data.y ?? [],
|
|
464
|
+
color: series_color(series_data),
|
|
465
|
+
label: series_data.label,
|
|
466
|
+
visible: true,
|
|
467
|
+
x_axis: series_data.x_axis,
|
|
468
|
+
y_axis: series_data.y_axis,
|
|
469
|
+
})),
|
|
470
|
+
)
|
|
471
|
+
const marginal_has_axis = $derived(
|
|
472
|
+
marginal_axis_presence(x2_series.length > 0, y2_series.length > 0),
|
|
459
473
|
)
|
|
460
|
-
const pad = $derived(decor.pad)
|
|
461
|
-
const legend_auto_outside = $derived(decor.legend_outside)
|
|
462
|
-
const legend_outside_x = $derived(decor.legend_pos.x)
|
|
463
|
-
const legend_outside_y = $derived(decor.legend_pos.y)
|
|
464
474
|
|
|
465
|
-
// Scales and data
|
|
466
|
-
let scales = $derived(
|
|
467
|
-
|
|
468
|
-
final_x_axis
|
|
469
|
-
ranges.current
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
final_x2_axis.scale_type ?? `linear`,
|
|
474
|
-
ranges.current.x2,
|
|
475
|
-
[pad.l, width - pad.r],
|
|
476
|
-
),
|
|
477
|
-
y: create_scale(
|
|
478
|
-
final_y_axis.scale_type ?? `linear`,
|
|
479
|
-
ranges.current.y,
|
|
480
|
-
[height - pad.b, pad.t],
|
|
481
|
-
),
|
|
482
|
-
y2: create_scale(
|
|
483
|
-
final_y2_axis.scale_type ?? `linear`,
|
|
484
|
-
ranges.current.y2,
|
|
485
|
-
[height - pad.b, pad.t],
|
|
475
|
+
// Scales and data (x/x2 share the horizontal pixel span, y/y2 the inverted vertical one)
|
|
476
|
+
let scales = $derived(
|
|
477
|
+
create_axis_scales(
|
|
478
|
+
{ x: final_x_axis, x2: final_x2_axis, y: final_y_axis, y2: final_y2_axis },
|
|
479
|
+
ranges.current,
|
|
480
|
+
pad,
|
|
481
|
+
width,
|
|
482
|
+
height,
|
|
486
483
|
),
|
|
487
|
-
|
|
484
|
+
)
|
|
488
485
|
|
|
489
486
|
// Pad-independent binning (no pixel scales) so the auto-place obstacle field can reuse it
|
|
490
487
|
let histogram_bins = $derived.by(() => {
|
|
491
488
|
if (selected_series.length === 0 || !width || !height) return []
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
.
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
return selected_series_entries.map(({ series_data, series_idx }) => {
|
|
499
|
-
const use_x2 = series_data.x_axis === `x2`
|
|
500
|
-
const active_hist = use_x2 && x2_hist_generator ? x2_hist_generator : hist_generator
|
|
501
|
-
const bins_arr = active_hist(series_data.y)
|
|
502
|
-
return {
|
|
503
|
-
id: series_data.id ?? series_idx,
|
|
504
|
-
series_idx,
|
|
505
|
-
label: series_data.label || `Series ${series_idx + 1}`,
|
|
506
|
-
color: selected_series.length === 1
|
|
507
|
-
? final_bar.color
|
|
508
|
-
: extract_series_color(series_data),
|
|
509
|
-
bins: bins_arr,
|
|
510
|
-
max_count: max(bins_arr, (data) => data.length) || 0,
|
|
511
|
-
x_axis: series_data.x_axis,
|
|
512
|
-
y_axis: series_data.y_axis,
|
|
513
|
-
}
|
|
489
|
+
return compute_histogram_bins(selected_series_entries, {
|
|
490
|
+
x_domain: ranges.current.x,
|
|
491
|
+
x2_domain: ranges.current.x2,
|
|
492
|
+
has_x2: x2_series.length > 0,
|
|
493
|
+
bin_count: bins,
|
|
494
|
+
series_color,
|
|
514
495
|
})
|
|
515
496
|
})
|
|
516
497
|
// Render-time data adds the pixel scales (pad-dependent)
|
|
@@ -522,49 +503,30 @@
|
|
|
522
503
|
})),
|
|
523
504
|
)
|
|
524
505
|
|
|
525
|
-
let ticks = $derived({
|
|
526
|
-
x
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
y: width && height
|
|
545
|
-
? generate_ticks(
|
|
546
|
-
ranges.current.y,
|
|
547
|
-
final_y_axis.scale_type ?? `linear`,
|
|
548
|
-
final_y_axis.ticks,
|
|
549
|
-
scales.y,
|
|
550
|
-
{ default_count: 6 },
|
|
551
|
-
)
|
|
552
|
-
: [],
|
|
553
|
-
y2: width && height && y2_series.length > 0
|
|
554
|
-
? generate_ticks(
|
|
555
|
-
ranges.current.y2,
|
|
556
|
-
final_y2_axis.scale_type ?? `linear`,
|
|
557
|
-
final_y2_axis.ticks,
|
|
558
|
-
scales.y2,
|
|
559
|
-
{ default_count: 6 },
|
|
560
|
-
)
|
|
561
|
-
: [],
|
|
506
|
+
let ticks = $derived.by(() => {
|
|
507
|
+
// x/y always render; x2/y2 only when their series exist (else their scale is a [0,1] sentinel)
|
|
508
|
+
const axis_ticks = (
|
|
509
|
+
axis: typeof final_x_axis,
|
|
510
|
+
range: Vec2,
|
|
511
|
+
scale: typeof scales.x,
|
|
512
|
+
default_count: number,
|
|
513
|
+
show = true,
|
|
514
|
+
) =>
|
|
515
|
+
width && height && show
|
|
516
|
+
? generate_ticks(range, axis.scale_type ?? `linear`, axis.ticks, scale, {
|
|
517
|
+
default_count,
|
|
518
|
+
})
|
|
519
|
+
: []
|
|
520
|
+
const x = axis_ticks(final_x_axis, ranges.current.x, scales.x, 8)
|
|
521
|
+
const x2 = axis_ticks(final_x2_axis, ranges.current.x2, scales.x2, 8, x2_series.length > 0)
|
|
522
|
+
const y = axis_ticks(final_y_axis, ranges.current.y, scales.y, 6)
|
|
523
|
+
const y2 = axis_ticks(final_y2_axis, ranges.current.y2, scales.y2, 6, y2_series.length > 0)
|
|
524
|
+
return { x, x2, y, y2 }
|
|
562
525
|
})
|
|
563
526
|
|
|
564
527
|
// Cache measured tick-label widths so expensive text measurement only runs
|
|
565
528
|
// when tick values/format change, not on every template rerender.
|
|
566
529
|
let tick_label_widths = $derived({
|
|
567
|
-
x2_max: measure_max_tick_width(ticks.x2, final_x2_axis.format ?? ``),
|
|
568
530
|
y_max: measure_max_tick_width(ticks.y, final_y_axis.format ?? ``),
|
|
569
531
|
y2_max: measure_max_tick_width(ticks.y2, final_y2_axis.format ?? ``),
|
|
570
532
|
})
|
|
@@ -595,14 +557,13 @@
|
|
|
595
557
|
})
|
|
596
558
|
|
|
597
559
|
// Calculate best legend placement using continuous grid sampling
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
if (!should_place || !width || !height) return null
|
|
560
|
+
const get_legend_placement = () => {
|
|
561
|
+
if (!should_show_legend || !width || !height) return null
|
|
601
562
|
|
|
602
563
|
const plot_width = width - pad.l - pad.r
|
|
603
564
|
const plot_height = height - pad.t - pad.b
|
|
604
565
|
|
|
605
|
-
|
|
566
|
+
return compute_element_placement({
|
|
606
567
|
plot_bounds: { x: pad.l, y: pad.t, width: plot_width, height: plot_height },
|
|
607
568
|
element: legend_element,
|
|
608
569
|
element_size: { width: 120, height: 60 }, // fallback before first render
|
|
@@ -610,17 +571,16 @@
|
|
|
610
571
|
exclude_rects: [],
|
|
611
572
|
points: hist_points_for_placement,
|
|
612
573
|
})
|
|
613
|
-
|
|
614
|
-
return result
|
|
615
|
-
})
|
|
574
|
+
}
|
|
616
575
|
|
|
617
576
|
// Tweened legend coordinates with shared placement stability gating
|
|
618
577
|
const legend_tween = create_placed_tween({
|
|
619
|
-
placement:
|
|
578
|
+
placement: get_legend_placement,
|
|
620
579
|
dims: () => ({ width, height }),
|
|
621
580
|
responsive: () => legend?.responsive ?? false,
|
|
622
581
|
element: () => legend_element,
|
|
623
582
|
tween: () => legend?.tween,
|
|
583
|
+
on_element_resize: () => (legend_size_revision += 1),
|
|
624
584
|
})
|
|
625
585
|
|
|
626
586
|
// Shared pan/zoom/touch/drag-rect interaction controller
|
|
@@ -630,7 +590,9 @@
|
|
|
630
590
|
({ x: final_x_axis, x2: final_x2_axis, y: final_y_axis, y2: final_y2_axis })[axis]
|
|
631
591
|
.scale_type,
|
|
632
592
|
// Clamp to at least 1 to avoid Infinity deltas when padding equals container size
|
|
633
|
-
|
|
593
|
+
plot_bounds: () => ({
|
|
594
|
+
x: pad.l,
|
|
595
|
+
y: pad.t,
|
|
634
596
|
width: Math.max(1, width - pad.l - pad.r),
|
|
635
597
|
height: Math.max(1, height - pad.t - pad.b),
|
|
636
598
|
}),
|
|
@@ -644,11 +606,13 @@
|
|
|
644
606
|
x_axis = { ...x_axis, range: next_x }
|
|
645
607
|
// gate x2/y2 on series presence: their scales are [0, 1] sentinels otherwise,
|
|
646
608
|
// so inverting would store a phantom range in the bindable prop
|
|
647
|
-
const next_x2 =
|
|
609
|
+
const next_x2 =
|
|
610
|
+
x2_series.length > 0 ? invert_rect_range(scales.x2, start.x, current.x) : null
|
|
648
611
|
if (next_x2) x2_axis = { ...x2_axis, range: next_x2 }
|
|
649
612
|
const next_y = invert_rect_range(scales.y, start.y, current.y)
|
|
650
613
|
if (next_y) y_axis = { ...y_axis, range: next_y }
|
|
651
|
-
const next_y2 =
|
|
614
|
+
const next_y2 =
|
|
615
|
+
y2_series.length > 0 ? invert_rect_range(scales.y2, start.y, current.y) : null
|
|
652
616
|
if (next_y2) y2_axis = { ...y2_axis, range: next_y2 }
|
|
653
617
|
},
|
|
654
618
|
on_reset: () => {
|
|
@@ -698,7 +662,10 @@
|
|
|
698
662
|
on_bar_hover?.({ value, count, property, event: evt })
|
|
699
663
|
}
|
|
700
664
|
|
|
701
|
-
const legend_vis = create_legend_visibility(
|
|
665
|
+
const legend_vis = create_legend_visibility(
|
|
666
|
+
() => series,
|
|
667
|
+
(next) => (series = next),
|
|
668
|
+
)
|
|
702
669
|
|
|
703
670
|
// Set theme-aware background when entering fullscreen
|
|
704
671
|
$effect(() => {
|
|
@@ -706,31 +673,24 @@
|
|
|
706
673
|
})
|
|
707
674
|
|
|
708
675
|
// State accessors for shared axis change handler
|
|
676
|
+
// Spread into existing state in each setter to preserve merged type structure
|
|
709
677
|
const axis_state: AxisChangeState<DataSeries> = {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
},
|
|
716
|
-
set_axis: (axis, config) => {
|
|
717
|
-
// Spread into existing state to preserve merged type structure
|
|
718
|
-
if (axis === `x`) x_axis = { ...x_axis, ...config }
|
|
719
|
-
else if (axis === `x2`) x2_axis = { ...x2_axis, ...config }
|
|
720
|
-
else if (axis === `y`) y_axis = { ...y_axis, ...config }
|
|
721
|
-
else y2_axis = { ...y2_axis, ...config }
|
|
678
|
+
axes: {
|
|
679
|
+
x: { get: () => x_axis, set: (config) => (x_axis = { ...x_axis, ...config }) },
|
|
680
|
+
x2: { get: () => x2_axis, set: (config) => (x2_axis = { ...x2_axis, ...config }) },
|
|
681
|
+
y: { get: () => y_axis, set: (config) => (y_axis = { ...y_axis, ...config }) },
|
|
682
|
+
y2: { get: () => y2_axis, set: (config) => (y2_axis = { ...y2_axis, ...config }) },
|
|
722
683
|
},
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
get_loading: () => axis_loading,
|
|
726
|
-
set_loading: (axis) => (axis_loading = axis),
|
|
684
|
+
series: { get: () => series, set: (next) => (series = next) },
|
|
685
|
+
loading: { get: () => axis_loading, set: (axis) => (axis_loading = axis) },
|
|
727
686
|
}
|
|
728
687
|
|
|
729
688
|
// Shared handler + one-shot auto-load bound to this component's state
|
|
730
|
-
const { handle_axis_change, try_auto_load } = create_axis_loader(
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
689
|
+
const { handle_axis_change, try_auto_load } = create_axis_loader(axis_state, () => ({
|
|
690
|
+
data_loader,
|
|
691
|
+
on_axis_change,
|
|
692
|
+
on_error,
|
|
693
|
+
}))
|
|
734
694
|
$effect(try_auto_load)
|
|
735
695
|
</script>
|
|
736
696
|
|
|
@@ -795,8 +755,7 @@
|
|
|
795
755
|
bind:this={svg_element}
|
|
796
756
|
role="application"
|
|
797
757
|
aria-label={rest[`aria-label`] ??
|
|
798
|
-
|
|
799
|
-
`Histogram`)}
|
|
758
|
+
([final_x_axis.label, final_y_axis.label].filter(Boolean).join(` vs `) || `Histogram`)}
|
|
800
759
|
tabindex="0"
|
|
801
760
|
onfocusin={() => pan_zoom.set_focused(true)}
|
|
802
761
|
onfocusout={() => pan_zoom.set_focused(false)}
|
|
@@ -863,17 +822,17 @@
|
|
|
863
822
|
<!-- X-axis -->
|
|
864
823
|
<PlotAxis
|
|
865
824
|
side="x"
|
|
866
|
-
ticks={ticks.x
|
|
825
|
+
ticks={ticks.x}
|
|
867
826
|
place={scales.x}
|
|
868
827
|
axis={final_x_axis}
|
|
869
|
-
domain={ranges.current.x
|
|
828
|
+
domain={ranges.current.x}
|
|
870
829
|
{pad}
|
|
871
830
|
{width}
|
|
872
831
|
{height}
|
|
873
832
|
show_grid={display.x_grid}
|
|
874
833
|
tick_label={(tick) => get_tick_label(tick, final_x_axis.ticks)}
|
|
875
834
|
label_x={(pad.l + width - pad.r) / 2 + (final_x_axis.label_shift?.x ?? 0)}
|
|
876
|
-
label_y={height -
|
|
835
|
+
label_y={height - pad.b + AXIS_TITLE_OFFSET + (final_x_axis.label_shift?.y ?? 0)}
|
|
877
836
|
axis_loading={axis_loading === `x`}
|
|
878
837
|
on_axis_change={(key) => handle_axis_change(`x`, key)}
|
|
879
838
|
/>
|
|
@@ -882,17 +841,17 @@
|
|
|
882
841
|
{#if x2_series.length > 0}
|
|
883
842
|
<PlotAxis
|
|
884
843
|
side="x2"
|
|
885
|
-
ticks={ticks.x2
|
|
844
|
+
ticks={ticks.x2}
|
|
886
845
|
place={scales.x2}
|
|
887
846
|
axis={final_x2_axis}
|
|
888
|
-
domain={ranges.current.x2
|
|
847
|
+
domain={ranges.current.x2}
|
|
889
848
|
{pad}
|
|
890
849
|
{width}
|
|
891
850
|
{height}
|
|
892
851
|
show_grid={display.x2_grid}
|
|
893
852
|
tick_label={(tick) => get_tick_label(tick, final_x2_axis.ticks)}
|
|
894
853
|
label_x={(pad.l + width - pad.r) / 2 + (final_x2_axis.label_shift?.x ?? 0)}
|
|
895
|
-
label_y={Math.max(12, pad.t - (final_x2_axis.label_shift?.y ??
|
|
854
|
+
label_y={Math.max(12, pad.t - (final_x2_axis.label_shift?.y ?? AXIS_TITLE_OFFSET))}
|
|
896
855
|
axis_loading={axis_loading === `x2`}
|
|
897
856
|
on_axis_change={(key) => handle_axis_change(`x2`, key)}
|
|
898
857
|
/>
|
|
@@ -901,10 +860,10 @@
|
|
|
901
860
|
<!-- Y-axis -->
|
|
902
861
|
<PlotAxis
|
|
903
862
|
side="y"
|
|
904
|
-
ticks={ticks.y
|
|
863
|
+
ticks={ticks.y}
|
|
905
864
|
place={scales.y}
|
|
906
865
|
axis={final_y_axis}
|
|
907
|
-
domain={ranges.current.y
|
|
866
|
+
domain={ranges.current.y}
|
|
908
867
|
{pad}
|
|
909
868
|
{width}
|
|
910
869
|
{height}
|
|
@@ -912,7 +871,8 @@
|
|
|
912
871
|
tick_label={(tick) => get_tick_label(tick, final_y_axis.ticks)}
|
|
913
872
|
label_x={Math.max(
|
|
914
873
|
12,
|
|
915
|
-
pad.l -
|
|
874
|
+
pad.l -
|
|
875
|
+
(final_y_axis.tick?.label?.inside ? 0 : tick_label_widths.y_max) -
|
|
916
876
|
LABEL_GAP_DEFAULT,
|
|
917
877
|
) + (final_y_axis.label_shift?.x ?? 0)}
|
|
918
878
|
label_y={pad.t + (height - pad.t - pad.b) / 2 + (final_y_axis.label_shift?.y ?? 0)}
|
|
@@ -924,10 +884,10 @@
|
|
|
924
884
|
{#if y2_series.length > 0}
|
|
925
885
|
<PlotAxis
|
|
926
886
|
side="y2"
|
|
927
|
-
ticks={ticks.y2
|
|
887
|
+
ticks={ticks.y2}
|
|
928
888
|
place={scales.y2}
|
|
929
889
|
axis={final_y2_axis}
|
|
930
|
-
domain={ranges.current.y2
|
|
890
|
+
domain={ranges.current.y2}
|
|
931
891
|
{pad}
|
|
932
892
|
{width}
|
|
933
893
|
{height}
|
|
@@ -941,24 +901,19 @@
|
|
|
941
901
|
{/if}
|
|
942
902
|
|
|
943
903
|
<!-- Histogram bars (rendered after axes so bars appear above grid lines) -->
|
|
944
|
-
{#each histogram_data as
|
|
945
|
-
{ id, bins, color, label, x_scale, y_scale, x_axis: srs_x_axis, y_axis, series_idx },
|
|
946
|
-
idx
|
|
947
|
-
(id ?? idx)
|
|
948
|
-
}
|
|
904
|
+
{#each histogram_data as { id, bins, color, label, x_scale, y_scale, x_axis: srs_x_axis, y_axis, series_idx }, idx (id ?? idx)}
|
|
949
905
|
<g
|
|
950
906
|
class="histogram-series"
|
|
951
907
|
data-series-idx={series_idx}
|
|
952
908
|
clip-path="url(#{clip_path_id})"
|
|
953
|
-
opacity={hovered_legend_series_idx !== null &&
|
|
954
|
-
hovered_legend_series_idx !== series_idx
|
|
909
|
+
opacity={hovered_legend_series_idx !== null && hovered_legend_series_idx !== series_idx
|
|
955
910
|
? 0.25
|
|
956
911
|
: 1}
|
|
957
912
|
>
|
|
958
913
|
{#each bins as bin, bin_idx (bin_idx)}
|
|
959
914
|
{@const bar_x = x_scale(bin.x0!)}
|
|
960
915
|
{@const bar_width = Math.max(1, Math.abs(x_scale(bin.x1!) - bar_x))}
|
|
961
|
-
{@const bar_height = Math.max(0,
|
|
916
|
+
{@const bar_height = Math.max(0, height - pad.b - y_scale(bin.length))}
|
|
962
917
|
{@const bar_y = y_scale(bin.length)}
|
|
963
918
|
{@const value = (bin.x0! + bin.x1!) / 2}
|
|
964
919
|
{#if bar_height > 0}
|
|
@@ -978,22 +933,22 @@
|
|
|
978
933
|
role="button"
|
|
979
934
|
tabindex="0"
|
|
980
935
|
onmousemove={(evt) =>
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
936
|
+
handle_mouse_move(
|
|
937
|
+
evt,
|
|
938
|
+
value,
|
|
939
|
+
bin.length,
|
|
940
|
+
label,
|
|
941
|
+
(y_axis ?? `y1`) as `y1` | `y2`,
|
|
942
|
+
series_idx,
|
|
943
|
+
(srs_x_axis ?? `x1`) as `x1` | `x2`,
|
|
944
|
+
)}
|
|
990
945
|
onmouseleave={() => {
|
|
991
946
|
hover_info = null
|
|
992
947
|
change(null)
|
|
993
948
|
on_bar_hover?.(null)
|
|
994
949
|
}}
|
|
995
950
|
onclick={(event) =>
|
|
996
|
-
|
|
951
|
+
on_bar_click?.({ value, count: bin.length, property: label, event })}
|
|
997
952
|
onkeydown={(event: KeyboardEvent) => {
|
|
998
953
|
if ([`Enter`, ` `].includes(event.key)) {
|
|
999
954
|
event.preventDefault()
|
|
@@ -1009,6 +964,23 @@
|
|
|
1009
964
|
|
|
1010
965
|
<!-- Reference lines: above all -->
|
|
1011
966
|
{@render ref_lines_layer(ref_lines_by_z.above_all)}
|
|
967
|
+
|
|
968
|
+
<!-- Marginal distribution strips -->
|
|
969
|
+
<PlotMarginals
|
|
970
|
+
marginals={resolved_marginals}
|
|
971
|
+
series={marginal_series}
|
|
972
|
+
{width}
|
|
973
|
+
{height}
|
|
974
|
+
{pad}
|
|
975
|
+
has_axis={marginal_has_axis}
|
|
976
|
+
axes={{
|
|
977
|
+
x1: marginal_axis(scales.x, ranges.current.x, final_x_axis),
|
|
978
|
+
x2: marginal_axis(scales.x2, ranges.current.x2, final_x2_axis),
|
|
979
|
+
y1: marginal_axis(scales.y, ranges.current.y, final_y_axis),
|
|
980
|
+
y2: marginal_axis(scales.y2, ranges.current.y2, final_y2_axis),
|
|
981
|
+
}}
|
|
982
|
+
id={clip_path_id}
|
|
983
|
+
/>
|
|
1012
984
|
</svg>
|
|
1013
985
|
|
|
1014
986
|
<!-- Tooltip (outside SVG for proper HTML rendering) -->
|
|
@@ -1026,8 +998,8 @@
|
|
|
1026
998
|
{#if tooltip}
|
|
1027
999
|
{@render tooltip({ ...hover_info, fullscreen })}
|
|
1028
1000
|
{:else}
|
|
1029
|
-
<div>Value: {
|
|
1030
|
-
<div>Count: {
|
|
1001
|
+
<div>Value: {format_value_or_num(value, hover_info.x_axis.format)}</div>
|
|
1002
|
+
<div>Count: {format_value_or_num(count, hover_info.y_axis.format)}</div>
|
|
1031
1003
|
{#if mode === `overlay`}<div>{property}</div>{/if}
|
|
1032
1004
|
{/if}
|
|
1033
1005
|
</PlotTooltip>
|
|
@@ -1065,29 +1037,29 @@
|
|
|
1065
1037
|
/>
|
|
1066
1038
|
{/if}
|
|
1067
1039
|
|
|
1068
|
-
{#if
|
|
1040
|
+
{#if should_show_legend && legend}
|
|
1069
1041
|
{@const legend_pos = placed_coords(
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1042
|
+
decor.legend_outside,
|
|
1043
|
+
decor.legend_pos,
|
|
1044
|
+
legend_tween.placed(),
|
|
1045
|
+
legend_tween.coords.current,
|
|
1046
|
+
{ x: pad.l + 10, y: pad.t + 10 },
|
|
1047
|
+
)}
|
|
1076
1048
|
<PlotLegend
|
|
1077
1049
|
bind:root_element={legend_element}
|
|
1078
1050
|
{...legend}
|
|
1079
1051
|
series_data={legend_data}
|
|
1080
|
-
on_toggle={legend?.on_toggle ??
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1052
|
+
on_toggle={legend?.on_toggle ??
|
|
1053
|
+
((series_idx: number) => {
|
|
1054
|
+
if (series_idx < 0 || series_idx >= series.length) return
|
|
1055
|
+
legend_vis.on_toggle(series_idx)
|
|
1056
|
+
on_series_toggle(series_idx)
|
|
1057
|
+
})}
|
|
1085
1058
|
on_double_click={legend?.on_double_click ?? legend_vis.on_double_click}
|
|
1086
1059
|
on_hover_change={legend_tween.set_locked}
|
|
1087
1060
|
on_item_hover={(item) =>
|
|
1088
|
-
(hovered_legend_series_idx =
|
|
1089
|
-
? item.series_idx
|
|
1090
|
-
: null)}
|
|
1061
|
+
(hovered_legend_series_idx =
|
|
1062
|
+
item != null && item.series_idx >= 0 ? item.series_idx : null)}
|
|
1091
1063
|
active_series_idx={hover_info?.series_idx ?? hovered_legend_series_idx}
|
|
1092
1064
|
style={`
|
|
1093
1065
|
position: absolute;
|
|
@@ -1153,7 +1125,9 @@
|
|
|
1153
1125
|
.histogram :global(.pane-toggle),
|
|
1154
1126
|
.histogram .header-controls {
|
|
1155
1127
|
opacity: 0;
|
|
1156
|
-
transition:
|
|
1128
|
+
transition:
|
|
1129
|
+
opacity 0.2s,
|
|
1130
|
+
background-color 0.2s;
|
|
1157
1131
|
}
|
|
1158
1132
|
.histogram:hover :global(.pane-toggle),
|
|
1159
1133
|
.histogram:hover .header-controls,
|