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.
Files changed (131) hide show
  1. package/dist/BohrAtom.svelte +105 -0
  2. package/dist/BohrAtom.svelte.d.ts +21 -0
  3. package/dist/ControlPanel.svelte +158 -0
  4. package/dist/ControlPanel.svelte.d.ts +18 -0
  5. package/dist/Icon.svelte +23 -0
  6. package/dist/Icon.svelte.d.ts +8 -0
  7. package/dist/InfoCard.svelte +79 -0
  8. package/dist/InfoCard.svelte.d.ts +23 -0
  9. package/dist/Nucleus.svelte +64 -0
  10. package/dist/Nucleus.svelte.d.ts +16 -0
  11. package/dist/Spinner.svelte +44 -0
  12. package/dist/Spinner.svelte.d.ts +7 -0
  13. package/dist/api.d.ts +6 -0
  14. package/dist/api.js +30 -0
  15. package/dist/colors/alloy-colors.json +111 -0
  16. package/dist/colors/dark-mode-colors.json +111 -0
  17. package/dist/colors/index.d.ts +26 -0
  18. package/dist/colors/index.js +72 -0
  19. package/dist/colors/jmol-colors.json +111 -0
  20. package/dist/colors/muted-colors.json +111 -0
  21. package/dist/colors/pastel-colors.json +111 -0
  22. package/dist/colors/vesta-colors.json +111 -0
  23. package/dist/composition/BarChart.svelte +260 -0
  24. package/dist/composition/BarChart.svelte.d.ts +33 -0
  25. package/dist/composition/BubbleChart.svelte +166 -0
  26. package/dist/composition/BubbleChart.svelte.d.ts +30 -0
  27. package/dist/composition/Composition.svelte +73 -0
  28. package/dist/composition/Composition.svelte.d.ts +27 -0
  29. package/dist/composition/PieChart.svelte +236 -0
  30. package/dist/composition/PieChart.svelte.d.ts +36 -0
  31. package/dist/composition/index.d.ts +5 -0
  32. package/dist/composition/index.js +5 -0
  33. package/dist/composition/parse.d.ts +14 -0
  34. package/dist/composition/parse.js +307 -0
  35. package/dist/element/ElementHeading.svelte +21 -0
  36. package/dist/element/ElementHeading.svelte.d.ts +8 -0
  37. package/dist/element/ElementPhoto.svelte +56 -0
  38. package/dist/element/ElementPhoto.svelte.d.ts +9 -0
  39. package/dist/element/ElementStats.svelte +73 -0
  40. package/dist/element/ElementStats.svelte.d.ts +8 -0
  41. package/dist/element/ElementTile.svelte +449 -0
  42. package/dist/element/ElementTile.svelte.d.ts +25 -0
  43. package/dist/element/data.d.ts +4958 -0
  44. package/dist/element/data.js +5628 -0
  45. package/dist/element/index.d.ts +4 -0
  46. package/dist/element/index.js +4 -0
  47. package/dist/icons.d.ts +435 -0
  48. package/dist/icons.js +435 -0
  49. package/dist/index.d.ts +82 -0
  50. package/dist/index.js +43 -0
  51. package/dist/io/decompress.d.ts +16 -0
  52. package/dist/io/decompress.js +78 -0
  53. package/dist/io/export.d.ts +9 -0
  54. package/dist/io/export.js +205 -0
  55. package/dist/io/parse.d.ts +53 -0
  56. package/dist/io/parse.js +747 -0
  57. package/dist/labels.d.ts +31 -0
  58. package/dist/labels.js +209 -0
  59. package/dist/material/MaterialCard.svelte +135 -0
  60. package/dist/material/MaterialCard.svelte.d.ts +10 -0
  61. package/dist/material/SymmetryCard.svelte +23 -0
  62. package/dist/material/SymmetryCard.svelte.d.ts +9 -0
  63. package/dist/material/index.d.ts +2 -0
  64. package/dist/material/index.js +2 -0
  65. package/dist/math.d.ts +24 -0
  66. package/dist/math.js +216 -0
  67. package/dist/periodic-table/PeriodicTable.svelte +284 -0
  68. package/dist/periodic-table/PeriodicTable.svelte.d.ts +50 -0
  69. package/dist/periodic-table/PropertySelect.svelte +20 -0
  70. package/dist/periodic-table/PropertySelect.svelte.d.ts +13 -0
  71. package/dist/periodic-table/TableInset.svelte +18 -0
  72. package/dist/periodic-table/TableInset.svelte.d.ts +9 -0
  73. package/dist/periodic-table/index.d.ts +9 -0
  74. package/dist/periodic-table/index.js +3 -0
  75. package/dist/plot/ColorBar.svelte +414 -0
  76. package/dist/plot/ColorBar.svelte.d.ts +22 -0
  77. package/dist/plot/ColorScaleSelect.svelte +31 -0
  78. package/dist/plot/ColorScaleSelect.svelte.d.ts +15 -0
  79. package/dist/plot/ElementScatter.svelte +38 -0
  80. package/dist/plot/ElementScatter.svelte.d.ts +14 -0
  81. package/dist/plot/Line.svelte +42 -0
  82. package/dist/plot/Line.svelte.d.ts +15 -0
  83. package/dist/plot/PlotLegend.svelte +206 -0
  84. package/dist/plot/PlotLegend.svelte.d.ts +18 -0
  85. package/dist/plot/ScatterPlot.svelte +1753 -0
  86. package/dist/plot/ScatterPlot.svelte.d.ts +114 -0
  87. package/dist/plot/ScatterPlotControls.svelte +505 -0
  88. package/dist/plot/ScatterPlotControls.svelte.d.ts +33 -0
  89. package/dist/plot/ScatterPoint.svelte +72 -0
  90. package/dist/plot/ScatterPoint.svelte.d.ts +17 -0
  91. package/dist/plot/index.d.ts +168 -0
  92. package/dist/plot/index.js +46 -0
  93. package/dist/state.svelte.d.ts +12 -0
  94. package/dist/state.svelte.js +11 -0
  95. package/dist/structure/Bond.svelte +68 -0
  96. package/dist/structure/Bond.svelte.d.ts +13 -0
  97. package/dist/structure/Lattice.svelte +115 -0
  98. package/dist/structure/Lattice.svelte.d.ts +15 -0
  99. package/dist/structure/Structure.svelte +298 -0
  100. package/dist/structure/Structure.svelte.d.ts +28 -0
  101. package/dist/structure/StructureCard.svelte +26 -0
  102. package/dist/structure/StructureCard.svelte.d.ts +9 -0
  103. package/dist/structure/StructureControls.svelte +383 -0
  104. package/dist/structure/StructureControls.svelte.d.ts +23 -0
  105. package/dist/structure/StructureLegend.svelte +130 -0
  106. package/dist/structure/StructureLegend.svelte.d.ts +17 -0
  107. package/dist/structure/StructureScene.svelte +331 -0
  108. package/dist/structure/StructureScene.svelte.d.ts +47 -0
  109. package/dist/structure/bonding.d.ts +16 -0
  110. package/dist/structure/bonding.js +150 -0
  111. package/dist/structure/index.d.ts +98 -0
  112. package/dist/structure/index.js +114 -0
  113. package/dist/structure/pbc.d.ts +6 -0
  114. package/dist/structure/pbc.js +72 -0
  115. package/dist/trajectory/Sidebar.svelte +412 -0
  116. package/dist/trajectory/Sidebar.svelte.d.ts +14 -0
  117. package/dist/trajectory/Trajectory.svelte +1084 -0
  118. package/dist/trajectory/Trajectory.svelte.d.ts +49 -0
  119. package/dist/trajectory/TrajectoryError.svelte +120 -0
  120. package/dist/trajectory/TrajectoryError.svelte.d.ts +12 -0
  121. package/dist/trajectory/extract.d.ts +5 -0
  122. package/dist/trajectory/extract.js +157 -0
  123. package/dist/trajectory/index.d.ts +16 -0
  124. package/dist/trajectory/index.js +49 -0
  125. package/dist/trajectory/parse.d.ts +13 -0
  126. package/dist/trajectory/parse.js +1093 -0
  127. package/dist/trajectory/plotting.d.ts +12 -0
  128. package/dist/trajectory/plotting.js +148 -0
  129. package/license +21 -0
  130. package/package.json +131 -0
  131. package/readme.md +95 -0
