Structure Widget
The structure widget turns a metadata-enabled Molkit SVG into an interactive teaching panel on your page: property overlays, an atom inspector, view tabs for visual sets, a resonance stepper, R-group pickers, and a 3D model with an optional electrostatic potential map. It ships as one self-contained script, molkit-widget.js, which defines window.MolkitWidget. Load that file and you have everything; the only other file is molkit-widget-esp.js, which the widget fetches from the same folder when a reader turns on a map.
The widget reads the attributes documented on Chemistry metadata. Any SVG from the Export SVG dialog of a current build carries them, including the 3D conformer the 3D tab needs and the mk:dipole records the dipole arrow uses. Without mk:dipole, the widget sums the drawn bond dipoles itself. Files from older builds lack some of it (for example mk:dipole-measured and data-mk-lp-delocalized); the widget still works with them but shows less.
Loading
Load the script once. It assigns window.MolkitWidget and then dispatches a molkit-widget-ready event on window, so a page that loads it asynchronously can wait for either.
<div id="mol-panel" style="width: 480px; height: 360px"></div><script src="/js/molkit-widget.js" defer></script><script> function start() { const inst = MolkitWidget.mount(document.getElementById('mol-panel'), { src: '/img/ethanol.svg', }); document.getElementById('close').addEventListener('click', () => MolkitWidget.destroy(inst)); } if (window.MolkitWidget) start(); else window.addEventListener('molkit-widget-ready', start, { once: true });</script>API
| Call | What it does |
|---|---|
MolkitWidget.mount(hostEl, opts) | Renders into hostEl and returns an instance handle synchronously. With opts.src the SVG is fetched first, so the widget appears after the fetch resolves |
MolkitWidget.update(inst, opts) | Replaces the structure in the same host, for example when the reader picks another molecule. Theme and sizing options carry over |
MolkitWidget.setTheme(inst, theme) | 'light' or 'dark'. Sets mk-light or mk-dark on the structure SVG and themes the widget chrome. Without a call, both follow the OS setting |
MolkitWidget.destroy(inst) | Disconnects observers, frees the 3D viewer, and empties the host |
MolkitWidget.version | '0.1.0' |
mount options:
| Option | Meaning |
|---|---|
src | URL of an exported SVG |
svgNode | An SVG element you already have, used instead of src |
initial | 'auto' (default). '3d' or 'both' opens in the 3D view |
large | true enlarges the widget and its hover cards for projection |
footer | true adds a credit bar at the bottom |
fillWindow | false hides the Fill window button, for hosts that are already full-page |
espAuto | true opens the figure with its electrostatic potential map on: the widget switches to the 3D tab and turns the map on once the 3D view is ready, at the camera angle stored in the export. Use it for a page that shows a figure’s map in place of its drawing. A file without a map just opens on the 3D tab |
The host element can be 0 by 0 at mount time. A ResizeObserver sizes the widget and the 3D viewer when the host gets its size. A failed fetch or an unparseable file renders an inline “Could not load structure.” message instead of throwing.
The lower-level MolkitChem.create(container, source, options) in public/molkit-chem.js is what the facade calls. It also accepts chrome: false (overlays only, no control bar), overlay (a property key to show on open), view (a view id to open on), maxWidth, and the callbacks onInspect(info) and onOverlay(key).
What the reader sees
Property overlays. One overlay is shown at a time: formal charge, oxidation state, hybridization, geometry, lone pairs, electronegativity, polarity. The legend text for geometry reads “VSEPR molecular geometry: the shape the bonded atoms make (water is bent).”
Atom card. Hover, tap, or keyboard focus shows an atom’s hybridization, geometry, bond angle, domains, formal charge, oxidation state, and octet, with a one-line explanation under each. Rows with no data are left out; an atom without data-mk-octet (a generic, a bridging hydrogen, a bare metal ion) has no Octet row. For an atom with data-mk-lp-delocalized, the hybridization line reads ”… domains, but a lone pair is delocalized into the adjacent π bond”, and a planar amide nitrogen’s angle line reads “sp² ideal: the lone pair is delocalized into the adjacent π bond, so it no longer compresses the angle”. For a centre whose nonbonding domain is one unpaired electron (NO2), the card says “unpaired electron” and explains that the angle opens.
View tabs. A visual set gets one tab per view (Lewis, VSEPR, Condensed, Bondline, Fischer, Orbitals) plus a 3D tab when the file carries a conformer. A view with two Lewis layouts gets a sub-toggle between them, and a set that mixes octet models gets an Expanded / Octet sub-toggle.
Orbital pictures. A named group that holds orbital pictures gets an Orbitals tab. When it holds several pictures, numbered buttons beside the tab choose one, and the line under the picture says what it shows: the author’s caption, or All orbitals or Pi system, followed by “(2 of 3)” and so on.
Resonance and R-group structures. A file that holds several resonance forms gets a stepper whose label reads “Form 1/3” and so on; step through the forms one at a time, or pick “All forms” from the rail to show them together. A generic structure with R-group definitions gets a picker rail at the side; choosing a substituent swaps in that molecule and returns the widget to the 2D view.
Window controls. Two buttons at the top right of the identity bar enlarge the widget. Fill window covers the browser window with a fixed overlay and works inside iframes; Full screen uses the browser’s Fullscreen API and falls back to the window overlay when the API is blocked. Pass fillWindow: false to hide the Fill window button on a page that is already full-page. With footer: true, a bar at the bottom reads “Made with Molkit” and links to molkit.com.
Lone pairs and Net dipole checkboxes. Lone pairs shows or hides every lone pair and appears only when the structure has some. Net dipole appears only while the polarity overlay is active and there is a molecular dipole arrow to hide; unchecking it hides the arrow in 2D and 3D while bond dipoles stay drawn.
Browser storage
The widget stores three choices per browser in localStorage. Every read and write is wrapped so the widget works when storage is blocked.
| Key | Values | Behaviour |
|---|---|---|
mkw-view | a view id, e.g. lewis, vsepr | Written when the reader picks a 2D view tab. Used on the next structure only if the file has no data-mk-default-view; the author’s default always wins |
mkw-lp | on, off | Lone pairs checkbox. With no stored value, lone pairs display as exported |
mkw-dipole | on, off | Net dipole checkbox. Default is on |
Initial view order: the view option to MolkitChem.create if that view exists, then the file’s data-mk-default-view, then mkw-view, then the first view.
The dipole arrow
The arrow is a prediction: the bond-sum record from mk:dipole. The gasteiger record is never displayed. In a visual set, each depiction’s arrow comes from the mk:dipole whose mk:conformer-3d has the same data-mk-view (and data-mk-lewis-layout) as the atoms on screen, because each conformer is aligned to its own drawing. Files without view tags fall back to matching by component index.
Each drawn species is classified into one of four states, and the legend shows a verdict and a note:
| State | When | Verdict text |
|---|---|---|
| not determinable | net formal charge is not zero, or the drawing is separate ions | ”Dipole not shown”, with the reason. Ions drawn in brackets get no arrow |
| zero by symmetry | prediction is zero and mk:dipole-measured has mu="0" | ”Nonpolar”, stating μ = 0 by symmetry |
| prediction zero | prediction is zero otherwise | ”Bond-dipole prediction: 0”. Without a measured value the note says this alone does not prove the molecule is nonpolar; with one, it names the measured moment |
| predicted | prediction is nonzero | ”Bond-dipole prediction → polar”, with “Measured μ = … D (year).” when a reference exists |
When mk:dipole-measured carries negative-end (carbon monoxide, nitric oxide), the verdict becomes “Measured dipole: negative end on C” (or N), and the note says the species departs from the rule of thumb and that the arrow shows the measured direction. For a radical, the note adds that the prediction points the right way but overstates the size. The predicted magnitude is never printed, because bond-sum is not in debye.
3D view
The 3D tab appears when the file has a mk:conformer-3d and the species type allows it. ionic shows the disabled reason “3D crystal view coming soon” and monatomic-ion shows “No 3D model for a single ion”. When the file has several conformers, the one marked data-mk-conformer-primary is used.
The interactive viewer uses 3Dmol.js, loaded on the first 3D open from https://cdn.jsdelivr.net/npm/3dmol@2.5.5/build/3Dmol-min.js. If window.$3Dmol is already defined, the widget uses it and makes no request, so a host that must work offline or avoid third-party scripts can load its own copy of 3Dmol before opening the 3D tab.
If 3Dmol cannot run, the widget draws a static 3D view that can still be dragged to rotate, with a message naming the cause:
- “This browser could not start WebGL, so interactive 3D is unavailable …” when the library loaded but WebGL failed.
- A message that interactive 3D is unavailable offline, when the library could not be fetched.
3D controls
The model responds to the mouse and keyboard: drag to rotate, roll the mouse wheel up to zoom in and down to zoom out (as in the 2D view), arrow keys rotate, + and - zoom, and Home resets the view. A control pad in the corner offers the same moves as buttons, laid out in three rows: Roll left, Rotate up, Roll right; Rotate left, Reset view, Rotate right; Zoom out, Rotate down, Zoom in. The chevron above the pad (Hide controls / Show controls) folds it away.
Three toggle buttons change the drawing:
| Toggle | Default | Effect |
|---|---|---|
| Element labels | on | Element symbols on the atoms |
| High-contrast colors | off | A higher-contrast atom palette |
| Spacefill (vs ball-and-stick) | off | Space-filling spheres instead of ball-and-stick |
The 3D model also draws the net dipole arrow, and it follows the Net dipole checkbox in the same way as the 2D view.
Coordinate bonds (:c) draw as dashed sticks, and delocalized bonds (:d) draw as a single stick with a dashed companion.
Electrostatic potential maps
When the figure carries an mk:esp block (see Chemistry metadata), the 3D view gets an Electrostatic potential map button. Nothing extra loads until a reader presses it. The first press fetches molkit-widget-esp.js from the folder molkit-widget.js was loaded from, then the map data, and turns the map on; later presses show and hide it. A legend in the corner shows the colour scale in kJ/mol.
A Map options button beside it opens a panel with Colours, Opacity, Show (surface, a cut through the molecule, or both) and, for a cut, Cut, Position and Contour lines. The i button shows the map’s caption, any note and its citations. The figure’s display settings from the export are the starting values; the reader’s changes are not stored.
A map in a separate .esp file is looked for in two places, in order:
- The path written in the SVG (for example
esp/water-1a2b3c4d.esp), resolved against the SVG’s own address. - The file name alone, under a site-wide folder you set with
MolkitWidget.espBaseorwindow.MolkitEspBase.
A file whose checksum differs from the one in the SVG is refused, and the button reports that the map could not be loaded. Only a plain relative path ending in .esp is followed. To serve molkit-widget-esp.js from somewhere else, set window.MolkitEspUrl to its address before the first press.
A map calculated on a different geometry (a relaxed one) moves the model to that geometry while the map is on and puts it back when it is off.
Building the widget from the Molkit repo
Host pages only need the built molkit-widget.js. If you work in the Molkit repository, npm run build:widget produces it by concatenating public/molkit-widget-kit.js (theme and tooltip layer), the engines in src-widget/, public/molkit-chem.js (the 2D, data and 3D renderer) and the facade src-widget/molkit-widget.facade.js. The same command builds public/molkit-widget-esp.js from src-widget/esp/; copy it next to molkit-widget.js on your site.
See also
- Chemistry metadata for every attribute the widget reads
- CSS theming for the
mk-lightandmk-darkclassessetThemeapplies - Embedding SVG exports for using exports without the widget
- Electrostatic Potential Maps for making the maps in Molkit