Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update scatter tooltip when hovering element tiles #9

Merged
merged 3 commits into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="@sveltejs/kit" />

declare module '*periodic-table-data.ts' {
const elements: import('./types').ChemicalElement[]
const elements: import('./lib/types').ChemicalElement[]
export default elements
}
4 changes: 2 additions & 2 deletions src/lib/ColorCustomizer.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { fade } from 'svelte/transition'
import { category_colors, default_category_colors } from '../colors'
import { active_category } from '../stores'
import { category_colors, default_category_colors } from './colors'
import { active_category } from './stores'

export let open = false
export let collapsible = true
Expand Down
6 changes: 4 additions & 2 deletions src/lib/EasterEgg.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script lang="ts">
import { pretty_num } from './labels'

export let x_angle = 0
export let y_angle = 0
export let auto_rotate: 'x' | 'y' | 'both' | 'none' = `none`
Expand All @@ -9,11 +11,11 @@
<div class:visible={show_easter_egg}>
<p>You found the easter egg!</p>
<label>
Rotate X = <span>{parseFloat(x_angle.toFixed(0))}</span>
Rotate X = <span>{pretty_num(x_angle)}</span>
<input type="range" bind:value={x_angle} max={360} />
</label>
<label>
Rotate Y = <span>{parseFloat(y_angle.toFixed(0))}</span>
Rotate Y = <span>{pretty_num(y_angle)}</span>
<input type="range" bind:value={y_angle} max={360} />
</label>
<section>
Expand Down
4 changes: 2 additions & 2 deletions src/lib/ElementPhoto.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { active_element } from '../stores'
import type { ChemicalElement } from '../types'
import { active_element } from './stores'
import type { ChemicalElement } from './types'

export let style = ``
// element defaults to active_element store but can be pinned by passing it as prop
Expand Down
13 changes: 6 additions & 7 deletions src/lib/ElementStats.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<script lang="ts">
import { last_element } from '../stores'
import { pretty_num } from './labels'

import { last_element } from './stores'

export let padding = `1vw 2vw`
export let precision = 2

$: element = $last_element // used to decide whether to show user tip to hover an element tile

$: density_unit = $last_element?.phase === `Gas` ? `g/liter` : `g/cm³`
</script>

