matterviz 0.1.0
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/BohrAtom.svelte +105 -0
- package/dist/BohrAtom.svelte.d.ts +21 -0
- package/dist/ControlPanel.svelte +158 -0
- package/dist/ControlPanel.svelte.d.ts +18 -0
- package/dist/Icon.svelte +23 -0
- package/dist/Icon.svelte.d.ts +8 -0
- package/dist/InfoCard.svelte +79 -0
- package/dist/InfoCard.svelte.d.ts +23 -0
- package/dist/Nucleus.svelte +64 -0
- package/dist/Nucleus.svelte.d.ts +16 -0
- package/dist/Spinner.svelte +44 -0
- package/dist/Spinner.svelte.d.ts +7 -0
- package/dist/api.d.ts +6 -0
- package/dist/api.js +30 -0
- package/dist/colors/alloy-colors.json +111 -0
- package/dist/colors/dark-mode-colors.json +111 -0
- package/dist/colors/index.d.ts +26 -0
- package/dist/colors/index.js +72 -0
- package/dist/colors/jmol-colors.json +111 -0
- package/dist/colors/muted-colors.json +111 -0
- package/dist/colors/pastel-colors.json +111 -0
- package/dist/colors/vesta-colors.json +111 -0
- package/dist/composition/BarChart.svelte +260 -0
- package/dist/composition/BarChart.svelte.d.ts +33 -0
- package/dist/composition/BubbleChart.svelte +166 -0
- package/dist/composition/BubbleChart.svelte.d.ts +30 -0
- package/dist/composition/Composition.svelte +73 -0
- package/dist/composition/Composition.svelte.d.ts +27 -0
- package/dist/composition/PieChart.svelte +236 -0
- package/dist/composition/PieChart.svelte.d.ts +36 -0
- package/dist/composition/index.d.ts +5 -0
- package/dist/composition/index.js +5 -0
- package/dist/composition/parse.d.ts +14 -0
- package/dist/composition/parse.js +307 -0
- package/dist/element/ElementHeading.svelte +21 -0
- package/dist/element/ElementHeading.svelte.d.ts +8 -0
- package/dist/element/ElementPhoto.svelte +56 -0
- package/dist/element/ElementPhoto.svelte.d.ts +9 -0
- package/dist/element/ElementStats.svelte +73 -0
- package/dist/element/ElementStats.svelte.d.ts +8 -0
- package/dist/element/ElementTile.svelte +449 -0
- package/dist/element/ElementTile.svelte.d.ts +25 -0
- package/dist/element/data.d.ts +4958 -0
- package/dist/element/data.js +5628 -0
- package/dist/element/index.d.ts +4 -0
- package/dist/element/index.js +4 -0
- package/dist/icons.d.ts +435 -0
- package/dist/icons.js +435 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.js +43 -0
- package/dist/io/decompress.d.ts +16 -0
- package/dist/io/decompress.js +78 -0
- package/dist/io/export.d.ts +9 -0
- package/dist/io/export.js +205 -0
- package/dist/io/parse.d.ts +53 -0
- package/dist/io/parse.js +747 -0
- package/dist/labels.d.ts +31 -0
- package/dist/labels.js +209 -0
- package/dist/material/MaterialCard.svelte +135 -0
- package/dist/material/MaterialCard.svelte.d.ts +10 -0
- package/dist/material/SymmetryCard.svelte +23 -0
- package/dist/material/SymmetryCard.svelte.d.ts +9 -0
- package/dist/material/index.d.ts +2 -0
- package/dist/material/index.js +2 -0
- package/dist/math.d.ts +24 -0
- package/dist/math.js +216 -0
- package/dist/periodic-table/PeriodicTable.svelte +284 -0
- package/dist/periodic-table/PeriodicTable.svelte.d.ts +50 -0
- package/dist/periodic-table/PropertySelect.svelte +20 -0
- package/dist/periodic-table/PropertySelect.svelte.d.ts +13 -0
- package/dist/periodic-table/TableInset.svelte +18 -0
- package/dist/periodic-table/TableInset.svelte.d.ts +9 -0
- package/dist/periodic-table/index.d.ts +9 -0
- package/dist/periodic-table/index.js +3 -0
- package/dist/plot/ColorBar.svelte +414 -0
- package/dist/plot/ColorBar.svelte.d.ts +22 -0
- package/dist/plot/ColorScaleSelect.svelte +31 -0
- package/dist/plot/ColorScaleSelect.svelte.d.ts +15 -0
- package/dist/plot/ElementScatter.svelte +38 -0
- package/dist/plot/ElementScatter.svelte.d.ts +14 -0
- package/dist/plot/Line.svelte +42 -0
- package/dist/plot/Line.svelte.d.ts +15 -0
- package/dist/plot/PlotLegend.svelte +206 -0
- package/dist/plot/PlotLegend.svelte.d.ts +18 -0
- package/dist/plot/ScatterPlot.svelte +1753 -0
- package/dist/plot/ScatterPlot.svelte.d.ts +114 -0
- package/dist/plot/ScatterPlotControls.svelte +505 -0
- package/dist/plot/ScatterPlotControls.svelte.d.ts +33 -0
- package/dist/plot/ScatterPoint.svelte +72 -0
- package/dist/plot/ScatterPoint.svelte.d.ts +17 -0
- package/dist/plot/index.d.ts +168 -0
- package/dist/plot/index.js +46 -0
- package/dist/state.svelte.d.ts +12 -0
- package/dist/state.svelte.js +11 -0
- package/dist/structure/Bond.svelte +68 -0
- package/dist/structure/Bond.svelte.d.ts +13 -0
- package/dist/structure/Lattice.svelte +115 -0
- package/dist/structure/Lattice.svelte.d.ts +15 -0
- package/dist/structure/Structure.svelte +298 -0
- package/dist/structure/Structure.svelte.d.ts +28 -0
- package/dist/structure/StructureCard.svelte +26 -0
- package/dist/structure/StructureCard.svelte.d.ts +9 -0
- package/dist/structure/StructureControls.svelte +383 -0
- package/dist/structure/StructureControls.svelte.d.ts +23 -0
- package/dist/structure/StructureLegend.svelte +130 -0
- package/dist/structure/StructureLegend.svelte.d.ts +17 -0
- package/dist/structure/StructureScene.svelte +331 -0
- package/dist/structure/StructureScene.svelte.d.ts +47 -0
- package/dist/structure/bonding.d.ts +16 -0
- package/dist/structure/bonding.js +150 -0
- package/dist/structure/index.d.ts +98 -0
- package/dist/structure/index.js +114 -0
- package/dist/structure/pbc.d.ts +6 -0
- package/dist/structure/pbc.js +72 -0
- package/dist/trajectory/Sidebar.svelte +412 -0
- package/dist/trajectory/Sidebar.svelte.d.ts +14 -0
- package/dist/trajectory/Trajectory.svelte +1084 -0
- package/dist/trajectory/Trajectory.svelte.d.ts +49 -0
- package/dist/trajectory/TrajectoryError.svelte +120 -0
- package/dist/trajectory/TrajectoryError.svelte.d.ts +12 -0
- package/dist/trajectory/extract.d.ts +5 -0
- package/dist/trajectory/extract.js +157 -0
- package/dist/trajectory/index.d.ts +16 -0
- package/dist/trajectory/index.js +49 -0
- package/dist/trajectory/parse.d.ts +13 -0
- package/dist/trajectory/parse.js +1093 -0
- package/dist/trajectory/plotting.d.ts +12 -0
- package/dist/trajectory/plotting.js +148 -0
- package/license +21 -0
- package/package.json +131 -0
- package/readme.md +95 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
<script lang="ts">import { get_elem_amounts, get_pbc_image_sites, Icon } from '..';
|
|
2
|
+
import { element_color_schemes } from '../colors';
|
|
3
|
+
import { decompress_file } from '../io/decompress';
|
|
4
|
+
import * as exports from '../io/export';
|
|
5
|
+
import { colors } from '../state.svelte';
|
|
6
|
+
import { Canvas } from '@threlte/core';
|
|
7
|
+
import { WebGLRenderer } from 'three';
|
|
8
|
+
import { BOND_DEFAULTS, CELL_DEFAULTS, StructureControls, StructureLegend, StructureScene, } from './index';
|
|
9
|
+
let { structure = $bindable(undefined), scene_props = $bindable({ atom_radius: 1, show_atoms: true, auto_rotate: 0 }), lattice_props = $bindable({
|
|
10
|
+
cell_edge_opacity: CELL_DEFAULTS.edge_opacity,
|
|
11
|
+
cell_surface_opacity: CELL_DEFAULTS.surface_opacity,
|
|
12
|
+
cell_edge_color: CELL_DEFAULTS.color,
|
|
13
|
+
cell_surface_color: CELL_DEFAULTS.color,
|
|
14
|
+
cell_line_width: CELL_DEFAULTS.line_width,
|
|
15
|
+
show_vectors: true,
|
|
16
|
+
}), controls_open = $bindable(false), background_color = $bindable(`#ffffff`), background_opacity = $bindable(0.1), reveal_buttons = 500, fullscreen = false, wrapper = $bindable(undefined), width = $bindable(0), height = $bindable(0), reset_text = `Reset camera`, color_scheme = $bindable(`Vesta`), hovered = $bindable(false), dragover = $bindable(false), allow_file_drop = true, tips_modal = $bindable(undefined), enable_tips = true, save_json_btn_text = `⬇ Save as JSON`, save_png_btn_text = `✎ Save as PNG`, save_xyz_btn_text = `📄 Save as XYZ`, png_dpi = $bindable(150), show_site_labels = $bindable(false), show_image_atoms = $bindable(true), show_full_controls = $bindable(false), tips_icon, fullscreen_toggle = true, bottom_left, on_file_drop, max_text_size = 5 * 1024 * 1024, // 5 MB default
|
|
17
|
+
...rest } = $props();
|
|
18
|
+
// Ensure scene_props always has some defaults merged in
|
|
19
|
+
$effect.pre(() => {
|
|
20
|
+
scene_props = {
|
|
21
|
+
atom_radius: 1,
|
|
22
|
+
show_atoms: true,
|
|
23
|
+
auto_rotate: 0,
|
|
24
|
+
bond_thickness: BOND_DEFAULTS.thickness,
|
|
25
|
+
...scene_props,
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
$effect.pre(() => {
|
|
29
|
+
colors.element = element_color_schemes[color_scheme];
|
|
30
|
+
});
|
|
31
|
+
let visible_buttons = $derived(reveal_buttons == true ||
|
|
32
|
+
(typeof reveal_buttons == `number` && reveal_buttons < width));
|
|
33
|
+
// only updates when structure or show_image_atoms change
|
|
34
|
+
let scene_structure = $derived(show_image_atoms && structure && `lattice` in structure
|
|
35
|
+
? get_pbc_image_sites(structure)
|
|
36
|
+
: structure);
|
|
37
|
+
// Track if camera has ever been moved from initial position
|
|
38
|
+
let camera_has_moved = $state(false);
|
|
39
|
+
let camera_is_moving = $state(false);
|
|
40
|
+
// Reset tracking when structure changes
|
|
41
|
+
$effect(() => {
|
|
42
|
+
if (structure)
|
|
43
|
+
camera_has_moved = false;
|
|
44
|
+
});
|
|
45
|
+
// Set camera_has_moved to true when camera starts moving
|
|
46
|
+
$effect(() => {
|
|
47
|
+
if (camera_is_moving)
|
|
48
|
+
camera_has_moved = true;
|
|
49
|
+
});
|
|
50
|
+
function reset_camera() {
|
|
51
|
+
// Reset camera position to trigger automatic positioning
|
|
52
|
+
scene_props.camera_position = [0, 0, 0];
|
|
53
|
+
camera_has_moved = false;
|
|
54
|
+
}
|
|
55
|
+
async function handle_file_drop(event) {
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
dragover = false;
|
|
58
|
+
if (!allow_file_drop)
|
|
59
|
+
return;
|
|
60
|
+
// Check for our custom internal file format first
|
|
61
|
+
const internal_data = event.dataTransfer?.getData(`application/x-matterviz-file`);
|
|
62
|
+
if (internal_data) {
|
|
63
|
+
try {
|
|
64
|
+
const file_info = JSON.parse(internal_data);
|
|
65
|
+
if (file_info.content && file_info.content.length > max_text_size) {
|
|
66
|
+
console.warn(`Internal file data too large: ${file_info.content.length} bytes`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
on_file_drop?.(file_info.content, file_info.name);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error(`Failed to process internal file data:`, error);
|
|
74
|
+
}
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.warn(`Failed to parse internal file data:`, error);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Check for plain text data (fallback)
|
|
82
|
+
const text_data = event.dataTransfer?.getData(`text/plain`);
|
|
83
|
+
if (text_data) {
|
|
84
|
+
if (text_data.length > max_text_size) {
|
|
85
|
+
console.warn(`Text data too large: ${text_data.length} bytes (max: ${max_text_size})`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
on_file_drop?.(text_data, `structure.json`);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error(`Failed to process text data:`, error);
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// Handle actual file drops from file system
|
|
97
|
+
const file = event.dataTransfer?.files[0];
|
|
98
|
+
if (!file)
|
|
99
|
+
return;
|
|
100
|
+
try {
|
|
101
|
+
const { content, filename } = await decompress_file(file);
|
|
102
|
+
if (content)
|
|
103
|
+
on_file_drop?.(content, filename);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error(`Failed to read file:`, error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export function toggle_fullscreen() {
|
|
110
|
+
if (!document.fullscreenElement && wrapper) {
|
|
111
|
+
wrapper.requestFullscreen().catch(console.error);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
document.exitFullscreen();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// set --struct-bg to background_color
|
|
118
|
+
$effect(() => {
|
|
119
|
+
if (typeof window !== `undefined` && wrapper && background_color) {
|
|
120
|
+
// Convert opacity (0-1) to hex alpha value (00-FF)
|
|
121
|
+
const alpha_hex = Math.round(background_opacity * 255)
|
|
122
|
+
.toString(16)
|
|
123
|
+
.padStart(2, `0`);
|
|
124
|
+
wrapper.style.setProperty(`--struct-bg`, `${background_color}${alpha_hex}`);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
// react to changes in the 'fullscreen' property
|
|
128
|
+
$effect(() => {
|
|
129
|
+
if (typeof window !== `undefined`) {
|
|
130
|
+
// react to changes in the 'fullscreen' property
|
|
131
|
+
if (fullscreen && !document.fullscreenElement && wrapper) {
|
|
132
|
+
wrapper.requestFullscreen().catch(console.error);
|
|
133
|
+
}
|
|
134
|
+
else if (!fullscreen && document.fullscreenElement) {
|
|
135
|
+
document.exitFullscreen();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
</script>
|
|
140
|
+
|
|
141
|
+
{#if structure?.sites}
|
|
142
|
+
<div
|
|
143
|
+
class="structure"
|
|
144
|
+
class:dragover
|
|
145
|
+
role="region"
|
|
146
|
+
bind:this={wrapper}
|
|
147
|
+
bind:clientWidth={width}
|
|
148
|
+
bind:clientHeight={height}
|
|
149
|
+
onmouseenter={() => (hovered = true)}
|
|
150
|
+
onmouseleave={() => (hovered = false)}
|
|
151
|
+
ondrop={handle_file_drop}
|
|
152
|
+
ondragover={(event) => {
|
|
153
|
+
event.preventDefault()
|
|
154
|
+
if (!allow_file_drop) return
|
|
155
|
+
dragover = true
|
|
156
|
+
}}
|
|
157
|
+
ondragleave={(event) => {
|
|
158
|
+
event.preventDefault()
|
|
159
|
+
dragover = false
|
|
160
|
+
}}
|
|
161
|
+
{...rest}
|
|
162
|
+
>
|
|
163
|
+
<section class:visible={visible_buttons}>
|
|
164
|
+
{#if camera_has_moved}
|
|
165
|
+
<button class="reset-camera" onclick={reset_camera} title={reset_text}>
|
|
166
|
+
<!-- Target/Focus icon for reset camera -->
|
|
167
|
+
<Icon icon="Reset" />
|
|
168
|
+
</button>
|
|
169
|
+
{/if}
|
|
170
|
+
{#if enable_tips}
|
|
171
|
+
<button class="info-icon" onclick={() => tips_modal?.showModal()}>
|
|
172
|
+
{#if tips_icon}{@render tips_icon()}{:else}<Icon icon="Info" />{/if}
|
|
173
|
+
</button>
|
|
174
|
+
{/if}
|
|
175
|
+
<button
|
|
176
|
+
onclick={toggle_fullscreen}
|
|
177
|
+
class="fullscreen-toggle"
|
|
178
|
+
title="Toggle fullscreen"
|
|
179
|
+
>
|
|
180
|
+
{#if typeof fullscreen_toggle === `function`}
|
|
181
|
+
{@render fullscreen_toggle()}
|
|
182
|
+
{:else if fullscreen_toggle}
|
|
183
|
+
<Icon icon="Fullscreen" style="transform: scale(0.9)" />
|
|
184
|
+
{/if}
|
|
185
|
+
</button>
|
|
186
|
+
|
|
187
|
+
<StructureControls
|
|
188
|
+
bind:controls_open
|
|
189
|
+
bind:scene_props
|
|
190
|
+
bind:lattice_props
|
|
191
|
+
bind:show_image_atoms
|
|
192
|
+
bind:show_site_labels
|
|
193
|
+
bind:show_full_controls
|
|
194
|
+
bind:background_color
|
|
195
|
+
bind:background_opacity
|
|
196
|
+
bind:color_scheme
|
|
197
|
+
bind:png_dpi
|
|
198
|
+
{structure}
|
|
199
|
+
{wrapper}
|
|
200
|
+
{save_json_btn_text}
|
|
201
|
+
{save_png_btn_text}
|
|
202
|
+
{save_xyz_btn_text}
|
|
203
|
+
/>
|
|
204
|
+
</section>
|
|
205
|
+
|
|
206
|
+
<StructureLegend elements={get_elem_amounts(structure)} bind:tips_modal />
|
|
207
|
+
|
|
208
|
+
<Canvas
|
|
209
|
+
createRenderer={(canvas) => {
|
|
210
|
+
const renderer = new WebGLRenderer({
|
|
211
|
+
canvas,
|
|
212
|
+
preserveDrawingBuffer: true,
|
|
213
|
+
antialias: true,
|
|
214
|
+
alpha: true,
|
|
215
|
+
}) // Store renderer reference for high-res export
|
|
216
|
+
;(canvas as exports.CanvasWithRenderer).__customRenderer = renderer
|
|
217
|
+
return renderer
|
|
218
|
+
}}
|
|
219
|
+
>
|
|
220
|
+
<StructureScene
|
|
221
|
+
structure={scene_structure}
|
|
222
|
+
{...scene_props}
|
|
223
|
+
{show_site_labels}
|
|
224
|
+
{lattice_props}
|
|
225
|
+
bind:camera_is_moving
|
|
226
|
+
/>
|
|
227
|
+
</Canvas>
|
|
228
|
+
|
|
229
|
+
<div class="bottom-left">
|
|
230
|
+
{@render bottom_left?.({ structure })}
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
{:else if structure}
|
|
234
|
+
<p class="warn">No sites found in structure</p>
|
|
235
|
+
{:else}
|
|
236
|
+
<p class="warn">No structure provided</p>
|
|
237
|
+
{/if}
|
|
238
|
+
|
|
239
|
+
<style>
|
|
240
|
+
.structure {
|
|
241
|
+
position: relative;
|
|
242
|
+
container-type: size;
|
|
243
|
+
height: var(--struct-height, 500px);
|
|
244
|
+
width: var(--struct-width, 100%);
|
|
245
|
+
max-width: var(--struct-max-width, 100%);
|
|
246
|
+
min-width: var(--struct-min-width, 300px);
|
|
247
|
+
border-radius: var(--struct-border-radius, 3pt);
|
|
248
|
+
background: var(--struct-bg, rgba(255, 255, 255, 0.1));
|
|
249
|
+
--struct-controls-transition-duration: 0.3s;
|
|
250
|
+
overflow: var(--struct-overflow, visible);
|
|
251
|
+
color: var(--struct-text-color);
|
|
252
|
+
}
|
|
253
|
+
.structure:fullscreen :global(canvas) {
|
|
254
|
+
height: 100vh !important;
|
|
255
|
+
width: 100vw !important;
|
|
256
|
+
}
|
|
257
|
+
.structure.dragover {
|
|
258
|
+
background: var(--struct-dragover-bg, rgba(0, 0, 0, 0.7));
|
|
259
|
+
}
|
|
260
|
+
div.bottom-left {
|
|
261
|
+
position: absolute;
|
|
262
|
+
bottom: 0;
|
|
263
|
+
left: 0;
|
|
264
|
+
font-size: var(--struct-bottom-left-font-size, 1.2em);
|
|
265
|
+
padding: var(--struct-bottom-left-padding, 1pt 5pt);
|
|
266
|
+
}
|
|
267
|
+
button {
|
|
268
|
+
background-color: transparent;
|
|
269
|
+
}
|
|
270
|
+
button:hover {
|
|
271
|
+
background-color: transparent !important;
|
|
272
|
+
}
|
|
273
|
+
section {
|
|
274
|
+
position: absolute;
|
|
275
|
+
display: flex;
|
|
276
|
+
justify-content: end;
|
|
277
|
+
top: var(--struct-buttons-top, 1ex);
|
|
278
|
+
right: var(--struct-buttons-right, 1ex);
|
|
279
|
+
gap: var(--struct-buttons-gap, 3pt);
|
|
280
|
+
z-index: 2;
|
|
281
|
+
}
|
|
282
|
+
section button {
|
|
283
|
+
pointer-events: auto;
|
|
284
|
+
font-size: 1em;
|
|
285
|
+
}
|
|
286
|
+
section :global(.controls-toggle) {
|
|
287
|
+
background-color: transparent;
|
|
288
|
+
}
|
|
289
|
+
section :global(.controls-toggle):hover {
|
|
290
|
+
background-color: transparent !important;
|
|
291
|
+
}
|
|
292
|
+
.structure :global(canvas) {
|
|
293
|
+
pointer-events: auto;
|
|
294
|
+
}
|
|
295
|
+
p.warn {
|
|
296
|
+
text-align: center;
|
|
297
|
+
}
|
|
298
|
+
</style>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AnyStructure } from '..';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { Props as ControlProps } from './StructureControls.svelte';
|
|
4
|
+
interface Props extends ControlProps {
|
|
5
|
+
reveal_buttons?: boolean | number;
|
|
6
|
+
fullscreen?: boolean;
|
|
7
|
+
width?: number;
|
|
8
|
+
height?: number;
|
|
9
|
+
reset_text?: string;
|
|
10
|
+
hovered?: boolean;
|
|
11
|
+
dragover?: boolean;
|
|
12
|
+
allow_file_drop?: boolean;
|
|
13
|
+
tips_modal?: HTMLDialogElement | undefined;
|
|
14
|
+
enable_tips?: boolean;
|
|
15
|
+
tips_icon?: Snippet<[]>;
|
|
16
|
+
fullscreen_toggle?: Snippet<[]> | boolean;
|
|
17
|
+
bottom_left?: Snippet<[{
|
|
18
|
+
structure: AnyStructure;
|
|
19
|
+
}]>;
|
|
20
|
+
on_file_drop?: (content: string, filename: string) => void;
|
|
21
|
+
max_text_size?: number;
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
declare const Structure: import("svelte").Component<Props, {
|
|
25
|
+
toggle_fullscreen: () => void;
|
|
26
|
+
}, "height" | "width" | "dragover" | "color_scheme" | "structure" | "controls_open" | "scene_props" | "lattice_props" | "show_image_atoms" | "show_site_labels" | "show_full_controls" | "background_color" | "background_opacity" | "wrapper" | "png_dpi" | "hovered" | "tips_modal">;
|
|
27
|
+
type Structure = ReturnType<typeof Structure>;
|
|
28
|
+
export default Structure;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script lang="ts">import { format_num, InfoCard } from '..';
|
|
2
|
+
import { density, electro_neg_formula } from './index';
|
|
3
|
+
let { structure, title = `Structure`, ...rest } = $props();
|
|
4
|
+
let { volume, a, b, c, alpha, beta, gamma } = $derived(structure?.lattice ?? {});
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<InfoCard
|
|
8
|
+
data={[
|
|
9
|
+
{ title: `Formula`, value: electro_neg_formula(structure) },
|
|
10
|
+
{ title: `Number of atoms`, value: structure?.sites?.length, fmt: `.0f` },
|
|
11
|
+
{ title: `Volume`, value: volume, unit: `ų` },
|
|
12
|
+
{ title: `Density`, value: density(structure), unit: `g/cm³` },
|
|
13
|
+
{
|
|
14
|
+
title: `Lattice lengths a, b, c`,
|
|
15
|
+
value: [a, b, c].map(format_num).join(`, `),
|
|
16
|
+
unit: `Å`,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
title: `Lattice angles α, β, γ`,
|
|
20
|
+
value: [alpha, beta, gamma].map(format_num).join(`°, `) + `°`,
|
|
21
|
+
},
|
|
22
|
+
// { title: 'Charge', value: structure?.charge },
|
|
23
|
+
]}
|
|
24
|
+
{...rest}
|
|
25
|
+
{title}
|
|
26
|
+
/>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type PymatgenStructure } from './index';
|
|
2
|
+
interface Props {
|
|
3
|
+
structure: PymatgenStructure;
|
|
4
|
+
title?: string;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
declare const StructureCard: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type StructureCard = ReturnType<typeof StructureCard>;
|
|
9
|
+
export default StructureCard;
|