matterviz 0.4.1 → 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 +75 -85
- 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 +26 -39
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +62 -74
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +511 -547
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
- package/dist/chempot-diagram/async-compute.svelte.js +1 -1
- package/dist/chempot-diagram/controls-state.svelte.js +1 -1
- package/dist/colors/index.d.ts +0 -4
- package/dist/colors/index.js +19 -20
- 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 +92 -95
- package/dist/composition/PieChart.svelte +55 -41
- package/dist/composition/format.js +1 -1
- 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 +11 -10
- package/dist/constants.js +11 -9
- 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 -92
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +109 -140
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +75 -94
- 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 +17 -21
- 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/helpers.d.ts +8 -10
- package/dist/convex-hull/helpers.js +36 -36
- package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
- package/dist/convex-hull/thermodynamics.js +18 -17
- package/dist/coordination/CoordinationBarPlot.svelte +38 -33
- 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 -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/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 -4
- package/dist/element/index.js +3 -18
- 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 +14 -22
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -7
- package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +37 -64
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
- package/dist/fermi-surface/compute.js +3 -3
- package/dist/fermi-surface/parse.js +22 -24
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +109 -148
- 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/io/ExportPane.svelte +10 -6
- package/dist/io/decompress.d.ts +2 -1
- package/dist/io/decompress.js +22 -35
- package/dist/io/export.d.ts +4 -0
- package/dist/io/export.js +5 -1
- package/dist/io/fetch.d.ts +0 -3
- package/dist/io/fetch.js +0 -11
- 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.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 +6 -6
- package/dist/labels.d.ts +6 -2
- package/dist/labels.js +43 -13
- package/dist/layout/FullscreenButton.svelte +2 -1
- package/dist/layout/FullscreenToggle.svelte +10 -4
- 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 +9 -10
- 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 +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 +2 -0
- package/dist/math.js +19 -0
- 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 +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 +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 +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 +3 -3
- 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 +21 -15
- package/dist/phase-diagram/utils.js +2 -3
- package/dist/plot/bar/BarPlot.svelte +430 -391
- 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 +29 -36
- package/dist/plot/bar/data.d.ts +5 -4
- package/dist/plot/bar/data.js +2 -1
- package/dist/plot/box/BoxPlot.svelte +301 -209
- 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.js +1 -1
- 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.js +9 -5
- 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 +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/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/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 +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.js +2 -2
- package/dist/plot/histogram/Histogram.svelte +304 -325
- 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/scatter/BinnedScatterPlot.svelte +263 -109
- package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
- package/dist/plot/scatter/ElementScatter.svelte +4 -1
- package/dist/plot/scatter/ScatterPlot.svelte +477 -385
- 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/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 +251 -329
- 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 +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 +1 -1
- package/dist/scene/bind-renderer.svelte.js +14 -6
- package/dist/settings.d.ts +19 -9
- package/dist/settings.js +77 -50
- package/dist/spectral/Bands.svelte +223 -230
- package/dist/spectral/BandsAndDos.svelte +11 -9
- package/dist/spectral/BrillouinBandsDos.svelte +19 -27
- package/dist/spectral/Dos.svelte +70 -73
- package/dist/spectral/helpers.d.ts +3 -3
- package/dist/spectral/helpers.js +25 -35
- 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 +115 -75
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/Bond.svelte +31 -23
- package/dist/structure/CanvasTooltip.svelte +15 -3
- package/dist/structure/CellSelect.svelte +11 -26
- 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 +473 -419
- package/dist/structure/Structure.svelte.d.ts +4 -2
- package/dist/structure/StructureCarousel.svelte +630 -0
- package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
- package/dist/structure/StructureControls.svelte +157 -399
- package/dist/structure/StructureControls.svelte.d.ts +1 -1
- package/dist/structure/StructureExportPane.svelte +17 -21
- package/dist/structure/StructureInfoPane.svelte +72 -66
- package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
- package/dist/structure/StructureScene.svelte +467 -476
- package/dist/structure/StructureScene.svelte.d.ts +3 -1
- package/dist/structure/StructureViewport.svelte +386 -0
- package/dist/structure/StructureViewport.svelte.d.ts +63 -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 +104 -38
- package/dist/structure/bonding.d.ts +10 -3
- package/dist/structure/bonding.js +84 -28
- 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 +39 -31
- 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 +16 -1
- package/dist/structure/index.js +13 -2
- 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 +243 -222
- package/dist/structure/partial-occupancy.js +4 -2
- package/dist/structure/pbc.js +78 -98
- package/dist/structure/polyhedra.d.ts +0 -1
- package/dist/structure/polyhedra.js +3 -18
- 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 +56 -68
- package/dist/symmetry/WyckoffTable.svelte +5 -24
- package/dist/symmetry/cell-transform.js +1 -0
- package/dist/symmetry/index.d.ts +1 -0
- package/dist/symmetry/index.js +8 -2
- package/dist/symmetry/spacegroups.js +3 -2
- package/dist/table/HeatmapTable.svelte +1102 -365
- 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 +515 -308
- package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
- package/dist/trajectory/TrajectoryError.svelte +11 -8
- package/dist/trajectory/TrajectoryExportPane.svelte +14 -31
- package/dist/trajectory/TrajectoryInfoPane.svelte +85 -97
- package/dist/trajectory/extract.js +56 -34
- package/dist/trajectory/format-detect.js +11 -9
- package/dist/trajectory/frame-reader.d.ts +2 -0
- package/dist/trajectory/frame-reader.js +33 -29
- package/dist/trajectory/helpers.d.ts +2 -0
- package/dist/trajectory/helpers.js +18 -7
- package/dist/trajectory/index.d.ts +1 -0
- package/dist/trajectory/index.js +3 -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 +2 -3
- package/dist/trajectory/parse/index.js +17 -20
- 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 +5 -0
- package/dist/trajectory/parse/vaspout-h5.js +284 -0
- package/dist/trajectory/parse/xyz.js +11 -7
- package/dist/trajectory/plotting.d.ts +8 -9
- package/dist/trajectory/plotting.js +99 -27
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +7 -0
- package/dist/xrd/XrdPlot.svelte +47 -61
- package/dist/xrd/broadening.js +2 -1
- package/dist/xrd/calc-xrd.js +2 -4
- package/dist/xrd/parse.d.ts +0 -1
- package/dist/xrd/parse.js +56 -73
- package/package.json +61 -33
- package/dist/api/mp.d.ts +0 -6
- package/dist/api/mp.js +0 -22
- package/dist/plot/sunburst/SunburstControls.svelte +0 -200
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
generics="Metadata extends Record<string, unknown> = Record<string, unknown>"
|
|
4
4
|
>
|
|
5
5
|
import type { D3InterpolateName } from '../../colors'
|
|
6
|
-
import { pick_contrast_color } from '../../colors'
|
|
7
|
-
import { export_svg_as_png, export_svg_as_svg } from '../../io/export'
|
|
8
6
|
import { format_value } from '../../labels'
|
|
9
7
|
import { FullscreenToggle, set_fullscreen_bg } from '../../layout'
|
|
10
8
|
import { DEG_TO_RAD, type Vec2 } from '../../math'
|
|
@@ -21,15 +19,37 @@
|
|
|
21
19
|
SunburstValueMode,
|
|
22
20
|
} from '..'
|
|
23
21
|
import { ColorBar, PlotLegend, PlotTooltip, SunburstControls } from '..'
|
|
24
|
-
import { closest_data_idx
|
|
25
|
-
import {
|
|
26
|
-
compute_element_placement,
|
|
27
|
-
filter_padding,
|
|
28
|
-
measure_text_width,
|
|
29
|
-
} from '../core/layout'
|
|
22
|
+
import { closest_data_idx } from '../core/interactions'
|
|
23
|
+
import { compute_element_placement, filter_padding } from '../core/layout'
|
|
30
24
|
import type { Sides } from '../core/layout'
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
25
|
+
import { SCALE_DEFAULTS } from '../core/types'
|
|
26
|
+
import {
|
|
27
|
+
ancestor_chain,
|
|
28
|
+
compute_metric_colors,
|
|
29
|
+
compute_node_dim,
|
|
30
|
+
compute_node_infos,
|
|
31
|
+
handle_hierarchy_escape,
|
|
32
|
+
hierarchy_legend_items,
|
|
33
|
+
is_activation_key,
|
|
34
|
+
node_handler_props,
|
|
35
|
+
pointer_pos,
|
|
36
|
+
prune_muted_ids,
|
|
37
|
+
safe_hierarchy_layout,
|
|
38
|
+
selection_within,
|
|
39
|
+
svg_label_font,
|
|
40
|
+
toggle_muted,
|
|
41
|
+
} from '../core/utils/hierarchy-chart'
|
|
42
|
+
import {
|
|
43
|
+
export_hierarchy_chart,
|
|
44
|
+
make_cached_contrast,
|
|
45
|
+
make_cached_text_width,
|
|
46
|
+
node_display_name,
|
|
47
|
+
} from '../core/utils/hierarchy-labels'
|
|
48
|
+
import {
|
|
49
|
+
arc_label_transform,
|
|
50
|
+
arrow_nav_target,
|
|
51
|
+
project_arcs,
|
|
52
|
+
} from './render'
|
|
33
53
|
import type { ScreenArc as ScreenArcOf } from './render'
|
|
34
54
|
import { compute_sunburst_layout, type PositionedArc } from './sunburst'
|
|
35
55
|
import { DEFAULTS } from '../../settings'
|
|
@@ -63,7 +83,7 @@
|
|
|
63
83
|
zoom_root_id = $bindable(null),
|
|
64
84
|
show_breadcrumbs = $bindable(DEFAULTS.sunburst.show_breadcrumbs),
|
|
65
85
|
color_values,
|
|
66
|
-
color_scale =
|
|
86
|
+
color_scale = SCALE_DEFAULTS.scheme,
|
|
67
87
|
color_range,
|
|
68
88
|
colorbar = {},
|
|
69
89
|
export_buttons = true,
|
|
@@ -91,66 +111,69 @@
|
|
|
91
111
|
header_controls,
|
|
92
112
|
controls_extra,
|
|
93
113
|
...rest
|
|
94
|
-
}: HTMLAttributes<HTMLDivElement> &
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
} = $props()
|
|
114
|
+
}: HTMLAttributes<HTMLDivElement> &
|
|
115
|
+
Omit<BasePlotProps, `change`> & {
|
|
116
|
+
data?: SunburstNode<Metadata> | SunburstNode<Metadata>[]
|
|
117
|
+
shape?: SunburstShape // polar rings (sunburst) or stacked rows (icicle)
|
|
118
|
+
value_mode?: SunburstValueMode
|
|
119
|
+
sort?: SunburstSort
|
|
120
|
+
level_lighten?: number
|
|
121
|
+
// Aggregate sibling arcs below this fraction of the total into one 'Other' leaf
|
|
122
|
+
// per parent (only when >= 2 qualify); 0 disables
|
|
123
|
+
min_fraction?: number
|
|
124
|
+
other_label?: string
|
|
125
|
+
max_depth?: number // rings shown below the current zoom root (0 = all)
|
|
126
|
+
inner_radius?: number // center hole as fraction of outer radius
|
|
127
|
+
pad_angle?: number // degrees between sibling arcs
|
|
128
|
+
show_labels?: boolean
|
|
129
|
+
label_rotation?: SunburstLabelRotation
|
|
130
|
+
label_text?: SunburstLabelText // what labels display (plotly textinfo equivalent)
|
|
131
|
+
zoom_on_click?: boolean
|
|
132
|
+
zoom_root_id?: string | number | null // id of the arc the view is rooted on
|
|
133
|
+
show_breadcrumbs?: boolean // clickable ancestor trail when zoomed
|
|
134
|
+
// Color arcs by a numeric metric (continuous colormap) instead of categorical
|
|
135
|
+
// inheritance; return null to keep an arc's categorical color
|
|
136
|
+
color_values?: (arc: PositionedArc<Metadata>) => number | null
|
|
137
|
+
color_scale?: D3InterpolateName
|
|
138
|
+
color_range?: Vec2 // defaults to the metric's [min, max]
|
|
139
|
+
colorbar?: ComponentProps<typeof ColorBar> | null // null hides it
|
|
140
|
+
export_buttons?: boolean // SVG/PNG download buttons in the controls pane
|
|
141
|
+
export_filename?: string
|
|
142
|
+
tween?: TweenOptions<{ x0: number; x1: number; y0: number; n_rings: number }>
|
|
143
|
+
value_format?: string
|
|
144
|
+
padding?: Sides
|
|
145
|
+
legend?: LegendConfig | null
|
|
146
|
+
show_legend?: boolean
|
|
147
|
+
tooltip?: Snippet<[SunburstNodeHandlerProps<Metadata>]>
|
|
148
|
+
// Fully replace the default arc path. NOTE: this also replaces the built-in
|
|
149
|
+
// hover/focus/click + tooltip wiring, so re-implement any interactivity you
|
|
150
|
+
// need inside the snippet.
|
|
151
|
+
arc_content?: Snippet<
|
|
152
|
+
[{ arc: PositionedArc<Metadata>; a0: number; a1: number; r0: number; r1: number }]
|
|
153
|
+
>
|
|
154
|
+
center_content?: Snippet<
|
|
155
|
+
[{ root: PositionedArc<Metadata> | null; radius: number; zoomed: boolean }]
|
|
156
|
+
>
|
|
157
|
+
change?: (data: SunburstNodeHandlerProps<Metadata> | null) => void
|
|
158
|
+
on_node_click?: (
|
|
159
|
+
data: SunburstNodeHandlerProps<Metadata> & { event: MouseEvent | KeyboardEvent },
|
|
160
|
+
) => void
|
|
161
|
+
on_node_hover?: (
|
|
162
|
+
data: (SunburstNodeHandlerProps<Metadata> & { event: MouseEvent | FocusEvent }) | null,
|
|
163
|
+
) => void
|
|
164
|
+
on_zoom?: (data: { root: SunburstNodeHandlerProps<Metadata> | null }) => void
|
|
165
|
+
header_controls?: Snippet<[{ height: number; width: number; fullscreen: boolean }]>
|
|
166
|
+
controls_extra?: Snippet<[{ zoom_root_id: string | number | null }]>
|
|
167
|
+
} = $props()
|
|
149
168
|
|
|
150
169
|
let [width, height] = $state([0, 0])
|
|
151
170
|
let wrapper: HTMLDivElement | undefined = $state()
|
|
152
171
|
let svg_element: SVGSVGElement | null = $state(null)
|
|
153
172
|
let center_el: SVGCircleElement | null = $state(null)
|
|
173
|
+
// Unique per instance so multiple sunbursts on one page don't collide on
|
|
174
|
+
// the hatch pattern's SVG id.
|
|
175
|
+
const uid = $props.id()
|
|
176
|
+
const hatch_pattern_id = `sunburst-hatch-${uid}`
|
|
154
177
|
|
|
155
178
|
let hovered_idx = $state<number | null>(null)
|
|
156
179
|
let hover_info = $state<SunburstNodeHandlerProps<Metadata> | null>(null)
|
|
@@ -171,28 +194,18 @@
|
|
|
171
194
|
)
|
|
172
195
|
let inner_height = $derived(avail_height - colorbar_reserve)
|
|
173
196
|
|
|
174
|
-
// Degrade to an empty layout (instead of crashing the host page) on invalid data.
|
|
175
197
|
// Layout depends only on data/value semantics - not on size or zoom.
|
|
176
|
-
let layout = $derived
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
})
|
|
185
|
-
} catch (err) {
|
|
186
|
-
console.error(err)
|
|
187
|
-
return { arcs: [], root: null, max_depth: 0 }
|
|
188
|
-
}
|
|
189
|
-
})
|
|
190
|
-
let arc_by_id = $derived(new Map(layout.arcs.map((arc) => [arc.id, arc])))
|
|
191
|
-
|
|
192
|
-
// Resolve the zoom root; stale ids (e.g. after a data swap) fall back to the root
|
|
193
|
-
let zoom_root = $derived(
|
|
194
|
-
(zoom_root_id != null ? arc_by_id.get(zoom_root_id) : null) ?? layout.root,
|
|
198
|
+
let layout = $derived(
|
|
199
|
+
safe_hierarchy_layout(data, {
|
|
200
|
+
value_mode,
|
|
201
|
+
sort,
|
|
202
|
+
level_lighten,
|
|
203
|
+
min_fraction,
|
|
204
|
+
other_label,
|
|
205
|
+
}),
|
|
195
206
|
)
|
|
207
|
+
// Resolve the zoom root; stale ids (e.g. after a data swap) fall back to the root
|
|
208
|
+
let zoom_root = $derived(layout.arcs.find((arc) => arc.id === zoom_root_id) ?? layout.root)
|
|
196
209
|
let zoomed = $derived((zoom_root?.depth ?? 0) > 0)
|
|
197
210
|
|
|
198
211
|
// Drop muted ids that no longer exist when data changes (untrack avoids a
|
|
@@ -200,11 +213,9 @@
|
|
|
200
213
|
// Hover/focus state is index-based, so a layout swap would otherwise leave a stale
|
|
201
214
|
// tooltip and highlight whatever unrelated node now occupies the old index.
|
|
202
215
|
$effect(() => {
|
|
203
|
-
const
|
|
204
|
-
layout.arcs.filter((arc) => arc.depth === 1).map((arc) => arc.id),
|
|
205
|
-
)
|
|
216
|
+
const { arcs } = layout
|
|
206
217
|
untrack(() => {
|
|
207
|
-
|
|
218
|
+
prune_muted_ids(arcs, muted_ids)
|
|
208
219
|
set_arc_hover(null)
|
|
209
220
|
focused_idx = null
|
|
210
221
|
})
|
|
@@ -274,7 +285,7 @@
|
|
|
274
285
|
const screen_path = (screen: ScreenArc): string =>
|
|
275
286
|
shape === `icicle`
|
|
276
287
|
? `M${screen.a0},${screen.r0}H${screen.a1}V${screen.r1}H${screen.a0}Z`
|
|
277
|
-
: arc_gen(screen) ?? ``
|
|
288
|
+
: (arc_gen(screen) ?? ``)
|
|
278
289
|
|
|
279
290
|
// The chart group's transform: sunburst draws around the center, icicle from the
|
|
280
291
|
// top-left of the padded plot area
|
|
@@ -293,25 +304,10 @@
|
|
|
293
304
|
}
|
|
294
305
|
|
|
295
306
|
// Continuous metric coloring: when color_values is given, arcs are colored by their
|
|
296
|
-
// metric on a d3 colormap (arcs returning null keep their categorical color)
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const vals = layout.arcs.map((arc) => {
|
|
301
|
-
const val = arc.depth === 0 ? null : color_values(arc)
|
|
302
|
-
return val != null && Number.isFinite(val) ? val : null
|
|
303
|
-
})
|
|
304
|
-
const finite = vals.filter((val) => val != null)
|
|
305
|
-
if (finite.length === 0) return null
|
|
306
|
-
const range = color_range ?? [Math.min(...finite), Math.max(...finite)]
|
|
307
|
-
const scale = create_color_scale({ scheme: color_scale, value_range: range }, range)
|
|
308
|
-
return {
|
|
309
|
-
range,
|
|
310
|
-
colors: vals.map((val, idx) =>
|
|
311
|
-
val == null ? layout.arcs[idx].color : `${scale(val)}`
|
|
312
|
-
),
|
|
313
|
-
}
|
|
314
|
-
})
|
|
307
|
+
// metric on a d3 colormap (arcs returning null keep their categorical color)
|
|
308
|
+
let metric = $derived(
|
|
309
|
+
compute_metric_colors(layout.arcs, color_values, color_scale, color_range),
|
|
310
|
+
)
|
|
315
311
|
const arc_color = (arc: PositionedArc<Metadata>): string =>
|
|
316
312
|
metric?.colors[arc.node_idx] ?? arc.color
|
|
317
313
|
// release the colorbar's reserved chart space when it's not rendered
|
|
@@ -319,83 +315,30 @@
|
|
|
319
315
|
if (!metric || colorbar == null) colorbar_height = 0
|
|
320
316
|
})
|
|
321
317
|
|
|
322
|
-
//
|
|
323
|
-
|
|
324
|
-
// range [node_idx, subtree_end].
|
|
325
|
-
let active = $derived.by(() => {
|
|
326
|
-
if (hovered_idx == null) return null
|
|
327
|
-
const hov = layout.arcs[hovered_idx]
|
|
328
|
-
if (!hov) return null
|
|
329
|
-
return (arc: PositionedArc<Metadata>): boolean =>
|
|
330
|
-
(arc.node_idx >= hov.node_idx && arc.node_idx <= hov.subtree_end) ||
|
|
331
|
-
(hov.node_idx >= arc.node_idx && hov.node_idx <= arc.subtree_end)
|
|
332
|
-
})
|
|
333
|
-
|
|
334
|
-
const is_muted = (arc: PositionedArc<Metadata>): boolean =>
|
|
335
|
-
arc.path.length > 0 && muted_ids.has(arc.path[0])
|
|
336
|
-
|
|
337
|
-
const MUTED_OPACITY = 0.12
|
|
338
|
-
const arc_opacity = (arc: PositionedArc<Metadata>): number => {
|
|
339
|
-
if (is_muted(arc)) return MUTED_OPACITY
|
|
340
|
-
if (active && !active(arc)) return 0.3
|
|
341
|
-
return 1
|
|
342
|
-
}
|
|
318
|
+
// Hovered arc + its ancestors/descendants stay fully opaque, others dim
|
|
319
|
+
let arc_dim = $derived(compute_node_dim(layout.arcs, muted_ids, hovered_idx))
|
|
343
320
|
|
|
344
321
|
// Black/white label text, whichever contrasts with the arc's fill (light arcs from
|
|
345
|
-
// explicit colors or level_lighten would hide white labels, esp. when highlighted)
|
|
346
|
-
|
|
347
|
-
// animation frame, and distinct arc colors are few.
|
|
348
|
-
const contrast_cache = new Map<string, string>()
|
|
349
|
-
const label_color = (arc: PositionedArc<Metadata>): string => {
|
|
350
|
-
const fill = arc_color(arc)
|
|
351
|
-
let contrast = contrast_cache.get(fill)
|
|
352
|
-
if (contrast === undefined) {
|
|
353
|
-
contrast = pick_contrast_color({ bg_color: fill })
|
|
354
|
-
contrast_cache.set(fill, contrast)
|
|
355
|
-
}
|
|
356
|
-
return contrast
|
|
357
|
-
}
|
|
322
|
+
// explicit colors or level_lighten would hide white labels, esp. when highlighted)
|
|
323
|
+
const contrast_for = make_cached_contrast()
|
|
358
324
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
arc.parent_idx != null ? layout.arcs[arc.parent_idx] : null
|
|
362
|
-
const arc_name = (arc: PositionedArc<Metadata>): string => arc.label ?? `${arc.id}`
|
|
325
|
+
const make_node_props = (arc: PositionedArc<Metadata>): SunburstNodeHandlerProps<Metadata> =>
|
|
326
|
+
node_handler_props(layout.arcs, arc, arc_color(arc))
|
|
363
327
|
|
|
364
|
-
function
|
|
365
|
-
arc: PositionedArc<Metadata>,
|
|
366
|
-
): SunburstNodeHandlerProps<Metadata> {
|
|
367
|
-
// Handler props are the arc minus its screen geometry, plus the parent id
|
|
368
|
-
const { x0, x1, y0, y1, subtree_end, parent_idx, ...node } = arc
|
|
369
|
-
return {
|
|
370
|
-
...node,
|
|
371
|
-
type: `node`,
|
|
372
|
-
color: arc_color(arc),
|
|
373
|
-
parent_id: parent_of(arc)?.id ?? null,
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// Anchor the tooltip at the cursor (mouse hover) so it follows the pointer across
|
|
378
|
-
// wide arcs; fall back to the arc centroid on keyboard focus (no cursor).
|
|
379
|
-
const event_pos = (event?: MouseEvent | FocusEvent): { x: number; y: number } | null =>
|
|
380
|
-
event instanceof MouseEvent ? get_relative_coords(event, svg_element) : null
|
|
381
|
-
|
|
382
|
-
function set_arc_hover(
|
|
383
|
-
screen: ScreenArc | null,
|
|
384
|
-
event?: MouseEvent | FocusEvent,
|
|
385
|
-
) {
|
|
328
|
+
function set_arc_hover(screen: ScreenArc | null, event?: MouseEvent | FocusEvent) {
|
|
386
329
|
// Same arc as before: only the cursor anchor moves - skip rebuilding the handler
|
|
387
330
|
// payload and re-firing change/on_node_hover on every mousemove within an arc.
|
|
388
331
|
// Requires hover_info: legend item hover sets hovered_idx alone (for dimming), and
|
|
389
332
|
// skipping then would leave the arc's own tooltip permanently suppressed.
|
|
390
333
|
if (screen && screen.arc.node_idx === hovered_idx && hover_info) {
|
|
391
|
-
hover_pos =
|
|
334
|
+
hover_pos = pointer_pos(event, svg_element) ?? hover_pos
|
|
392
335
|
return
|
|
393
336
|
}
|
|
394
337
|
if (screen) {
|
|
395
338
|
hovered = true
|
|
396
339
|
hovered_idx = screen.arc.node_idx
|
|
397
340
|
hover_info = make_node_props(screen.arc)
|
|
398
|
-
hover_pos =
|
|
341
|
+
hover_pos = pointer_pos(event, svg_element) ?? arc_center(screen)
|
|
399
342
|
change(hover_info)
|
|
400
343
|
if (event) on_node_hover?.({ ...hover_info, event })
|
|
401
344
|
} else {
|
|
@@ -412,7 +355,7 @@
|
|
|
412
355
|
|
|
413
356
|
const screen_arc_from_event = (event: Event): ScreenArc | null => {
|
|
414
357
|
const idx = closest_data_idx(event, `data-sunburst-node-idx`, svg_element)
|
|
415
|
-
return idx == null ? null : screen_arcs[idx] ?? null
|
|
358
|
+
return idx == null ? null : (screen_arcs[idx] ?? null)
|
|
416
359
|
}
|
|
417
360
|
|
|
418
361
|
function handle_arc_hover_event(event: MouseEvent | FocusEvent) {
|
|
@@ -424,25 +367,15 @@
|
|
|
424
367
|
|
|
425
368
|
// Re-root the view on the given arc (or the data root when null) and notify
|
|
426
369
|
function zoom_to(arc: PositionedArc<Metadata> | null) {
|
|
427
|
-
|
|
370
|
+
const root = arc && arc.depth > 0 ? arc : null
|
|
371
|
+
zoom_root_id = root?.id ?? null
|
|
428
372
|
// The clicked arc collapses into the hole - drop the now-stale hover/tooltip
|
|
429
373
|
set_arc_hover(null)
|
|
430
|
-
on_zoom?.({ root:
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// True while the user has an uncollapsed text selection inside this chart. Labels
|
|
434
|
-
// are selectable text, and the mouseup that ends a selection drag also fires a
|
|
435
|
-
// click - selecting a label must not zoom or fire on_node_click.
|
|
436
|
-
function selection_in_chart(): boolean {
|
|
437
|
-
const selection = globalThis.getSelection?.()
|
|
438
|
-
return Boolean(
|
|
439
|
-
selection && !selection.isCollapsed && selection.anchorNode &&
|
|
440
|
-
wrapper?.contains(selection.anchorNode),
|
|
441
|
-
)
|
|
374
|
+
on_zoom?.({ root: root && make_node_props(root) })
|
|
442
375
|
}
|
|
443
376
|
|
|
444
377
|
function handle_arc_click(event: MouseEvent | KeyboardEvent) {
|
|
445
|
-
if (event instanceof MouseEvent &&
|
|
378
|
+
if (event instanceof MouseEvent && selection_within(wrapper)) return
|
|
446
379
|
const screen = screen_arc_from_event(event)
|
|
447
380
|
if (!screen) return
|
|
448
381
|
const { arc } = screen
|
|
@@ -451,7 +384,7 @@
|
|
|
451
384
|
}
|
|
452
385
|
|
|
453
386
|
function zoom_out(event?: Event) {
|
|
454
|
-
if (event instanceof MouseEvent &&
|
|
387
|
+
if (event instanceof MouseEvent && selection_within(wrapper)) return
|
|
455
388
|
if (!zoomed) return
|
|
456
389
|
zoom_to(breadcrumb_arcs.at(-2) ?? null)
|
|
457
390
|
}
|
|
@@ -461,7 +394,7 @@
|
|
|
461
394
|
// the center zoom-out button already fired its own click action twice - compounding
|
|
462
395
|
// a third full reset would teleport step-by-step zoom-outs straight to the root)
|
|
463
396
|
function handle_dblclick(event: MouseEvent) {
|
|
464
|
-
if (screen_arc_from_event(event) ||
|
|
397
|
+
if (screen_arc_from_event(event) || selection_within(wrapper)) return
|
|
465
398
|
const target = event.target as Element | null
|
|
466
399
|
if (target?.closest?.(`.center-circle, .center-label`)) return
|
|
467
400
|
if (zoomed) zoom_to(null)
|
|
@@ -489,8 +422,6 @@
|
|
|
489
422
|
)
|
|
490
423
|
}
|
|
491
424
|
|
|
492
|
-
const is_activation_key = (evt: KeyboardEvent) => [`Enter`, ` `].includes(evt.key)
|
|
493
|
-
|
|
494
425
|
function handle_arc_keydown(event: KeyboardEvent) {
|
|
495
426
|
const nav_target = nav_target_from_event(event)
|
|
496
427
|
if (nav_target != null) {
|
|
@@ -524,57 +455,48 @@
|
|
|
524
455
|
const arc_clickable = (arc: PositionedArc<Metadata>): boolean =>
|
|
525
456
|
Boolean(on_node_click) || (zoom_on_click && !arc.is_leaf)
|
|
526
457
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
// measureText is far too slow to run for every visible arc on every tween frame.
|
|
530
|
-
let label_font = $derived.by(() => {
|
|
531
|
-
if (!svg_element) return `11px sans-serif`
|
|
532
|
-
const { fontSize, fontFamily } = getComputedStyle(svg_element)
|
|
533
|
-
return `${fontSize} ${fontFamily}`
|
|
534
|
-
})
|
|
535
|
-
const text_width_cache = new Map<string, number>()
|
|
536
|
-
function cached_text_width(text: string, font: string): number {
|
|
537
|
-
const key = `${font}|${text}`
|
|
538
|
-
let text_width = text_width_cache.get(key)
|
|
539
|
-
if (text_width === undefined) {
|
|
540
|
-
if (text_width_cache.size > 10_000) text_width_cache.clear() // growth guard
|
|
541
|
-
text_width = measure_text_width(text, font)
|
|
542
|
-
text_width_cache.set(key, text_width)
|
|
543
|
-
}
|
|
544
|
-
return text_width
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
// What an arc's label displays, per the label_text mode (plotly textinfo equivalent)
|
|
548
|
-
const arc_label_str = (arc: PositionedArc<Metadata>): string => {
|
|
549
|
-
const name = arc_name(arc)
|
|
550
|
-
if (label_text === `label`) return name
|
|
551
|
-
const val = format_value(arc.value, value_format)
|
|
552
|
-
if (label_text === `value`) return val
|
|
553
|
-
const pct = format_value(arc.fraction, `.1%`)
|
|
554
|
-
if (label_text === `percent`) return pct
|
|
555
|
-
return label_text === `label+value` ? `${name} ${val}` : `${name} ${pct}`
|
|
556
|
-
}
|
|
458
|
+
let label_font = $derived(svg_label_font(svg_element))
|
|
459
|
+
const cached_text_width = make_cached_text_width()
|
|
557
460
|
|
|
558
|
-
// Per-arc label text, measured width
|
|
559
|
-
// computed once per layout/
|
|
560
|
-
//
|
|
461
|
+
// Per-arc label text, measured width, fill/label colors, clickability and aria
|
|
462
|
+
// string - all view-independent, so computed once per layout/option change
|
|
463
|
+
// instead of per animation frame
|
|
561
464
|
let arc_info = $derived(
|
|
562
|
-
layout.arcs
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
465
|
+
compute_node_infos(layout.arcs, {
|
|
466
|
+
label_text,
|
|
467
|
+
value_format,
|
|
468
|
+
label_font,
|
|
469
|
+
color_for: arc_color,
|
|
470
|
+
text_width: cached_text_width,
|
|
471
|
+
contrast: contrast_for,
|
|
472
|
+
clickable: arc_clickable,
|
|
569
473
|
}),
|
|
570
474
|
)
|
|
571
475
|
|
|
572
|
-
//
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
476
|
+
// Downscale steps tried when no label variant fits at full size: narrow
|
|
477
|
+
// slices keep a (smaller) label instead of losing it entirely.
|
|
478
|
+
const LABEL_FONT_SCALES = [1, 0.85, 0.7]
|
|
479
|
+
|
|
480
|
+
// Label text + placement transform for an arc; null = no variant fits, hide
|
|
481
|
+
// the label. Full font size wins over richer text: within each scale the
|
|
482
|
+
// richest variant that fits is used (extended -> label -> label_short).
|
|
483
|
+
function label_attrs(
|
|
484
|
+
screen: ScreenArc,
|
|
485
|
+
): { transform: string; text: string; font_scale: number } | null {
|
|
486
|
+
for (const font_scale of LABEL_FONT_SCALES) {
|
|
487
|
+
for (const { text, width: text_w } of arc_info[screen.arc.node_idx].variants) {
|
|
488
|
+
const transform = arc_label_transform(
|
|
489
|
+
screen,
|
|
490
|
+
text_w * font_scale,
|
|
491
|
+
shape,
|
|
492
|
+
label_rotation,
|
|
493
|
+
radius,
|
|
494
|
+
font_scale,
|
|
495
|
+
)
|
|
496
|
+
if (transform) return { transform, text, font_scale }
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return null
|
|
578
500
|
}
|
|
579
501
|
|
|
580
502
|
// Legend: one item per depth-1 category, toggling mutes (dims) rather than removes.
|
|
@@ -596,21 +518,12 @@
|
|
|
596
518
|
points: settled.map(arc_center),
|
|
597
519
|
})
|
|
598
520
|
})
|
|
599
|
-
let legend_data = $derived
|
|
600
|
-
depth1_arcs
|
|
601
|
-
series_idx: idx,
|
|
602
|
-
label: arc_name(arc),
|
|
603
|
-
visible: !muted_ids.has(arc.id),
|
|
604
|
-
display_style: { symbol_type: `Square` as const, symbol_color: arc_color(arc) },
|
|
605
|
-
}))
|
|
521
|
+
let legend_data: LegendItem[] = $derived(
|
|
522
|
+
hierarchy_legend_items(depth1_arcs, muted_ids, arc_color),
|
|
606
523
|
)
|
|
607
524
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
if (id === undefined) return
|
|
611
|
-
if (muted_ids.has(id)) muted_ids.delete(id)
|
|
612
|
-
else muted_ids.add(id)
|
|
613
|
-
}
|
|
525
|
+
const toggle_category = (series_idx: number) =>
|
|
526
|
+
toggle_muted(muted_ids, depth1_arcs[series_idx]?.id)
|
|
614
527
|
|
|
615
528
|
$effect(() => set_fullscreen_bg(wrapper, fullscreen, `--sunburst-fullscreen-bg`))
|
|
616
529
|
|
|
@@ -619,62 +532,24 @@
|
|
|
619
532
|
let zoom_out_label = $derived.by(() => {
|
|
620
533
|
const parent = breadcrumb_arcs.at(-2)
|
|
621
534
|
if (!parent) return ``
|
|
622
|
-
return parent.depth === 0 ? `full chart` :
|
|
623
|
-
})
|
|
624
|
-
|
|
625
|
-
// Ancestor chain from the root to the current zoom root (clickable breadcrumb trail)
|
|
626
|
-
let breadcrumb_arcs = $derived.by(() => {
|
|
627
|
-
if (!zoom_root || zoom_root.depth === 0) return []
|
|
628
|
-
const chain: PositionedArc<Metadata>[] = []
|
|
629
|
-
for (
|
|
630
|
-
let cur: PositionedArc<Metadata> | null = zoom_root;
|
|
631
|
-
cur;
|
|
632
|
-
cur = parent_of(cur)
|
|
633
|
-
) chain.unshift(cur)
|
|
634
|
-
return chain
|
|
535
|
+
return parent.depth === 0 ? `full chart` : node_display_name(parent)
|
|
635
536
|
})
|
|
636
537
|
|
|
637
|
-
|
|
638
|
-
// as presentation attributes (inlined onto a clone by the io/export helpers)
|
|
639
|
-
const export_inline_styles = [
|
|
640
|
-
`fill`,
|
|
641
|
-
`stroke`,
|
|
642
|
-
`stroke-width`,
|
|
643
|
-
`text-anchor`,
|
|
644
|
-
`dominant-baseline`,
|
|
645
|
-
`font-size`,
|
|
646
|
-
`font-family`,
|
|
647
|
-
`font-weight`,
|
|
648
|
-
`opacity`,
|
|
649
|
-
]
|
|
538
|
+
let breadcrumb_arcs = $derived(ancestor_chain(layout.arcs, zoom_root))
|
|
650
539
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
if (format === `svg`) {
|
|
654
|
-
export_svg_as_svg(svg_element, `${export_filename}.svg`, export_inline_styles)
|
|
655
|
-
} else {
|
|
656
|
-
export_svg_as_png(svg_element, `${export_filename}.png`, 150, export_inline_styles)
|
|
657
|
-
}
|
|
658
|
-
}
|
|
540
|
+
const export_chart = (format: `svg` | `png`) =>
|
|
541
|
+
export_hierarchy_chart(svg_element, export_filename, format)
|
|
659
542
|
</script>
|
|
660
543
|
|
|
661
544
|
<svelte:window
|
|
662
|
-
onkeydown={(evt) =>
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
if (zoomed) {
|
|
671
|
-
evt.preventDefault()
|
|
672
|
-
zoom_out()
|
|
673
|
-
} else if (fullscreen) {
|
|
674
|
-
evt.preventDefault()
|
|
675
|
-
fullscreen = false
|
|
676
|
-
}
|
|
677
|
-
}}
|
|
545
|
+
onkeydown={(evt) =>
|
|
546
|
+
handle_hierarchy_escape(evt, {
|
|
547
|
+
wrapper,
|
|
548
|
+
fullscreen,
|
|
549
|
+
zoomed,
|
|
550
|
+
zoom_out: () => zoom_out(),
|
|
551
|
+
exit_fullscreen: () => (fullscreen = false),
|
|
552
|
+
})}
|
|
678
553
|
/>
|
|
679
554
|
|
|
680
555
|
<div
|
|
@@ -682,7 +557,7 @@
|
|
|
682
557
|
bind:clientWidth={width}
|
|
683
558
|
bind:clientHeight={height}
|
|
684
559
|
{...rest}
|
|
685
|
-
class=
|
|
560
|
+
class={[`sunburst`, rest.class]}
|
|
686
561
|
class:fullscreen
|
|
687
562
|
class:icicle={shape === `icicle`}
|
|
688
563
|
>
|
|
@@ -691,6 +566,7 @@
|
|
|
691
566
|
{@render header_controls?.({ height, width, fullscreen })}
|
|
692
567
|
{#if show_controls}
|
|
693
568
|
<SunburstControls
|
|
569
|
+
chart="sunburst"
|
|
694
570
|
toggle_props={{
|
|
695
571
|
...controls_toggle_props,
|
|
696
572
|
// join the header flex row instead of absolute positioning (overrides
|
|
@@ -731,7 +607,7 @@
|
|
|
731
607
|
disabled={crumb_idx === breadcrumb_arcs.length - 1}
|
|
732
608
|
onclick={() => zoom_to(crumb)}
|
|
733
609
|
>
|
|
734
|
-
{crumb.depth === 0 ? `all` : crumb.label ?? crumb.id}
|
|
610
|
+
{crumb.depth === 0 ? `all` : (crumb.label ?? crumb.id)}
|
|
735
611
|
</button>
|
|
736
612
|
{/each}
|
|
737
613
|
</nav>
|
|
@@ -744,6 +620,12 @@
|
|
|
744
620
|
aria-label={rest[`aria-label`] ?? `${shape === `icicle` ? `Icicle` : `Sunburst`} chart`}
|
|
745
621
|
onmouseleave={() => set_arc_hover(null)}
|
|
746
622
|
>
|
|
623
|
+
<!-- inert unless some arc references it via fill -->
|
|
624
|
+
<defs>
|
|
625
|
+
<pattern id={hatch_pattern_id} patternUnits="userSpaceOnUse" width="8" height="8">
|
|
626
|
+
<path class="hatch-pattern-line" d="M-1,1 l2,-2 M0,8 l8,-8 M7,9 l2,-2" />
|
|
627
|
+
</pattern>
|
|
628
|
+
</defs>
|
|
747
629
|
<!-- Hover/click delegation sits on the chart group (not the arcs group) so
|
|
748
630
|
labels - which carry the same data-sunburst-node-idx and are selectable text -
|
|
749
631
|
forward interactions to their arc instead of swallowing them -->
|
|
@@ -764,20 +646,37 @@
|
|
|
764
646
|
{#if arc_content}
|
|
765
647
|
{@render arc_content(screen)}
|
|
766
648
|
{:else}
|
|
767
|
-
|
|
649
|
+
<!-- @const so the path is generated (and info looked up) once per
|
|
650
|
+
arc per frame, shared by the base path and the hatch overlay -->
|
|
651
|
+
{@const info = arc_info[screen.arc.node_idx]}
|
|
652
|
+
{@const opacity = arc_dim[screen.arc.node_idx].opacity}
|
|
653
|
+
{@const path_d = screen_path(screen)}
|
|
768
654
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
769
655
|
<path
|
|
770
|
-
d={
|
|
656
|
+
d={path_d}
|
|
771
657
|
data-sunburst-node-idx={screen.arc.node_idx}
|
|
772
|
-
fill={
|
|
773
|
-
fill-opacity={
|
|
774
|
-
role={clickable ? `button` : undefined}
|
|
775
|
-
tabindex={clickable
|
|
776
|
-
?
|
|
658
|
+
fill={info.fill}
|
|
659
|
+
fill-opacity={opacity}
|
|
660
|
+
role={info.clickable ? `button` : undefined}
|
|
661
|
+
tabindex={info.clickable
|
|
662
|
+
? screen.arc.node_idx === roving_idx
|
|
663
|
+
? 0
|
|
664
|
+
: -1
|
|
777
665
|
: undefined}
|
|
778
|
-
aria-label={clickable ?
|
|
779
|
-
style:cursor={clickable ? `pointer` : `default`}
|
|
666
|
+
aria-label={info.clickable ? info.aria : undefined}
|
|
667
|
+
style:cursor={info.clickable ? `pointer` : `default`}
|
|
780
668
|
/>
|
|
669
|
+
{#if screen.arc.hatch}
|
|
670
|
+
<!-- Decorative texture overlay (e.g. preemptible jobs); rendered as
|
|
671
|
+
the base path's next sibling so the hover 'pull' can track it -->
|
|
672
|
+
<path
|
|
673
|
+
class="arc-hatch"
|
|
674
|
+
aria-hidden="true"
|
|
675
|
+
d={path_d}
|
|
676
|
+
fill="url(#{hatch_pattern_id})"
|
|
677
|
+
fill-opacity={opacity}
|
|
678
|
+
/>
|
|
679
|
+
{/if}
|
|
781
680
|
{/if}
|
|
782
681
|
{/each}
|
|
783
682
|
</g>
|
|
@@ -789,13 +688,15 @@
|
|
|
789
688
|
{#each visible_arcs as screen (screen.arc.node_idx)}
|
|
790
689
|
{@const lbl = label_attrs(screen)}
|
|
791
690
|
{#if lbl}
|
|
691
|
+
{@const info = arc_info[screen.arc.node_idx]}
|
|
792
692
|
<text
|
|
793
693
|
class="arc-label"
|
|
794
694
|
data-sunburst-node-idx={screen.arc.node_idx}
|
|
795
695
|
transform={lbl.transform}
|
|
796
|
-
fill={
|
|
797
|
-
fill-opacity={
|
|
798
|
-
style:cursor={
|
|
696
|
+
fill={info.label_fill}
|
|
697
|
+
fill-opacity={arc_dim[screen.arc.node_idx].label_opacity}
|
|
698
|
+
style:cursor={info.clickable ? `pointer` : `text`}
|
|
699
|
+
style:font-size={lbl.font_scale === 1 ? undefined : `${lbl.font_scale}em`}
|
|
799
700
|
>
|
|
800
701
|
{lbl.text}
|
|
801
702
|
</text>
|
|
@@ -857,14 +758,13 @@
|
|
|
857
758
|
{#if tooltip}
|
|
858
759
|
{@render tooltip(hover_info)}
|
|
859
760
|
{:else}
|
|
860
|
-
<strong>{hover_info.label_path.join(` › `)}</strong>: {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
761
|
+
<strong>{hover_info.label_path.join(` › `)}</strong>: {format_value(
|
|
762
|
+
hover_info.value,
|
|
763
|
+
value_format,
|
|
764
|
+
)}
|
|
765
|
+
({format_value(hover_info.fraction, `.1%`)} of total{hover_info.depth > 1
|
|
865
766
|
? `, ${format_value(hover_info.parent_fraction, `.1%`)} of parent`
|
|
866
|
-
: ``
|
|
867
|
-
})
|
|
767
|
+
: ``})
|
|
868
768
|
{/if}
|
|
869
769
|
</PlotTooltip>
|
|
870
770
|
{/if}
|
|
@@ -878,9 +778,10 @@
|
|
|
878
778
|
series_data={legend_data}
|
|
879
779
|
on_toggle={legend?.on_toggle ?? toggle_category}
|
|
880
780
|
on_item_hover={(item) =>
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
781
|
+
(hovered_idx =
|
|
782
|
+
item != null && item.series_idx >= 0
|
|
783
|
+
? (depth1_arcs[item.series_idx]?.node_idx ?? null)
|
|
784
|
+
: null)}
|
|
884
785
|
style={`position: absolute; left: ${legend_left}px; top: ${legend_top}px; pointer-events: auto; ${
|
|
885
786
|
legend?.style ?? ``
|
|
886
787
|
}`}
|
|
@@ -890,10 +791,10 @@
|
|
|
890
791
|
{#if metric && colorbar != null}
|
|
891
792
|
<div
|
|
892
793
|
bind:clientHeight={colorbar_height}
|
|
893
|
-
style="position: absolute; bottom: var(--sunburst-colorbar-bottom, 8px); left: 50
|
|
794
|
+
style="position: absolute; bottom: var(--sunburst-colorbar-bottom, 8px); left: var(--sunburst-colorbar-left, 50%); transform: var(--sunburst-colorbar-transform, translateX(-50%)); width: var(--sunburst-colorbar-width, 40%); min-width: 120px; pointer-events: auto;"
|
|
894
795
|
>
|
|
895
796
|
<ColorBar
|
|
896
|
-
|
|
797
|
+
{color_scale}
|
|
897
798
|
range={metric.range}
|
|
898
799
|
{...colorbar}
|
|
899
800
|
wrapper_style={`width: 100%; ${colorbar?.wrapper_style ?? ``}`}
|
|
@@ -986,7 +887,9 @@
|
|
|
986
887
|
.sunburst :global(.pane-toggle),
|
|
987
888
|
.sunburst .header-controls {
|
|
988
889
|
opacity: 0;
|
|
989
|
-
transition:
|
|
890
|
+
transition:
|
|
891
|
+
opacity 0.2s,
|
|
892
|
+
background-color 0.2s;
|
|
990
893
|
}
|
|
991
894
|
.sunburst:hover :global(.pane-toggle),
|
|
992
895
|
.sunburst:hover .header-controls,
|
|
@@ -1009,13 +912,32 @@
|
|
|
1009
912
|
presentation attributes is not reliably supported across browsers */
|
|
1010
913
|
stroke: var(--sunburst-arc-stroke, var(--plot-bg, white));
|
|
1011
914
|
stroke-width: var(--sunburst-arc-stroke-width, 0.25);
|
|
1012
|
-
transition:
|
|
915
|
+
transition:
|
|
916
|
+
fill-opacity 0.15s ease,
|
|
917
|
+
transform 0.15s ease;
|
|
1013
918
|
/* hover 'pull': scaling about the chart center offsets the arc radially */
|
|
1014
919
|
transform-origin: 0 0;
|
|
1015
920
|
}
|
|
1016
|
-
|
|
921
|
+
/* the hatch overlay (an arc's next sibling) rides along with its hover 'pull' */
|
|
922
|
+
.sunburst:not(.icicle) .arcs path:hover,
|
|
923
|
+
.sunburst:not(.icicle) .arcs path:hover + path.arc-hatch {
|
|
1017
924
|
transform: scale(var(--sunburst-hover-scale, 1.02));
|
|
1018
925
|
}
|
|
926
|
+
/* decorative overlay: never intercepts pointer events, no border of its own */
|
|
927
|
+
.arcs path.arc-hatch {
|
|
928
|
+
stroke: none;
|
|
929
|
+
pointer-events: none;
|
|
930
|
+
}
|
|
931
|
+
/* subtle by default: thin stripes inheriting the arc border color (itself
|
|
932
|
+
defaulting to the chart bg) at low opacity, so hatching matches the gaps
|
|
933
|
+
between slices instead of reading as solid white */
|
|
934
|
+
.hatch-pattern-line {
|
|
935
|
+
stroke: var(
|
|
936
|
+
--sunburst-hatch-stroke,
|
|
937
|
+
color-mix(in srgb, var(--sunburst-arc-stroke, var(--plot-bg, white)) 30%, transparent)
|
|
938
|
+
);
|
|
939
|
+
stroke-width: var(--sunburst-hatch-stroke-width, 0.35);
|
|
940
|
+
}
|
|
1019
941
|
.center-circle {
|
|
1020
942
|
fill: var(--sunburst-center-bg, transparent);
|
|
1021
943
|
}
|