# Equilibrium

> EquilibriumModel is a reaction in a closed vessel.

Page: https://fframes-kit.pages.dev/docs/chemistry/equilibrium/
Cargo feature: `chemistry` (`fframes-kit = { version = "..", features = ["chemistry"] }`)

`EquilibriumModel` is a reaction in a closed vessel. Each species has a name, a coefficient
(negative for a reactant) and a starting concentration in mol/L. The mixture moves along the
reaction to where the reaction quotient `Q` equals `k`, closing in by a factor of `e` every
`settle` seconds. `disturb(at, species, delta)` adds or removes some of a species later, and the
mixture settles again, as Le Chatelier's principle says. `concentrations(seconds)` and
`quotient` give the numbers.

`Equilibrium` shows the concentrations as bars, reactants in `reactant_color` and products in
`product_color`, starting the model's clock at `delay`. With `labels` each bar has its formula
under it (the digits set as subscripts) and its concentration over it. A line above compares
`Q` with `K`: whether the reaction runs forward, runs in reverse or is at equilibrium. Gallery
scene: `Equilibrium` (hydrogen iodide, then more hydrogen).

Gallery clip of `Equilibrium`: https://fframes-kit.pages.dev/media/scenes/Equilibrium-1d7adf62.mp4

```rust
use fframes_kit::prelude::*;

let model = EquilibriumModel::new(&[("H2", -1, 1.0), ("I2", -1, 1.0), ("HI", 2, 0.0)], 49.0, 0.5)
    .disturb(3.0, 0, 1.0);
// settled again long after the extra hydrogen
assert!((model.quotient(&model.concentrations(30.0)) - 49.0).abs() < 1e-6);

fn figure<'a>(ui: &mut Ui<'a, '_, '_>, model: &'a EquilibriumModel) -> Svgr<'a> {
    ui.show(Equilibrium {
        model: Some(model),
        delay: 0.5,
        ..ui.defaults()
    })
}
```

## API

Components are plain structs. Set the fields you need and fill the rest with `..ui.defaults()`: the defaults below come from the current theme (`theme.` values are fields of `Theme`).

### Equilibrium

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `model` | `Option<&EquilibriumModel>` | `None` | The `EquilibriumModel` whose concentrations are drawn; `None` draws nothing. |
| `delay` | `f32` | `0.0` | Seconds after the container's start when the model's clock starts. |
| `center` | `(f64, f64)` | `(0.0, 0.0)` | The middle of the bar area, in units of `ui.space`. |
| `width` | `f32` | `900.0` | Width in pixels of the bar area, shared equally between the species. |
| `height` | `f32` | `420.0` | Height in pixels of the bar area, the bar height at `max` mol/L. |
| `max` | `Option<f64>` | `None` | Concentration in mol/L that fills the full height; `None` uses the model's highest concentration. |
| `labels` | `bool` | `true` | Writes each species name and concentration and the `Q` against `K` line; `false` for bare bars. |
| `reactant_color` | `Color` | `theme.colors.accent` | Colour of the bars of reactants (negative coefficient). |
| `product_color` | `Color` | `theme.colors.highlight` | Colour of the bars of products (positive coefficient). |
| `axis_color` | `Color` | `theme.colors.muted` | Colour of the baseline under the bars. |
| `text_color` | `Color` | `theme.colors.text` | Colour of the names, concentrations and the `Q`/`K` line. |
| `equal_color` | `Color` | `Color::hex("#69db7c")` | Colour of the `Q`/`K` line once the mixture is at equilibrium. |
| `stroke_width` | `f32` | `theme.stroke.regular` | Width in pixels of the baseline. |
| `enter` | `Option<EnterAnim>` | `None` | How the baseline draws; `None` shows it from the start. |
| `exit` | `Option<ExitAnim>` | `None` | How the baseline leaves at the end of the container; `None` stays. |
| `parts_enter` | `Option<FadeIn>` | `None` | Fade in of the bars and labels; `None` for none. |
| `parts_exit` | `Option<FadeOut>` | `None` | Fade out of the bars and labels before the end; `None` for none. |

Feature `chemistry` · [Source](https://github.com/khanhthanhdev/fframes-kit/blob/main/fframes-kit/src/kits/chemistry/equilibrium.rs#L166)
