Structure

Bi2Zr2O8-Fm3m.json

No structure provided

🧬 molecule JSON XYZ
🧬 C2HO-scientific-notation.xyz
🧬 C5-extra-data.xyz
🧬 benzene.json
🧬 cyclohexane.xyz
🧬 ethanol.json
🧬 methane.json
🧬 methyl.json
🧬 water.json
svelte<script lang="ts">
  import { page } from '$app/state'
  import { goto } from '$app/navigation'
  import { browser } from '$app/environment'
  import { Structure } from 'matterviz'
  import Select from 'svelte-multiselect'
  import { structure_files } from '$site/structures'
  import { molecule_files } from '$site/molecules'
  import FilePicker from '$lib/FilePicker.svelte'
  import { decode_url_safe_base64, get_electro_neg_formula } from '$lib'

  let current_filename = $state(`Bi2Zr2O8-Fm3m.json`)
  // Inline structure data from URL hash (used by ferrox render CLI)
  let hash_structure_string = $state<string>()

  const all_files = [...structure_files, ...molecule_files]
  function get_file_url(filename: string): string {
    const file_info = all_files.find((file) => file.name === filename)
    return file_info?.url || `/structures/${filename}`
  }

  $effect(() => {
    if (!browser) return
    // Support #structure=BASE64 for CLI-generated links (ferrox render).
    // Must use window.location.hash since SvelteKit's page.url.hash is always empty.
    const hash = window.location.hash
    if (hash.startsWith(`#structure=`)) {
      const raw = hash.slice(`#structure=`.length)
      const decoded = decode_url_safe_base64(raw)
      if (decoded !== undefined) {
        hash_structure_string = decoded
        current_filename = `CLI structure`
      } else {
        console.error(`Failed to decode base64 structure from URL hash`)
      }
      return
    }
    const file = page.url.searchParams.get(`file`)
    if (file && file !== current_filename) current_filename = file
  })
</script>

<Structure
  data_url={hash_structure_string ? undefined : get_file_url(current_filename)}
  structure_string={hash_structure_string}
  on_file_load={(data: { filename: string }) => {
    current_filename = data.filename
    page.url.searchParams.set(`file`, current_filename)
    goto(`${page.url.pathname}?${page.url.searchParams.toString()}`, {
      replaceState: true,
      keepFocus: true,
      noScroll: true,
    })
  }}
>
  <h3 style="position: absolute; margin: 1ex 1em; font-family: monospace; z-index: 1">
    {current_filename}
  </h3>
</Structure>

<FilePicker
  files={all_files}
  show_category_filters
  style="margin-block: 2em"
/>

Different Crystal Systems

Showcasing structures with different crystal systems.

  • mp-10018 cubic

  • mp-1183057 trigonal

  • mp-1183085 orthorhombic

  • mp-1183089 monoclinic

  • mp-1207297 tetragonal

  • mp-686119 triclinic

  • mp-862690 hexagonal

  • Po-simple cubic

svelte<script lang="ts">
  import { CRYSTAL_SYSTEMS, Structure } from 'matterviz'
  import { structures } from '$site/structures'
</script>

<ul class="crystal-systems">
  {#each structures.filter((struct) =>
      CRYSTAL_SYSTEMS.some((system) => struct.id.includes(system))
    ) as
    structure
    (structure.id)
  }
    {@const mp_id = structure.id.split(`-`).slice(0, 2).join(`-`)}
    {@const href = `https://materialsproject.org/materials/${mp_id}`}
    {@const crystal_system = structure.id.split(`-`).at(-1) || 'unknown'}
    <li>
      <h3><a {href}>{mp_id}</a> <small>{crystal_system}</small></h3>
      <Structure {structure} />
    </li>
  {/each}
</ul>

<style>
  ul.crystal-systems {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(500px, 1fr));
    gap: 1.5em;
    list-style: none;
    padding: 0;
    text-align: center;
    width: 95vw;
    margin: 2em calc(50cqw - 47.5vw);
  }
  ul.crystal-systems h3 {
    margin: 0.5em auto;
    font-size: 1.1em;
    display: flex;
    place-items: center;
    place-content: center;
  }
  ul.crystal-systems small {
    margin: 0 0 0 0.5em;
    font-weight: lighter;
    color: var(--text-color-muted);
  }
</style>

Load Structure from String

You can load structures directly from text content using the structure_string prop, supporting various formats (CIF, POSCAR, XYZ, JSON, etc.).

No structure provided

svelte<script lang="ts">
  import { Structure } from 'matterviz'
  import { format_num } from '$lib'
  import c2ho_scientific_notation_xyz from '$site/molecules/C2HO-scientific-notation.xyz?raw'
  import c5_extra_data_xyz from '$site/molecules/C5-extra-data.xyz?raw'
  import cyclohexane from '$site/molecules/cyclohexane.xyz?raw'
  import aviary_CuF3K_triolith from '$site/structures/aviary-CuF3K-triolith.poscar?raw'
  import ba_ti_o3_tetragonal from '$site/structures/BaTiO3-tetragonal.poscar?raw'
  import mof_issue_127 from '$site/structures/mof-issue-127.cif?raw'
  import na_cl_cubic from '$site/structures/NaCl-cubic.poscar?raw'
  import ru_p_complex_cif from '$site/structures/P24Ru4H252C296S24N16.cif?raw'
  import pf_sd_1601634_cif from '$site/structures/PF-sd-1601634.cif?raw'
  import extended_xyz_quartz from '$site/structures/quartz.extxyz?raw'
  import scientific_notation_poscar from '$site/structures/scientific-notation.poscar?raw'
  import selective_dynamics from '$site/structures/selective-dynamics.poscar?raw'
  import tio2_cif from '$site/structures/TiO2.cif?raw'
  import vasp4_format from '$site/structures/vasp4-format.poscar?raw'

  const structure_files = [
    { name: `MOF (CIF)`, content: mof_issue_127 },
    { name: `Ru Complex (CIF)`, content: ru_p_complex_cif },
    { name: `PF Structure (CIF)`, content: pf_sd_1601634_cif },
    { name: `Cyclohexane (XYZ)`, content: cyclohexane },
    { name: `C2HO (XYZ)`, content: c2ho_scientific_notation_xyz },
    { name: `C5 (XYZ)`, content: c5_extra_data_xyz },
    { name: `CuF3K (POSCAR)`, content: aviary_CuF3K_triolith },
    { name: `BaTiO3 (POSCAR)`, content: ba_ti_o3_tetragonal },
    { name: `NaCl (POSCAR)`, content: na_cl_cubic },
    { name: `Quartz (ExtXYZ)`, content: extended_xyz_quartz },
    { name: `Scientific Notation (POSCAR)`, content: scientific_notation_poscar },
    { name: `Selective Dynamics (POSCAR)`, content: selective_dynamics },
    { name: `TiO2 (CIF)`, content: tio2_cif },
    { name: `VASP4 Format (POSCAR)`, content: vasp4_format },
  ]

  let selected_idx = $state(0)
  let parsed_structure = $state(undefined)
  let selected_file = $derived(structure_files[selected_idx])
</script>

<label style="display: block; margin-block: 1em">
  Structure:
  <select bind:value={selected_idx}>
    {#each structure_files as file, idx (file.name)}
      <option value={idx}>{file.name}</option>
    {/each}
  </select>
  &ensp;(parsed <strong>{parsed_structure?.sites?.length || 0}</strong> atoms from {
    format_num(selected_file.content.length)
  }B)
</label>

<Structure
  structure_string={selected_file.content}
  bind:structure={parsed_structure}
/>