# FoodWeb

> FoodWeb draws who eats whom: species, and the arrows of eats as (prey, predator) pairs pointing the way energy flows.

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

`FoodWeb` draws who eats whom: `species`, and the arrows of `eats` as `(prey, predator)`
pairs pointing the way energy flows. Names that are not in `species` are left out.

- **Levels:** producers (species that eat nothing here) sit at the bottom, and every other
  species sits one level above its highest prey, so the longest food chain sets its trophic
  level (`levels()`).
- **Order:** each level is ordered by where its prey and predators sit, to keep arrows from
  crossing. Arrows that would run through another species bend round it.
- **Look:** each species is a pill coloured by its level from `level_colors`, and the levels
  are named at the left from `level_names`.
- **Motion:** from `delay` the levels appear from the bottom, one every `level_time` seconds,
  and the arrows into each level draw as it does. With `flow`, dots of energy then run along
  every arrow.

Gallery scene: `FoodWeb`.

Gallery clip of `FoodWeb`: https://fframes-kit.pages.dev/media/scenes/FoodWeb-ec024487.mp4

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

let pond = FoodWeb {
    species: ["Algae", "Snail", "Fish", "Heron"].map(String::from).to_vec(),
    eats: [("Algae", "Snail"), ("Snail", "Fish"), ("Algae", "Fish"), ("Fish", "Heron")]
        .map(|(a, b)| (a.to_owned(), b.to_owned()))
        .to_vec(),
    ..FoodWeb::default()
};
assert_eq!(pond.levels(), [0, 1, 2, 3]); // the fish eats the snail, so it sits above it

fn pond_web<'a>(ui: &mut Ui<'a, '_, '_>) -> Svgr<'a> {
    ui.show(FoodWeb { flow: false, ..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`).

### FoodWeb

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `species` | `Vec<String>` | — | Names of the species, each drawn as a pill. |
| `eats` | `Vec<(String, String)>` | `pairs .iter() .map(\|&(a, b)\| (a.to_owned(), b.to_owned())) .collect()` | `(prey, predator)` pairs by species name; each draws an arrow from prey to predator, the way energy flows. |
| `delay` | `f32` | `0.0` | Seconds after the container's start before the bottom level appears. |
| `level_time` | `f32` | `0.8` | Seconds between one trophic level appearing and the next above it. |
| `center` | `(f64, f64)` | `(0.4, -0.35)` | The middle of the web, in units of `ui.space`. |
| `level_gap` | `f32` | `150.0` | Pixels between neighbouring trophic levels. |
| `slot` | `f32` | `230.0` | Pixels between neighbouring species on one level. |
| `flow` | `bool` | `true` | Dots of energy run along every arrow once it is drawn when `true`. |
| `level_colors` | `Vec<Color>` | — | Fill of the species pills by trophic level, producers first; the last colour repeats for higher levels. |
| `level_names` | `Vec<String>` | — | Names written at the left of each level, producers first; a level past the end has no name. |
| `arrow_color` | `Color` | `theme.colors.muted` | Colour of the arrows. |
| `flow_color` | `Color` | `Color::hex("#ffe066")` | Colour of the energy dots. |
| `name_style` | `TextStyle` | `name_style` | The font of the species names: family, size in pixels and weight. |
| `level_style` | `TextStyle` | `theme.typography.caption` | The font of the level names: family, size in pixels and weight. |
| `text_color` | `Color` | `Color::WHITE` | Colour of the species names. |
| `level_color` | `Color` | `theme.colors.muted` | Colour of the level names. |
| `enter` | `Option<FadeIn>` | `None` | Fade in at the start; `None` for none. |
| `exit` | `Option<FadeOut>` | `None` | Fade out before the end; `None` for none. |

Methods:

- `fn levels(&self) -> Vec<usize>`: The trophic level of each of `species`: 0 for producers (they eat nothing here), otherwise one above the highest of their prey, so the longest food chain sets it. Feeding cycles stop climbing after one level per species.

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