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
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
// Format: compact "001" for single-digit, spaced "10 0 1" for multi-digit
|
|
9
9
|
let hkl_text = $derived(
|
|
10
|
-
value.every((
|
|
10
|
+
value.every((component) => Math.abs(component) < 10) ? value.join(``) : value.join(` `),
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
// Parse hkl string: supports compact "001"/"-101" and spaced/comma "10, 0, 1"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
const spaced = input.trim().split(/[,\s]+/)
|
|
17
17
|
if (spaced.length === 3) {
|
|
18
18
|
const nums = spaced.map(Number)
|
|
19
|
-
if (nums.every((
|
|
19
|
+
if (nums.every((num) => !isNaN(num))) return nums as Vec3
|
|
20
20
|
}
|
|
21
21
|
// Fall back to compact single-digit format: "001", "-101"
|
|
22
22
|
const compact = input.replace(/\s+/g, ``)
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
return null
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
function
|
|
29
|
-
const parsed = parse_hkl(
|
|
28
|
+
function oninput(event: Event & { currentTarget: HTMLInputElement }) {
|
|
29
|
+
const parsed = parse_hkl(event.currentTarget.value)
|
|
30
30
|
if (parsed) value = parsed
|
|
31
31
|
}
|
|
32
32
|
</script>
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
<input
|
|
37
37
|
type="text"
|
|
38
38
|
value={hkl_text}
|
|
39
|
-
oninput
|
|
39
|
+
{oninput}
|
|
40
40
|
placeholder="001"
|
|
41
41
|
maxlength="12"
|
|
42
42
|
title="Miller indices (e.g. 001, -101, or 10 0 1)"
|
package/dist/api/optimade.js
CHANGED
|
@@ -102,10 +102,10 @@ export const decode_structure_id = (encoded_id) => decodeURIComponent(encoded_id
|
|
|
102
102
|
export function detect_provider_from_slug(slug, providers) {
|
|
103
103
|
const decoded_slug = decode_structure_id(slug);
|
|
104
104
|
const prefix = decoded_slug.split(`-`)[0].toLowerCase();
|
|
105
|
-
return providers.find((
|
|
105
|
+
return providers.find((provider) => provider.id === prefix)?.id ?? ``;
|
|
106
106
|
}
|
|
107
107
|
export async function fetch_optimade_structure(structure_id, provider, providers) {
|
|
108
|
-
const provider_config = providers.find((
|
|
108
|
+
const provider_config = providers.find((entry) => entry.id === provider);
|
|
109
109
|
if (!provider_config)
|
|
110
110
|
throw new Error(`Unknown provider: ${provider}`);
|
|
111
111
|
const base_url = await resolve_provider_url(provider_config.attributes.base_url);
|
|
@@ -118,7 +118,7 @@ export async function fetch_optimade_structure(structure_id, provider, providers
|
|
|
118
118
|
return Array.isArray(data.data) ? data.data[0] : data.data;
|
|
119
119
|
}
|
|
120
120
|
export async function fetch_suggested_structures(provider, providers, limit = 12) {
|
|
121
|
-
const provider_config = providers.find((
|
|
121
|
+
const provider_config = providers.find((entry) => entry.id === provider);
|
|
122
122
|
if (!provider_config)
|
|
123
123
|
throw new Error(`Unknown provider: ${provider}`);
|
|
124
124
|
try {
|
|
@@ -293,8 +293,11 @@
|
|
|
293
293
|
})
|
|
294
294
|
|
|
295
295
|
function onkeydown(event: KeyboardEvent) {
|
|
296
|
-
const target = event.target
|
|
297
|
-
if (
|
|
296
|
+
const target = event.target
|
|
297
|
+
if (
|
|
298
|
+
target instanceof HTMLElement &&
|
|
299
|
+
(target.tagName === `INPUT` || target.tagName === `TEXTAREA`)
|
|
300
|
+
) return
|
|
298
301
|
|
|
299
302
|
if (event.key === `f` && fullscreen_toggle) toggle_fullscreen(wrapper)
|
|
300
303
|
else if (event.key === `i`) info_pane_open = !info_pane_open
|
|
@@ -78,6 +78,6 @@ type $$ComponentProps = {
|
|
|
78
78
|
on_fullscreen_change?: (data: BZHandlerData) => void;
|
|
79
79
|
on_hover?: (data: BZHoverData | null) => void;
|
|
80
80
|
} & HTMLAttributes<HTMLDivElement>;
|
|
81
|
-
declare const BrillouinZone: import("svelte").Component<$$ComponentProps, {}, "structure" | "height" | "width" | "dragover" | "
|
|
81
|
+
declare const BrillouinZone: import("svelte").Component<$$ComponentProps, {}, "structure" | "height" | "width" | "dragover" | "loading" | "fullscreen" | "hovered" | "controls_open" | "camera_projection" | "vector_scale" | "info_pane_open" | "wrapper" | "png_dpi" | "error_msg" | "bz_order" | "surface_color" | "surface_opacity" | "edge_color" | "edge_width" | "show_vectors" | "show_ibz" | "ibz_color" | "ibz_opacity" | "bz_data" | "ibz_data">;
|
|
82
82
|
type BrillouinZone = ReturnType<typeof BrillouinZone>;
|
|
83
83
|
export default BrillouinZone;
|
|
@@ -102,9 +102,7 @@
|
|
|
102
102
|
</label>
|
|
103
103
|
|
|
104
104
|
<h4 id="export-as-data"
|
|
105
|
-
{@attach tooltip({
|
|
106
|
-
content: `Includes vertices, faces, edges, and reciprocal lattice vectors`,
|
|
107
|
-
})}
|
|
105
|
+
{@attach tooltip({ content: `Includes vertices, faces, edges, and reciprocal lattice vectors` })}
|
|
108
106
|
>
|
|
109
107
|
Export as data
|
|
110
108
|
</h4>
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
// Reciprocal Lattice section
|
|
95
95
|
const k_lattice_items: InfoItem[] = bz_data.k_lattice.map((vec, idx) => ({
|
|
96
96
|
label: [`b₁`, `b₂`, `b₃`][idx],
|
|
97
|
-
value: `(${vec.map((
|
|
97
|
+
value: `(${vec.map((coord) => format_num(coord, `.3~f`)).join(`, `)})`,
|
|
98
98
|
key: `reciprocal-${[`b1`, `b2`, `b3`][idx]}`,
|
|
99
99
|
}))
|
|
100
100
|
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
})
|
|
119
119
|
|
|
120
120
|
const computed_camera_position = $derived.by(() =>
|
|
121
|
-
camera_position || ([10, 3, 8].map((
|
|
121
|
+
camera_position || ([10, 3, 8].map((coord) => coord * Math.max(1, bz_size)) as Vec3)
|
|
122
122
|
)
|
|
123
123
|
|
|
124
124
|
const gizmo_props = $derived({
|
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
const e2: Vec3 = math.subtract(v2, v0)
|
|
190
190
|
const normal_vec = math.cross_3d(e1, e2)
|
|
191
191
|
const len = Math.hypot(...normal_vec)
|
|
192
|
-
const norm = len > 1e-10 ? normal_vec.map((
|
|
192
|
+
const norm = len > 1e-10 ? normal_vec.map((coord) => coord / len) : [0, 0, 0]
|
|
193
193
|
normals.push(...norm, ...norm, ...norm)
|
|
194
194
|
}
|
|
195
195
|
}
|
|
@@ -388,8 +388,8 @@
|
|
|
388
388
|
<!-- Reciprocal lattice vectors -->
|
|
389
389
|
{#if show_vectors && bz_data.k_lattice}
|
|
390
390
|
{#each bz_data.k_lattice as vec, idx (idx)}
|
|
391
|
-
{@const scaled_vec = vec.map((
|
|
392
|
-
{@const label_position = scaled_vec.map((
|
|
391
|
+
{@const scaled_vec = vec.map((coord) => coord * vector_scale) as Vec3}
|
|
392
|
+
{@const label_position = scaled_vec.map((coord) => coord * 1.15) as Vec3}
|
|
393
393
|
<Arrow
|
|
394
394
|
position={[0, 0, 0]}
|
|
395
395
|
vector={scaled_vec}
|
|
@@ -443,7 +443,7 @@
|
|
|
443
443
|
{#if k_path_labels}
|
|
444
444
|
{#each k_path_labels as { position, label }, idx (`${label}-${idx}`)}
|
|
445
445
|
{#if label}
|
|
446
|
-
<extras.HTML center position={position.map((
|
|
446
|
+
<extras.HTML center position={position.map((coord) => coord * 1.1) as Vec3}>
|
|
447
447
|
<span
|
|
448
448
|
style="background: rgba(0, 0, 0, 0.3); padding: 0 3px; border-radius: 2px; color: white"
|
|
449
449
|
>
|
|
@@ -8,9 +8,7 @@ const normalize = (vec) => {
|
|
|
8
8
|
return mag < 1e-10 ? [0, 0, 0] : [vec[0] / mag, vec[1] / mag, vec[2] / mag];
|
|
9
9
|
};
|
|
10
10
|
// Check if rotation matrix is identity
|
|
11
|
-
|
|
12
|
-
return rot.every((row, idx) => row.every((val, jdx) => Math.abs(val - (idx === jdx ? 1 : 0)) < TOL));
|
|
13
|
-
}
|
|
11
|
+
const is_identity_rotation = (rot) => rot.every((row, idx) => row.every((val, jdx) => Math.abs(val - (idx === jdx ? 1 : 0)) < TOL));
|
|
14
12
|
// Extract unique point group rotation matrices from space group operations.
|
|
15
13
|
// Returns fractional-coordinate rotations (W matrices from spglib convention).
|
|
16
14
|
// These must be converted to Cartesian k-space before use in clipping.
|
|
@@ -149,12 +147,12 @@ max_planes_by_order = { 1: 26, 2: 80, 3: 150 }) {
|
|
|
149
147
|
const dist_sq = pt[0] ** 2 + pt[1] ** 2 + pt[2] ** 2;
|
|
150
148
|
return { normal: normalize(pt), dist: Math.sqrt(dist_sq) / 2, dist_sq };
|
|
151
149
|
})
|
|
152
|
-
.filter((
|
|
150
|
+
.filter((plane) => plane !== null)
|
|
153
151
|
.sort((a, b) => a.dist_sq - b.dist_sq)
|
|
154
152
|
.slice(0, max_planes);
|
|
155
153
|
// Pre-compute plane data for fast access
|
|
156
|
-
const normals = planes.map((
|
|
157
|
-
const distances = planes.map((
|
|
154
|
+
const normals = planes.map((plane) => plane.normal);
|
|
155
|
+
const distances = planes.map((plane) => plane.dist);
|
|
158
156
|
const dedup = new VertexDeduplicator(TOL * 10);
|
|
159
157
|
const vertices = [];
|
|
160
158
|
// Test all three-plane intersections
|
|
@@ -203,7 +201,7 @@ export function compute_convex_hull(vertices, edge_sharp_angle_deg = 5) {
|
|
|
203
201
|
if (vertices.length < 4) {
|
|
204
202
|
throw new Error(`Need ≥4 vertices for convex hull, got ${vertices.length}`);
|
|
205
203
|
}
|
|
206
|
-
const geometry = new ConvexGeometry(vertices.map((
|
|
204
|
+
const geometry = new ConvexGeometry(vertices.map((vertex) => new Vector3(...vertex)));
|
|
207
205
|
const pos = geometry.getAttribute(`position`);
|
|
208
206
|
const geometry_index = geometry.index;
|
|
209
207
|
// Deduplicate vertices from Three.js geometry
|
|
@@ -211,9 +209,9 @@ export function compute_convex_hull(vertices, edge_sharp_angle_deg = 5) {
|
|
|
211
209
|
const vert_map = new Map();
|
|
212
210
|
for (let idx_vertex = 0; idx_vertex < pos.count; idx_vertex++) {
|
|
213
211
|
const vert = [pos.getX(idx_vertex), pos.getY(idx_vertex), pos.getZ(idx_vertex)];
|
|
214
|
-
const existing_idx = unique_verts.findIndex((
|
|
215
|
-
Math.abs(
|
|
216
|
-
Math.abs(
|
|
212
|
+
const existing_idx = unique_verts.findIndex((unique_vert) => Math.abs(unique_vert[0] - vert[0]) < TOL &&
|
|
213
|
+
Math.abs(unique_vert[1] - vert[1]) < TOL &&
|
|
214
|
+
Math.abs(unique_vert[2] - vert[2]) < TOL);
|
|
217
215
|
vert_map.set(idx_vertex, existing_idx === -1 ? unique_verts.push(vert) - 1 : existing_idx);
|
|
218
216
|
}
|
|
219
217
|
// Build faces with deduplicated vertex indices
|
|
@@ -227,23 +225,25 @@ export function compute_convex_hull(vertices, edge_sharp_angle_deg = 5) {
|
|
|
227
225
|
geometry_index.getX(idx_face * 3 + 2),
|
|
228
226
|
]
|
|
229
227
|
: [idx_face * 3, idx_face * 3 + 1, idx_face * 3 + 2];
|
|
230
|
-
faces.push(tri.map((
|
|
231
|
-
const mapped = vert_map.get(
|
|
228
|
+
faces.push(tri.map((vertex_idx) => {
|
|
229
|
+
const mapped = vert_map.get(vertex_idx);
|
|
232
230
|
if (mapped === undefined)
|
|
233
|
-
throw new Error(`Vertex ${
|
|
231
|
+
throw new Error(`Vertex ${vertex_idx} not mapped`);
|
|
234
232
|
return mapped;
|
|
235
233
|
}));
|
|
236
234
|
}
|
|
237
235
|
// Compute face normals and build edge-to-face adjacency
|
|
238
236
|
const face_normals = faces.map((face) => {
|
|
239
|
-
const [v0, v1, v2] = face.slice(0, 3).map((
|
|
237
|
+
const [v0, v1, v2] = face.slice(0, 3).map((vertex_idx) => unique_verts[vertex_idx]);
|
|
240
238
|
return normalize(math.cross_3d(math.subtract(v1, v0), math.subtract(v2, v0)));
|
|
241
239
|
});
|
|
242
240
|
const edge_to_faces = new Map();
|
|
243
241
|
faces.forEach((face, face_idx) => {
|
|
244
|
-
face.forEach((
|
|
245
|
-
const
|
|
246
|
-
const key =
|
|
242
|
+
face.forEach((from_vertex_idx, idx) => {
|
|
243
|
+
const to_vertex_idx = face[(idx + 1) % face.length];
|
|
244
|
+
const key = from_vertex_idx < to_vertex_idx
|
|
245
|
+
? `${from_vertex_idx},${to_vertex_idx}`
|
|
246
|
+
: `${to_vertex_idx},${from_vertex_idx}`;
|
|
247
247
|
const adj = edge_to_faces.get(key);
|
|
248
248
|
if (adj)
|
|
249
249
|
adj.push(face_idx);
|
|
@@ -322,14 +322,14 @@ export function compute_ibz_clipping_planes(point_group_ops) {
|
|
|
322
322
|
return planes;
|
|
323
323
|
}
|
|
324
324
|
// Flip a clipping plane to the opposite half-space
|
|
325
|
-
const flip_plane = (
|
|
326
|
-
normal: math.scale(
|
|
327
|
-
dist: -
|
|
325
|
+
const flip_plane = (plane) => ({
|
|
326
|
+
normal: math.scale(plane.normal, -1),
|
|
327
|
+
dist: -plane.dist,
|
|
328
328
|
});
|
|
329
329
|
// Clip polyhedron vertices by a half-space, adding intersection points where edges cross
|
|
330
330
|
function clip_polyhedron_by_plane(vertices, faces, plane) {
|
|
331
331
|
const { normal, dist } = plane;
|
|
332
|
-
const signed_dists = vertices.map((
|
|
332
|
+
const signed_dists = vertices.map((vertex) => math.dot(vertex, normal) - dist);
|
|
333
333
|
// Keep vertices inside the half-space
|
|
334
334
|
const result = vertices.filter((_, idx) => signed_dists[idx] <= TOL);
|
|
335
335
|
// Build edge set from faces
|
|
@@ -5,4 +5,4 @@ export { default as BrillouinZoneInfoPane } from './BrillouinZoneInfoPane.svelte
|
|
|
5
5
|
export { default as BrillouinZoneScene } from './BrillouinZoneScene.svelte';
|
|
6
6
|
export { default as BrillouinZoneTooltip } from './BrillouinZoneTooltip.svelte';
|
|
7
7
|
export * from './compute';
|
|
8
|
-
export * from './types';
|
|
8
|
+
export type * from './types';
|
package/dist/brillouin/index.js
CHANGED
|
@@ -5,4 +5,3 @@ export { default as BrillouinZoneInfoPane } from './BrillouinZoneInfoPane.svelte
|
|
|
5
5
|
export { default as BrillouinZoneScene } from './BrillouinZoneScene.svelte';
|
|
6
6
|
export { default as BrillouinZoneTooltip } from './BrillouinZoneTooltip.svelte';
|
|
7
7
|
export * from './compute';
|
|
8
|
-
export * from './types';
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import type { Matrix3x3, Vec3 } from '../math';
|
|
1
|
+
import type { Matrix3x3, Point2D, Vec3 } from '../math';
|
|
2
2
|
import type { Crystal } from '../structure';
|
|
3
3
|
import type { TooltipConfig, TooltipProp } from '../tooltip';
|
|
4
4
|
export type BZHoverData = {
|
|
5
5
|
position_cartesian: Vec3;
|
|
6
6
|
position_fractional: Vec3 | null;
|
|
7
|
-
screen_position:
|
|
8
|
-
x: number;
|
|
9
|
-
y: number;
|
|
10
|
-
};
|
|
7
|
+
screen_position: Point2D;
|
|
11
8
|
is_ibz: boolean;
|
|
12
9
|
bz_order: number;
|
|
13
10
|
bz_volume: number;
|
|
@@ -18,17 +15,16 @@ export type BZTooltipConfig = TooltipConfig<BZHoverData>;
|
|
|
18
15
|
export type BZTooltipProp = TooltipProp<BZHoverData, [{
|
|
19
16
|
hover_data: BZHoverData;
|
|
20
17
|
}]>;
|
|
21
|
-
|
|
18
|
+
type BZMeshData = {
|
|
22
19
|
vertices: Vec3[];
|
|
23
20
|
faces: number[][];
|
|
24
21
|
edges: Vec3[][];
|
|
22
|
+
};
|
|
23
|
+
export type IrreducibleBZData = BZMeshData & {
|
|
25
24
|
volume: number;
|
|
26
25
|
};
|
|
27
|
-
export type BrillouinZoneData = {
|
|
26
|
+
export type BrillouinZoneData = BZMeshData & {
|
|
28
27
|
order: number;
|
|
29
|
-
vertices: Vec3[];
|
|
30
|
-
faces: number[][];
|
|
31
|
-
edges: Vec3[][];
|
|
32
28
|
k_lattice: Matrix3x3;
|
|
33
29
|
volume: number;
|
|
34
30
|
};
|
|
@@ -41,8 +37,7 @@ export type BrillouinZoneProps = {
|
|
|
41
37
|
edge_width?: number;
|
|
42
38
|
show_vectors?: boolean;
|
|
43
39
|
};
|
|
44
|
-
export type ConvexHullData = {
|
|
45
|
-
vertices: Vec3[];
|
|
46
|
-
faces: number[][];
|
|
40
|
+
export type ConvexHullData = Pick<BZMeshData, `vertices` | `faces`> & {
|
|
47
41
|
edges: [number, number][];
|
|
48
42
|
};
|
|
43
|
+
export {};
|
|
@@ -233,9 +233,9 @@ const is_hover_info_3d = (value: ChemPotHoverInfo | null): value is ChemPotHover
|
|
|
233
233
|
<h5 id="neighbors">Neighbors ({hover_info.neighbors.length})</h5>
|
|
234
234
|
<p>
|
|
235
235
|
{
|
|
236
|
-
hover_info.neighbors.map((
|
|
237
|
-
|
|
238
|
-
)
|
|
236
|
+
hover_info.neighbors.map((formula) =>
|
|
237
|
+
get_electro_neg_formula(formula, true, ``, `.3~s`)
|
|
238
|
+
).join(`, `)
|
|
239
239
|
}
|
|
240
240
|
</p>
|
|
241
241
|
{/if}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import type { D3InterpolateName } from '../colors'
|
|
3
3
|
import { get_electro_neg_formula } from '../composition/format'
|
|
4
4
|
import { extract_formula_elements } from '../composition/parse'
|
|
5
5
|
import TemperatureSlider from '../convex-hull/TemperatureSlider.svelte'
|
|
@@ -433,9 +433,8 @@
|
|
|
433
433
|
let copy_status = $state(false)
|
|
434
434
|
let copy_timeout_id: ReturnType<typeof setTimeout> | null = null
|
|
435
435
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
}
|
|
436
|
+
const get_svg_element = (): SVGSVGElement | null =>
|
|
437
|
+
scatter_wrapper?.querySelector<SVGSVGElement>(`svg`) ?? null
|
|
439
438
|
|
|
440
439
|
function get_json_string(): string {
|
|
441
440
|
return JSON.stringify(
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
get_formula_label_segments,
|
|
6
|
-
type FormulaLabelSegment,
|
|
7
|
-
} from '../composition/format'
|
|
2
|
+
import type { D3InterpolateName } from '../colors'
|
|
3
|
+
import { get_electro_neg_formula, get_formula_label_segments } from '../composition/format'
|
|
4
|
+
import type { FormulaLabelSegment } from '../composition/format'
|
|
8
5
|
import { extract_formula_elements } from '../composition/parse'
|
|
9
6
|
import TemperatureSlider from '../convex-hull/TemperatureSlider.svelte'
|
|
10
7
|
import type { PhaseData } from '../convex-hull/types'
|
|
@@ -74,6 +71,9 @@
|
|
|
74
71
|
} from './types'
|
|
75
72
|
import { CHEMPOT_DEFAULTS } from './types'
|
|
76
73
|
|
|
74
|
+
const edge_key = (key_a: string, key_b: string): string =>
|
|
75
|
+
key_a < key_b ? `${key_a}|${key_b}` : `${key_b}|${key_a}`
|
|
76
|
+
|
|
77
77
|
let {
|
|
78
78
|
entries = [],
|
|
79
79
|
config = {},
|
|
@@ -153,9 +153,8 @@
|
|
|
153
153
|
: CHEMPOT_DEFAULTS.formula_colors,
|
|
154
154
|
)
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
156
|
+
const formula_label_segments = (formula: string): FormulaLabelSegment[] =>
|
|
157
|
+
get_formula_label_segments(get_electro_neg_formula(formula, true, ``, `.3~s`))
|
|
159
158
|
|
|
160
159
|
function normalize_projection_triplet(
|
|
161
160
|
maybe_triplet: string[] | undefined,
|
|
@@ -421,7 +420,11 @@
|
|
|
421
420
|
label_font_size: bbox_diagonal(padded),
|
|
422
421
|
})
|
|
423
422
|
}
|
|
424
|
-
const fonts = scale_to_font_range(
|
|
423
|
+
const fonts = scale_to_font_range(
|
|
424
|
+
result.map((render_domain) => render_domain.label_font_size),
|
|
425
|
+
9,
|
|
426
|
+
15,
|
|
427
|
+
)
|
|
425
428
|
for (let idx = 0; idx < result.length; idx++) result[idx].label_font_size = fonts[idx]
|
|
426
429
|
return result
|
|
427
430
|
})
|
|
@@ -792,8 +795,8 @@
|
|
|
792
795
|
// Compute edges in swizzled (Three.js) coords since ConvexGeometry works there
|
|
793
796
|
const swizzled = domain.points_3d.map((point) => to_render_xyz(point))
|
|
794
797
|
for (const [pa, pb] of get_domain_edges(swizzled)) {
|
|
795
|
-
const ka = pa.map((
|
|
796
|
-
const kb = pb.map((
|
|
798
|
+
const ka = pa.map((coord) => coord.toFixed(4)).join(`,`)
|
|
799
|
+
const kb = pb.map((coord) => coord.toFixed(4)).join(`,`)
|
|
797
800
|
const key = ka < kb ? `${ka}|${kb}` : `${kb}|${ka}`
|
|
798
801
|
if (seen.has(key)) continue
|
|
799
802
|
seen.add(key)
|
|
@@ -893,17 +896,17 @@
|
|
|
893
896
|
|
|
894
897
|
// Domain vertex centroids in render coords (swizzled + axis stretch), matching hull_base_geometry.
|
|
895
898
|
const centroids = render_domains
|
|
896
|
-
.filter((
|
|
897
|
-
.map((
|
|
899
|
+
.filter((domain) => !domain.is_draw_formula && domain.points_3d.length > 0)
|
|
900
|
+
.map((domain) => {
|
|
898
901
|
let sx = 0, sy = 0, sz = 0
|
|
899
|
-
for (const pt of
|
|
902
|
+
for (const pt of domain.points_3d) {
|
|
900
903
|
const [x_val, y_val, z_val] = to_render_xyz(pt)
|
|
901
904
|
sx += x_val
|
|
902
905
|
sy += y_val
|
|
903
906
|
sz += z_val
|
|
904
907
|
}
|
|
905
|
-
const
|
|
906
|
-
return { formula:
|
|
908
|
+
const n_points = domain.points_3d.length
|
|
909
|
+
return { formula: domain.formula, cx: sx / n_points, cy: sy / n_points, cz: sz / n_points }
|
|
907
910
|
})
|
|
908
911
|
|
|
909
912
|
// Assign each face to the nearest domain centroid
|
|
@@ -936,8 +939,6 @@
|
|
|
936
939
|
`${round(pos.getX(vert_idx))},${round(pos.getY(vert_idx))},${
|
|
937
940
|
round(pos.getZ(vert_idx))
|
|
938
941
|
}`
|
|
939
|
-
const ekey = (ka: string, kb: string): string =>
|
|
940
|
-
ka < kb ? `${ka}|${kb}` : `${kb}|${ka}`
|
|
941
942
|
// Compute face normals
|
|
942
943
|
const normals: Vec3[] = []
|
|
943
944
|
for (let face_idx = 0; face_idx < n_faces; face_idx++) {
|
|
@@ -961,9 +962,9 @@
|
|
|
961
962
|
const keys = [vkey(base), vkey(base + 1), vkey(base + 2)]
|
|
962
963
|
for (
|
|
963
964
|
const ek of [
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
965
|
+
edge_key(keys[0], keys[1]),
|
|
966
|
+
edge_key(keys[1], keys[2]),
|
|
967
|
+
edge_key(keys[0], keys[2]),
|
|
967
968
|
]
|
|
968
969
|
) {
|
|
969
970
|
const list = edge_faces.get(ek)
|
|
@@ -1132,9 +1133,8 @@
|
|
|
1132
1133
|
})
|
|
1133
1134
|
|
|
1134
1135
|
// Deduplicate 3D points within tolerance (reuses compute.ts dedup_points)
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
}
|
|
1136
|
+
const dedup_3d = (pts: number[][], tol: number = 1e-4): number[][] =>
|
|
1137
|
+
dedup_points(pts, tol).unique
|
|
1138
1138
|
|
|
1139
1139
|
const controls_series = $derived<DataSeries3D[]>([
|
|
1140
1140
|
{
|
|
@@ -1243,7 +1243,7 @@
|
|
|
1243
1243
|
if (unique_points.length === 3) {
|
|
1244
1244
|
const geom = new THREE.BufferGeometry()
|
|
1245
1245
|
const vectors = unique_points.map((pt) => to_vec3(pt))
|
|
1246
|
-
const verts = new Float32Array(vectors.flatMap((
|
|
1246
|
+
const verts = new Float32Array(vectors.flatMap((vec) => [vec.x, vec.y, vec.z]))
|
|
1247
1247
|
geom.setAttribute(`position`, new THREE.Float32BufferAttribute(verts, 3))
|
|
1248
1248
|
geom.setIndex([0, 1, 2, 2, 1, 0]) // both winding orders for double-sided pick
|
|
1249
1249
|
geom.computeVertexNormals()
|
|
@@ -1387,7 +1387,7 @@
|
|
|
1387
1387
|
|
|
1388
1388
|
// Bounding box of all data points in DATA coordinates (before swizzle)
|
|
1389
1389
|
const raw_data_bbox = $derived.by(() => {
|
|
1390
|
-
const pts = render_domains.flatMap((
|
|
1390
|
+
const pts = render_domains.flatMap((domain) => domain.points_3d)
|
|
1391
1391
|
if (pts.length === 0) return { mins: [0, 0, 0], maxs: [1, 1, 1] }
|
|
1392
1392
|
const mins = [Infinity, Infinity, Infinity]
|
|
1393
1393
|
const maxs = [-Infinity, -Infinity, -Infinity]
|
|
@@ -1486,11 +1486,10 @@
|
|
|
1486
1486
|
// Place axis label just past the outer end of the axis (the end closer to 0).
|
|
1487
1487
|
// In isometric 3D, the end near 0 projects outward at the front edge of the
|
|
1488
1488
|
// bounding box, while the negative end projects inward toward the center.
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
}
|
|
1489
|
+
const outer_end = (range: [number, number]): number =>
|
|
1490
|
+
Math.abs(range[0]) <= Math.abs(range[1]) ? range[0] : range[1]
|
|
1492
1491
|
// Direction from range center toward outer end (to extend the label beyond the grid)
|
|
1493
|
-
|
|
1492
|
+
const outer_direction = (range: [number, number]): number => {
|
|
1494
1493
|
const end = outer_end(range)
|
|
1495
1494
|
const mid = (range[0] + range[1]) / 2
|
|
1496
1495
|
return end >= mid ? 1 : -1
|
|
@@ -1524,7 +1523,7 @@
|
|
|
1524
1523
|
line_geom = make_line_geom(ls, le)
|
|
1525
1524
|
// Axis label past the outer end of the axis (near 0, projects outward)
|
|
1526
1525
|
label_pos = swiz(
|
|
1527
|
-
outer_end(r0) +
|
|
1526
|
+
outer_end(r0) + outer_direction(r0) * axis_label_dist,
|
|
1528
1527
|
back[1] + out_x * tick_label_dist * 0.5,
|
|
1529
1528
|
back[2] + out_y * tick_label_dist,
|
|
1530
1529
|
)
|
|
@@ -1555,7 +1554,7 @@
|
|
|
1555
1554
|
line_geom = make_line_geom(ls, le)
|
|
1556
1555
|
label_pos = swiz(
|
|
1557
1556
|
back[0],
|
|
1558
|
-
outer_end(r1) +
|
|
1557
|
+
outer_end(r1) + outer_direction(r1) * axis_label_dist,
|
|
1559
1558
|
back[2] + out_y * tick_label_dist,
|
|
1560
1559
|
)
|
|
1561
1560
|
for (const val of ticks) {
|
|
@@ -1582,7 +1581,7 @@
|
|
|
1582
1581
|
label_pos = swiz(
|
|
1583
1582
|
back[0],
|
|
1584
1583
|
back[1] + out_x * tick_label_dist,
|
|
1585
|
-
outer_end(r2) +
|
|
1584
|
+
outer_end(r2) + outer_direction(r2) * axis_label_dist,
|
|
1586
1585
|
)
|
|
1587
1586
|
for (const val of ticks) {
|
|
1588
1587
|
tick_geoms.push(make_line_geom(
|
|
@@ -12,7 +12,6 @@ const get_reduced_formula = (composition) => {
|
|
|
12
12
|
const amounts = Object.values(composition).filter((amt) => amt > 0);
|
|
13
13
|
if (amounts.length === 0)
|
|
14
14
|
return {};
|
|
15
|
-
// For fractional amounts, find smallest multiplier (1–100) that yields near-integer ratios
|
|
16
15
|
let scale = 1;
|
|
17
16
|
if (!amounts.every((amt) => Number.isInteger(amt))) {
|
|
18
17
|
scale = 0;
|
|
@@ -371,12 +370,7 @@ export function compute_domains(hyperplanes, border_hyperplanes, hyperplane_entr
|
|
|
371
370
|
if (!advance_combo())
|
|
372
371
|
break;
|
|
373
372
|
}
|
|
374
|
-
|
|
375
|
-
for (const key of Object.keys(domains)) {
|
|
376
|
-
if (domains[key].length === 0)
|
|
377
|
-
delete domains[key];
|
|
378
|
-
}
|
|
379
|
-
return domains;
|
|
373
|
+
return Object.fromEntries(Object.entries(domains).filter(([, domain]) => domain.length > 0));
|
|
380
374
|
}
|
|
381
375
|
// Apply element padding: replace coordinates close to default_min_limit with
|
|
382
376
|
// actual_min - padding for cleaner visual bounds. Single pass over all points.
|
|
@@ -9,7 +9,7 @@ export interface TempFilterPayload {
|
|
|
9
9
|
available_temperatures: number[];
|
|
10
10
|
temp_filtered_entries: PhaseData[];
|
|
11
11
|
}
|
|
12
|
-
export declare
|
|
12
|
+
export declare const get_projection_source_entries: (entries: PhaseData[], temp_filtered_entries: PhaseData[]) => PhaseData[];
|
|
13
13
|
export declare function get_temp_filter_payload(entries: PhaseData[], temperature: number | undefined, config: ChemPotDiagramConfig, props: TempFilterProps): TempFilterPayload;
|
|
14
14
|
export declare function get_valid_temperature(temperature: number | undefined, has_temp_data: boolean, available_temperatures: number[]): number | undefined;
|
|
15
15
|
export {};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { analyze_temperature_data, filter_entries_at_temperature, } from '../convex-hull/helpers';
|
|
2
2
|
import { CHEMPOT_DEFAULTS } from './types';
|
|
3
|
-
export
|
|
4
|
-
return temp_filtered_entries.length > 0 ? temp_filtered_entries : entries;
|
|
5
|
-
}
|
|
3
|
+
export const get_projection_source_entries = (entries, temp_filtered_entries) => (temp_filtered_entries.length > 0 ? temp_filtered_entries : entries);
|
|
6
4
|
const resolve_temp_filter_options = (config, props) => ({
|
|
7
5
|
interpolate: config.interpolate_temperature ??
|
|
8
6
|
props.interpolate_temperature ??
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { D3InterpolateName } from '../colors';
|
|
2
2
|
import type { PhaseData } from '../convex-hull/types';
|
|
3
|
+
import type { Point2D } from '../math';
|
|
3
4
|
export type ChemPotLimits = Partial<Record<string, [number, number]>>;
|
|
4
5
|
export type ChemPotColorMode = `none` | `energy` | `formation_energy` | `arity` | `entries`;
|
|
5
6
|
export type ChemPotProjectionMode = `single` | `grid`;
|
|
@@ -32,14 +33,12 @@ export interface ChemPotDiagramData {
|
|
|
32
33
|
hyperplane_entries: PhaseData[];
|
|
33
34
|
lims: [number, number][];
|
|
34
35
|
}
|
|
35
|
-
export interface ChemPotHoverPointer {
|
|
36
|
-
x: number;
|
|
37
|
-
y: number;
|
|
38
|
-
}
|
|
39
36
|
export interface ChemPotHoverInfoBase {
|
|
40
37
|
formula: string;
|
|
41
38
|
view: `2d` | `3d`;
|
|
42
|
-
pointer?:
|
|
39
|
+
pointer?: Point2D;
|
|
40
|
+
n_points: number;
|
|
41
|
+
axis_ranges: AxisRangeData[];
|
|
43
42
|
}
|
|
44
43
|
export interface AxisRangeData {
|
|
45
44
|
element: string;
|
|
@@ -48,16 +47,12 @@ export interface AxisRangeData {
|
|
|
48
47
|
}
|
|
49
48
|
export interface ChemPotHoverInfo2D extends ChemPotHoverInfoBase {
|
|
50
49
|
view: `2d`;
|
|
51
|
-
n_points: number;
|
|
52
|
-
axis_ranges: AxisRangeData[];
|
|
53
50
|
}
|
|
54
51
|
export interface ChemPotHoverInfo3D extends ChemPotHoverInfoBase {
|
|
55
52
|
view: `3d`;
|
|
56
53
|
n_vertices: number;
|
|
57
54
|
n_edges: number;
|
|
58
|
-
n_points: number;
|
|
59
55
|
ann_loc: number[];
|
|
60
|
-
axis_ranges: AxisRangeData[];
|
|
61
56
|
touches_limits: string[];
|
|
62
57
|
is_elemental: boolean;
|
|
63
58
|
is_draw_formula: boolean;
|
package/dist/colors/index.js
CHANGED
|
@@ -103,6 +103,7 @@ export function pick_contrast_color(options = {}) {
|
|
|
103
103
|
export const contrast_color = (options = {}) => (node) => {
|
|
104
104
|
node.style.color = pick_contrast_color({ ...options, bg_color: get_bg_color(node) });
|
|
105
105
|
};
|
|
106
|
+
const is_valid_bg = (bg) => bg !== `` && bg !== `rgba(0, 0, 0, 0)` && bg !== `transparent`;
|
|
106
107
|
// Detect and return the page background color from html/body elements or user preferences
|
|
107
108
|
export function get_page_background(fallback_dark = `#1a1a1a`, fallback_light = `#ffffff`) {
|
|
108
109
|
if (typeof window === `undefined`)
|
|
@@ -111,7 +112,6 @@ export function get_page_background(fallback_dark = `#1a1a1a`, fallback_light =
|
|
|
111
112
|
const html_bg = getComputedStyle(document.documentElement).backgroundColor;
|
|
112
113
|
const body_bg = getComputedStyle(document.body).backgroundColor;
|
|
113
114
|
// Check if background is not transparent/unset
|
|
114
|
-
const is_valid_bg = (bg) => bg && bg !== `rgba(0, 0, 0, 0)` && bg !== `transparent`;
|
|
115
115
|
// Prefer body background as it's more likely to be styled by the theme
|
|
116
116
|
if (is_valid_bg(body_bg))
|
|
117
117
|
return body_bg;
|
|
@@ -186,10 +186,10 @@ export function add_alpha(color, alpha) {
|
|
|
186
186
|
return color;
|
|
187
187
|
// Extract RGB, ignoring any existing alpha channel
|
|
188
188
|
const is_short = hex.length === 3 || hex.length === 4;
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
const
|
|
192
|
-
return `rgba(${
|
|
189
|
+
const red = parseInt(is_short ? hex[0] + hex[0] : hex.slice(0, 2), 16);
|
|
190
|
+
const green = parseInt(is_short ? hex[1] + hex[1] : hex.slice(2, 4), 16);
|
|
191
|
+
const blue = parseInt(is_short ? hex[2] + hex[2] : hex.slice(4, 6), 16);
|
|
192
|
+
return `rgba(${red}, ${green}, ${blue}, ${clamped_alpha})`;
|
|
193
193
|
}
|
|
194
194
|
// Handle rgb() colors
|
|
195
195
|
if (color.startsWith(`rgb(`)) {
|
|
@@ -135,7 +135,8 @@
|
|
|
135
135
|
onkeydown={(event: KeyboardEvent) => {
|
|
136
136
|
if ([`Enter`, ` `].includes(event.key)) {
|
|
137
137
|
event.preventDefault()
|
|
138
|
-
const target = event.currentTarget
|
|
138
|
+
const target = event.currentTarget
|
|
139
|
+
if (!(target instanceof Element)) return
|
|
139
140
|
const rect = target.getBoundingClientRect()
|
|
140
141
|
context_menu.x = window.scrollX + rect.left + rect.width / 2
|
|
141
142
|
context_menu.y = window.scrollY + rect.top + rect.height / 2
|