{#if element}
Expand All @@ -19,14 +18,14 @@
Atomic Mass
<abbr title="Dalton aka atomic mass unit">(u)</abbr>
</p>
<strong>{parseFloat(element.atomic_mass?.toFixed(precision))}</strong>
<strong>{pretty_num(element.atomic_mass)}</strong>
</section>
<section>
<p>
Density
<abbr title="grams per cubic centimeter">({density_unit})</abbr>
<abbr title="grams per cubic centimeter">(g/cm³)</abbr>
</p>
<strong>{parseFloat(element.density?.toFixed(precision))}</strong>
<strong>{pretty_num(element.density)}</strong>
</section>
<section>
<p>Phase</p>
Expand Down
9 changes: 5 additions & 4 deletions src/lib/ElementTile.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<script lang="ts">
import { active_category, active_element, last_element } from '../stores'
import type { ChemicalElement } from '../types'
import { pretty_num } from './labels'

import { active_category, active_element, last_element } from './stores'
import type { ChemicalElement } from './types'

export let element: ChemicalElement
export let bg_color: string | null
export let show_number = true
export let show_name = true
export let value: number | undefined = undefined
export let precision = 2

$: category = element.category.replaceAll(` `, `-`)
// background color defaults to category color (initialized in colors.ts, user editable in ColorCustomizer.ts)
Expand All @@ -30,7 +31,7 @@
</span>
{#if value}
<span class="value">
{parseFloat(value.toFixed(precision))}
{pretty_num(value)}
</span>
{:else if show_name}
<span class="name">
Expand Down
4 changes: 2 additions & 2 deletions src/lib/PeriodicTable.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script lang="ts">
import elements from '../periodic-table-data.ts'
import { active_element, color_scale, heatmap, last_element } from '../stores'
import BohrAtom from './BohrAtom.svelte'
import ElementPhoto from './ElementPhoto.svelte'
import ElementStats from './ElementStats.svelte'
import ElementTile from './ElementTile.svelte'
import elements from './periodic-table-data.ts'
import ScatterPlot from './ScatterPlot.svelte'
import { active_element, color_scale, heatmap, last_element } from './stores'
import TableInset from './TableInset.svelte'

export let show_names = true
Expand Down
6 changes: 3 additions & 3 deletions src/lib/PropertySelect.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script lang="ts">
import Select from 'svelte-multiselect'
import { heatmap_labels } from '../labels'
import { heatmap } from '../stores'
import type { ChemicalElement } from '../types'
import { heatmap_labels } from './labels'
import { heatmap } from './stores'
import type { ChemicalElement } from './types'
export let selected: (keyof ChemicalElement)[] = []

$: $heatmap = heatmap_labels[selected[0]] ?? null
Expand Down
17 changes: 11 additions & 6 deletions src/lib/ScatterPlot.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script lang="ts">
import { bisector, extent } from 'd3-array'
import { scaleLinear } from 'd3-scale'
import { element_property_labels } from '../labels'
import elements from '../periodic-table-data.ts'
import { active_element, color_scale, heatmap } from '../stores'
import type { ChemicalElement, PlotPoint } from '../types'
import { element_property_labels, pretty_num } from './labels'
import Line from './Line.svelte'
import elements from './periodic-table-data.ts'
import Datapoint from './ScatterPoint.svelte'
import { active_element, color_scale, heatmap } from './stores'
import type { ChemicalElement, PlotPoint } from './types'

export let style = ``
export let xlim: [number | null, number | null] = [null, null]
Expand Down Expand Up @@ -46,6 +46,10 @@

let tooltip_point: PlotPoint
let hovered = false
$: if ($active_element?.number) {
hovered = true
tooltip_point = data_points[$active_element.number]
}
const bisect = bisector((data_point: PlotPoint) => data_point[0]).right

function on_mouse_move(event: MouseEvent) {
Expand Down Expand Up @@ -104,10 +108,10 @@
{@const [x, y] = [x_scale(atomic_num), y_scale(raw_y)]}
<circle cx={x} cy={y} r="5" fill="orange" />
{#if hovered}
<foreignObject x={x + 5} {y} width="150" height="200">
<foreignObject x={x + 5} {y} width="170" height="100">
<strong>{atomic_num} - {tooltip_point[2].name}</strong>
{#if raw_y}
<br />{heatmap_label} = {parseFloat(raw_y.toFixed(2))}{heatmap_unit}
<br />{heatmap_label} = {pretty_num(raw_y)}{heatmap_unit ?? ``}
{/if}
</foreignObject>
{/if}
Expand All @@ -127,6 +131,7 @@
fill: white;
font-weight: lighter;
overflow: visible;
z-index: 1;
}
g.tick {
font-size: 9pt;
Expand Down
File renamed without changes.
10 changes: 9 additions & 1 deletion src/labels.ts → src/lib/labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const element_property_labels: Partial<
atomic_mass: [`Atomic Mass`, `u`],
melting_point: [`Melting Point`, `K`],
boiling_point: [`Boiling Point`, `K`],
density: [`Density`, `solid: g/cm³, gas: g/liter`],
density: [`Density`, `g/cm³`],
atomic_radius: [`Atomic Radius`, `Å`],
covalent_radius: [`Covalent Radius`, `Å`],
electronegativity: [`Electronegativity`, null],
Expand Down Expand Up @@ -39,3 +39,11 @@ export const heatmap_labels: Partial<Record<string, keyof ChemicalElement>> =
return [label + (unit ? ` (${unit})` : ``), key]
})
)

export const pretty_num = (num: number, precision = 2) => {
if (num < 0.01 || num > 10000) {
return num.toExponential(precision)
} else {
return parseFloat(num.toFixed(precision))
}
}
26 changes: 13 additions & 13 deletions src/periodic-table-data.ts → src/lib/periodic-table-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default [
appearance: `colorless gas`,
atomic_mass: 1.008,
category: `diatomic nonmetal`,
density: 0.08988,
density: 0.00008988,
discoverer: `Henry Cavendish`,
molar_heat: 28.836,
number: 1,
Expand Down Expand Up @@ -51,7 +51,7 @@ export default [
appearance: `colorless gas, exhibiting a red-orange glow when placed in a high-voltage electric field`,
atomic_mass: 4.0026022,
category: `noble gas`,
density: 0.1786,
density: 0.0001786,
discoverer: `Pierre Janssen`,
molar_heat: null,
number: 2,
Expand Down Expand Up @@ -271,7 +271,7 @@ export default [
appearance: `colorless gas, liquid or solid`,
atomic_mass: 14.007,
category: `diatomic nonmetal`,
density: 1.251,
density: 0.001251,
discoverer: `Daniel Rutherford`,
molar_heat: null,
number: 7,
Expand Down Expand Up @@ -315,7 +315,7 @@ export default [
appearance: null,
atomic_mass: 15.999,
category: `diatomic nonmetal`,
density: 1.429,
density: 0.001429,
discoverer: `Carl Scheele`,
molar_heat: null,
number: 8,
Expand Down Expand Up @@ -361,7 +361,7 @@ export default [
appearance: null,
atomic_mass: 18.9984031636,
category: `diatomic nonmetal`,
density: 1.696,
density: 0.001696,
discoverer: `André-Marie Ampère`,
molar_heat: null,
number: 9,
Expand Down Expand Up @@ -407,7 +407,7 @@ export default [
appearance: `colorless gas exhibiting an orange-red glow when placed in a high voltage electric field`,
atomic_mass: 20.17976,
category: `noble gas`,
density: 0.9002,
density: 0.0009002,
discoverer: `Morris Travers`,
molar_heat: null,
number: 10,
Expand Down Expand Up @@ -736,7 +736,7 @@ export default [
appearance: `pale yellow-green gas`,
atomic_mass: 35.45,
category: `diatomic nonmetal`,
density: 3.2,
density: 0.0032,
discoverer: `Carl Wilhelm Scheele`,
molar_heat: null,
number: 17,
Expand Down Expand Up @@ -783,7 +783,7 @@ export default [
appearance: `colorless gas exhibiting a lilac/violet glow when placed in a high voltage electric field`,
atomic_mass: 39.9481,
category: `noble gas`,
density: 1.784,
density: 0.001784,
discoverer: `Lord Rayleigh`,
molar_heat: null,
number: 18,
Expand Down Expand Up @@ -1623,7 +1623,7 @@ export default [
appearance: `colorless gas, exhibiting a whitish glow in a high electric field`,
atomic_mass: 83.7982,
category: `noble gas`,
density: 3.749,
density: 0.003749,
discoverer: `William Ramsay`,
molar_heat: null,
number: 36,
Expand Down Expand Up @@ -2430,7 +2430,7 @@ export default [
appearance: `colorless gas, exhibiting a blue glow when placed in a high voltage electric field`,
atomic_mass: 131.2936,
category: `noble gas`,
density: 5.894,
density: 0.005894,
discoverer: `William Ramsay`,
molar_heat: null,
number: 54,
Expand Down Expand Up @@ -3405,7 +3405,7 @@ export default [
period: 6,
phase: `Solid`,
spectral_img: null,
summary: `Osmium (from Greek osme (ὀσμή) meaning "smell") is a chemical element with symbol Os and atomic number 76. It is a hard, brittle, bluish-white transition metal in the platinum group that is found as a trace element in alloys, mostly in platinum ores. Osmium is the densest naturally occurring element, with a density of 22.59 g/cm3.`,
summary: `Osmium (from Greek osme (ὀσμή) meaning "smell") is a chemical element with symbol Os and atomic number 76. It is a hard, brittle, bluish-white transition metal in the platinum group that is found as a trace element in alloys, mostly in platinum ores. Osmium is the densest naturally occurring element, with a density of 22.59 g/cm^3.`,
symbol: `Os`,
shells: [2, 8, 18, 32, 14, 2],
electron_configuration: `1s2 2s2 2p6 3s2 3p6 4s2 3d10 4p6 5s2 4d10 5p6 6s2 4f14 5d6`,
Expand Down Expand Up @@ -3838,7 +3838,7 @@ export default [
appearance: `colorless gas, occasionally glows green or red in discharge tubes`,
atomic_mass: 222,
category: `noble gas`,
density: 9.73,
density: 0.00973,
discoverer: `Friedrich Ernst Dorn`,
molar_heat: null,
number: 86,
Expand Down Expand Up @@ -4987,7 +4987,7 @@ export default [
molar_heat: null,
number: 112,
period: 7,
phase: `Gas`,
phase: `Solid`,
spectral_img: null,
summary: `Copernicium is a chemical element with symbol Cn and atomic number 112. It is an extremely radioactive synthetic element that can only be created in a laboratory. The most stable known isotope, copernicium-285, has a half-life of approximately 29 seconds, but it is possible that this copernicium isotope may have a nuclear isomer with a longer half-life, 8.9 min.`,
symbol: `Cn`,
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import EasterEgg from '$lib/EasterEgg.svelte'
import PeriodicTable from '$lib/PeriodicTable.svelte'
import PropertySelect from '$lib/PropertySelect.svelte'
import { heatmap } from '$lib/stores'
import '../app.css'
import { heatmap } from '../stores'

let window_width: number
let x_angle = 0
Expand Down
2 changes: 1 addition & 1 deletion src/routes/[slug]/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import elements from '$lib/periodic-table-data'
import { error } from '@sveltejs/kit'
import elements from '../../periodic-table-data'
import type { PageServerLoad } from './$types'

export const load: PageServerLoad = ({ params }) => {
Expand Down
19 changes: 8 additions & 11 deletions src/routes/[slug]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,24 @@
import BohrAtom from '$lib/BohrAtom.svelte'
import ElementPhoto from '$lib/ElementPhoto.svelte'
import ElementStats from '$lib/ElementStats.svelte'
import { element_property_labels, heatmap_labels, pretty_num } from '$lib/labels'
import PropertySelect from '$lib/PropertySelect.svelte'
import ScatterPlot from '$lib/ScatterPlot.svelte'
import { element_property_labels, heatmap_labels } from '../../labels'
import { active_element } from '../../stores'
import type { ChemicalElement } from '../../types'
import { active_element } from '$lib/stores'
import type { ChemicalElement } from '$lib/types'
import type { PageData } from './$types'

export let data: PageData

$: ({ element } = data)
$: $active_element = element
$: [$active_element, element] = [data.element, data.element]

$: key_vals = Object.entries(element_property_labels).map(([key, [label, unit]]) => {
let value = element[key as keyof ChemicalElement]
if (typeof value === `number`) value = parseFloat(value.toFixed(2))
if (typeof value === `number`) {
value = pretty_num(value)
}
if (Array.isArray(value)) value = value.join(`, `)
if (unit) {
if (label === `Density`) {
if (element.phase === `Gas`) unit = `g/liter`
else unit = `g/cm³`
}
value = `${value} &thinsp;${unit}`
}
return [label, value]
Expand All @@ -47,7 +44,7 @@
<PropertySelect selected={[initial_heatmap]} />

<section>
<ElementPhoto style="border-radius: 4pt;" />
<ElementPhoto />

<ScatterPlot ylim={[0, null]} />
</section>
Expand Down
2 changes: 1 addition & 1 deletion src/routes/bohr-atoms/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import BohrAtom from '$lib/BohrAtom.svelte'
import elements from '$lib/periodic-table-data'
import Toggle from '$lib/Toggle.svelte'
import elements from '../../periodic-table-data'

let orbiting = true
</script>
Expand Down
2 changes: 1 addition & 1 deletion tests/element-data.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, test } from '@playwright/test'

import element_data from '../src/periodic-table-data.ts'
import element_data from '../src/lib/periodic-table-data.ts'

export const category_counts: Record<string, number> = {}

Expand Down