matterviz 0.3.5 → 0.3.7
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/MillerIndexInput.svelte +5 -5
- package/dist/api/optimade.js +3 -3
- package/dist/brillouin/BrillouinZone.svelte +5 -2
- package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneExportPane.svelte +1 -3
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +1 -1
- package/dist/brillouin/BrillouinZoneScene.svelte +5 -5
- package/dist/brillouin/compute.js +21 -21
- package/dist/brillouin/index.d.ts +1 -1
- package/dist/brillouin/index.js +0 -1
- package/dist/brillouin/types.d.ts +8 -13
- package/dist/chempot-diagram/ChemPotDiagram.svelte +3 -3
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +3 -4
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +33 -34
- package/dist/chempot-diagram/compute.js +1 -7
- package/dist/chempot-diagram/temperature.d.ts +1 -1
- package/dist/chempot-diagram/temperature.js +1 -3
- package/dist/chempot-diagram/types.d.ts +4 -9
- package/dist/colors/index.js +5 -5
- package/dist/composition/Composition.svelte +2 -1
- package/dist/composition/Formula.svelte +7 -4
- package/dist/composition/FormulaFilter.svelte +1 -3
- package/dist/composition/format.js +4 -4
- package/dist/composition/parse.d.ts +2 -1
- package/dist/composition/parse.js +61 -46
- package/dist/convex-hull/ConvexHull2D.svelte +62 -51
- package/dist/convex-hull/ConvexHull3D.svelte +101 -90
- package/dist/convex-hull/ConvexHull4D.svelte +70 -58
- package/dist/convex-hull/ConvexHullControls.svelte +24 -35
- package/dist/convex-hull/ConvexHullInfoPane.svelte +8 -5
- package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +2 -0
- package/dist/convex-hull/ConvexHullStats.svelte +9 -2
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +2 -0
- package/dist/convex-hull/GasPressureControls.svelte +7 -7
- package/dist/convex-hull/StructurePopup.svelte +65 -30
- package/dist/convex-hull/StructurePopup.svelte.d.ts +6 -6
- package/dist/convex-hull/TemperatureSlider.svelte +8 -5
- package/dist/convex-hull/barycentric-coords.d.ts +2 -2
- package/dist/convex-hull/barycentric-coords.js +2 -2
- package/dist/convex-hull/gas-thermodynamics.js +2 -4
- package/dist/convex-hull/helpers.d.ts +13 -2
- package/dist/convex-hull/helpers.js +37 -16
- package/dist/convex-hull/index.d.ts +1 -0
- package/dist/convex-hull/index.js +1 -0
- package/dist/convex-hull/thermodynamics.d.ts +2 -1
- package/dist/convex-hull/thermodynamics.js +7 -7
- package/dist/convex-hull/types.d.ts +15 -15
- package/dist/effects.svelte.d.ts +12 -0
- package/dist/effects.svelte.js +37 -0
- package/dist/element/BohrAtom.svelte +4 -4
- package/dist/element/data.json.gz.d.ts +3 -1
- package/dist/element/index.d.ts +1 -1
- package/dist/element/index.js +0 -1
- package/dist/fermi-surface/FermiSurface.svelte +4 -4
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceControls.svelte +15 -19
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +8 -6
- package/dist/fermi-surface/compute.js +2 -2
- package/dist/fermi-surface/export.js +13 -26
- package/dist/fermi-surface/parse.js +8 -12
- package/dist/fermi-surface/types.d.ts +2 -5
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +21 -3
- package/dist/heatmap-matrix/index.js +6 -6
- package/dist/io/decompress.d.ts +2 -1
- package/dist/io/decompress.js +1 -1
- package/dist/io/export.js +1 -1
- package/dist/io/index.d.ts +1 -1
- package/dist/io/index.js +0 -1
- package/dist/io/url-drop.js +7 -1
- package/dist/isosurface/IsosurfaceControls.svelte +11 -25
- package/dist/isosurface/slice.js +1 -1
- package/dist/isosurface/types.js +12 -12
- package/dist/labels.d.ts +1 -1
- package/dist/labels.js +14 -11
- package/dist/layout/InfoTag.svelte +6 -4
- package/dist/layout/PropertyFilter.svelte +4 -2
- package/dist/layout/json-tree/JsonTree.svelte +22 -14
- package/dist/layout/json-tree/JsonValue.svelte +2 -2
- package/dist/layout/json-tree/types.d.ts +3 -2
- package/dist/layout/json-tree/types.js +0 -1
- package/dist/layout/json-tree/utils.d.ts +4 -4
- package/dist/layout/json-tree/utils.js +12 -20
- package/dist/marching-cubes.js +13 -15
- package/dist/math.d.ts +11 -1
- package/dist/math.js +15 -6
- package/dist/overlays/DragControlTab.svelte +98 -0
- package/dist/overlays/DragControlTab.svelte.d.ts +8 -0
- package/dist/overlays/DraggablePane.svelte +7 -84
- package/dist/overlays/index.d.ts +1 -0
- package/dist/overlays/index.js +1 -0
- package/dist/periodic-table/PeriodicTable.svelte +11 -11
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +4 -2
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramControls.svelte +4 -9
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +2 -10
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +2 -3
- package/dist/phase-diagram/TdbInfoPanel.svelte +3 -3
- package/dist/phase-diagram/build-diagram.js +11 -18
- package/dist/phase-diagram/diagram-input.d.ts +5 -9
- package/dist/phase-diagram/index.d.ts +2 -2
- package/dist/phase-diagram/index.js +0 -2
- package/dist/phase-diagram/parse.d.ts +2 -2
- package/dist/phase-diagram/parse.js +6 -10
- package/dist/phase-diagram/svg-to-diagram.js +15 -15
- package/dist/phase-diagram/types.d.ts +5 -11
- package/dist/phase-diagram/utils.d.ts +2 -2
- package/dist/phase-diagram/utils.js +9 -11
- package/dist/plot/BarPlot.svelte +162 -314
- package/dist/plot/BarPlot.svelte.d.ts +5 -4
- package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
- package/dist/plot/BinnedScatterPlot.svelte +1114 -0
- package/dist/plot/BinnedScatterPlot.svelte.d.ts +66 -0
- package/dist/plot/ColorBar.svelte +19 -17
- package/dist/plot/ColorBar.svelte.d.ts +1 -1
- package/dist/plot/FillArea.svelte +2 -4
- package/dist/plot/FillArea.svelte.d.ts +1 -1
- package/dist/plot/Histogram.svelte +167 -281
- package/dist/plot/Histogram.svelte.d.ts +1 -1
- package/dist/plot/HistogramControls.svelte.d.ts +1 -1
- package/dist/plot/InteractiveAxisLabel.svelte +5 -3
- package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
- package/dist/plot/PlotAxis.svelte +169 -0
- package/dist/plot/PlotAxis.svelte.d.ts +24 -0
- package/dist/plot/PlotControls.svelte.d.ts +1 -1
- package/dist/plot/ReferenceLine3D.svelte +53 -51
- package/dist/plot/ReferencePlane.svelte +39 -42
- package/dist/plot/ScatterPlot.svelte +300 -367
- package/dist/plot/ScatterPlot.svelte.d.ts +8 -5
- package/dist/plot/ScatterPlot3D.svelte +33 -6
- package/dist/plot/ScatterPlot3D.svelte.d.ts +3 -2
- package/dist/plot/ScatterPlot3DControls.svelte +9 -9
- package/dist/plot/ScatterPlotControls.svelte +3 -4
- package/dist/plot/ScatterPoint.svelte +18 -27
- package/dist/plot/ScatterPoint.svelte.d.ts +4 -3
- package/dist/plot/Surface3D.svelte +4 -7
- package/dist/plot/ZeroLines.svelte +2 -1
- package/dist/plot/ZeroLines.svelte.d.ts +2 -1
- package/dist/plot/ZoomRect.svelte +2 -2
- package/dist/plot/ZoomRect.svelte.d.ts +3 -3
- package/dist/plot/adaptive-density.d.ts +69 -0
- package/dist/plot/adaptive-density.js +191 -0
- package/dist/plot/auto-place.d.ts +43 -0
- package/dist/plot/auto-place.js +122 -0
- package/dist/plot/axis-utils.js +3 -5
- package/dist/plot/binned-scatter-types.d.ts +59 -0
- package/dist/plot/binned-scatter-types.js +1 -0
- package/dist/plot/data-cleaning.js +1 -1
- package/dist/plot/data-transform.js +1 -1
- package/dist/plot/fill-utils.d.ts +4 -9
- package/dist/plot/fill-utils.js +29 -44
- package/dist/plot/index.d.ts +4 -0
- package/dist/plot/index.js +2 -0
- package/dist/plot/interactions.d.ts +4 -4
- package/dist/plot/interactions.js +4 -3
- package/dist/plot/layout.d.ts +20 -2
- package/dist/plot/layout.js +59 -16
- package/dist/plot/reference-line.d.ts +1 -1
- package/dist/plot/reference-line.js +9 -11
- package/dist/plot/scales.d.ts +1 -1
- package/dist/plot/scales.js +20 -23
- package/dist/plot/types.d.ts +30 -58
- package/dist/plot/types.js +2 -6
- package/dist/plot/utils/label-placement.d.ts +24 -3
- package/dist/plot/utils/label-placement.js +82 -12
- package/dist/plot/utils/series-visibility.d.ts +8 -2
- package/dist/plot/utils/series-visibility.js +23 -5
- package/dist/rdf/RdfPlot.svelte +5 -5
- package/dist/rdf/calc-rdf.js +3 -3
- package/dist/sanitize.d.ts +2 -0
- package/dist/sanitize.js +2 -0
- package/dist/spectral/Bands.svelte +1 -1
- package/dist/spectral/BandsAndDos.svelte +22 -16
- package/dist/spectral/BrillouinBandsDos.svelte +20 -16
- package/dist/spectral/Dos.svelte +1 -1
- package/dist/spectral/helpers.d.ts +4 -2
- package/dist/spectral/helpers.js +44 -35
- package/dist/spectral/index.d.ts +1 -1
- package/dist/spectral/index.js +0 -1
- package/dist/structure/AtomLegend.svelte +23 -6
- package/dist/structure/AtomLegend.svelte.d.ts +1 -0
- package/dist/structure/CanvasTooltip.svelte +9 -9
- package/dist/structure/CanvasTooltip.svelte.d.ts +1 -1
- package/dist/structure/CellSelect.svelte +14 -16
- package/dist/structure/Structure.svelte +317 -68
- package/dist/structure/Structure.svelte.d.ts +4 -2
- package/dist/structure/StructureControls.svelte +20 -45
- package/dist/structure/StructureExportPane.svelte +2 -1
- package/dist/structure/StructureInfoPane.svelte +10 -8
- package/dist/structure/StructureScene.svelte +527 -177
- package/dist/structure/StructureScene.svelte.d.ts +5 -2
- package/dist/structure/atom-properties.js +4 -4
- package/dist/structure/bond-order-perception.js +115 -98
- package/dist/structure/bonding.d.ts +27 -1
- package/dist/structure/bonding.js +187 -16
- package/dist/structure/export.js +1 -1
- package/dist/structure/index.d.ts +3 -2
- package/dist/structure/index.js +0 -2
- package/dist/structure/parse.js +88 -59
- package/dist/symmetry/WyckoffTable.svelte +7 -0
- package/dist/symmetry/index.js +13 -14
- package/dist/table/HeatmapTable.svelte +45 -66
- package/dist/table/HeatmapTable.svelte.d.ts +1 -1
- package/dist/table/ToggleMenu.svelte +19 -10
- package/dist/theme/themes.mjs +12 -0
- package/dist/tooltip/index.d.ts +1 -1
- package/dist/tooltip/index.js +0 -1
- package/dist/trajectory/Trajectory.svelte +43 -15
- package/dist/trajectory/TrajectoryInfoPane.svelte +2 -2
- package/dist/trajectory/extract.js +1 -1
- package/dist/trajectory/frame-reader.js +4 -4
- package/dist/trajectory/helpers.d.ts +5 -4
- package/dist/trajectory/helpers.js +9 -17
- package/dist/trajectory/index.d.ts +2 -2
- package/dist/trajectory/index.js +2 -2
- package/dist/trajectory/parse/ase.js +4 -4
- package/dist/trajectory/parse/hdf5.js +1 -1
- package/dist/trajectory/parse/index.js +2 -3
- package/dist/trajectory/parse/lammps.js +1 -1
- package/dist/trajectory/parse/vasp.js +1 -1
- package/dist/trajectory/plotting.d.ts +1 -1
- package/dist/trajectory/plotting.js +38 -38
- package/dist/trajectory/types.d.ts +1 -1
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +9 -0
- package/dist/xrd/calc-xrd.js +3 -4
- package/dist/xrd/parse.js +1 -1
- package/package.json +42 -22
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { format_value } from '../labels'
|
|
3
|
+
import AxisLabel from './AxisLabel.svelte'
|
|
4
|
+
import type { Sides } from './layout'
|
|
5
|
+
import type { AxisConfig } from './types'
|
|
6
|
+
import { DEFAULT_GRID_STYLE } from './types'
|
|
7
|
+
|
|
8
|
+
type Side = `x` | `x2` | `y` | `y2`
|
|
9
|
+
|
|
10
|
+
// Reusable single-axis renderer: baseline, per-tick (grid + tick mark + label), and AxisLabel.
|
|
11
|
+
// One <g class="{side}-axis"> with per-tick <g class="tick">; mirror the structure across all
|
|
12
|
+
// four sides so consumers (ScatterPlot/BarPlot/Histogram/BinnedScatterPlot) share one template.
|
|
13
|
+
let {
|
|
14
|
+
side,
|
|
15
|
+
ticks,
|
|
16
|
+
place,
|
|
17
|
+
axis = {},
|
|
18
|
+
pad,
|
|
19
|
+
width,
|
|
20
|
+
height,
|
|
21
|
+
show_grid = false,
|
|
22
|
+
show_baseline = true,
|
|
23
|
+
tick_label,
|
|
24
|
+
domain,
|
|
25
|
+
unit_on_first_tick = false,
|
|
26
|
+
label_x,
|
|
27
|
+
label_y,
|
|
28
|
+
axis_loading = false,
|
|
29
|
+
on_axis_change,
|
|
30
|
+
}: {
|
|
31
|
+
side: Side
|
|
32
|
+
ticks: number[]
|
|
33
|
+
place: (value: number) => number // data value -> pixel for this axis
|
|
34
|
+
axis?: AxisConfig
|
|
35
|
+
pad: Required<Sides>
|
|
36
|
+
width: number
|
|
37
|
+
height: number
|
|
38
|
+
show_grid?: boolean
|
|
39
|
+
show_baseline?: boolean // axis spine line (ScatterPlot omits it)
|
|
40
|
+
tick_label?: (tick: number) => string | null | undefined // custom/categorical label
|
|
41
|
+
domain?: [number, number] // when set, cull off-plot ticks and hide out-of-domain labels
|
|
42
|
+
unit_on_first_tick?: boolean // append axis.unit after the first tick label (ScatterPlot)
|
|
43
|
+
label_x?: number
|
|
44
|
+
label_y?: number
|
|
45
|
+
axis_loading?: boolean
|
|
46
|
+
on_axis_change?: (key: string) => void
|
|
47
|
+
} = $props()
|
|
48
|
+
|
|
49
|
+
const is_x = $derived(side === `x` || side === `x2`)
|
|
50
|
+
const inside = $derived(axis.tick?.label?.inside ?? false)
|
|
51
|
+
const rotation = $derived(axis.tick?.label?.rotation ?? 0)
|
|
52
|
+
const shift_x = $derived(axis.tick?.label?.shift?.x ?? 0)
|
|
53
|
+
const shift_y = $derived(axis.tick?.label?.shift?.y ?? 0)
|
|
54
|
+
const stroke = $derived(axis.color || `var(--border-color, gray)`)
|
|
55
|
+
const text_fill = $derived(axis.color || `var(--text-color)`)
|
|
56
|
+
const plot_w = $derived(width - pad.l - pad.r)
|
|
57
|
+
const plot_h = $derived(height - pad.b - pad.t)
|
|
58
|
+
const axis_y = $derived(side === `x` ? height - pad.b : pad.t) // baseline y for x/x2
|
|
59
|
+
const axis_x = $derived(side === `y` ? pad.l : width - pad.r) // baseline x for y/y2
|
|
60
|
+
|
|
61
|
+
const show_label = $derived(
|
|
62
|
+
Boolean(axis.label || axis.options?.length) && label_x != null && label_y != null,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
// Tick-invariant label geometry (depends only on side/inside/rotation/shift)
|
|
66
|
+
const text_x = $derived(
|
|
67
|
+
is_x ? shift_x : (side === `y` ? (inside ? 8 : -8) : (inside ? -8 : 8)) + shift_x,
|
|
68
|
+
)
|
|
69
|
+
const text_y = $derived(
|
|
70
|
+
is_x ? (side === `x` ? (inside ? -8 : 8) : (inside ? 8 : -8)) + shift_y : shift_y,
|
|
71
|
+
)
|
|
72
|
+
const text_anchor = $derived(
|
|
73
|
+
is_x
|
|
74
|
+
? (rotation === 0
|
|
75
|
+
? `middle`
|
|
76
|
+
: side === `x`
|
|
77
|
+
? (inside ? `end` : `start`)
|
|
78
|
+
: (inside ? `start` : `end`)) // x2 rotates opposite to x
|
|
79
|
+
: (side === `y` ? (inside ? `start` : `end`) : (inside ? `end` : `start`)),
|
|
80
|
+
)
|
|
81
|
+
const text_baseline = $derived(
|
|
82
|
+
is_x
|
|
83
|
+
? (side === `x` ? (inside ? `auto` : `hanging`) : (inside ? `hanging` : `auto`))
|
|
84
|
+
: `central`,
|
|
85
|
+
)
|
|
86
|
+
const text_transform = $derived(
|
|
87
|
+
rotation !== 0 ? `rotate(${rotation}, ${text_x}, ${text_y})` : undefined,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
// Tick-invariant line geometry within the per-tick group (origin sits on the axis).
|
|
91
|
+
// Keep tick marks' y1="0"/x1="0" explicit: BarPlot's grid test selects `.tick line:not([y1='0'])`.
|
|
92
|
+
const grid_line = $derived(
|
|
93
|
+
is_x
|
|
94
|
+
? (side === `x` ? { y1: -plot_h, y2: 0 } : { y1: 0, y2: plot_h })
|
|
95
|
+
: (side === `y` ? { x1: 0, x2: plot_w } : { x1: -plot_w, x2: 0 }),
|
|
96
|
+
)
|
|
97
|
+
const tick_mark = $derived(
|
|
98
|
+
is_x
|
|
99
|
+
? (side === `x`
|
|
100
|
+
? { y1: 0, y2: inside ? -5 : 5 }
|
|
101
|
+
: { y1: inside ? 0 : -5, y2: inside ? 5 : 0 })
|
|
102
|
+
: (side === `y`
|
|
103
|
+
? { x1: inside ? 0 : -5, x2: inside ? 5 : 0 }
|
|
104
|
+
: { x1: inside ? -5 : 0, x2: inside ? 0 : 5 }),
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
// ScatterPlot mode: cull ticks whose pixel pos is off-plot and hide labels outside the data domain
|
|
108
|
+
const in_domain = (tick: number): boolean =>
|
|
109
|
+
!domain || (tick >= Math.min(...domain) && tick <= Math.max(...domain))
|
|
110
|
+
const in_plot = (pos: number): boolean =>
|
|
111
|
+
!domain ||
|
|
112
|
+
(is_x ? pos >= pad.l && pos <= width - pad.r : pos >= pad.t && pos <= height - pad.b)
|
|
113
|
+
const tick_text = (tick: number): string =>
|
|
114
|
+
tick_label?.(tick) ?? format_value(tick, axis.format ?? ``)
|
|
115
|
+
</script>
|
|
116
|
+
|
|
117
|
+
<g class="{side}-axis">
|
|
118
|
+
{#if show_baseline}
|
|
119
|
+
{#if is_x}
|
|
120
|
+
<line x1={pad.l} x2={width - pad.r} y1={axis_y} y2={axis_y} {stroke} stroke-width="1" />
|
|
121
|
+
{:else}
|
|
122
|
+
<line x1={axis_x} x2={axis_x} y1={pad.t} y2={height - pad.b} {stroke} stroke-width="1" />
|
|
123
|
+
{/if}
|
|
124
|
+
{/if}
|
|
125
|
+
{#each ticks as tick, idx (tick)}
|
|
126
|
+
{@const pos = place(tick)}
|
|
127
|
+
{#if isFinite(pos) && in_plot(pos)}
|
|
128
|
+
<g class="tick" transform="translate({is_x ? pos : axis_x}, {is_x ? axis_y : pos})">
|
|
129
|
+
{#if show_grid}
|
|
130
|
+
<line {...grid_line} {...DEFAULT_GRID_STYLE} {...axis.grid_style} />
|
|
131
|
+
{/if}
|
|
132
|
+
<line {...tick_mark} {stroke} stroke-width="1" />
|
|
133
|
+
{#if in_domain(tick)}
|
|
134
|
+
<text
|
|
135
|
+
x={text_x}
|
|
136
|
+
y={text_y}
|
|
137
|
+
text-anchor={text_anchor}
|
|
138
|
+
dominant-baseline={text_baseline}
|
|
139
|
+
fill={text_fill}
|
|
140
|
+
transform={text_transform}
|
|
141
|
+
>
|
|
142
|
+
{tick_text(tick)}{#if unit_on_first_tick && idx === 0 && axis.unit}‌ {axis
|
|
143
|
+
.unit}{/if}
|
|
144
|
+
</text>
|
|
145
|
+
{/if}
|
|
146
|
+
</g>
|
|
147
|
+
{/if}
|
|
148
|
+
{/each}
|
|
149
|
+
{#if show_label}
|
|
150
|
+
<AxisLabel
|
|
151
|
+
x={label_x ?? 0}
|
|
152
|
+
y={label_y ?? 0}
|
|
153
|
+
rotate={side === `y` || side === `y2`}
|
|
154
|
+
label={axis.label ?? ``}
|
|
155
|
+
options={axis.options}
|
|
156
|
+
selected_key={axis.selected_key}
|
|
157
|
+
loading={axis_loading}
|
|
158
|
+
axis_type={side}
|
|
159
|
+
color={axis.color}
|
|
160
|
+
on_select={(key) => on_axis_change?.(key)}
|
|
161
|
+
/>
|
|
162
|
+
{/if}
|
|
163
|
+
</g>
|
|
164
|
+
|
|
165
|
+
<style>
|
|
166
|
+
.tick text {
|
|
167
|
+
font-size: var(--tick-font-size, 0.8em);
|
|
168
|
+
}
|
|
169
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Sides } from './layout';
|
|
2
|
+
import type { AxisConfig } from './types';
|
|
3
|
+
type Side = `x` | `x2` | `y` | `y2`;
|
|
4
|
+
type $$ComponentProps = {
|
|
5
|
+
side: Side;
|
|
6
|
+
ticks: number[];
|
|
7
|
+
place: (value: number) => number;
|
|
8
|
+
axis?: AxisConfig;
|
|
9
|
+
pad: Required<Sides>;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
show_grid?: boolean;
|
|
13
|
+
show_baseline?: boolean;
|
|
14
|
+
tick_label?: (tick: number) => string | null | undefined;
|
|
15
|
+
domain?: [number, number];
|
|
16
|
+
unit_on_first_tick?: boolean;
|
|
17
|
+
label_x?: number;
|
|
18
|
+
label_y?: number;
|
|
19
|
+
axis_loading?: boolean;
|
|
20
|
+
on_axis_change?: (key: string) => void;
|
|
21
|
+
};
|
|
22
|
+
declare const PlotAxis: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
23
|
+
type PlotAxis = ReturnType<typeof PlotAxis>;
|
|
24
|
+
export default PlotAxis;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { PlotControlsProps } from './index';
|
|
2
|
-
declare const PlotControls: import("svelte").Component<PlotControlsProps, {}, "display" | "show_controls" | "
|
|
2
|
+
declare const PlotControls: import("svelte").Component<PlotControlsProps, {}, "display" | "show_controls" | "x_axis" | "y_axis" | "controls_open" | "x2_axis" | "y2_axis">;
|
|
3
3
|
type PlotControls = ReturnType<typeof PlotControls>;
|
|
4
4
|
export default PlotControls;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
// ReferenceLine3D: 3D reference lines for axis-parallel, segments, and extended lines
|
|
3
3
|
// Uses Line2 for proper variable-width lines (WebGL ignores linewidth on basic lines)
|
|
4
|
-
import type { Vec3 } from '../math'
|
|
4
|
+
import type { Point3D, Vec3 } from '../math'
|
|
5
5
|
import { T, useThrelte } from '@threlte/core'
|
|
6
6
|
import * as THREE from 'three'
|
|
7
7
|
import { Line2 } from 'three/examples/jsm/lines/Line2.js'
|
|
@@ -32,66 +32,68 @@
|
|
|
32
32
|
})
|
|
33
33
|
return (ux: number, uy: number, uz: number) => transform(ux, uy, uz)
|
|
34
34
|
})
|
|
35
|
+
const endpoints_from = (point_a: Vec3, point_b: Vec3): [Point3D, Point3D] => [
|
|
36
|
+
to_coords(...point_a),
|
|
37
|
+
to_coords(...point_b),
|
|
38
|
+
]
|
|
35
39
|
|
|
36
40
|
// Compute line endpoints based on type
|
|
37
41
|
let endpoints = $derived.by(
|
|
38
|
-
():
|
|
39
|
-
| [{ x: number; y: number; z: number }, { x: number; y: number; z: number }]
|
|
40
|
-
| null => {
|
|
42
|
+
(): [Point3D, Point3D] | null => {
|
|
41
43
|
if (ref_line.visible === false) return null
|
|
42
44
|
const [x_min, x_max] = span_or(ref_line.x_span, x_range)
|
|
43
45
|
const [y_min, y_max] = span_or(ref_line.y_span, y_range)
|
|
44
46
|
const [z_min, z_max] = span_or(ref_line.z_span, z_range)
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const eps = 1e-6
|
|
80
|
-
const valid_t = t_values.filter((t) => {
|
|
81
|
-
const [px, py, pz] = [p1x + t * dx, p1y + t * dy, p1z + t * dz]
|
|
82
|
-
return px >= x_min - eps && px <= x_max + eps &&
|
|
83
|
-
py >= y_min - eps && py <= y_max + eps && pz >= z_min - eps &&
|
|
84
|
-
pz <= z_max + eps
|
|
85
|
-
})
|
|
86
|
-
if (valid_t.length < 2) return null
|
|
87
|
-
const t_min = Math.min(...valid_t)
|
|
88
|
-
const t_max = Math.max(...valid_t)
|
|
89
|
-
return [
|
|
90
|
-
to_coords(p1x + t_min * dx, p1y + t_min * dy, p1z + t_min * dz),
|
|
91
|
-
to_coords(p1x + t_max * dx, p1y + t_max * dy, p1z + t_max * dz),
|
|
48
|
+
if (ref_line.type === `x-axis`) {
|
|
49
|
+
return endpoints_from([x_min, ref_line.y, ref_line.z], [x_max, ref_line.y, ref_line.z])
|
|
50
|
+
}
|
|
51
|
+
if (ref_line.type === `y-axis`) {
|
|
52
|
+
return endpoints_from([ref_line.x, y_min, ref_line.z], [ref_line.x, y_max, ref_line.z])
|
|
53
|
+
}
|
|
54
|
+
if (ref_line.type === `z-axis`) {
|
|
55
|
+
return endpoints_from([ref_line.x, ref_line.y, z_min], [ref_line.x, ref_line.y, z_max])
|
|
56
|
+
}
|
|
57
|
+
if (ref_line.type === `segment`) {
|
|
58
|
+
return endpoints_from(ref_line.p1, ref_line.p2)
|
|
59
|
+
}
|
|
60
|
+
if (ref_line.type === `line`) {
|
|
61
|
+
// Extend line through two points to bounding box
|
|
62
|
+
const [p1x, p1y, p1z] = ref_line.p1
|
|
63
|
+
const [dx, dy, dz] = [
|
|
64
|
+
ref_line.p2[0] - p1x,
|
|
65
|
+
ref_line.p2[1] - p1y,
|
|
66
|
+
ref_line.p2[2] - p1z,
|
|
67
|
+
]
|
|
68
|
+
// Find t values at each boundary plane
|
|
69
|
+
const t_values = [
|
|
70
|
+
...(dx !== 0 ? [(x_min - p1x) / dx, (x_max - p1x) / dx] : []),
|
|
71
|
+
...(dy !== 0 ? [(y_min - p1y) / dy, (y_max - p1y) / dy] : []),
|
|
72
|
+
...(dz !== 0 ? [(z_min - p1z) / dz, (z_max - p1z) / dz] : []),
|
|
73
|
+
]
|
|
74
|
+
// Keep only t values where the resulting point is inside bounds
|
|
75
|
+
const eps = 1e-6
|
|
76
|
+
const valid_t = t_values.filter((t_value) => {
|
|
77
|
+
const [px, py, pz] = [
|
|
78
|
+
p1x + t_value * dx,
|
|
79
|
+
p1y + t_value * dy,
|
|
80
|
+
p1z + t_value * dz,
|
|
92
81
|
]
|
|
93
|
-
|
|
82
|
+
return (
|
|
83
|
+
px >= x_min - eps && px <= x_max + eps &&
|
|
84
|
+
py >= y_min - eps && py <= y_max + eps &&
|
|
85
|
+
pz >= z_min - eps && pz <= z_max + eps
|
|
86
|
+
)
|
|
87
|
+
})
|
|
88
|
+
if (valid_t.length < 2) return null
|
|
89
|
+
const t_min = Math.min(...valid_t)
|
|
90
|
+
const t_max = Math.max(...valid_t)
|
|
91
|
+
return endpoints_from(
|
|
92
|
+
[p1x + t_min * dx, p1y + t_min * dy, p1z + t_min * dz],
|
|
93
|
+
[p1x + t_max * dx, p1y + t_max * dy, p1z + t_max * dz],
|
|
94
|
+
)
|
|
94
95
|
}
|
|
96
|
+
return null
|
|
95
97
|
},
|
|
96
98
|
)
|
|
97
99
|
|
|
@@ -45,49 +45,46 @@
|
|
|
45
45
|
function compute_geometry(): THREE.BufferGeometry | null {
|
|
46
46
|
if (ref_plane.visible === false) return null
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
])
|
|
57
|
-
}
|
|
58
|
-
case `xz`: {
|
|
59
|
-
const yval = ref_plane.y
|
|
60
|
-
return quad([
|
|
61
|
-
[x_min, yval, z_min],
|
|
62
|
-
[x_max, yval, z_min],
|
|
63
|
-
[x_max, yval, z_max],
|
|
64
|
-
[x_min, yval, z_max],
|
|
65
|
-
])
|
|
66
|
-
}
|
|
67
|
-
case `yz`: {
|
|
68
|
-
const xval = ref_plane.x
|
|
69
|
-
return quad([
|
|
70
|
-
[xval, y_min, z_min],
|
|
71
|
-
[xval, y_max, z_min],
|
|
72
|
-
[xval, y_max, z_max],
|
|
73
|
-
[xval, y_min, z_max],
|
|
74
|
-
])
|
|
75
|
-
}
|
|
76
|
-
case `normal`: {
|
|
77
|
-
if (Math.hypot(...ref_plane.normal) < 1e-9) return null // degenerate normal
|
|
78
|
-
return create_plane_from_normal(ref_plane.normal, ref_plane.point)
|
|
79
|
-
}
|
|
80
|
-
case `points`: {
|
|
81
|
-
const { p1, p2, p3 } = ref_plane
|
|
82
|
-
const v1: Vec3 = [p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]]
|
|
83
|
-
const v2: Vec3 = [p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]]
|
|
84
|
-
const cross = cross_3d(v1, v2)
|
|
85
|
-
if (Math.hypot(...cross) < 1e-9) return null // collinear points
|
|
86
|
-
return create_plane_from_normal(normalize_vec3(cross), p1)
|
|
87
|
-
}
|
|
88
|
-
default:
|
|
89
|
-
return null
|
|
48
|
+
if (ref_plane.type === `xy`) {
|
|
49
|
+
const zval = ref_plane.z
|
|
50
|
+
return quad([
|
|
51
|
+
[x_min, y_min, zval],
|
|
52
|
+
[x_max, y_min, zval],
|
|
53
|
+
[x_max, y_max, zval],
|
|
54
|
+
[x_min, y_max, zval],
|
|
55
|
+
])
|
|
90
56
|
}
|
|
57
|
+
if (ref_plane.type === `xz`) {
|
|
58
|
+
const yval = ref_plane.y
|
|
59
|
+
return quad([
|
|
60
|
+
[x_min, yval, z_min],
|
|
61
|
+
[x_max, yval, z_min],
|
|
62
|
+
[x_max, yval, z_max],
|
|
63
|
+
[x_min, yval, z_max],
|
|
64
|
+
])
|
|
65
|
+
}
|
|
66
|
+
if (ref_plane.type === `yz`) {
|
|
67
|
+
const xval = ref_plane.x
|
|
68
|
+
return quad([
|
|
69
|
+
[xval, y_min, z_min],
|
|
70
|
+
[xval, y_max, z_min],
|
|
71
|
+
[xval, y_max, z_max],
|
|
72
|
+
[xval, y_min, z_max],
|
|
73
|
+
])
|
|
74
|
+
}
|
|
75
|
+
if (ref_plane.type === `normal`) {
|
|
76
|
+
if (Math.hypot(...ref_plane.normal) < 1e-9) return null // degenerate normal
|
|
77
|
+
return create_plane_from_normal(ref_plane.normal, ref_plane.point)
|
|
78
|
+
}
|
|
79
|
+
if (ref_plane.type === `points`) {
|
|
80
|
+
const { p1, p2, p3 } = ref_plane
|
|
81
|
+
const v1: Vec3 = [p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]]
|
|
82
|
+
const v2: Vec3 = [p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]]
|
|
83
|
+
const cross = cross_3d(v1, v2)
|
|
84
|
+
if (Math.hypot(...cross) < 1e-9) return null // collinear points
|
|
85
|
+
return create_plane_from_normal(normalize_vec3(cross), p1)
|
|
86
|
+
}
|
|
87
|
+
return null
|
|
91
88
|
}
|
|
92
89
|
|
|
93
90
|
// Create geometry with proper disposal on dependency change
|