Interactive example
svelte<script lang="ts">
import { ColorBar, ColorScaleSelect, PeriodicTable, TableInset } from 'matterviz'
import { format_num } from 'matterviz/labels'
import mp_elem_counts from './mp-element-counts.json'
import wbm_elem_counts from './wbm-element-counts.json'
let log_scale = $state(true)
let data_name = $state(`MP`)
let color_scale = $derived(`interpolateViridis`)
let heatmap_values = $derived(
Object.values(data_name == `WBM` ? wbm_elem_counts : mp_elem_counts),
)
let total = $derived(heatmap_values.reduce((sum, val) => sum + val, 0))
let nice_range = $state([])
// the table inset is only ~10 element cells wide; below this width the controls no
// longer fit inside it and spill over the heading, so they move below the table
let demo_width = $state(1000)
let controls_in_inset = $derived(demo_width >= 700)
</script>
{#snippet controls()}
<section>
<span>
Data set  
{#each [`MP`, `WBM`] as data_set (data_set)}
<input type="radio" bind:group={data_name} value={data_set} /> {data_set}
{/each}
</span>
<span>Log color scale <input type="checkbox" bind:checked={log_scale} /></span>
<ColorScaleSelect bind:value={color_scale} />
<ColorBar
range={[1, Math.max(...heatmap_values)]}
scale={color_scale}
bind:nice_range
scale_type={log_scale ? `log` : `linear`}
wrapper_style="width: 80%; --cbar-padding: 0.4em 0.8em 0;"
bar_style="width: 100%;"
/>
</section>
{/snippet}
<h1 id="color-scales" style="text-align: center">Color Scales</h1>
<h2 id="element-occurrence-counts" style="text-align: center">
{{ MP: `Materials Project` }[data_name] ?? data_name} Element Occurrence Counts
</h2>
<div bind:clientWidth={demo_width}>
<PeriodicTable
{heatmap_values}
log={log_scale}
{color_scale}
bind:color_scale_range={nice_range}
>
{#snippet inset({ active_element })}
<TableInset style="align-content: center; --ptable-inset-padding: 0.25em 0.5em 1.4em">
{#if controls_in_inset}
{@render controls()}
{/if}
<strong style="height: 25pt">
{#if active_element?.name}
{@const elem_counts = data_name == `WBM` ? wbm_elem_counts : mp_elem_counts}
{active_element?.name}: {format_num(elem_counts[active_element?.symbol])}
<!-- compute percent of total -->
{#if elem_counts[active_element?.symbol] > 0}
({format_num(elem_counts[active_element?.symbol] / total, `.2~%`)})
{/if}
{/if}
</strong>
</TableInset>
{/snippet}
</PeriodicTable>
{#if !controls_in_inset}
{@render controls()}
{/if}
</div>