matterviz 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/EmptyState.svelte +10 -4
- package/dist/FilePicker.svelte +12 -14
- package/dist/Icon.svelte +7 -4
- package/dist/MillerIndexInput.svelte +2 -2
- package/dist/app.css +53 -0
- package/dist/brillouin/BrillouinZone.svelte +132 -219
- package/dist/brillouin/BrillouinZone.svelte.d.ts +9 -20
- package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
- package/dist/brillouin/BrillouinZoneExportPane.svelte +47 -96
- package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +15 -42
- package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
- package/dist/brillouin/BrillouinZoneScene.svelte +63 -230
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +3 -23
- package/dist/brillouin/ReciprocalVectors.svelte +39 -0
- package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
- package/dist/brillouin/compute.d.ts +2 -0
- package/dist/brillouin/compute.js +80 -77
- package/dist/brillouin/geometry.d.ts +8 -0
- package/dist/brillouin/geometry.js +57 -0
- package/dist/brillouin/index.d.ts +2 -0
- package/dist/brillouin/index.js +2 -0
- package/dist/brillouin/types.d.ts +2 -2
- package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
- package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +143 -246
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +652 -976
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
- package/dist/chempot-diagram/async-compute.svelte.js +1 -1
- package/dist/chempot-diagram/color.d.ts +3 -6
- package/dist/chempot-diagram/color.js +5 -5
- package/dist/chempot-diagram/compute.d.ts +3 -3
- package/dist/chempot-diagram/compute.js +3 -1
- package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
- package/dist/chempot-diagram/controls-state.svelte.js +42 -0
- package/dist/chempot-diagram/export.d.ts +47 -0
- package/dist/chempot-diagram/export.js +133 -0
- package/dist/chempot-diagram/index.d.ts +1 -0
- package/dist/chempot-diagram/index.js +1 -0
- package/dist/chempot-diagram/pointer.d.ts +0 -10
- package/dist/chempot-diagram/pointer.js +4 -4
- package/dist/chempot-diagram/types.d.ts +3 -3
- package/dist/colors/index.d.ts +0 -4
- package/dist/colors/index.js +21 -22
- package/dist/composition/BarChart.svelte +37 -31
- package/dist/composition/BubbleChart.svelte +17 -17
- package/dist/composition/Composition.svelte +7 -11
- package/dist/composition/Formula.svelte +18 -25
- package/dist/composition/FormulaFilter.svelte +96 -98
- package/dist/composition/PieChart.svelte +60 -46
- package/dist/composition/chem-sys.js +3 -2
- package/dist/composition/format.js +4 -3
- package/dist/composition/index.d.ts +2 -0
- package/dist/composition/index.js +14 -0
- package/dist/composition/parse.d.ts +2 -3
- package/dist/composition/parse.js +27 -28
- package/dist/constants.js +11 -9
- package/dist/controls.d.ts +1 -0
- package/dist/controls.js +0 -1
- package/dist/convex-hull/ConvexHull.svelte +20 -25
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
- package/dist/convex-hull/ConvexHull2D.svelte +176 -256
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +269 -804
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +236 -755
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullChrome.svelte +264 -0
- package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
- package/dist/convex-hull/ConvexHullControls.svelte +128 -49
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
- package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
- package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
- package/dist/convex-hull/ConvexHullStats.svelte +210 -351
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
- package/dist/convex-hull/ConvexHullTooltip.svelte +16 -14
- package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
- package/dist/convex-hull/GasPressureControls.svelte +5 -12
- package/dist/convex-hull/StructurePopup.svelte +17 -21
- package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
- package/dist/convex-hull/TemperatureSlider.svelte +4 -10
- package/dist/convex-hull/barycentric-coords.d.ts +2 -4
- package/dist/convex-hull/barycentric-coords.js +6 -33
- package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
- package/dist/convex-hull/canvas-interactions.svelte.js +279 -0
- package/dist/convex-hull/helpers.d.ts +47 -17
- package/dist/convex-hull/helpers.js +186 -101
- package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
- package/dist/convex-hull/hull-state.svelte.js +124 -0
- package/dist/convex-hull/index.d.ts +9 -7
- package/dist/convex-hull/index.js +7 -2
- package/dist/convex-hull/thermodynamics.js +109 -937
- package/dist/convex-hull/types.d.ts +12 -4
- package/dist/convex-hull/types.js +12 -0
- package/dist/coordination/CoordinationBarPlot.svelte +41 -43
- 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 +6 -8
- 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 +24 -29
- package/dist/element/ElementTile.svelte.d.ts +1 -1
- package/dist/element/Nucleus.svelte +4 -2
- package/dist/element/data.d.ts +1 -2
- package/dist/element/helpers.d.ts +4 -0
- package/dist/element/helpers.js +18 -0
- package/dist/element/index.d.ts +1 -0
- package/dist/element/index.js +3 -0
- package/dist/feedback/DragOverlay.svelte +5 -3
- package/dist/feedback/DragOverlay.svelte.d.ts +2 -1
- package/dist/feedback/StatusMessage.svelte +20 -7
- package/dist/fermi-surface/FermiSlice.svelte +21 -18
- package/dist/fermi-surface/FermiSurface.svelte +78 -165
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +9 -20
- package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
- package/dist/fermi-surface/FermiSurfaceScene.svelte +93 -272
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
- package/dist/fermi-surface/compute.js +14 -13
- package/dist/fermi-surface/export.js +4 -15
- package/dist/fermi-surface/index.d.ts +0 -1
- package/dist/fermi-surface/index.js +0 -1
- package/dist/fermi-surface/parse.d.ts +1 -1
- package/dist/fermi-surface/parse.js +84 -97
- package/dist/fermi-surface/types.d.ts +2 -2
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +161 -185
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +6 -5
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +12 -9
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
- package/dist/heatmap-matrix/index.d.ts +8 -2
- package/dist/icons.d.ts +4 -0
- package/dist/icons.js +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/io/ExportPane.svelte +170 -0
- package/dist/io/ExportPane.svelte.d.ts +17 -0
- package/dist/io/decompress.d.ts +2 -1
- package/dist/io/decompress.js +22 -36
- package/dist/io/export.d.ts +9 -1
- package/dist/io/export.js +37 -29
- package/dist/io/fetch.d.ts +2 -4
- package/dist/io/fetch.js +0 -11
- package/dist/io/file-drop.d.ts +7 -0
- package/dist/io/file-drop.js +13 -0
- package/dist/io/index.d.ts +1 -0
- package/dist/io/index.js +3 -0
- package/dist/io/is-binary.d.ts +9 -0
- package/dist/io/is-binary.js +45 -1
- package/dist/io/types.d.ts +13 -0
- package/dist/io/url-drop.js +13 -25
- package/dist/isosurface/Isosurface.svelte +17 -23
- package/dist/isosurface/IsosurfaceControls.svelte +37 -42
- package/dist/isosurface/parse-vaspwave.d.ts +3 -0
- package/dist/isosurface/parse-vaspwave.js +138 -0
- package/dist/isosurface/parse.js +50 -48
- package/dist/labels.d.ts +6 -2
- package/dist/labels.js +44 -14
- package/dist/layout/FullscreenButton.svelte +34 -0
- package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
- package/dist/layout/FullscreenToggle.svelte +12 -12
- package/dist/layout/InfoCard.svelte +7 -18
- 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 +21 -17
- package/dist/layout/SubpageGrid.svelte +3 -1
- package/dist/layout/ViewerChrome.svelte +115 -0
- package/dist/layout/ViewerChrome.svelte.d.ts +18 -0
- package/dist/layout/fullscreen.d.ts +4 -0
- package/dist/layout/fullscreen.js +3 -5
- package/dist/layout/fullscreen.svelte.d.ts +8 -0
- package/dist/layout/fullscreen.svelte.js +36 -0
- package/dist/layout/index.d.ts +4 -0
- package/dist/layout/index.js +4 -0
- package/dist/layout/json-tree/JsonNode.svelte +8 -11
- package/dist/layout/json-tree/JsonTree.svelte +53 -77
- package/dist/layout/json-tree/JsonValue.svelte +7 -15
- package/dist/layout/json-tree/utils.js +14 -23
- package/dist/math.d.ts +9 -3
- package/dist/math.js +37 -21
- package/dist/overlays/ContextMenu.svelte +4 -2
- package/dist/overlays/CopyButton.svelte +11 -5
- package/dist/overlays/DragControlTab.svelte +6 -1
- package/dist/overlays/DraggablePane.svelte +81 -26
- package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
- package/dist/overlays/GlassChip.svelte +30 -0
- package/dist/overlays/GlassChip.svelte.d.ts +8 -0
- package/dist/overlays/InfoPaneCards.svelte +11 -23
- package/dist/overlays/index.d.ts +11 -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 +115 -146
- package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
- package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
- package/dist/periodic-table/TableInset.svelte +9 -4
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
- package/dist/phase-diagram/PhaseDiagramControls.svelte +73 -96
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +49 -134
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
- package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
- package/dist/phase-diagram/build-diagram.js +3 -3
- package/dist/phase-diagram/colors.js +1 -1
- package/dist/phase-diagram/diagram-input.d.ts +1 -2
- package/dist/phase-diagram/parse.d.ts +2 -1
- package/dist/phase-diagram/parse.js +15 -15
- package/dist/phase-diagram/svg-to-diagram.js +21 -15
- package/dist/phase-diagram/utils.js +2 -3
- package/dist/plot/bar/BarPlot.svelte +494 -692
- package/dist/plot/bar/BarPlot.svelte.d.ts +9 -15
- package/dist/plot/bar/BarPlotControls.svelte +1 -3
- package/dist/plot/bar/BarPlotControls.svelte.d.ts +5 -7
- package/dist/plot/bar/SpacegroupBarPlot.svelte +31 -37
- package/dist/plot/bar/data.d.ts +5 -4
- package/dist/plot/bar/data.js +2 -1
- package/dist/plot/box/BoxPlot.svelte +361 -439
- package/dist/plot/box/BoxPlot.svelte.d.ts +6 -3
- package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
- package/dist/plot/box/Violin.svelte.d.ts +2 -1
- package/dist/plot/box/box-plot.d.ts +3 -2
- package/dist/plot/box/box-plot.js +6 -3
- package/dist/plot/box/kde.d.ts +2 -1
- package/dist/plot/box/kde.js +4 -4
- package/dist/plot/core/auto-place.d.ts +1 -1
- package/dist/plot/core/auto-place.js +5 -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 +106 -111
- package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
- 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 +21 -11
- package/dist/plot/core/components/Line.svelte.d.ts +5 -2
- package/dist/plot/core/components/PlotAxis.svelte +42 -18
- package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
- package/dist/plot/core/components/PlotControls.svelte +65 -41
- package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
- 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 +56 -59
- package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
- package/dist/plot/core/components/ReferencePlane.svelte +9 -10
- package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
- 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 +29 -476
- package/dist/plot/core/data-transform.js +9 -5
- package/dist/plot/core/fill-utils.d.ts +7 -4
- package/dist/plot/core/fill-utils.js +34 -9
- package/dist/plot/core/index.d.ts +1 -0
- package/dist/plot/core/index.js +1 -0
- package/dist/plot/core/interactions.d.ts +5 -1
- package/dist/plot/core/interactions.js +14 -2
- package/dist/plot/core/layout.d.ts +3 -1
- package/dist/plot/core/layout.js +22 -13
- 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 +35 -0
- package/dist/plot/core/pan-zoom.svelte.js +221 -0
- package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
- package/dist/plot/core/placed-tween.svelte.js +68 -0
- package/dist/plot/core/reference-line.d.ts +10 -10
- package/dist/plot/core/reference-line.js +7 -7
- package/dist/plot/core/scales.d.ts +40 -25
- package/dist/plot/core/scales.js +49 -21
- package/dist/plot/core/svg.d.ts +2 -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 +47 -331
- package/dist/plot/core/types.js +23 -20
- package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
- package/dist/plot/core/utils/hierarchy-chart.js +179 -0
- package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
- package/dist/plot/core/utils/hierarchy-labels.js +99 -0
- package/dist/plot/core/utils/label-placement.d.ts +1 -1
- package/dist/plot/core/utils/label-placement.js +5 -5
- package/dist/plot/core/utils.d.ts +2 -1
- package/dist/plot/histogram/Histogram.svelte +373 -631
- package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
- package/dist/plot/histogram/HistogramControls.svelte +30 -28
- package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
- 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 +79 -73
- package/dist/plot/sankey/Sankey.svelte.d.ts +3 -3
- package/dist/plot/sankey/SankeyControls.svelte +22 -16
- package/dist/plot/sankey/sankey.js +3 -1
- package/dist/plot/scatter/BinnedScatterPlot.svelte +264 -112
- package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +11 -4
- package/dist/plot/scatter/ElementScatter.svelte +4 -1
- package/dist/plot/scatter/ScatterPlot.svelte +623 -821
- package/dist/plot/scatter/ScatterPlot.svelte.d.ts +9 -15
- 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/binned-scatter-types.d.ts +6 -12
- package/dist/plot/scatter/binned-scatter-types.js +6 -1
- package/dist/plot/scatter/index.d.ts +1 -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 +40 -60
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
- package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +17 -15
- package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +232 -234
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
- package/dist/plot/scatter-3d/Surface3D.svelte +9 -17
- package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
- package/dist/plot/sunburst/Sunburst.svelte +256 -338
- package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
- 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 +14 -4
- package/dist/plot/treemap/Treemap.svelte +907 -0
- package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
- package/dist/plot/treemap/index.d.ts +3 -0
- package/dist/plot/treemap/index.js +4 -0
- package/dist/plot/treemap/treemap.d.ts +26 -0
- package/dist/plot/treemap/treemap.js +99 -0
- package/dist/rdf/RdfPlot.svelte +22 -26
- package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
- package/dist/rdf/calc-rdf.js +4 -8
- package/dist/sanitize.js +14 -3
- package/dist/scene/SceneCamera.svelte +62 -0
- package/dist/scene/SceneCamera.svelte.d.ts +19 -0
- package/dist/scene/bind-renderer.svelte.d.ts +2 -0
- package/dist/scene/bind-renderer.svelte.js +22 -0
- package/dist/scene/index.d.ts +4 -0
- package/dist/scene/index.js +5 -0
- package/dist/scene/props.js +52 -0
- package/dist/scene/types.d.ts +26 -0
- package/dist/scene/types.js +1 -0
- package/dist/settings.d.ts +33 -11
- package/dist/settings.js +136 -51
- package/dist/spectral/Bands.svelte +231 -237
- package/dist/spectral/Bands.svelte.d.ts +3 -2
- package/dist/spectral/BandsAndDos.svelte +29 -29
- package/dist/spectral/BrillouinBandsDos.svelte +21 -29
- package/dist/spectral/Dos.svelte +75 -77
- package/dist/spectral/Dos.svelte.d.ts +2 -1
- package/dist/spectral/helpers.d.ts +9 -9
- package/dist/spectral/helpers.js +66 -70
- package/dist/state.svelte.d.ts +0 -7
- package/dist/state.svelte.js +5 -24
- package/dist/structure/Arrow.svelte +6 -21
- package/dist/structure/ArrowInstances.svelte +160 -0
- package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
- package/dist/structure/AtomLegend.svelte +115 -75
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/Bond.svelte +31 -23
- package/dist/structure/CanvasTooltip.svelte +16 -3
- package/dist/structure/CellSelect.svelte +22 -29
- package/dist/structure/CellSelect.svelte.d.ts +2 -1
- 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 +725 -735
- package/dist/structure/Structure.svelte.d.ts +8 -16
- package/dist/structure/StructureCarousel.svelte +630 -0
- package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
- package/dist/structure/StructureControls.svelte +298 -325
- package/dist/structure/StructureControls.svelte.d.ts +5 -3
- package/dist/structure/StructureExportPane.svelte +62 -168
- package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
- package/dist/structure/StructureInfoPane.svelte +77 -69
- package/dist/structure/StructureInfoPane.svelte.d.ts +6 -6
- package/dist/structure/StructureScene.svelte +758 -600
- package/dist/structure/StructureScene.svelte.d.ts +24 -20
- package/dist/structure/StructureViewport.svelte +386 -0
- package/dist/structure/StructureViewport.svelte.d.ts +63 -0
- package/dist/structure/atom-label-placement.d.ts +18 -0
- package/dist/structure/atom-label-placement.js +115 -0
- package/dist/structure/atom-properties.d.ts +3 -1
- package/dist/structure/atom-properties.js +115 -54
- package/dist/structure/bond-order-perception.js +2 -4
- package/dist/structure/bonding.d.ts +12 -2
- package/dist/structure/bonding.js +172 -73
- package/dist/structure/edit-history.d.ts +6 -0
- package/dist/structure/edit-history.js +27 -0
- package/dist/structure/export.d.ts +25 -4
- package/dist/structure/export.js +103 -153
- package/dist/structure/format-detect.d.ts +1 -0
- package/dist/structure/format-detect.js +22 -0
- package/dist/structure/geometry.d.ts +9 -0
- package/dist/structure/geometry.js +27 -0
- package/dist/structure/index.d.ts +18 -1
- package/dist/structure/index.js +15 -2
- package/dist/structure/measure.d.ts +1 -1
- package/dist/structure/measure.js +6 -12
- package/dist/structure/parse.d.ts +5 -3
- package/dist/structure/parse.js +551 -567
- package/dist/structure/partial-occupancy.d.ts +0 -1
- package/dist/structure/partial-occupancy.js +5 -3
- package/dist/structure/pbc.d.ts +1 -1
- package/dist/structure/pbc.js +204 -51
- package/dist/structure/polyhedra.d.ts +40 -0
- package/dist/structure/polyhedra.js +587 -0
- package/dist/structure/site.d.ts +4 -0
- package/dist/structure/site.js +1 -0
- package/dist/structure/supercell.d.ts +1 -2
- package/dist/structure/supercell.js +10 -15
- package/dist/structure/validation.js +5 -6
- package/dist/symmetry/SymmetryElementControls.svelte +69 -0
- package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
- package/dist/symmetry/SymmetryElements.svelte +350 -0
- package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
- package/dist/symmetry/SymmetryStats.svelte +142 -49
- package/dist/symmetry/WyckoffTable.svelte +58 -16
- package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
- package/dist/symmetry/cell-transform.js +8 -14
- package/dist/symmetry/index.d.ts +15 -4
- package/dist/symmetry/index.js +308 -81
- package/dist/symmetry/spacegroups.d.ts +5 -1
- package/dist/symmetry/spacegroups.js +18 -3
- package/dist/symmetry/symmetry-elements.d.ts +33 -0
- package/dist/symmetry/symmetry-elements.js +521 -0
- package/dist/symmetry/wyckoff-db.d.ts +9 -0
- package/dist/symmetry/wyckoff-db.js +87 -0
- package/dist/table/HeatmapTable.svelte +1104 -378
- package/dist/table/HeatmapTable.svelte.d.ts +12 -2
- package/dist/table/ToggleMenu.svelte +5 -12
- 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/index.d.ts +1 -5
- package/dist/theme/index.js +4 -10
- package/dist/theme/themes.mjs +14 -7
- package/dist/tooltip/KCoords.svelte +4 -1
- package/dist/tooltip/TooltipContent.svelte +2 -5
- package/dist/trajectory/Trajectory.svelte +556 -352
- package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
- package/dist/trajectory/TrajectoryError.svelte +11 -8
- package/dist/trajectory/TrajectoryExportPane.svelte +28 -54
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
- package/dist/trajectory/TrajectoryInfoPane.svelte +88 -99
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
- package/dist/trajectory/constants.js +6 -2
- package/dist/trajectory/extract.js +73 -71
- package/dist/trajectory/format-detect.d.ts +0 -1
- package/dist/trajectory/format-detect.js +13 -17
- package/dist/trajectory/frame-reader.d.ts +2 -1
- package/dist/trajectory/frame-reader.js +74 -136
- package/dist/trajectory/helpers.d.ts +12 -2
- package/dist/trajectory/helpers.js +68 -37
- package/dist/trajectory/index.d.ts +1 -0
- package/dist/trajectory/index.js +3 -0
- package/dist/trajectory/parse/ase.d.ts +9 -1
- package/dist/trajectory/parse/ase.js +47 -32
- package/dist/trajectory/parse/diagnostics.d.ts +3 -0
- package/dist/trajectory/parse/diagnostics.js +14 -0
- 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 +3 -4
- package/dist/trajectory/parse/index.js +68 -119
- package/dist/trajectory/parse/lammps.d.ts +0 -2
- package/dist/trajectory/parse/lammps.js +14 -16
- package/dist/trajectory/parse/pymatgen.d.ts +2 -0
- package/dist/trajectory/parse/pymatgen.js +74 -0
- package/dist/trajectory/parse/vasp.js +13 -9
- 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 +5 -0
- package/dist/trajectory/parse/vaspout-h5.js +284 -0
- package/dist/trajectory/parse/xyz.d.ts +9 -21
- package/dist/trajectory/parse/xyz.js +38 -39
- package/dist/trajectory/plotting.d.ts +8 -10
- package/dist/trajectory/plotting.js +102 -127
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +8 -1
- package/dist/xrd/XrdPlot.svelte +56 -85
- package/dist/xrd/broadening.d.ts +2 -1
- package/dist/xrd/broadening.js +2 -1
- package/dist/xrd/calc-xrd.js +8 -15
- package/dist/xrd/index.d.ts +2 -2
- package/dist/xrd/parse.d.ts +0 -1
- package/dist/xrd/parse.js +56 -73
- package/package.json +77 -36
- package/dist/api/mp.d.ts +0 -6
- package/dist/api/mp.js +0 -22
- package/dist/element/data.json +0 -11864
- package/dist/fermi-surface/marching-cubes.d.ts +0 -2
- package/dist/fermi-surface/marching-cubes.js +0 -2
- package/dist/plot/core/hover-lock.svelte.d.ts +0 -14
- package/dist/plot/core/hover-lock.svelte.js +0 -45
- package/dist/plot/sunburst/SunburstControls.svelte +0 -200
- package/dist/structure/label-placement.d.ts +0 -14
- package/dist/structure/label-placement.js +0 -72
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// Renders marginal-distribution strips on any side of a 2D plot. Used by every 2D plot:
|
|
3
|
+
// each passes its resolved `marginals`, a generic `series` adapter, the shared positional
|
|
4
|
+
// scales/ranges, and the inflated `pad`. This must be a direct child of the host <svg>
|
|
5
|
+
// (outside the plot clip group); each strip self-clips. See core/marginals.ts for the math.
|
|
6
|
+
import type { Vec2 } from '../../../math'
|
|
7
|
+
import type { Rect, Sides } from '../layout'
|
|
8
|
+
import type {
|
|
9
|
+
MarginalAxes,
|
|
10
|
+
MarginalAxisBinding,
|
|
11
|
+
MarginalCurve,
|
|
12
|
+
MarginalHover,
|
|
13
|
+
MarginalRenderContext,
|
|
14
|
+
MarginalSeriesCurve,
|
|
15
|
+
MarginalSeriesInput,
|
|
16
|
+
MarginalSide,
|
|
17
|
+
ResolvedMarginalConfig,
|
|
18
|
+
ResolvedMarginals,
|
|
19
|
+
ScaleFn,
|
|
20
|
+
} from '../marginals'
|
|
21
|
+
import {
|
|
22
|
+
MARGINAL_SIDES,
|
|
23
|
+
compute_marginal_curve,
|
|
24
|
+
curves_max,
|
|
25
|
+
default_axis_for_side,
|
|
26
|
+
default_marginal_label,
|
|
27
|
+
marginal_hit,
|
|
28
|
+
marginal_strip_rect,
|
|
29
|
+
marginal_value_format,
|
|
30
|
+
marginal_value_scale,
|
|
31
|
+
} from '../marginals'
|
|
32
|
+
import { line_curve_factory } from '../fill-utils'
|
|
33
|
+
import PlotTooltip from './PlotTooltip.svelte'
|
|
34
|
+
import { sanitize_html } from '../../../sanitize'
|
|
35
|
+
import { format_value } from '../../../labels'
|
|
36
|
+
import { ticks as d3_ticks } from 'd3-array'
|
|
37
|
+
import { area, curveMonotoneX, curveMonotoneY, line } from 'd3-shape'
|
|
38
|
+
|
|
39
|
+
let {
|
|
40
|
+
marginals,
|
|
41
|
+
series,
|
|
42
|
+
width,
|
|
43
|
+
height,
|
|
44
|
+
pad,
|
|
45
|
+
has_axis = { top: false, bottom: true, left: true, right: false },
|
|
46
|
+
axes,
|
|
47
|
+
id,
|
|
48
|
+
}: {
|
|
49
|
+
marginals: ResolvedMarginals
|
|
50
|
+
series: MarginalSeriesInput[]
|
|
51
|
+
width: number
|
|
52
|
+
height: number
|
|
53
|
+
pad: Required<Sides>
|
|
54
|
+
has_axis?: Record<MarginalSide, boolean>
|
|
55
|
+
axes: MarginalAxes
|
|
56
|
+
id: string // unique per host plot; used to scope each strip's clipPath
|
|
57
|
+
} = $props()
|
|
58
|
+
|
|
59
|
+
// The marginal datum under the pointer (set by the hit-rects, drives the tooltip below)
|
|
60
|
+
let hovered = $state<MarginalHover | null>(null)
|
|
61
|
+
|
|
62
|
+
// Map a pointer event on a strip hit-rect to a MarginalHover via the pure marginal_hit. The svg
|
|
63
|
+
// has no scaling viewBox, so wrapper px = svg user-space px = the coords PlotTooltip expects.
|
|
64
|
+
const on_marginal_move = (
|
|
65
|
+
event: PointerEvent,
|
|
66
|
+
ctx: MarginalRenderContext,
|
|
67
|
+
): MarginalHover | null => {
|
|
68
|
+
const svg = (event.currentTarget as Element).closest(`svg`)
|
|
69
|
+
if (!svg) return null
|
|
70
|
+
const box = svg.getBoundingClientRect()
|
|
71
|
+
return marginal_hit(ctx, event.clientX - box.left, event.clientY - box.top)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Keep strip pointer/mouse events off the host plot's own handlers (hover, pan, zoom)
|
|
75
|
+
const stop = (event: Event) => event.stopPropagation()
|
|
76
|
+
|
|
77
|
+
// A strip shows a hover tooltip unless opted out via hover:false or replaced by a custom snippet
|
|
78
|
+
const is_hoverable = (config: ResolvedMarginalConfig) =>
|
|
79
|
+
config.hover !== false && !config.snippet
|
|
80
|
+
|
|
81
|
+
// PlotMarginals renders inside the <svg>, which can't host an HTML tooltip. Relocate the tooltip
|
|
82
|
+
// div to be a sibling of the <svg> (in the positioned plot wrapper) so it positions in wrapper px
|
|
83
|
+
// and stacks above HTML overlays (legend, colorbar) — like each host plot's own PlotTooltip.
|
|
84
|
+
const portal_to_wrapper = (node: HTMLElement) => {
|
|
85
|
+
node.closest(`svg`)?.parentElement?.append(node)
|
|
86
|
+
return () => node.remove()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Precompute tooltip content off the hot pointer path (recomputes only when `hovered` changes).
|
|
90
|
+
// `head_label`/`head_value` form the position row (bin range for bars, else a single position);
|
|
91
|
+
// `value` is the count/density/CDF row (null for rug, which has no value). A per-side
|
|
92
|
+
// `config.tooltip` snippet overrides this default content.
|
|
93
|
+
const tip = $derived.by(() => {
|
|
94
|
+
if (!hovered) return null
|
|
95
|
+
const {
|
|
96
|
+
kind,
|
|
97
|
+
config,
|
|
98
|
+
color,
|
|
99
|
+
format,
|
|
100
|
+
pos,
|
|
101
|
+
pos0,
|
|
102
|
+
pos1,
|
|
103
|
+
pos_label,
|
|
104
|
+
value,
|
|
105
|
+
label,
|
|
106
|
+
axis_title,
|
|
107
|
+
} = hovered
|
|
108
|
+
const bg_color = color.trim().toLowerCase() === `currentcolor` ? null : color
|
|
109
|
+
const pos_fmt = format || `.3~g`
|
|
110
|
+
// Position row = `<axis title>: <value>`. The title uses the host axis's markup convention
|
|
111
|
+
// (e.g. E<sub>hull</sub>), so it's sanitized HTML; the value/category portion stays literal
|
|
112
|
+
// text (matches how tick labels render, so a literal `<` in a bin label isn't mangled). `||`
|
|
113
|
+
// (not `??`) so an empty/whitespace axis title falls back to the generic `range`/`pos` label.
|
|
114
|
+
const head_label = sanitize_html(axis_title?.trim() || (kind === `bars` ? `range` : `pos`))
|
|
115
|
+
const head_value =
|
|
116
|
+
kind === `bars`
|
|
117
|
+
? `${format_value(pos0 ?? pos, pos_fmt)}–${format_value(pos1 ?? pos, pos_fmt)}`
|
|
118
|
+
: (pos_label ?? format_value(pos, pos_fmt))
|
|
119
|
+
const value_row =
|
|
120
|
+
kind === `rug`
|
|
121
|
+
? null
|
|
122
|
+
: `${default_marginal_label(config)}: ${format_value(value ?? 0, marginal_value_format(config))}`
|
|
123
|
+
return {
|
|
124
|
+
bg_color,
|
|
125
|
+
snippet: config.tooltip,
|
|
126
|
+
label,
|
|
127
|
+
head_label,
|
|
128
|
+
head_value,
|
|
129
|
+
value: value_row,
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
type RugMark = { x1: number; y1: number; x2: number; y2: number }
|
|
134
|
+
type LinePt = { pos: number; value: number }
|
|
135
|
+
type CurveRender = {
|
|
136
|
+
kind: MarginalCurve[`kind`]
|
|
137
|
+
fill: string
|
|
138
|
+
fill_opacity: number
|
|
139
|
+
stroke: string
|
|
140
|
+
stroke_width: number
|
|
141
|
+
opacity: number
|
|
142
|
+
bars: Rect[]
|
|
143
|
+
area_path: string
|
|
144
|
+
line_path: string
|
|
145
|
+
rug: RugMark[]
|
|
146
|
+
}
|
|
147
|
+
type ValueAxisRender = {
|
|
148
|
+
spine: { x1: number; y1: number; x2: number; y2: number }
|
|
149
|
+
ticks: { x: number; y: number; text: string }[]
|
|
150
|
+
anchor: string // text-anchor shared by all tick labels
|
|
151
|
+
baseline: string // dominant-baseline shared by all tick labels
|
|
152
|
+
title: { x: number; y: number; text: string; transform?: string }
|
|
153
|
+
}
|
|
154
|
+
type SideRender = {
|
|
155
|
+
side: MarginalSide
|
|
156
|
+
config: ResolvedMarginalConfig
|
|
157
|
+
rect: Rect
|
|
158
|
+
clip_id: string
|
|
159
|
+
ctx: MarginalRenderContext
|
|
160
|
+
curves: CurveRender[]
|
|
161
|
+
value_axis: ValueAxisRender | null
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// The axis a marginal binds to (x2/y2 fall back to x1/y1), with scale_type defaulted to linear
|
|
165
|
+
const axis_props = (axis: MarginalAxisBinding) => {
|
|
166
|
+
const ax = axes[axis] ?? (axis === `x2` ? axes.x1 : axes.y1)
|
|
167
|
+
return { ...ax, scale_type: ax.scale_type ?? `linear` }
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Values a series contributes for a given side (x for top/bottom, y for left/right)
|
|
171
|
+
const series_values = (
|
|
172
|
+
srs: MarginalSeriesInput,
|
|
173
|
+
is_x: boolean,
|
|
174
|
+
): { positions: ArrayLike<number>; weights: ArrayLike<number> | undefined } => ({
|
|
175
|
+
positions: (is_x ? srs.x : srs.y) ?? [],
|
|
176
|
+
weights: srs.weight,
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
// Flatten several series into one positions/weights pair (for `reduce` and merged per_series=false)
|
|
180
|
+
const merge_values = (
|
|
181
|
+
list: MarginalSeriesInput[],
|
|
182
|
+
is_x: boolean,
|
|
183
|
+
): { positions: number[]; weights: number[] | undefined } => {
|
|
184
|
+
const positions: number[] = []
|
|
185
|
+
const weights: number[] = []
|
|
186
|
+
let has_weight = false
|
|
187
|
+
for (const srs of list) {
|
|
188
|
+
const { positions: pos, weights: wts } = series_values(srs, is_x)
|
|
189
|
+
for (let idx = 0; idx < pos.length; idx++) {
|
|
190
|
+
positions.push(pos[idx])
|
|
191
|
+
if (wts) {
|
|
192
|
+
has_weight = true
|
|
193
|
+
weights.push(wts[idx])
|
|
194
|
+
} else weights.push(1)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return { positions, weights: has_weight ? weights : undefined }
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Build the SVG primitives for one curve given the side's scales
|
|
201
|
+
const build_curve_render = (
|
|
202
|
+
curve: MarginalSeriesCurve,
|
|
203
|
+
side: MarginalSide,
|
|
204
|
+
is_x: boolean,
|
|
205
|
+
pos_scale: ScaleFn,
|
|
206
|
+
val_scale: ScaleFn,
|
|
207
|
+
baseline: number,
|
|
208
|
+
config: ResolvedMarginalConfig,
|
|
209
|
+
): CurveRender => {
|
|
210
|
+
const color = config.color ?? curve.color
|
|
211
|
+
const fill = config.fill ?? color
|
|
212
|
+
const fill_opacity = config.fill_opacity ?? 0.6
|
|
213
|
+
const stroke = config.stroke ?? color
|
|
214
|
+
const { stroke_width, opacity } = config
|
|
215
|
+
const data = curve.curve
|
|
216
|
+
const base: CurveRender = {
|
|
217
|
+
kind: data.kind,
|
|
218
|
+
fill,
|
|
219
|
+
fill_opacity,
|
|
220
|
+
stroke,
|
|
221
|
+
stroke_width,
|
|
222
|
+
opacity,
|
|
223
|
+
bars: [],
|
|
224
|
+
area_path: ``,
|
|
225
|
+
line_path: ``,
|
|
226
|
+
rug: [],
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (data.kind === `bars`) {
|
|
230
|
+
base.stroke = config.stroke ?? `none` // histogram bars are fill-only unless a stroke is set
|
|
231
|
+
base.bars = data.bins
|
|
232
|
+
.filter((item) => item.value > 0)
|
|
233
|
+
.map((item) => {
|
|
234
|
+
// bar spans [pos0, pos1] on the positional axis and [baseline, value] on the value axis
|
|
235
|
+
const pos_min = Math.min(pos_scale(item.pos0), pos_scale(item.pos1))
|
|
236
|
+
const pos_len = Math.max(0, Math.abs(pos_scale(item.pos1) - pos_scale(item.pos0)))
|
|
237
|
+
const value_px = val_scale(item.value)
|
|
238
|
+
const val_min = Math.min(value_px, baseline)
|
|
239
|
+
const val_len = Math.abs(baseline - value_px)
|
|
240
|
+
return is_x
|
|
241
|
+
? { x: pos_min, y: val_min, width: pos_len, height: val_len }
|
|
242
|
+
: { x: val_min, y: pos_min, width: val_len, height: pos_len }
|
|
243
|
+
})
|
|
244
|
+
// all four must be finite: a custom reduce/data bin with a non-finite edge/value would
|
|
245
|
+
// otherwise emit width/height="Infinity" (invalid SVG). mirrors marginal_hit's bar filter
|
|
246
|
+
.filter((bar) => [bar.x, bar.y, bar.width, bar.height].every(isFinite))
|
|
247
|
+
return base
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (data.kind === `line`) {
|
|
251
|
+
const raw_pts = data.points.filter((pt) => isFinite(pt.pos) && isFinite(pt.value))
|
|
252
|
+
if (raw_pts.length < 2) return base
|
|
253
|
+
// area fills (kde/cdf) read better lighter than histogram bars
|
|
254
|
+
base.fill_opacity = config.fill_opacity ?? 0.5
|
|
255
|
+
// For monotone, the monotonic axis is the position axis: x for top/bottom, y for left/right
|
|
256
|
+
const curve_name = config.curve ?? `monotone`
|
|
257
|
+
const curve_fn =
|
|
258
|
+
curve_name === `monotone`
|
|
259
|
+
? is_x
|
|
260
|
+
? curveMonotoneX
|
|
261
|
+
: curveMonotoneY
|
|
262
|
+
: line_curve_factory(curve_name)
|
|
263
|
+
// Position maps to x for top/bottom strips and to y for left/right strips; value is the
|
|
264
|
+
// cross-axis. The line generator is symmetric; the area differs only in which axis baselines.
|
|
265
|
+
const px = (pt: LinePt) => (is_x ? pos_scale(pt.pos) : val_scale(pt.value))
|
|
266
|
+
const py = (pt: LinePt) => (is_x ? val_scale(pt.value) : pos_scale(pt.pos))
|
|
267
|
+
// drop points whose scaled pixels are non-finite (degenerate/log scales) so the path stays
|
|
268
|
+
// valid — mirrors marginal_hit, which also skips non-finite scaled coords
|
|
269
|
+
const pts = raw_pts.filter((pt) => isFinite(px(pt)) && isFinite(py(pt)))
|
|
270
|
+
if (pts.length < 2) return base
|
|
271
|
+
const area_gen = is_x
|
|
272
|
+
? area<LinePt>().x(px).y0(baseline).y1(py)
|
|
273
|
+
: area<LinePt>().y(py).x0(baseline).x1(px)
|
|
274
|
+
base.line_path = line<LinePt>().x(px).y(py).curve(curve_fn)(pts) ?? ``
|
|
275
|
+
base.area_path = area_gen.curve(curve_fn)(pts) ?? ``
|
|
276
|
+
return base
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// rug: short ticks at each position, drawn from the plot-facing edge outward
|
|
280
|
+
const rug_len = Math.min(config.size, 10)
|
|
281
|
+
const dir = side === `top` || side === `left` ? -1 : 1
|
|
282
|
+
base.rug = data.positions
|
|
283
|
+
.map((p) => pos_scale(p))
|
|
284
|
+
.filter((px) => isFinite(px))
|
|
285
|
+
.map((px) =>
|
|
286
|
+
is_x
|
|
287
|
+
? { x1: px, y1: baseline, x2: px, y2: baseline + dir * rug_len }
|
|
288
|
+
: { x1: baseline, y1: px, x2: baseline + dir * rug_len, y2: px },
|
|
289
|
+
)
|
|
290
|
+
// rug ticks are unfilled lines, so `opacity` (already config.opacity in base) controls them
|
|
291
|
+
return base
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Build the strip's value-axis (spine + a few value ticks + title), mirroring a regular axis:
|
|
295
|
+
// tick labels sit just OUTSIDE the spine (away from the strip's data) and the title sits beyond
|
|
296
|
+
// them. x-strips (top/bottom) read as a y-axis (vertical spine at the strip's left edge, labels
|
|
297
|
+
// to the left, rotated title); y-strips read as an x-axis (horizontal spine at the strip's bottom
|
|
298
|
+
// edge — which coincides with the host plot's x-axis baseline — labels below, title below them).
|
|
299
|
+
const build_value_axis = (
|
|
300
|
+
is_x: boolean,
|
|
301
|
+
rect: Rect,
|
|
302
|
+
val_scale: ScaleFn,
|
|
303
|
+
domain: Vec2,
|
|
304
|
+
config: ResolvedMarginalConfig,
|
|
305
|
+
): ValueAxisRender => {
|
|
306
|
+
const fmt = marginal_value_format(config)
|
|
307
|
+
const title = default_marginal_label(config)
|
|
308
|
+
const [v0, v1] = [val_scale(domain[0]), val_scale(domain[1])] // spine ends in px
|
|
309
|
+
const gap = 6 // spine -> tick label
|
|
310
|
+
// value px + label per tick, minus non-finite and the baseline tick (v0, plot-facing edge):
|
|
311
|
+
// it's only `gap` px from the host plot's adjacent axis tick, so they'd overlap (e.g. a CDF
|
|
312
|
+
// `0%` over the plot's top y-tick). The spine still spans full range — zero edge implied.
|
|
313
|
+
const tick_px = d3_ticks(domain[0], domain[1], 3)
|
|
314
|
+
.map((value) => ({ vpx: val_scale(value), text: format_value(value, fmt) }))
|
|
315
|
+
.filter(({ vpx }) => isFinite(vpx) && Math.abs(vpx - v0) > 1)
|
|
316
|
+
if (is_x) {
|
|
317
|
+
// labels left of the spine (anchor end); title rotated beyond the widest label
|
|
318
|
+
const label_w = Math.max(0, ...tick_px.map(({ text }) => text.length)) * 6 // ~px at 0.65em
|
|
319
|
+
const ty = rect.y + rect.height / 2
|
|
320
|
+
const title_x = rect.x - gap - label_w - 10
|
|
321
|
+
return {
|
|
322
|
+
spine: { x1: rect.x, y1: v0, x2: rect.x, y2: v1 },
|
|
323
|
+
ticks: tick_px.map(({ vpx, text }) => ({ x: rect.x - gap, y: vpx, text })),
|
|
324
|
+
anchor: `end`,
|
|
325
|
+
baseline: `central`,
|
|
326
|
+
title: { x: title_x, y: ty, text: title, transform: `rotate(-90, ${title_x}, ${ty})` },
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// value axis at the strip's BOTTOM edge (= host plot's x-axis baseline) so it reads as an
|
|
330
|
+
// extension of the main x-axis; labels hang below the spine, title below them
|
|
331
|
+
const axis_y = rect.y + rect.height
|
|
332
|
+
return {
|
|
333
|
+
spine: { x1: v0, y1: axis_y, x2: v1, y2: axis_y },
|
|
334
|
+
ticks: tick_px.map(({ vpx, text }) => ({ x: vpx, y: axis_y + gap, text })),
|
|
335
|
+
anchor: `middle`,
|
|
336
|
+
baseline: `hanging`,
|
|
337
|
+
title: { x: rect.x + rect.width / 2, y: axis_y + gap + 16, text: title },
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Compute the render model for every active side
|
|
342
|
+
const side_renders = $derived.by<SideRender[]>(() => {
|
|
343
|
+
if (!width || !height) return []
|
|
344
|
+
const visible = series.filter((srs) => srs.visible ?? true)
|
|
345
|
+
const out: SideRender[] = []
|
|
346
|
+
|
|
347
|
+
for (const side of MARGINAL_SIDES) {
|
|
348
|
+
const config = marginals[side]
|
|
349
|
+
if (!config) continue
|
|
350
|
+
const is_x = side === `top` || side === `bottom`
|
|
351
|
+
const axis = config.axis ?? default_axis_for_side(side)
|
|
352
|
+
const {
|
|
353
|
+
scale: pos_scale,
|
|
354
|
+
range: positional_range,
|
|
355
|
+
scale_type,
|
|
356
|
+
format,
|
|
357
|
+
tick_label,
|
|
358
|
+
label: axis_title,
|
|
359
|
+
} = axis_props(axis)
|
|
360
|
+
const rect = marginal_strip_rect(side, pad, width, height, config, has_axis[side])
|
|
361
|
+
if (rect.width <= 0 || rect.height <= 0) continue
|
|
362
|
+
|
|
363
|
+
const ctx_base = { config, side, positional_range, scale_type }
|
|
364
|
+
|
|
365
|
+
// Only summarize series that render on the axis this side binds to (a top/x1 marginal
|
|
366
|
+
// ignores x2 series; a right/y1 marginal ignores y2 series)
|
|
367
|
+
const axis_series = visible.filter((srs) =>
|
|
368
|
+
is_x ? (srs.x_axis ?? `x1`) === axis : (srs.y_axis ?? `y1`) === axis,
|
|
369
|
+
)
|
|
370
|
+
const merged_color = config.color ?? axis_series[0]?.color ?? `currentColor`
|
|
371
|
+
// One combined curve (for reduce / data / merged), colored once
|
|
372
|
+
const single = (curve: MarginalCurve): MarginalSeriesCurve[] => [
|
|
373
|
+
{ series_idx: -1, color: merged_color, curve },
|
|
374
|
+
]
|
|
375
|
+
const compute = (
|
|
376
|
+
pos: ArrayLike<number>,
|
|
377
|
+
wts: ArrayLike<number> | undefined,
|
|
378
|
+
): MarginalCurve =>
|
|
379
|
+
compute_marginal_curve(pos, wts, config, positional_range, scale_type)
|
|
380
|
+
|
|
381
|
+
// Resolve which curves to draw (precedence: reduce > data > per-series > merged)
|
|
382
|
+
let curves: MarginalSeriesCurve[]
|
|
383
|
+
if (config.reduce) {
|
|
384
|
+
const { positions, weights } = merge_values(axis_series, is_x)
|
|
385
|
+
curves = single(config.reduce(positions, weights, ctx_base))
|
|
386
|
+
} else if (config.data) {
|
|
387
|
+
const values = typeof config.data === `function` ? config.data(ctx_base) : config.data
|
|
388
|
+
curves = single(compute(values, undefined))
|
|
389
|
+
} else if (config.per_series) {
|
|
390
|
+
curves = axis_series.map((srs, idx) => {
|
|
391
|
+
const { positions, weights } = series_values(srs, is_x)
|
|
392
|
+
return {
|
|
393
|
+
series_idx: idx,
|
|
394
|
+
color: srs.color,
|
|
395
|
+
label: srs.label,
|
|
396
|
+
curve: compute(positions, weights),
|
|
397
|
+
}
|
|
398
|
+
})
|
|
399
|
+
} else {
|
|
400
|
+
const { positions, weights } = merge_values(axis_series, is_x)
|
|
401
|
+
curves = single(compute(positions, weights))
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Shared per-side value scale so per-series curves are directly comparable. Auto-scale adds
|
|
405
|
+
// 5% headroom above the peak so the tallest curve's line stroke isn't clipped at the strip's
|
|
406
|
+
// far edge (the clip rect sits exactly at value=max). A pinned value_range is honored as-is.
|
|
407
|
+
const max = curves_max(curves.map((entry) => entry.curve))
|
|
408
|
+
const domain: Vec2 = config.value_range ?? [0, max * 1.05]
|
|
409
|
+
const { scale: val_scale, baseline } = marginal_value_scale(side, rect, domain)
|
|
410
|
+
|
|
411
|
+
const ctx: MarginalRenderContext = {
|
|
412
|
+
...ctx_base,
|
|
413
|
+
rect,
|
|
414
|
+
positional_scale: pos_scale,
|
|
415
|
+
value_scale: val_scale,
|
|
416
|
+
baseline,
|
|
417
|
+
curves,
|
|
418
|
+
series: axis_series,
|
|
419
|
+
format,
|
|
420
|
+
tick_label,
|
|
421
|
+
axis_title,
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
out.push({
|
|
425
|
+
side,
|
|
426
|
+
config,
|
|
427
|
+
rect,
|
|
428
|
+
clip_id: `${id}-${side}`,
|
|
429
|
+
ctx,
|
|
430
|
+
// A snippet renders the strip itself, so skip building the built-in SVG primitives
|
|
431
|
+
curves: config.snippet
|
|
432
|
+
? []
|
|
433
|
+
: curves.map((curve) =>
|
|
434
|
+
build_curve_render(curve, side, is_x, pos_scale, val_scale, baseline, config),
|
|
435
|
+
),
|
|
436
|
+
// Value axis only when there's something to scale: a pinned value_range, or positive
|
|
437
|
+
// non-rug content (max > 0). This skips rug (no value), empty curves (degenerate [0,0]
|
|
438
|
+
// domain), and snippets (which draw their own).
|
|
439
|
+
value_axis:
|
|
440
|
+
config.value_axis && !config.snippet && (config.value_range != null || max > 0)
|
|
441
|
+
? build_value_axis(is_x, rect, val_scale, domain, config)
|
|
442
|
+
: null,
|
|
443
|
+
})
|
|
444
|
+
}
|
|
445
|
+
return out
|
|
446
|
+
})
|
|
447
|
+
</script>
|
|
448
|
+
|
|
449
|
+
{#each side_renders as render (render.side)}
|
|
450
|
+
{@const { side, config, rect, clip_id, ctx, curves, value_axis } = render}
|
|
451
|
+
<defs>
|
|
452
|
+
<clipPath id={clip_id}>
|
|
453
|
+
<rect x={rect.x} y={rect.y} width={rect.width} height={rect.height} />
|
|
454
|
+
</clipPath>
|
|
455
|
+
</defs>
|
|
456
|
+
<g
|
|
457
|
+
class={[`marginal`, `marginal-${side}`, config.class]}
|
|
458
|
+
clip-path="url(#{clip_id})"
|
|
459
|
+
style={config.style}
|
|
460
|
+
>
|
|
461
|
+
{#if config.snippet}
|
|
462
|
+
{@render config.snippet(ctx)}
|
|
463
|
+
{:else}
|
|
464
|
+
{#each curves as curve, curve_idx (curve_idx)}
|
|
465
|
+
<!-- Discriminate on the actual curve kind so a custom `reduce`/`data` returning any
|
|
466
|
+
kind renders correctly (empty primitives simply render nothing) -->
|
|
467
|
+
{#if curve.kind === `bars`}
|
|
468
|
+
{#each curve.bars as bar, bar_idx (bar_idx)}
|
|
469
|
+
<rect
|
|
470
|
+
x={bar.x}
|
|
471
|
+
y={bar.y}
|
|
472
|
+
width={bar.width}
|
|
473
|
+
height={bar.height}
|
|
474
|
+
fill={curve.fill}
|
|
475
|
+
fill-opacity={curve.fill_opacity}
|
|
476
|
+
stroke={curve.stroke}
|
|
477
|
+
stroke-width={curve.stroke_width}
|
|
478
|
+
opacity={curve.opacity}
|
|
479
|
+
/>
|
|
480
|
+
{/each}
|
|
481
|
+
{:else if curve.kind === `rug`}
|
|
482
|
+
{#each curve.rug as mark, mark_idx (mark_idx)}
|
|
483
|
+
<line
|
|
484
|
+
x1={mark.x1}
|
|
485
|
+
y1={mark.y1}
|
|
486
|
+
x2={mark.x2}
|
|
487
|
+
y2={mark.y2}
|
|
488
|
+
stroke={curve.stroke}
|
|
489
|
+
stroke-width={curve.stroke_width}
|
|
490
|
+
opacity={curve.opacity}
|
|
491
|
+
/>
|
|
492
|
+
{/each}
|
|
493
|
+
{:else}
|
|
494
|
+
{#if curve.area_path}
|
|
495
|
+
<path
|
|
496
|
+
d={curve.area_path}
|
|
497
|
+
fill={curve.fill}
|
|
498
|
+
fill-opacity={curve.fill_opacity}
|
|
499
|
+
stroke="none"
|
|
500
|
+
opacity={curve.opacity}
|
|
501
|
+
/>
|
|
502
|
+
{/if}
|
|
503
|
+
{#if curve.line_path}
|
|
504
|
+
<path
|
|
505
|
+
d={curve.line_path}
|
|
506
|
+
fill="none"
|
|
507
|
+
stroke={curve.stroke}
|
|
508
|
+
stroke-width={curve.stroke_width}
|
|
509
|
+
opacity={curve.opacity}
|
|
510
|
+
/>
|
|
511
|
+
{/if}
|
|
512
|
+
{/if}
|
|
513
|
+
{/each}
|
|
514
|
+
{/if}
|
|
515
|
+
</g>
|
|
516
|
+
<!-- Value-axis (spine + ticks + title). Unclipped so the corner title isn't cut off. -->
|
|
517
|
+
{#if value_axis}
|
|
518
|
+
<g class={[`marginal-axis`, `marginal-axis-${side}`]}>
|
|
519
|
+
<line {...value_axis.spine} />
|
|
520
|
+
{#each value_axis.ticks as tick, tick_idx (tick_idx)}
|
|
521
|
+
<text
|
|
522
|
+
x={tick.x}
|
|
523
|
+
y={tick.y}
|
|
524
|
+
text-anchor={value_axis.anchor}
|
|
525
|
+
dominant-baseline={value_axis.baseline}>{tick.text}</text
|
|
526
|
+
>
|
|
527
|
+
{/each}
|
|
528
|
+
{#if value_axis.title.text}
|
|
529
|
+
<text
|
|
530
|
+
class="marginal-axis-title"
|
|
531
|
+
x={value_axis.title.x}
|
|
532
|
+
y={value_axis.title.y}
|
|
533
|
+
text-anchor="middle"
|
|
534
|
+
dominant-baseline="central"
|
|
535
|
+
transform={value_axis.title.transform}>{value_axis.title.text}</text
|
|
536
|
+
>
|
|
537
|
+
{/if}
|
|
538
|
+
</g>
|
|
539
|
+
{/if}
|
|
540
|
+
<!-- Transparent hit-rect for hover tooltips. Sits outside the pointer-events:none <g> (so it
|
|
541
|
+
opts back in) and only on built-in strips the user hasn't opted out of via hover:false.
|
|
542
|
+
stopPropagation keeps strip pointer/mouse moves from reaching the host plot's own
|
|
543
|
+
hover/pan-zoom handlers (avoids a double tooltip and accidental drag-from-strip). -->
|
|
544
|
+
{#if is_hoverable(config)}
|
|
545
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
546
|
+
<rect
|
|
547
|
+
class={[`marginal-hit`, `marginal-hit-${side}`]}
|
|
548
|
+
x={rect.x}
|
|
549
|
+
y={rect.y}
|
|
550
|
+
width={rect.width}
|
|
551
|
+
height={rect.height}
|
|
552
|
+
fill="transparent"
|
|
553
|
+
style="pointer-events: all"
|
|
554
|
+
onpointermove={(event) => {
|
|
555
|
+
event.stopPropagation()
|
|
556
|
+
hovered = on_marginal_move(event, ctx)
|
|
557
|
+
}}
|
|
558
|
+
onpointerleave={() => (hovered = null)}
|
|
559
|
+
onmousemove={stop}
|
|
560
|
+
onpointerdown={stop}
|
|
561
|
+
onmousedown={stop}
|
|
562
|
+
/>
|
|
563
|
+
{/if}
|
|
564
|
+
{/each}
|
|
565
|
+
|
|
566
|
+
<!-- Single shared hover tooltip for all strips. Rendered in a foreignObject HTML div that the
|
|
567
|
+
portal relocates to the plot wrapper (an svg can't host an HTML sibling), so it reuses the
|
|
568
|
+
same PlotTooltip, positioning, and z-index as each host plot's own tooltip. Only mounted when
|
|
569
|
+
some strip is actually hoverable (skips the empty portal on plots with no/snippet marginals). -->
|
|
570
|
+
{#if side_renders.some((render) => is_hoverable(render.config))}
|
|
571
|
+
<foreignObject width="0" height="0" style="overflow: visible">
|
|
572
|
+
<div
|
|
573
|
+
xmlns="http://www.w3.org/1999/xhtml"
|
|
574
|
+
style="display: contents"
|
|
575
|
+
{@attach portal_to_wrapper}
|
|
576
|
+
>
|
|
577
|
+
{#if hovered && tip}
|
|
578
|
+
<PlotTooltip
|
|
579
|
+
x={hovered.x}
|
|
580
|
+
y={hovered.y}
|
|
581
|
+
offset={{ x: 10, y: 5 }}
|
|
582
|
+
constrain_to={{ width, height }}
|
|
583
|
+
fallback_size={{ width: 120, height: 44 }}
|
|
584
|
+
bg_color={tip.bg_color}
|
|
585
|
+
>
|
|
586
|
+
{#if tip.snippet}
|
|
587
|
+
{@render tip.snippet(hovered)}
|
|
588
|
+
{:else}
|
|
589
|
+
<!-- contiguous (no source whitespace) so rows don't pick up stray leading spaces;
|
|
590
|
+
head_label is pre-sanitized @html so an axis title with markup renders, while the
|
|
591
|
+
value/category portion stays literal text -->
|
|
592
|
+
{#if tip.label}<strong>{tip.label}</strong><br />{/if}{@html tip.head_label}: {tip.head_value}{#if tip.value}<br
|
|
593
|
+
/>{tip.value}{/if}
|
|
594
|
+
{/if}
|
|
595
|
+
</PlotTooltip>
|
|
596
|
+
{/if}
|
|
597
|
+
</div>
|
|
598
|
+
</foreignObject>
|
|
599
|
+
{/if}
|
|
600
|
+
|
|
601
|
+
<style>
|
|
602
|
+
.marginal,
|
|
603
|
+
.marginal-axis {
|
|
604
|
+
pointer-events: none;
|
|
605
|
+
}
|
|
606
|
+
.marginal-axis line {
|
|
607
|
+
stroke: var(--border-color, gray);
|
|
608
|
+
}
|
|
609
|
+
.marginal-axis text {
|
|
610
|
+
fill: var(--text-color);
|
|
611
|
+
font-size: var(--marginal-axis-font-size, 0.65em);
|
|
612
|
+
}
|
|
613
|
+
.marginal-axis-title {
|
|
614
|
+
font-size: var(--marginal-axis-title-font-size, 0.75em);
|
|
615
|
+
}
|
|
616
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Sides } from '../layout';
|
|
2
|
+
import type { MarginalAxes, MarginalSeriesInput, MarginalSide, ResolvedMarginals } from '../marginals';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
marginals: ResolvedMarginals;
|
|
5
|
+
series: MarginalSeriesInput[];
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
pad: Required<Sides>;
|
|
9
|
+
has_axis?: Record<MarginalSide, boolean>;
|
|
10
|
+
axes: MarginalAxes;
|
|
11
|
+
id: string;
|
|
12
|
+
};
|
|
13
|
+
declare const PlotMarginals: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
14
|
+
type PlotMarginals = ReturnType<typeof PlotMarginals>;
|
|
15
|
+
export default PlotMarginals;
|
|
@@ -14,9 +14,7 @@
|
|
|
14
14
|
selected_key = $bindable(),
|
|
15
15
|
on_select,
|
|
16
16
|
disabled = false,
|
|
17
|
-
format_option = (
|
|
18
|
-
opt: Option,
|
|
19
|
-
) => (opt.unit ? `${opt.label} (${opt.unit})` : opt.label),
|
|
17
|
+
format_option = (opt: Option) => (opt.unit ? `${opt.label} (${opt.unit})` : opt.label),
|
|
20
18
|
...rest
|
|
21
19
|
}: Omit<HTMLButtonAttributes, `onclick`> & {
|
|
22
20
|
options: Option[]
|
|
@@ -59,11 +57,9 @@
|
|
|
59
57
|
// Inline styles for portal elements (can't use scoped CSS for elements in document.body)
|
|
60
58
|
const portal_styles = {
|
|
61
59
|
container: `position: fixed; transform: translateX(-50%); z-index: 10000;`,
|
|
62
|
-
ul:
|
|
63
|
-
`margin: 0; padding: 0; list-style: none; background: var(--dropdown-bg, white); border: 1px solid var(--dropdown-border, #ccc); border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); min-width: max-content; max-height: 300px; overflow-y: auto; font-size: 14px;`,
|
|
60
|
+
ul: `margin: 0; padding: 0; list-style: none; background: var(--dropdown-bg, white); border: 1px solid var(--dropdown-border, #ccc); border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); min-width: max-content; max-height: 300px; overflow-y: auto; font-size: 14px;`,
|
|
64
61
|
li: `margin: 0;`,
|
|
65
|
-
btn:
|
|
66
|
-
`display: block; width: 100%; padding: var(--dropdown-padding-v, 3px) var(--dropdown-padding-h, 10px); border: none; background: transparent; font: inherit; color: var(--dropdown-color, black); text-align: left; cursor: pointer; white-space: nowrap;`,
|
|
62
|
+
btn: `display: block; width: 100%; padding: var(--dropdown-padding-v, 3px) var(--dropdown-padding-h, 10px); border: none; background: transparent; font: inherit; color: var(--dropdown-color, black); text-align: left; cursor: pointer; white-space: nowrap;`,
|
|
67
63
|
btn_selected: `font-weight: 500; background: rgba(0, 100, 200, 0.15);`,
|
|
68
64
|
}
|
|
69
65
|
|
|
@@ -206,7 +202,7 @@
|
|
|
206
202
|
aria-expanded={dropdown_open}
|
|
207
203
|
aria-haspopup="listbox"
|
|
208
204
|
{...rest}
|
|
209
|
-
class=
|
|
205
|
+
class={[`portal-select-trigger`, rest.class]}
|
|
210
206
|
>
|
|
211
207
|
{@html sanitize_html(format_option(selected_option))}
|
|
212
208
|
<span class="arrow">▾</span>
|