matterviz 0.4.0 → 0.4.1
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/brillouin/BrillouinZone.svelte +68 -145
- package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -14
- package/dist/brillouin/BrillouinZoneExportPane.svelte +43 -96
- package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +9 -32
- package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
- package/dist/brillouin/BrillouinZoneScene.svelte +49 -203
- 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.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +100 -191
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +176 -464
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -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.js +2 -2
- package/dist/composition/FormulaFilter.svelte +6 -5
- package/dist/composition/PieChart.svelte +5 -5
- package/dist/composition/chem-sys.js +3 -2
- package/dist/composition/format.js +3 -2
- package/dist/composition/parse.d.ts +0 -1
- package/dist/composition/parse.js +17 -19
- package/dist/controls.d.ts +1 -0
- package/dist/controls.js +0 -1
- package/dist/convex-hull/ConvexHull.svelte +8 -10
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
- package/dist/convex-hull/ConvexHull2D.svelte +94 -175
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +176 -680
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +180 -680
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullChrome.svelte +268 -0
- package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
- package/dist/convex-hull/ConvexHullControls.svelte +88 -7
- 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 +29 -168
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
- package/dist/convex-hull/ConvexHullTooltip.svelte +11 -2
- package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
- 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 +278 -0
- package/dist/convex-hull/helpers.d.ts +39 -7
- package/dist/convex-hull/helpers.js +154 -69
- 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 +91 -920
- package/dist/convex-hull/types.d.ts +12 -4
- package/dist/convex-hull/types.js +12 -0
- package/dist/coordination/CoordinationBarPlot.svelte +4 -11
- package/dist/element/BohrAtom.svelte +2 -1
- package/dist/element/ElementTile.svelte.d.ts +1 -1
- package/dist/element/index.d.ts +4 -0
- package/dist/element/index.js +18 -0
- package/dist/feedback/DragOverlay.svelte +3 -1
- package/dist/feedback/DragOverlay.svelte.d.ts +1 -0
- package/dist/feedback/StatusMessage.svelte +13 -3
- package/dist/fermi-surface/FermiSurface.svelte +67 -146
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -14
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +72 -224
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
- package/dist/fermi-surface/compute.js +11 -10
- 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 +64 -75
- package/dist/fermi-surface/types.d.ts +2 -2
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +55 -40
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +4 -3
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +3 -2
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
- package/dist/heatmap-matrix/index.d.ts +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/io/ExportPane.svelte +166 -0
- package/dist/io/ExportPane.svelte.d.ts +17 -0
- package/dist/io/decompress.js +1 -2
- package/dist/io/export.d.ts +5 -1
- package/dist/io/export.js +32 -28
- package/dist/io/fetch.d.ts +2 -1
- package/dist/io/file-drop.d.ts +7 -0
- package/dist/io/file-drop.js +13 -0
- package/dist/io/index.d.ts +2 -0
- package/dist/io/index.js +10 -0
- package/dist/io/types.d.ts +13 -0
- package/dist/isosurface/parse.js +46 -44
- package/dist/labels.js +1 -1
- package/dist/layout/FullscreenButton.svelte +33 -0
- package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
- package/dist/layout/FullscreenToggle.svelte +8 -14
- package/dist/layout/ViewerChrome.svelte +116 -0
- package/dist/layout/ViewerChrome.svelte.d.ts +17 -0
- package/dist/layout/fullscreen.d.ts +4 -0
- package/dist/layout/fullscreen.svelte.d.ts +8 -0
- package/dist/layout/fullscreen.svelte.js +37 -0
- package/dist/layout/index.d.ts +3 -0
- package/dist/layout/index.js +3 -0
- package/dist/math.d.ts +7 -3
- package/dist/math.js +18 -21
- package/dist/overlays/index.d.ts +4 -0
- package/dist/periodic-table/PeriodicTable.svelte +9 -8
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramControls.svelte +3 -2
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +47 -132
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
- package/dist/phase-diagram/colors.js +1 -1
- package/dist/phase-diagram/parse.d.ts +2 -1
- package/dist/plot/bar/BarPlot.svelte +79 -316
- package/dist/plot/bar/BarPlot.svelte.d.ts +7 -15
- package/dist/plot/bar/BarPlotControls.svelte.d.ts +1 -1
- package/dist/plot/bar/SpacegroupBarPlot.svelte +2 -1
- package/dist/plot/box/BoxPlot.svelte +76 -246
- package/dist/plot/box/BoxPlot.svelte.d.ts +4 -3
- package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
- package/dist/plot/box/Violin.svelte.d.ts +1 -1
- package/dist/plot/box/box-plot.d.ts +3 -2
- package/dist/plot/box/box-plot.js +5 -2
- 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 +4 -1
- package/dist/plot/core/components/ColorBar.svelte +5 -5
- package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
- package/dist/plot/core/components/Line.svelte +3 -2
- package/dist/plot/core/components/Line.svelte.d.ts +3 -2
- package/dist/plot/core/components/PlotAxis.svelte +2 -1
- package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
- package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
- package/dist/plot/core/components/ReferenceLine3D.svelte +2 -2
- package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
- package/dist/plot/core/components/ReferencePlane.svelte +2 -2
- package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
- package/dist/plot/core/data-cleaning.js +18 -18
- package/dist/plot/core/fill-utils.d.ts +4 -3
- package/dist/plot/core/fill-utils.js +6 -3
- package/dist/plot/core/interactions.d.ts +5 -1
- package/dist/plot/core/interactions.js +14 -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 +6 -6
- package/dist/plot/core/scales.d.ts +17 -25
- package/dist/plot/core/scales.js +10 -8
- package/dist/plot/core/svg.d.ts +2 -1
- package/dist/plot/core/types.d.ts +18 -7
- package/dist/plot/core/utils/label-placement.d.ts +1 -1
- package/dist/plot/core/utils/label-placement.js +3 -3
- package/dist/plot/core/utils.d.ts +2 -1
- package/dist/plot/histogram/Histogram.svelte +77 -314
- package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
- package/dist/plot/sankey/Sankey.svelte +2 -5
- package/dist/plot/sankey/Sankey.svelte.d.ts +1 -1
- package/dist/plot/sankey/sankey.js +3 -1
- package/dist/plot/scatter/BinnedScatterPlot.svelte +3 -5
- package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +4 -4
- package/dist/plot/scatter/ScatterPlot.svelte +160 -450
- package/dist/plot/scatter/ScatterPlot.svelte.d.ts +7 -15
- package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
- package/dist/plot/scatter/binned-scatter-types.d.ts +4 -11
- package/dist/plot/scatter/index.d.ts +1 -1
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte +15 -26
- package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
- package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +9 -10
- package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +122 -121
- package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
- package/dist/plot/scatter-3d/Surface3D.svelte +6 -5
- package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
- package/dist/plot/sunburst/Sunburst.svelte +16 -20
- package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
- package/dist/plot/sunburst/SunburstControls.svelte.d.ts +1 -1
- package/dist/plot/sunburst/sunburst.js +4 -1
- package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
- package/dist/sanitize.js +13 -2
- 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 +14 -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 +14 -2
- package/dist/settings.js +59 -1
- package/dist/spectral/Bands.svelte +8 -7
- package/dist/spectral/Bands.svelte.d.ts +3 -2
- package/dist/spectral/BandsAndDos.svelte +22 -24
- package/dist/spectral/BrillouinBandsDos.svelte +3 -3
- package/dist/spectral/Dos.svelte +5 -4
- package/dist/spectral/Dos.svelte.d.ts +2 -1
- package/dist/spectral/helpers.d.ts +6 -6
- package/dist/spectral/helpers.js +43 -37
- package/dist/state.svelte.d.ts +0 -7
- package/dist/state.svelte.js +0 -6
- package/dist/structure/Arrow.svelte +2 -4
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/CanvasTooltip.svelte +1 -0
- package/dist/structure/CellSelect.svelte +11 -3
- package/dist/structure/CellSelect.svelte.d.ts +2 -1
- package/dist/structure/Lattice.svelte +2 -2
- package/dist/structure/Structure.svelte +291 -355
- package/dist/structure/Structure.svelte.d.ts +5 -15
- package/dist/structure/StructureControls.svelte +217 -2
- package/dist/structure/StructureControls.svelte.d.ts +5 -3
- package/dist/structure/StructureExportPane.svelte +54 -156
- package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
- package/dist/structure/StructureInfoPane.svelte +5 -3
- package/dist/structure/StructureInfoPane.svelte.d.ts +5 -5
- package/dist/structure/StructureScene.svelte +365 -198
- package/dist/structure/StructureScene.svelte.d.ts +22 -20
- package/dist/structure/{label-placement.d.ts → atom-label-placement.d.ts} +3 -3
- package/dist/structure/{label-placement.js → atom-label-placement.js} +12 -2
- package/dist/structure/atom-properties.d.ts +1 -1
- package/dist/structure/atom-properties.js +11 -16
- package/dist/structure/bond-order-perception.js +2 -4
- package/dist/structure/bonding.d.ts +3 -0
- package/dist/structure/bonding.js +91 -48
- package/dist/structure/export.d.ts +24 -4
- package/dist/structure/export.js +64 -122
- package/dist/structure/index.d.ts +2 -0
- package/dist/structure/index.js +2 -0
- package/dist/structure/parse.d.ts +3 -2
- package/dist/structure/parse.js +333 -370
- package/dist/structure/partial-occupancy.d.ts +0 -1
- package/dist/structure/partial-occupancy.js +1 -1
- package/dist/structure/pbc.d.ts +1 -1
- package/dist/structure/pbc.js +186 -13
- package/dist/structure/polyhedra.d.ts +41 -0
- package/dist/structure/polyhedra.js +602 -0
- package/dist/structure/site.d.ts +4 -0
- package/dist/structure/site.js +1 -0
- package/dist/structure/supercell.js +3 -2
- 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 +354 -0
- package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
- package/dist/symmetry/SymmetryStats.svelte +111 -6
- package/dist/symmetry/WyckoffTable.svelte +68 -7
- package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
- package/dist/symmetry/cell-transform.js +7 -14
- package/dist/symmetry/index.d.ts +14 -4
- package/dist/symmetry/index.js +301 -80
- package/dist/symmetry/spacegroups.d.ts +5 -1
- package/dist/symmetry/spacegroups.js +15 -1
- 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 +4 -15
- package/dist/table/HeatmapTable.svelte.d.ts +1 -1
- package/dist/trajectory/Trajectory.svelte +58 -61
- package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
- package/dist/trajectory/TrajectoryExportPane.svelte +15 -24
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
- package/dist/trajectory/TrajectoryInfoPane.svelte +3 -2
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
- package/dist/trajectory/constants.js +6 -2
- package/dist/trajectory/extract.js +17 -37
- package/dist/trajectory/format-detect.d.ts +0 -1
- package/dist/trajectory/format-detect.js +3 -9
- package/dist/trajectory/frame-reader.d.ts +0 -1
- package/dist/trajectory/frame-reader.js +62 -128
- package/dist/trajectory/helpers.d.ts +10 -2
- package/dist/trajectory/helpers.js +56 -36
- 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/index.d.ts +1 -1
- package/dist/trajectory/parse/index.js +54 -102
- package/dist/trajectory/parse/lammps.d.ts +0 -2
- package/dist/trajectory/parse/lammps.js +8 -6
- package/dist/trajectory/parse/pymatgen.d.ts +2 -0
- package/dist/trajectory/parse/pymatgen.js +74 -0
- package/dist/trajectory/parse/vasp.js +4 -3
- package/dist/trajectory/parse/xyz.d.ts +9 -21
- package/dist/trajectory/parse/xyz.js +28 -33
- package/dist/trajectory/plotting.d.ts +0 -1
- package/dist/trajectory/plotting.js +3 -100
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +1 -1
- package/dist/xrd/XrdPlot.svelte +14 -29
- package/dist/xrd/broadening.d.ts +2 -1
- package/dist/xrd/calc-xrd.js +6 -11
- package/dist/xrd/index.d.ts +2 -2
- package/package.json +29 -16
- 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
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
lang="ts"
|
|
3
3
|
generics="Metadata extends Record<string, unknown> = Record<string, unknown>"
|
|
4
4
|
>
|
|
5
|
-
import type { D3ColorSchemeName, D3InterpolateName } from '../../colors'
|
|
6
5
|
import { format_num } from '../../labels'
|
|
7
6
|
import type { Vec2, Vec3 } from '../../math'
|
|
8
7
|
import type {
|
|
@@ -13,12 +12,13 @@
|
|
|
13
12
|
InternalPoint3D,
|
|
14
13
|
RefLine3D,
|
|
15
14
|
RefPlane,
|
|
16
|
-
ScaleType,
|
|
17
15
|
Scatter3DHandlerEvent,
|
|
16
|
+
SizeScaleConfig,
|
|
18
17
|
StyleOverrides3D,
|
|
19
18
|
Surface3DConfig,
|
|
20
19
|
} from '../core/types'
|
|
21
|
-
import {
|
|
20
|
+
import { bind_renderer } from '../../scene'
|
|
21
|
+
import { T, useTask } from '@threlte/core'
|
|
22
22
|
import * as extras from '@threlte/extras'
|
|
23
23
|
import { scaleLinear } from 'd3-scale'
|
|
24
24
|
import { type ComponentProps, onDestroy, type Snippet, untrack } from 'svelte'
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
import { normalize_to_scene } from '../core/reference-line'
|
|
32
32
|
import ReferenceLine3D from '../core/components/ReferenceLine3D.svelte'
|
|
33
33
|
import ReferencePlane from '../core/components/ReferencePlane.svelte'
|
|
34
|
-
import {
|
|
34
|
+
import { create_size_scale } from '../core/scales'
|
|
35
35
|
import Surface3D from './Surface3D.svelte'
|
|
36
36
|
|
|
37
37
|
let {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
surfaces = [],
|
|
46
46
|
ref_lines = [],
|
|
47
47
|
ref_planes = [],
|
|
48
|
-
|
|
48
|
+
color_scale_fn = () => get_series_color(0),
|
|
49
49
|
size_scale = { type: `linear`, radius_range: [0.05, 0.2] },
|
|
50
50
|
camera_position = [10, 10, 10] as Vec3,
|
|
51
51
|
camera_projection = `perspective` as CameraProjection3D,
|
|
@@ -81,16 +81,9 @@
|
|
|
81
81
|
surfaces?: Surface3DConfig[]
|
|
82
82
|
ref_lines?: RefLine3D[]
|
|
83
83
|
ref_planes?: RefPlane[]
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
value_range?: [number, number]
|
|
88
|
-
}
|
|
89
|
-
size_scale?: {
|
|
90
|
-
type?: ScaleType
|
|
91
|
-
radius_range?: [number, number]
|
|
92
|
-
value_range?: [number, number]
|
|
93
|
-
}
|
|
84
|
+
// Color scale function for color_values (computed once by the ScatterPlot3D wrapper)
|
|
85
|
+
color_scale_fn?: (value: number) => string
|
|
86
|
+
size_scale?: SizeScaleConfig
|
|
94
87
|
camera_position?: Vec3
|
|
95
88
|
camera_projection?: CameraProjection3D
|
|
96
89
|
auto_rotate?: number
|
|
@@ -116,10 +109,10 @@
|
|
|
116
109
|
height?: number
|
|
117
110
|
} = $props()
|
|
118
111
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
scene =
|
|
122
|
-
camera =
|
|
112
|
+
// Mirrors scene/camera into bindable props and tags the canvas so export_canvas_as_png can re-render at export DPI
|
|
113
|
+
bind_renderer((threlte_scene, threlte_camera) => {
|
|
114
|
+
scene = threlte_scene
|
|
115
|
+
camera = threlte_camera
|
|
123
116
|
})
|
|
124
117
|
|
|
125
118
|
extras.interactivity()
|
|
@@ -182,24 +175,28 @@
|
|
|
182
175
|
function sample_surface(
|
|
183
176
|
surface: Surface3DConfig,
|
|
184
177
|
): { x: number; y: number; z: number }[] {
|
|
185
|
-
const
|
|
178
|
+
const grid_steps = 10
|
|
186
179
|
const pts: { x: number; y: number; z: number }[] = []
|
|
187
180
|
if (surface.type === `grid` && surface.z_fn) {
|
|
188
181
|
const [x0, x1] = surface.x_range ?? [-1, 1]
|
|
189
182
|
const [y0, y1] = surface.y_range ?? [-1, 1]
|
|
190
|
-
for (let
|
|
191
|
-
for (let
|
|
192
|
-
const x = x0 + (
|
|
183
|
+
for (let idx_x = 0; idx_x <= grid_steps; idx_x++) {
|
|
184
|
+
for (let idx_y = 0; idx_y <= grid_steps; idx_y++) {
|
|
185
|
+
const x = x0 + (idx_x / grid_steps) * (x1 - x0),
|
|
186
|
+
y = y0 + (idx_y / grid_steps) * (y1 - y0)
|
|
193
187
|
pts.push({ x, y, z: surface.z_fn(x, y) })
|
|
194
188
|
}
|
|
195
189
|
}
|
|
196
190
|
} else if (surface.type === `parametric` && surface.parametric_fn) {
|
|
197
191
|
const [u0, u1] = surface.u_range ?? [0, 1]
|
|
198
192
|
const [v0, v1] = surface.v_range ?? [0, 1]
|
|
199
|
-
for (let
|
|
200
|
-
for (let
|
|
193
|
+
for (let idx_u = 0; idx_u <= grid_steps; idx_u++) {
|
|
194
|
+
for (let idx_v = 0; idx_v <= grid_steps; idx_v++) {
|
|
201
195
|
pts.push(
|
|
202
|
-
surface.parametric_fn(
|
|
196
|
+
surface.parametric_fn(
|
|
197
|
+
u0 + (idx_u / grid_steps) * (u1 - u0),
|
|
198
|
+
v0 + (idx_v / grid_steps) * (v1 - v0),
|
|
199
|
+
),
|
|
203
200
|
)
|
|
204
201
|
}
|
|
205
202
|
}
|
|
@@ -209,15 +206,14 @@
|
|
|
209
206
|
return pts.filter((pt) => isFinite(pt.x) && isFinite(pt.y) && isFinite(pt.z))
|
|
210
207
|
}
|
|
211
208
|
|
|
212
|
-
// Compute axis range with D3's nice()
|
|
209
|
+
// Compute axis range with D3's nice(); data_min/data_max are the finite extent (Infinity/-Infinity when empty)
|
|
213
210
|
function compute_range(
|
|
214
|
-
|
|
211
|
+
[data_min, data_max]: Vec2,
|
|
215
212
|
range?: [number | null, number | null],
|
|
216
213
|
): Vec2 {
|
|
217
214
|
if (range?.[0] != null && range?.[1] != null) return range as Vec2
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
let [min, max] = [Math.min(...valid), Math.max(...valid)]
|
|
215
|
+
if (data_min > data_max) return [0, 1] // no finite values
|
|
216
|
+
let [min, max] = [data_min, data_max]
|
|
221
217
|
const pad = min === max
|
|
222
218
|
? (min === 0 ? 1 : Math.abs(min * 0.1))
|
|
223
219
|
: (max - min) * 0.05
|
|
@@ -227,49 +223,39 @@
|
|
|
227
223
|
.domain() as Vec2
|
|
228
224
|
}
|
|
229
225
|
|
|
230
|
-
// Collect xyz
|
|
226
|
+
// Collect xyz extents from points and surfaces in one pass (no intermediate arrays)
|
|
231
227
|
let surface_samples = $derived(surfaces.flatMap(sample_surface))
|
|
232
|
-
let
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
228
|
+
let data_extents = $derived.by(() => {
|
|
229
|
+
const extents = {
|
|
230
|
+
x: [Infinity, -Infinity] as Vec2,
|
|
231
|
+
y: [Infinity, -Infinity] as Vec2,
|
|
232
|
+
z: [Infinity, -Infinity] as Vec2,
|
|
233
|
+
}
|
|
234
|
+
for (const points of [all_points, surface_samples]) {
|
|
235
|
+
for (const pt of points) {
|
|
236
|
+
for (const axis of [`x`, `y`, `z`] as const) {
|
|
237
|
+
const val = pt[axis]
|
|
238
|
+
if (!isFinite(val)) continue
|
|
239
|
+
const extent = extents[axis]
|
|
240
|
+
if (val < extent[0]) extent[0] = val
|
|
241
|
+
if (val > extent[1]) extent[1] = val
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return extents
|
|
246
|
+
})
|
|
247
|
+
let x_range = $derived(compute_range(data_extents.x, x_axis.range))
|
|
248
|
+
let y_range = $derived(compute_range(data_extents.y, y_axis.range))
|
|
249
|
+
let z_range = $derived(compute_range(data_extents.z, z_axis.range))
|
|
250
250
|
|
|
251
251
|
const normalize_x = (value: number) => normalize_to_scene(value, x_range, scene_x)
|
|
252
252
|
const normalize_y = (value: number) => normalize_to_scene(value, y_range, scene_y)
|
|
253
253
|
const normalize_z = (value: number) => normalize_to_scene(value, z_range, scene_z)
|
|
254
254
|
|
|
255
|
-
//
|
|
256
|
-
let all_color_values = $derived(
|
|
257
|
-
all_points.map((pt) => pt.color_value).filter((val): val is number => val != null),
|
|
258
|
-
)
|
|
259
|
-
let auto_color_range: [number, number] = $derived.by(() => {
|
|
260
|
-
if (all_color_values.length === 0) return [0, 1]
|
|
261
|
-
let min = all_color_values[0]
|
|
262
|
-
let max = all_color_values[0]
|
|
263
|
-
for (const val of all_color_values) {
|
|
264
|
-
if (val < min) min = val
|
|
265
|
-
else if (val > max) max = val
|
|
266
|
-
}
|
|
267
|
-
return [min, max]
|
|
268
|
-
})
|
|
255
|
+
// Size scale (the color scale is computed by the wrapper and passed as a prop)
|
|
269
256
|
let all_size_values = $derived(
|
|
270
257
|
all_points.map((pt) => pt.size_value).filter((val): val is number => val != null),
|
|
271
258
|
)
|
|
272
|
-
let color_scale_fn = $derived(create_color_scale(color_scale, auto_color_range))
|
|
273
259
|
let size_scale_fn = $derived(create_size_scale(size_scale, all_size_values))
|
|
274
260
|
|
|
275
261
|
// Process points with normalized positions
|
|
@@ -331,83 +317,98 @@
|
|
|
331
317
|
)
|
|
332
318
|
|
|
333
319
|
// Series line data for connecting points
|
|
334
|
-
type
|
|
320
|
+
type SeriesLineInput = {
|
|
335
321
|
series_idx: number
|
|
322
|
+
positions: number[]
|
|
336
323
|
color: string
|
|
337
324
|
width: number
|
|
338
325
|
dashed: boolean
|
|
326
|
+
}
|
|
327
|
+
type SeriesLineData = SeriesLineInput & {
|
|
339
328
|
line2: Line2
|
|
340
329
|
geometry: LineGeometry
|
|
341
330
|
material: LineMaterial
|
|
342
331
|
}
|
|
343
332
|
|
|
344
|
-
//
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
for (const line_data of untrack(() => series_lines)) {
|
|
350
|
-
line_data.geometry.dispose()
|
|
351
|
-
line_data.material.dispose()
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
const lines: SeriesLineData[] = []
|
|
333
|
+
// Per-series fat-line inputs (ordered positions + resolved stroke style) as a derived so
|
|
334
|
+
// the effect below can diff against previous lines and only rebuild what changed
|
|
335
|
+
let line_inputs = $derived.by((): SeriesLineInput[] => {
|
|
336
|
+
const eligible: SeriesLineInput[] = []
|
|
337
|
+
const positions_by_series = new Map<number, number[]>()
|
|
355
338
|
for (let series_idx = 0; series_idx < series.length; series_idx++) {
|
|
356
339
|
const srs = series[series_idx]
|
|
357
|
-
|
|
340
|
+
const line_style = srs?.line_style
|
|
341
|
+
if (!line_style) continue
|
|
358
342
|
if (!(series_visibility[series_idx] ?? srs.visible ?? true)) continue
|
|
359
|
-
|
|
360
|
-
// Get points for this series in order
|
|
361
|
-
const series_points = processed_points
|
|
362
|
-
.filter((pt) => pt.series_idx === series_idx)
|
|
363
|
-
.sort((a, b) => a.point_idx - b.point_idx)
|
|
364
|
-
|
|
365
|
-
if (series_points.length < 2) continue
|
|
366
|
-
|
|
367
|
-
// Create fat line geometry (LineGeometry for Line2)
|
|
368
343
|
const positions: number[] = []
|
|
369
|
-
|
|
370
|
-
positions.push(pt.x, pt.y, pt.z)
|
|
371
|
-
}
|
|
372
|
-
const geometry = new LineGeometry()
|
|
373
|
-
geometry.setPositions(positions)
|
|
374
|
-
|
|
375
|
-
// Determine line style
|
|
376
|
-
const line_style = srs.line_style
|
|
344
|
+
positions_by_series.set(series_idx, positions)
|
|
377
345
|
const color = line_style.stroke ??
|
|
378
346
|
(Array.isArray(srs.point_style)
|
|
379
347
|
? srs.point_style[0]?.fill
|
|
380
348
|
: srs.point_style?.fill) ??
|
|
381
349
|
get_series_color(series_idx)
|
|
382
|
-
|
|
383
|
-
const dashed = Boolean(line_style.line_dash)
|
|
384
|
-
|
|
385
|
-
// Create LineMaterial for fat lines (linewidth is in pixels when resolution is set)
|
|
386
|
-
// Use placeholder resolution; the separate resolution effect updates it
|
|
387
|
-
const material = new LineMaterial({
|
|
388
|
-
color: new THREE.Color(color).getHex(),
|
|
389
|
-
linewidth: line_width, // Width in pixels
|
|
390
|
-
dashed,
|
|
391
|
-
dashScale: dashed ? 2 : 1,
|
|
392
|
-
dashSize: 0.1,
|
|
393
|
-
gapSize: 0.05,
|
|
394
|
-
resolution: new THREE.Vector2(1, 1),
|
|
395
|
-
})
|
|
396
|
-
|
|
397
|
-
const line2 = new Line2(geometry, material)
|
|
398
|
-
line2.computeLineDistances()
|
|
399
|
-
|
|
400
|
-
lines.push({
|
|
350
|
+
eligible.push({
|
|
401
351
|
series_idx,
|
|
352
|
+
positions,
|
|
402
353
|
color,
|
|
403
|
-
width:
|
|
404
|
-
dashed,
|
|
405
|
-
line2,
|
|
406
|
-
geometry,
|
|
407
|
-
material,
|
|
354
|
+
width: line_style.stroke_width ?? 2,
|
|
355
|
+
dashed: Boolean(line_style.line_dash),
|
|
408
356
|
})
|
|
409
357
|
}
|
|
410
|
-
|
|
358
|
+
// processed_points are emitted in (series_idx, point_idx) order, so one ordered pass replaces the old per-series filter + sort
|
|
359
|
+
for (const pt of processed_points) {
|
|
360
|
+
positions_by_series.get(pt.series_idx)?.push(pt.x, pt.y, pt.z)
|
|
361
|
+
}
|
|
362
|
+
return eligible.filter((input) => input.positions.length >= 6) // >= 2 points
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
const same_line_input = (prev: SeriesLineData, next: SeriesLineInput): boolean =>
|
|
366
|
+
prev.color === next.color && prev.width === next.width &&
|
|
367
|
+
prev.dashed === next.dashed &&
|
|
368
|
+
prev.positions.length === next.positions.length &&
|
|
369
|
+
prev.positions.every((coord, idx) => coord === next.positions[idx])
|
|
370
|
+
|
|
371
|
+
// Track previous lines for reuse/cleanup
|
|
372
|
+
let series_lines: SeriesLineData[] = $state([])
|
|
373
|
+
|
|
374
|
+
$effect(() => {
|
|
375
|
+
const inputs = line_inputs
|
|
376
|
+
untrack(() => {
|
|
377
|
+
const prev_by_idx = new Map(series_lines.map((line) => [line.series_idx, line]))
|
|
378
|
+
const next_lines = inputs.map((input): SeriesLineData => {
|
|
379
|
+
const prev = prev_by_idx.get(input.series_idx)
|
|
380
|
+
if (prev && same_line_input(prev, input)) {
|
|
381
|
+
prev_by_idx.delete(input.series_idx) // reused - don't dispose below
|
|
382
|
+
return prev
|
|
383
|
+
}
|
|
384
|
+
// Create fat line geometry (LineGeometry for Line2)
|
|
385
|
+
const geometry = new LineGeometry()
|
|
386
|
+
geometry.setPositions(input.positions)
|
|
387
|
+
// Create LineMaterial for fat lines (linewidth is in pixels when resolution
|
|
388
|
+
// is set). Use placeholder resolution; the separate resolution effect updates it
|
|
389
|
+
const material = new LineMaterial({
|
|
390
|
+
color: new THREE.Color(input.color).getHex(),
|
|
391
|
+
linewidth: input.width, // Width in pixels
|
|
392
|
+
dashed: input.dashed,
|
|
393
|
+
dashScale: input.dashed ? 2 : 1,
|
|
394
|
+
dashSize: 0.1,
|
|
395
|
+
gapSize: 0.05,
|
|
396
|
+
resolution: new THREE.Vector2(1, 1),
|
|
397
|
+
})
|
|
398
|
+
const line2 = new Line2(geometry, material)
|
|
399
|
+
line2.computeLineDistances()
|
|
400
|
+
return { ...input, line2, geometry, material }
|
|
401
|
+
})
|
|
402
|
+
// Dispose lines that were replaced or removed
|
|
403
|
+
for (const stale of prev_by_idx.values()) {
|
|
404
|
+
stale.geometry.dispose()
|
|
405
|
+
stale.material.dispose()
|
|
406
|
+
}
|
|
407
|
+
// Skip reassignment when every line was reused to avoid invalidating consumers
|
|
408
|
+
const unchanged = next_lines.length === series_lines.length &&
|
|
409
|
+
next_lines.every((line, idx) => line === series_lines[idx])
|
|
410
|
+
if (!unchanged) series_lines = next_lines
|
|
411
|
+
})
|
|
411
412
|
})
|
|
412
413
|
|
|
413
414
|
// Update LineMaterial resolution when canvas size changes
|
|
@@ -434,7 +435,7 @@
|
|
|
434
435
|
|
|
435
436
|
// Generate axis ticks using D3's smart tick generation
|
|
436
437
|
function gen_ticks(
|
|
437
|
-
range:
|
|
438
|
+
range: Vec2,
|
|
438
439
|
ticks?: AxisConfig3D[`ticks`],
|
|
439
440
|
): number[] {
|
|
440
441
|
if (Array.isArray(ticks)) return ticks
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { D3ColorSchemeName, D3InterpolateName } from '../../colors';
|
|
2
1
|
import type { Vec3 } from '../../math';
|
|
3
|
-
import type { AxisConfig3D, CameraProjection3D, DataSeries3D, DisplayConfig3D, InternalPoint3D, RefLine3D, RefPlane,
|
|
2
|
+
import type { AxisConfig3D, CameraProjection3D, DataSeries3D, DisplayConfig3D, InternalPoint3D, RefLine3D, RefPlane, Scatter3DHandlerEvent, SizeScaleConfig, StyleOverrides3D, Surface3DConfig } from '../core/types';
|
|
4
3
|
import * as extras from '@threlte/extras';
|
|
5
4
|
import { type ComponentProps, type Snippet } from 'svelte';
|
|
6
5
|
import type { Camera, Scene } from 'three';
|
|
@@ -16,16 +15,8 @@ declare function $$render<Metadata extends Record<string, unknown> = Record<stri
|
|
|
16
15
|
surfaces?: Surface3DConfig[];
|
|
17
16
|
ref_lines?: RefLine3D[];
|
|
18
17
|
ref_planes?: RefPlane[];
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
scheme?: D3ColorSchemeName | D3InterpolateName;
|
|
22
|
-
value_range?: [number, number];
|
|
23
|
-
};
|
|
24
|
-
size_scale?: {
|
|
25
|
-
type?: ScaleType;
|
|
26
|
-
radius_range?: [number, number];
|
|
27
|
-
value_range?: [number, number];
|
|
28
|
-
};
|
|
18
|
+
color_scale_fn?: (value: number) => string;
|
|
19
|
+
size_scale?: SizeScaleConfig;
|
|
29
20
|
camera_position?: Vec3;
|
|
30
21
|
camera_projection?: CameraProjection3D;
|
|
31
22
|
auto_rotate?: number;
|
|
@@ -51,7 +42,7 @@ declare function $$render<Metadata extends Record<string, unknown> = Record<stri
|
|
|
51
42
|
height?: number;
|
|
52
43
|
};
|
|
53
44
|
exports: {};
|
|
54
|
-
bindings: "
|
|
45
|
+
bindings: "scene" | "camera" | "orbit_controls" | "hovered_point";
|
|
55
46
|
slots: {};
|
|
56
47
|
events: {};
|
|
57
48
|
};
|
|
@@ -59,7 +50,7 @@ declare class __sveltets_Render<Metadata extends Record<string, unknown> = Recor
|
|
|
59
50
|
props(): ReturnType<typeof $$render<Metadata>>['props'];
|
|
60
51
|
events(): ReturnType<typeof $$render<Metadata>>['events'];
|
|
61
52
|
slots(): ReturnType<typeof $$render<Metadata>>['slots'];
|
|
62
|
-
bindings(): "
|
|
53
|
+
bindings(): "scene" | "camera" | "orbit_controls" | "hovered_point";
|
|
63
54
|
exports(): {};
|
|
64
55
|
}
|
|
65
56
|
interface $$IsomorphicComponent {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Vec2 } from '../../math'
|
|
2
3
|
import type { Surface3DConfig } from '../core/types'
|
|
3
4
|
import { T } from '@threlte/core'
|
|
4
5
|
import * as THREE from 'three'
|
|
@@ -13,9 +14,9 @@
|
|
|
13
14
|
scene_z = 5,
|
|
14
15
|
}: {
|
|
15
16
|
config: Surface3DConfig
|
|
16
|
-
x_range?:
|
|
17
|
-
y_range?:
|
|
18
|
-
z_range?:
|
|
17
|
+
x_range?: Vec2
|
|
18
|
+
y_range?: Vec2
|
|
19
|
+
z_range?: Vec2
|
|
19
20
|
scene_x?: number
|
|
20
21
|
scene_y?: number
|
|
21
22
|
scene_z?: number
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
// Normalize value to scene coordinates (centered around 0)
|
|
25
26
|
const normalize = (
|
|
26
27
|
value: number,
|
|
27
|
-
[min_val, max_val]:
|
|
28
|
+
[min_val, max_val]: Vec2,
|
|
28
29
|
scene_size: number,
|
|
29
30
|
): number => ((value - min_val) / (max_val - min_val || 1) - 0.5) * scene_size
|
|
30
31
|
|
|
@@ -96,7 +97,7 @@
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
// Parse resolution config into [res_a, res_b]
|
|
99
|
-
const get_resolution = ():
|
|
100
|
+
const get_resolution = (): Vec2 =>
|
|
100
101
|
Array.isArray(config.resolution)
|
|
101
102
|
? config.resolution
|
|
102
103
|
: [config.resolution ?? 20, config.resolution ?? 20]
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import type { Vec2 } from '../../math';
|
|
1
2
|
import type { Surface3DConfig } from '../core/types';
|
|
2
3
|
type $$ComponentProps = {
|
|
3
4
|
config: Surface3DConfig;
|
|
4
|
-
x_range?:
|
|
5
|
-
y_range?:
|
|
6
|
-
z_range?:
|
|
5
|
+
x_range?: Vec2;
|
|
6
|
+
y_range?: Vec2;
|
|
7
|
+
z_range?: Vec2;
|
|
7
8
|
scene_x?: number;
|
|
8
9
|
scene_y?: number;
|
|
9
10
|
scene_z?: number;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { export_svg_as_png, export_svg_as_svg } from '../../io/export'
|
|
8
8
|
import { format_value } from '../../labels'
|
|
9
9
|
import { FullscreenToggle, set_fullscreen_bg } from '../../layout'
|
|
10
|
-
import { DEG_TO_RAD } from '../../math'
|
|
10
|
+
import { DEG_TO_RAD, type Vec2 } from '../../math'
|
|
11
11
|
import type {
|
|
12
12
|
BasePlotProps,
|
|
13
13
|
LegendConfig,
|
|
@@ -29,12 +29,8 @@
|
|
|
29
29
|
} from '../core/layout'
|
|
30
30
|
import type { Sides } from '../core/layout'
|
|
31
31
|
import { create_color_scale } from '../core/scales'
|
|
32
|
-
import {
|
|
33
|
-
|
|
34
|
-
arrow_nav_target,
|
|
35
|
-
project_arcs,
|
|
36
|
-
type ScreenArc as ScreenArcOf,
|
|
37
|
-
} from './render'
|
|
32
|
+
import { arc_label_transform, arrow_nav_target, project_arcs } from './render'
|
|
33
|
+
import type { ScreenArc as ScreenArcOf } from './render'
|
|
38
34
|
import { compute_sunburst_layout, type PositionedArc } from './sunburst'
|
|
39
35
|
import { DEFAULTS } from '../../settings'
|
|
40
36
|
import { arc as d3_arc } from 'd3-shape'
|
|
@@ -118,7 +114,7 @@
|
|
|
118
114
|
// inheritance; return null to keep an arc's categorical color
|
|
119
115
|
color_values?: (arc: PositionedArc<Metadata>) => number | null
|
|
120
116
|
color_scale?: D3InterpolateName
|
|
121
|
-
color_range?:
|
|
117
|
+
color_range?: Vec2 // defaults to the metric's [min, max]
|
|
122
118
|
colorbar?: ComponentProps<typeof ColorBar> | null // null hides it
|
|
123
119
|
export_buttons?: boolean // SVG/PNG download buttons in the controls pane
|
|
124
120
|
export_filename?: string
|
|
@@ -266,10 +262,10 @@
|
|
|
266
262
|
|
|
267
263
|
let arc_gen = $derived(
|
|
268
264
|
d3_arc<ScreenArc>()
|
|
269
|
-
.startAngle((
|
|
270
|
-
.endAngle((
|
|
271
|
-
.innerRadius((
|
|
272
|
-
.outerRadius((
|
|
265
|
+
.startAngle((screen) => screen.a0)
|
|
266
|
+
.endAngle((screen) => screen.a1)
|
|
267
|
+
.innerRadius((screen) => screen.r0)
|
|
268
|
+
.outerRadius((screen) => screen.r1)
|
|
273
269
|
.padAngle(pad_angle * DEG_TO_RAD)
|
|
274
270
|
.padRadius(radius || 1),
|
|
275
271
|
)
|
|
@@ -287,19 +283,19 @@
|
|
|
287
283
|
)
|
|
288
284
|
|
|
289
285
|
// Arc centroid in container (pad-offset) pixel space, for tooltip + legend placement
|
|
290
|
-
const arc_center = (
|
|
286
|
+
const arc_center = (screen: ScreenArc): { x: number; y: number } => {
|
|
291
287
|
if (shape === `icicle`) {
|
|
292
|
-
return { x: pad.l + (
|
|
288
|
+
return { x: pad.l + (screen.a0 + screen.a1) / 2, y: pad.t + (screen.r0 + screen.r1) / 2 }
|
|
293
289
|
}
|
|
294
|
-
const mid_a = (
|
|
295
|
-
const mid_r = (
|
|
290
|
+
const mid_a = (screen.a0 + screen.a1) / 2
|
|
291
|
+
const mid_r = (screen.r0 + screen.r1) / 2
|
|
296
292
|
return { x: cx + Math.sin(mid_a) * mid_r, y: cy - Math.cos(mid_a) * mid_r }
|
|
297
293
|
}
|
|
298
294
|
|
|
299
295
|
// Continuous metric coloring: when color_values is given, arcs are colored by their
|
|
300
296
|
// metric on a d3 colormap (arcs returning null keep their categorical color).
|
|
301
297
|
// The user accessor runs exactly once per arc.
|
|
302
|
-
let metric = $derived.by<{ range:
|
|
298
|
+
let metric = $derived.by<{ range: Vec2; colors: string[] } | null>(() => {
|
|
303
299
|
if (!color_values) return null
|
|
304
300
|
const vals = layout.arcs.map((arc) => {
|
|
305
301
|
const val = arc.depth === 0 ? null : color_values(arc)
|
|
@@ -574,10 +570,10 @@
|
|
|
574
570
|
)
|
|
575
571
|
|
|
576
572
|
// Label text + placement transform for an arc; null = doesn't fit, hide the label
|
|
577
|
-
function label_attrs(
|
|
578
|
-
const { text, width: text_w } = arc_info[
|
|
573
|
+
function label_attrs(screen: ScreenArc): { transform: string; text: string } | null {
|
|
574
|
+
const { text, width: text_w } = arc_info[screen.arc.node_idx]
|
|
579
575
|
if (!text) return null
|
|
580
|
-
const transform = arc_label_transform(
|
|
576
|
+
const transform = arc_label_transform(screen, text_w, shape, label_rotation)
|
|
581
577
|
return transform ? { transform, text } : null
|
|
582
578
|
}
|
|
583
579
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { D3InterpolateName } from '../../colors';
|
|
2
|
+
import { type Vec2 } from '../../math';
|
|
2
3
|
import type { BasePlotProps, LegendConfig, SunburstLabelRotation, SunburstLabelText, SunburstNode, SunburstNodeHandlerProps, SunburstShape, SunburstSort, SunburstValueMode } from '..';
|
|
3
4
|
import { ColorBar } from '..';
|
|
4
5
|
import type { Sides } from '../core/layout';
|
|
@@ -26,7 +27,7 @@ declare function $$render<Metadata extends Record<string, unknown> = Record<stri
|
|
|
26
27
|
show_breadcrumbs?: boolean;
|
|
27
28
|
color_values?: (arc: PositionedArc<Metadata>) => number | null;
|
|
28
29
|
color_scale?: D3InterpolateName;
|
|
29
|
-
color_range?:
|
|
30
|
+
color_range?: Vec2;
|
|
30
31
|
colorbar?: ComponentProps<typeof ColorBar> | null;
|
|
31
32
|
export_buttons?: boolean;
|
|
32
33
|
export_filename?: string;
|
|
@@ -73,7 +74,7 @@ declare function $$render<Metadata extends Record<string, unknown> = Record<stri
|
|
|
73
74
|
}]>;
|
|
74
75
|
};
|
|
75
76
|
exports: {};
|
|
76
|
-
bindings: "data" | "show_controls" | "
|
|
77
|
+
bindings: "data" | "show_controls" | "show_labels" | "fullscreen" | "hovered" | "controls_open" | "shape" | "value_mode" | "max_depth" | "inner_radius" | "pad_angle" | "min_fraction" | "label_rotation" | "label_text" | "zoom_on_click" | "show_breadcrumbs" | "zoom_root_id";
|
|
77
78
|
slots: {};
|
|
78
79
|
events: {};
|
|
79
80
|
};
|
|
@@ -81,7 +82,7 @@ declare class __sveltets_Render<Metadata extends Record<string, unknown> = Recor
|
|
|
81
82
|
props(): ReturnType<typeof $$render<Metadata>>['props'];
|
|
82
83
|
events(): ReturnType<typeof $$render<Metadata>>['events'];
|
|
83
84
|
slots(): ReturnType<typeof $$render<Metadata>>['slots'];
|
|
84
|
-
bindings(): "data" | "show_controls" | "
|
|
85
|
+
bindings(): "data" | "show_controls" | "show_labels" | "fullscreen" | "hovered" | "controls_open" | "shape" | "value_mode" | "max_depth" | "inner_radius" | "pad_angle" | "min_fraction" | "label_rotation" | "label_text" | "zoom_on_click" | "show_breadcrumbs" | "zoom_root_id";
|
|
85
86
|
exports(): {};
|
|
86
87
|
}
|
|
87
88
|
interface $$IsomorphicComponent {
|
|
@@ -21,6 +21,6 @@ type $$ComponentProps = {
|
|
|
21
21
|
pane_props?: HTMLAttributes<HTMLDivElement>;
|
|
22
22
|
children?: Snippet;
|
|
23
23
|
};
|
|
24
|
-
declare const SunburstControls: import("svelte").Component<$$ComponentProps, {}, "show_controls" | "
|
|
24
|
+
declare const SunburstControls: import("svelte").Component<$$ComponentProps, {}, "show_controls" | "show_labels" | "controls_open" | "shape" | "value_mode" | "max_depth" | "inner_radius" | "pad_angle" | "min_fraction" | "label_rotation" | "label_text" | "zoom_on_click" | "show_breadcrumbs">;
|
|
25
25
|
type SunburstControls = ReturnType<typeof SunburstControls>;
|
|
26
26
|
export default SunburstControls;
|
|
@@ -7,11 +7,14 @@
|
|
|
7
7
|
import { hsl } from 'd3-color';
|
|
8
8
|
import { hierarchy, partition } from 'd3-hierarchy';
|
|
9
9
|
import { DEFAULT_SERIES_COLORS } from '../core/types';
|
|
10
|
+
import { DEFAULTS } from '../../settings';
|
|
10
11
|
// Compute normalized arc extents, resolved colors and breadcrumbs for a node tree.
|
|
11
12
|
// Never mutates user data: d3-hierarchy wraps inputs in HierarchyNodes and all derived
|
|
12
13
|
// fields (value overrides, ids, colors) are written onto the returned arcs only.
|
|
13
14
|
export function compute_sunburst_layout(data, opts = {}) {
|
|
14
|
-
const {
|
|
15
|
+
const {
|
|
16
|
+
// value_mode/min_fraction fallbacks derive from DEFAULTS.sunburst to prevent drift
|
|
17
|
+
value_mode = DEFAULTS.sunburst.value_mode, sort = `none`, level_lighten = 0, min_fraction = DEFAULTS.sunburst.min_fraction, other_label = `Other`, } = opts;
|
|
15
18
|
// Fresh object each call (not a shared constant) so callers can't corrupt each other
|
|
16
19
|
if (Array.isArray(data) ? data.length === 0 : !data) {
|
|
17
20
|
return { arcs: [], root: null, max_depth: 0 };
|
|
@@ -22,6 +22,6 @@ type $$ComponentProps = {
|
|
|
22
22
|
drag_dropped?: Crystal[];
|
|
23
23
|
dragging?: boolean;
|
|
24
24
|
} & ComponentProps<typeof ScatterPlot>;
|
|
25
|
-
declare const RdfPlot: import("svelte").Component<$$ComponentProps, {}, "loading" | "
|
|
25
|
+
declare const RdfPlot: import("svelte").Component<$$ComponentProps, {}, "loading" | "dragging" | "error_msg" | "drag_dropped">;
|
|
26
26
|
type RdfPlot = ReturnType<typeof RdfPlot>;
|
|
27
27
|
export default RdfPlot;
|
package/dist/sanitize.js
CHANGED
|
@@ -75,21 +75,32 @@ const stringify_html_input = (html) => {
|
|
|
75
75
|
return ``;
|
|
76
76
|
}
|
|
77
77
|
};
|
|
78
|
+
// Memoize by input: two DOMPurify passes per call are costly when a component re-sanitizes
|
|
79
|
+
// many cells on every render (e.g. HeatmapTable). Sanitization is deterministic for the
|
|
80
|
+
// fixed config, so caching is output-identical.
|
|
81
|
+
const sanitize_cache = new Map();
|
|
78
82
|
// Sanitize HTML string, allowing only safe formatting tags and links.
|
|
79
83
|
// Two-pass: happy-dom promotes dangerous children when a non-allowed parent is
|
|
80
84
|
// stripped (e.g. <div><script>…</script></div> → <script>…</script>). The first
|
|
81
85
|
// pass explicitly removes dangerous tags so they can't survive promotion.
|
|
82
86
|
export function sanitize_html(html) {
|
|
83
87
|
const str = stringify_html_input(html);
|
|
88
|
+
const cached = sanitize_cache.get(str);
|
|
89
|
+
if (cached !== undefined)
|
|
90
|
+
return cached;
|
|
84
91
|
const dp = get_purify();
|
|
85
92
|
if (!dp)
|
|
86
|
-
return str;
|
|
93
|
+
return str; // no DOM (SSR): return as-is, don't cache
|
|
87
94
|
// oxfmt-ignore
|
|
88
95
|
const safe = dp.sanitize(str, { ADD_ATTR: [`target`], FORBID_TAGS: [
|
|
89
96
|
`script`, `style`, `iframe`, `object`, `embed`, `form`, `input`, `textarea`,
|
|
90
97
|
`select`, `button`, `meta`, `link`, `base`, `template`, `noscript`,
|
|
91
98
|
] });
|
|
92
|
-
|
|
99
|
+
const result = dp.sanitize(safe, { ALLOWED_TAGS: SAFE_TAGS, ALLOWED_ATTR: SAFE_ATTRS });
|
|
100
|
+
if (sanitize_cache.size >= 4096)
|
|
101
|
+
sanitize_cache.clear(); // bound memory (rarely hit)
|
|
102
|
+
sanitize_cache.set(str, result);
|
|
103
|
+
return result;
|
|
93
104
|
}
|
|
94
105
|
export const compact_formula = (formula) => formula.replaceAll(/\s+/g, ``);
|
|
95
106
|
// Sanitize a chemical formula with optional subscript formatting
|