@@ -0,0 +1,12 @@
1
+ import type { DataSeries } from '../plot';
2
+ import type { Trajectory, TrajectoryDataExtractor } from './index';
3
+ export declare const Y2_PROPERTIES: Set<string>;
4
+ export interface PlotSeriesOptions {
5
+ property_labels?: Record<string, string>;
6
+ units?: Record<string, string>;
7
+ colors?: string[];
8
+ y2_properties?: Set<string>;
9
+ default_visible_properties?: Set<string>;
10
+ }
11
+ export declare function generate_plot_series(trajectory: Trajectory, data_extractor: TrajectoryDataExtractor, options?: PlotSeriesOptions): DataSeries[];
12
+ export declare function should_hide_plot(trajectory: Trajectory | undefined, plot_series: DataSeries[], tolerance?: number): boolean;
@@ -0,0 +1,148 @@
1
+ // Plotting utilities for trajectory visualization
2
+ import { plot_colors } from '../colors';
3
+ import { get_clean_label } from '../labels';
4
+ // Properties that should be assigned to the secondary y-axis
5
+ export const Y2_PROPERTIES = new Set([
6
+ `force_max`,
7
+ `force_norm`,
8
+ `stress_max`,
9
+ `stress_frobenius`,
10
+ `volume`,
11
+ `density`,
12
+ `pressure`,
13
+ `temperature`,
14
+ ]);
15
+ // Generate plot data series from trajectory
16
+ export function generate_plot_series(trajectory, data_extractor, options = {}) {
17
+ if (!trajectory || trajectory.frames.length === 0)
18
+ return [];
19
+ const { property_labels, units, colors = plot_colors, y2_properties = Y2_PROPERTIES, default_visible_properties = new Set([`energy`, `force_max`, `stress_frobenius`]), } = options;
20
+ // Single pass: extract data and detect constants simultaneously
21
+ const property_data = new Map();
22
+ // Extract data from all frames in a single pass
23
+ trajectory.frames.forEach((frame) => {
24
+ const data = data_extractor(frame, trajectory);
25
+ for (const [key, value] of Object.entries(data)) {
26
+ // Skip non-numeric values, step, and marker properties
27
+ if (typeof value !== `number` || key === `Step` || key.startsWith(`_constant_`)) {
28
+ continue;
29
+ }
30
+ if (!property_data.has(key)) {
31
+ property_data.set(key, {
32
+ values: [],
33
+ sum: 0,
34
+ sum_squares: 0,
35
+ min: value,
36
+ max: value,
37
+ });
38
+ }
39
+ const prop = property_data.get(key);
40
+ if (!prop)
41
+ continue;
42
+ prop.values.push(value);
43
+ prop.sum += value;
44
+ prop.sum_squares += value * value;
45
+ prop.min = Math.min(prop.min, value);
46
+ prop.max = Math.max(prop.max, value);
47
+ }
48
+ });
49
+ // Filter out constant properties and create series
50
+ const series = [];
51
+ let color_idx = 0;
52
+ for (const [key, prop] of property_data) {
53
+ const n = prop.values.length;
54
+ if (n <= 1)
55
+ continue;
56
+ // Fast constant detection using coefficient of variation
57
+ const mean = prop.sum / n;
58
+ const variance = (prop.sum_squares - prop.sum * prop.sum / n) / n;
59
+ const coefficient_of_variation = Math.abs(mean) > 1e-10
60
+ ? Math.sqrt(variance) / Math.abs(mean)
61
+ : Math.sqrt(variance);
62
+ const lower_key = key.toLowerCase();
63
+ const is_energy = lower_key === `energy`;
64
+ const has_significant_variation = coefficient_of_variation >= 1e-6;
65
+ // Skip properties with very low variation (effectively constant)
66
+ // Exception: always include energy regardless of variation
67
+ if (!has_significant_variation && !is_energy) {
68
+ continue;
69
+ }
70
+ // Create series data
71
+ const x_values = Array.from({ length: n }, (_, idx) => idx);
72
+ const y_values = prop.values;
73
+ const color = colors[color_idx % colors.length];
74
+ const y_axis = y2_properties.has(lower_key) ? `y2` : `y1`;
75
+ // For energy: only visible by default if it has significant variation
76
+ // For other properties: use the normal default visibility logic
77
+ const is_default_visible = is_energy
78
+ ? has_significant_variation &&
79
+ (default_visible_properties.has(lower_key) || default_visible_properties.has(key))
80
+ : (default_visible_properties.has(lower_key) || default_visible_properties.has(key));
81
+ // Extract unit and create clean label
82
+ const unit = units?.[lower_key] || units?.[key] || ``;
83
+ const clean_label = get_clean_label(key, property_labels);
84
+ const full_label = unit ? `${clean_label} (${unit})` : clean_label;
85
+ series.push({
86
+ x: x_values,
87
+ y: y_values,
88
+ label: full_label,
89
+ unit,
90
+ y_axis,
91
+ visible: is_default_visible,
92
+ markers: n < 30 ? `line+points` : `line`,
93
+ metadata: x_values.map(() => ({ series_label: full_label })),
94
+ line_style: {
95
+ stroke: color,
96
+ stroke_width: 2,
97
+ },
98
+ point_style: {
99
+ fill: color,
100
+ radius: 4,
101
+ stroke: color,
102
+ stroke_width: 1,
103
+ },
104
+ });
105
+ color_idx++;
106
+ }
107
+ // Fallback visibility for volume/density if no priority properties are visible
108
+ const has_visible_priority = series.some((s) => s.visible &&
109
+ ![`volume`, `density`].some((prop) => s.label?.toLowerCase().includes(prop)));
110
+ if (!has_visible_priority) {
111
+ series.forEach((s) => {
112
+ const label_lower = s.label?.toLowerCase() || ``;
113
+ if (label_lower.includes(`volume`) || label_lower.includes(`density`)) {
114
+ s.visible = true;
115
+ }
116
+ });
117
+ }
118
+ // Sort by visibility for legend ordering
119
+ series.sort((a, b) => Number(b.visible) - Number(a.visible));
120
+ return series;
121
+ }
122
+ // Check if all plotted values are constant (should hide plot)
123
+ export function should_hide_plot(trajectory, plot_series, tolerance = 1e-10) {
124
+ if (!trajectory || trajectory.frames.length <= 1)
125
+ return false;
126
+ // If there are no series to plot, hide the plot
127
+ if (plot_series.length === 0)
128
+ return true;
129
+ // Get all visible series, and if none are visible, check fallback properties
130
+ let visible_series = plot_series.filter((s) => s.visible);
131
+ // If no explicit properties are visible, fall back to volume and density if they exist
132
+ if (visible_series.length === 0) {
133
+ const fallback_properties = [`volume`, `density`];
134
+ visible_series = plot_series.filter((s) => fallback_properties.some((prop) => s.label?.toLowerCase().includes(prop.toLowerCase())));
135
+ }
136
+ if (visible_series.length === 0)
137
+ return true;
138
+ for (const series of visible_series) {
139
+ if (series.y.length <= 1)
140
+ continue;
141
+ const first_value = series.y[0];
142
+ const has_variation = series.y.some((value) => Math.abs(value - first_value) > tolerance);
143
+ if (has_variation) {
144
+ return false; // Found variation, don't hide plot
145
+ }
146
+ }
147
+ return true; // All series are constant, hide plot
148
+ }
package/license ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Janosh Riebesell
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ The software is provided "as is", without warranty of any kind, express or
16
+ implied, including but not limited to the warranties of merchantability,
17
+ fitness for a particular purpose and noninfringement. In no event shall the
18
+ authors or copyright holders be liable for any claim, damages or other
19
+ liability, whether in an action of contract, tort or otherwise, arising from,
20
+ out of or in connection with the software or the use or other dealings in the
21
+ software.
package/package.json ADDED
@@ -0,0 +1,131 @@
1
+ {
2
+ "name": "matterviz",
3
+ "description": "Interactive visualizations for materials science: periodic tables, 3D structures, MD trajectories, heatmaps, scatter plots.",
4
+ "author": "Janosh Riebesell <janosh.riebesell@gmail.com>",
5
+ "homepage": "https://janosh.github.io/matterviz",
6
+ "repository": "https://github.com/janosh/matterviz",
7
+ "license": "MIT",
8
+ "version": "0.1.0",
9
+ "type": "module",
10
+ "svelte": "./dist/index.js",
11
+ "bugs": "https://github.com/janosh/matterviz/issues",
12
+ "dependencies": {
13
+ "@sveltejs/kit": "^2.21.5",
14
+ "@threlte/core": "8.0.5",
15
+ "@threlte/extras": "^9.3.0",
16
+ "@types/d3-force": "^3.0.10",
17
+ "@types/d3-hierarchy": "^3.1.7",
18
+ "@types/js-yaml": "^4.0.9",
19
+ "d3": "^7.9.0",
20
+ "d3-array": "^3.2.4",
21
+ "d3-color": "^3.1.0",
22
+ "d3-force": "^3.0.0",
23
+ "d3-format": "^3.1.0",
24
+ "d3-hierarchy": "^3.1.2",
25
+ "d3-interpolate-path": "^2.3.0",
26
+ "d3-scale": "^4.0.2",
27
+ "d3-scale-chromatic": "^3.1.0",
28
+ "d3-shape": "^3.2.0",
29
+ "h5wasm": "^0.8.1",
30
+ "highlight.js": "^11.11.1",
31
+ "js-yaml": "^4.1.0",
32
+ "svelte": "5.34.3",
33
+ "svelte-multiselect": "11.1.1",
34
+ "svelte-zoo": "^0.4.19",
35
+ "three": "^0.177.0"
36
+ },
37
+ "devDependencies": {
38
+ "@playwright/test": "^1.53.0",
39
+ "@rollup/plugin-yaml": "^4.1.2",
40
+ "@stylistic/eslint-plugin": "^4.4.1",
41
+ "@sveltejs/adapter-static": "3.0.8",
42
+ "@sveltejs/package": "^2.3.11",
43
+ "@sveltejs/vite-plugin-svelte": "^5.1.0",
44
+ "@types/d3-array": "^3.2.1",
45
+ "@types/d3-color": "^3.1.3",
46
+ "@types/d3-format": "^3.0.4",
47
+ "@types/d3-interpolate-path": "^2.0.3",
48
+ "@types/d3-scale": "^4.0.9",
49
+ "@types/d3-scale-chromatic": "^3.1.0",
50
+ "@types/d3-shape": "^3.1.7",
51
+ "@types/d3-time-format": "^4.0.3",
52
+ "@types/three": "^0.177.0",
53
+ "@vitest/coverage-v8": "^3.2.3",
54
+ "d3-time-format": "^4.1.0",
55
+ "eslint": "^9.29.0",
56
+ "eslint-plugin-svelte": "^3.9.2",
57
+ "happy-dom": "^18.0.1",
58
+ "hastscript": "^9.0.1",
59
+ "mdsvex": "^0.12.6",
60
+ "mdsvexamples": "^0.5.0",
61
+ "prettier": "^3.5.3",
62
+ "prettier-plugin-svelte": "^3.4.0",
63
+ "rehype-autolink-headings": "^7.1.0",
64
+ "rehype-katex": "^7.0.1",
65
+ "rehype-slug": "^6.0.0",
66
+ "remark-math": "3.0.1",
67
+ "sharp": "^0.34.2",
68
+ "svelte-check": "^4.2.1",
69
+ "svelte-preprocess": "^6.0.3",
70
+ "svelte-toc": "^0.6.1",
71
+ "svelte2tsx": "^0.7.39",
72
+ "typescript": "5.8.3",
73
+ "typescript-eslint": "^8.34.1",
74
+ "vite": "^6.3.5",
75
+ "vitest": "^3.2.3"
76
+ },
77
+ "keywords": [
78
+ "svelte",
79
+ "periodic table",
80
+ "chemistry",
81
+ "data viz",
82
+ "plotting",
83
+ "component"
84
+ ],
85
+ "publishConfig": {
86
+ "access": "public"
87
+ },
88
+ "exports": {
89
+ "./element/data": {
90
+ "types": "./dist/element/data.d.ts",
91
+ "default": "./dist/element/data.js"
92
+ },
93
+ ".": {
94
+ "types": "./dist/index.d.ts",
95
+ "svelte": "./dist/index.js",
96
+ "default": "./dist/index.js"
97
+ },
98
+ "./composition": {
99
+ "types": "./dist/composition.d.ts",
100
+ "default": "./dist/composition.js"
101
+ },
102
+ "./colors": {
103
+ "types": "./dist/colors.d.ts",
104
+ "default": "./dist/colors.js"
105
+ },
106
+ "./io": {
107
+ "types": "./dist/io.d.ts",
108
+ "default": "./dist/io.js"
109
+ },
110
+ "./labels": {
111
+ "types": "./dist/labels.d.ts",
112
+ "default": "./dist/labels.js"
113
+ },
114
+ "./math": {
115
+ "types": "./dist/math.d.ts",
116
+ "default": "./dist/math.js"
117
+ },
118
+ "./periodic-table": {
119
+ "types": "./dist/periodic-table.d.ts",
120
+ "default": "./dist/periodic-table.js"
121
+ },
122
+ "./plot": {
123
+ "types": "./dist/plot.d.ts",
124
+ "default": "./dist/plot.js"
125
+ }
126
+ },
127
+ "types": "./dist/index.d.ts",
128
+ "files": [
129
+ "dist"
130
+ ]
131
+ }
package/readme.md ADDED
@@ -0,0 +1,95 @@
1
+ <h1 align="center">
2
+ <img src="static/logo.svg" alt="Logo" height="100">
3
+ </h1>
4
+
5
+ <h4 align="center">
6
+
7
+ [![Tests](https://github.com/janosh/matterviz/actions/workflows/test.yml/badge.svg)](https://github.com/janosh/matterviz/actions/workflows/test.yml)
8
+ [![GH Pages](https://github.com/janosh/matterviz/actions/workflows/gh-pages.yml/badge.svg)](https://github.com/janosh/matterviz/actions/workflows/gh-pages.yml)
9
+ [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/janosh/matterviz/main.svg?badge_token=nUqJfPCFS4uyMwcFSDIfdQ)](https://results.pre-commit.ci/latest/github/janosh/matterviz/main?badge_token=nUqJfPCFS4uyMwcFSDIfdQ)
10
+ [![Open in StackBlitz](https://img.shields.io/badge/Open%20in-StackBlitz-darkblue?logo=stackblitz)](https://stackblitz.com/github/janosh/matterviz)
11
+
12
+ </h4>
13
+
14
+ `matterviz` is a toolkit for building interactive web UIs for materials science: periodic tables, 3d crystal structures (and molecules, though needs some improvements!), Bohr atoms, nuclei, heatmaps, scatter plots. It's under active development and not yet ready for production use but we appreciate any feedback from beta testers! ๐Ÿ™
15
+
16
+ ![Screenshot of landing page](static/2023-02-13-landing-page.webp)
17
+
18
+ ## ๐Ÿ“ฆ &thinsp; Heatmap
19
+
20
+ This screenshot demonstrates the periodicity of elemental properties (i.e. why it's called periodic table). In this case, you're seeing recurring bumps and valleys in the first ionization energy as a function of atomic number.
21
+
22
+ ![Screenshot of periodic table heatmap](static/2023-02-13-heatmap.webp)
23
+
24
+ ## โš›๏ธ &thinsp; 3D Structure Viewer
25
+
26
+ ![3D Structure Viewer](https://github.com/janosh/matterviz/assets/30958850/72f78ad8-16fc-4eab-84ca-a985ce27e2b1)
27
+
28
+ ## โš›๏ธ &thinsp; Element Details Pages
29
+
30
+ The details page for gold.
31
+
32
+ <https://user-images.githubusercontent.com/30958850/186975855-8e0d94f9-e4e3-47a2-9354-9c012b37307c.mp4>
33
+
34
+ ## ๐Ÿ”จ &thinsp; Installation
35
+
36
+ ```sh
37
+ npm install --dev matterviz
38
+ ```
39
+
40
+ ## ๐Ÿ“™ &thinsp; Usage
41
+
42
+ Import the `PeriodicTable` component and pass it some heatmap values:
43
+
44
+ ```svelte
45
+ <script>
46
+ import { PeriodicTable } from 'matterviz'
47
+
48
+ const heatmap_values = { H: 10, He: 4, Li: 8, Fe: 3, O: 24 }
49
+ </script>
50
+
51
+ <PeriodicTable {heatmap_values} />
52
+ ```
53
+
54
+ ## ๐ŸŽฌ &thinsp; Events
55
+
56
+ `PeriodicTable.svelte` forwards the following events from each `ElementTile`:
57
+
58
+ 1. `click`
59
+ 1. `mouseenter`
60
+ 1. `mouseleave`
61
+ 1. `keyup`
62
+ 1. `keydown`
63
+
64
+ Each event is a Svelte `dispatch` event with the following `detail` payload:
65
+
66
+ ```ts
67
+ detail: {
68
+ element: ChemicalElement
69
+ active: boolean // whether the event target tile is currently active
70
+ dom_event: Event // the DOM event that triggered the Svelte dispatch
71
+ }
72
+ ```
73
+
74
+ See `DispatchPayload` and `PeriodicTableEvents` in `src/lib/index.ts`
75
+
76
+ ## ๐Ÿงช &thinsp; Coverage
77
+
78
+ | Statements | Branches | Lines |
79
+ | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
80
+ | ![Statements](https://img.shields.io/badge/statements-99.84%25-brightgreen.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-82.92%25-yellow.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-99.84%25-brightgreen.svg?style=flat) |
81
+
82
+ ## ๐Ÿ™ &thinsp; Acknowledgements
83
+
84
+ - Element properties in `src/lib/element-data.ts` were combined from [`Bowserinator/Periodic-Table-JSON`](https://github.com/Bowserinator/Periodic-Table-JSON/blob/master/PeriodicTableJSON.json) under Creative Commons license and [`robertwb/Periodic Table of Elements.csv`](https://gist.github.com/robertwb/22aa4dbfb6bcecd94f2176caa912b952) (unlicensed).
85
+ - Thanks to [Images of Elements](https://images-of-elements.com) for providing photos of elemental crystals and glowing excited gases.
86
+ - Thanks to [@kadinzhang](https://github.com/kadinzhang) and their [Periodicity project](https://ptable.netlify.app) [[code](https://github.com/kadinzhang/Periodicity)] for the idea to display animated Bohr model atoms and inset a scatter plot into the periodic table to visualize the periodic nature of elemental properties.
87
+ - Big thanks to all sources of element images. See [`fetch-elem-images.ts`](https://github.com/janosh/matterviz/blob/-/src/fetch-elem-images.ts) and [`static/elements`](https://github.com/janosh/matterviz/tree/main/static/elements).
88
+ - Thanks to [@ixxie](https://github.com/ixxie) ([shenhav.fyi](https://shenhav.fyi)) for a lot of great suggestions, UX ideas, helping me learn [`threlte`](https://threlte.xyz) and contributing the [`Bond.svelte`](https://github.com/janosh/matterviz/blob/-/src/lib/structure/Bond.svelte) component.
89
+
90
+ This project would not have been possible as a one-person side project without many fine open-source projects. ๐Ÿ™ To name just a few:
91
+
92
+ | 3D graphics | 2D graphics | Docs | Bundler | Testing |
93
+ | :-----------------------------: | :--------------------------------------: | :------------------------------------------: | :---------------------------------: | :----------------------------------: |
94
+ | [three.js](https://threejs.org) | [d3](https://d3js.org) | [mdsvex](https://mdsvex.com) | [vite](https://vitejs.dev) | [playwright](https://playwright.dev) |
95
+ | [threlte](https://threlte.xyz) | [sharp](https://sharp.pixelplumbing.com) | [rehype](https://github.com/rehypejs/rehype) | [sveltekit](https://kit.svelte.dev) | [vitest](https://vitest.dev) |