# CartesianChart

CartesianChart ist eine vielseitige Diagrammkomponente zur Darstellung von Metriken über Zeit. Sie kann entweder als Liniendiagramm (Line) oder Flächendiagramm (Area) konfiguriert werden.

## Overview

# Playground

Verwende `<CartesianChart />`, um ein CartesianChart darzustellen. Beachte
dabei, dass zum Rendern entweder das übergeordnete Parent eine feste Höhe
vorgeben muss oder das Chart selbst über die Property `height` eine eigene Höhe
erhalten muss. Mit `typedCartesianChart<T>` lässt sich ein Chart für einen
bestimmten Datentyp erzeugen.

```tsx
import { typedCartesianChart } from "@mittwald/flow-react-components";

export default () => {
  const CartesianChart = typedCartesianChart<{
    Zeit: string;
    Datenbanken: number;
    Projekte: number;
  }>();

  return (
    <CartesianChart.Chart
      data={[
        {
          Zeit: "0 Uhr",
          Datenbanken: 40,
          Projekte: 24,
        },
        {
          Zeit: "1 Uhr",
          Datenbanken: 30,
          Projekte: 13,
        },
        {
          Zeit: "2 Uhr",
          Datenbanken: 20,
          Projekte: 78,
        },
        {
          Zeit: "3 Uhr",
          Datenbanken: 27,
          Projekte: 39,
        },
      ]}
    >
      <CartesianChart.Area dataKey="Datenbanken" unit="%" />
      <CartesianChart.Area
        dataKey="Projekte"
        color="palatinate-blue"
        unit="%"
      />
      <CartesianChart.XAxis dataKey="Zeit" />
      <CartesianChart.YAxis domain={[0, 100]} unit=" %" />
      <CartesianChart.Grid />
      <CartesianChart.Legend />
      <CartesianChart.Tooltip />
    </CartesianChart.Chart>
  );
}
```

---

# Darstellungstypen

Im CartesianChart können unterschiedliche Darstellungstypen wie `<Area />`,
`<Line />` oder eine Kombination aus beiden verwendet werden.

**Line:** Zeigt die Entwicklung einzelner Objekte über einen Zeitraum und
ermöglicht den Vergleich zwischen ihnen.

```tsx
import {
  typedCartesianChart,
  Heading,
  Section,
} from "@mittwald/flow-react-components";

export default () => {
  const data = [
    {
      Datum: "1.9.2025",
      "Projekt A": 1256,
      "Projekt B": 345,
      "Projekt C": 467,
    },
    {
      Datum: "2.9.2025",
      "Projekt A": 1342,
      "Projekt B": 876,
      "Projekt C": 45,
    },
    {
      Datum: "3.9.2025",
      "Projekt A": 342,
      "Projekt B": 576,
      "Projekt C": 123,
    },
  ];

  const CartesianChart = typedCartesianChart<{
    Datum: string;
    "Projekt A": number;
    "Projekt B": number;
    "Projekt C": number;
  }>();

  return (
    <Section>
      <Heading>Besucher</Heading>
      <CartesianChart.Chart data={data} height="300px">
        <CartesianChart.Line dataKey="Projekt A" />
        <CartesianChart.Line
          dataKey="Projekt B"
          color="palatinate-blue"
        />
        <CartesianChart.Line
          dataKey="Projekt C"
          color="tangerine"
        />
        <CartesianChart.XAxis dataKey="Datum" />
        <CartesianChart.YAxis />
        <CartesianChart.Grid />
        <CartesianChart.Legend />
        <CartesianChart.Tooltip
          formatter={(v, k) => `${k} (${v} Besucher)`}
        />
      </CartesianChart.Chart>
    </Section>
  );
}
```

**Area:** Zeigt die Entwicklung des Gesamtwerts über einen Zeitraum und den
jeweiligen Anteil einzelner Objekte daran.

```tsx
import {
  Heading,
  Section,
  typedCartesianChart,
} from "@mittwald/flow-react-components";

export default () => {
  const data = [
    {
      Datum: "1.9.2025",
      Datenbanken: 10,
      Webspace: 15.4,
      Email: 5.1,
    },
    {
      Datum: "2.9.2025",
      Datenbanken: 32.9,
      Webspace: 25.6,
      Email: 10,
    },
    {
      Datum: "3.9.2025",
      Datenbanken: 40,
      Webspace: 20.2,
      Email: 8,
    },
  ];

  const CartesianChart = typedCartesianChart<{
    Datum: string;
    Datenbanken: number;
    Webspace: number;
    Email: number;
  }>();

  return (
    <Section>
      <Heading>Speicherplatz</Heading>
      <CartesianChart.Chart data={data} height="300px">
        <CartesianChart.Area
          dataKey="Datenbanken"
          unit="%"
        />
        <CartesianChart.Area
          dataKey="Webspace"
          color="palatinate-blue"
          unit="%"
        />
        <CartesianChart.Area
          dataKey="Email"
          color="tangerine"
          unit="%"
        />
        <CartesianChart.XAxis dataKey="Datum" />
        <CartesianChart.YAxis domain={[0, 100]} unit=" %" />
        <CartesianChart.Grid />
        <CartesianChart.Legend />
        <CartesianChart.Tooltip
          formatter={(value, name) =>
            `${name}: ${Intl.NumberFormat(undefined, {
              style: "unit",
              unit: "gigabyte",
            }).format(
              typeof value === "number" ? value : 0,
            )}`
          }
          progressBarFormatter={(value) =>
            Intl.NumberFormat(undefined, {
              style: "unit",
              unit: "gigabyte",
            }).format(typeof value === "number" ? value : 0)
          }
        />
      </CartesianChart.Chart>
    </Section>
  );
}
```

---

# Color

Für die Farbgebung der Daten können
[Categorical Colors](/02-foundations/01-design/02-colors#categorical-color) oder
eigene Farben verwendet werden. Es sollte sichergestellt sein, dass Farben, die
direkt nebeneinander liegen, einen ausreichenden Kontrast zueinander haben.

```tsx
import { typedCartesianChart } from "@mittwald/flow-react-components";

export default () => {
  const CartesianChart = typedCartesianChart<{
    Zeit: string;
    Datenbanken: number;
    Projekte: number;
  }>();

  return (
    <CartesianChart.Chart
      data={[
        {
          Zeit: "0 Uhr",
          Datenbanken: 40,
          Projekte: 24,
        },
        {
          Zeit: "1 Uhr",
          Datenbanken: 30,
          Projekte: 13,
        },
        {
          Zeit: "2 Uhr",
          Datenbanken: 20,
          Projekte: 78,
        },
        {
          Zeit: "3 Uhr",
          Datenbanken: 27,
          Projekte: 39,
        },
      ]}
    >
      <CartesianChart.Area
        dataKey="Datenbanken"
        color="lime"
        unit="%"
      />
      <CartesianChart.Area
        dataKey="Projekte"
        color="#555"
        unit="%"
      />
      <CartesianChart.XAxis dataKey="Zeit" />
      <CartesianChart.YAxis domain={[0, 100]} unit=" %" />
      <CartesianChart.Grid />
      <CartesianChart.Legend />
      <CartesianChart.Tooltip />
    </CartesianChart.Chart>
  );
}
```

---

# Synchronisierte Charts

Zwei CartesianCharts können synchronisiert werden, um den gleichen Zeitraum
darzustellen. Dadurch lassen sich verschiedene Metriken zeitlich exakt
vergleichen.

```tsx
import {
  typedCartesianChart,
  Heading,
  Section,
} from "@mittwald/flow-react-components";

export default () => {
  interface ChartData {
    Zeit: string;
    Datenbanken: number;
    Projekte: number;
  }

  const CartesianChart = typedCartesianChart<ChartData>();

  return (
    <Section>
      <Heading>CPU</Heading>
      <CartesianChart.Chart
        data={[
          {
            Zeit: "0 Uhr",
            Datenbanken: 40,
            Projekte: 24,
          },
          {
            Zeit: "1 Uhr",
            Datenbanken: 30,
            Projekte: 13,
          },
          {
            Zeit: "2 Uhr",
            Datenbanken: 20,
            Projekte: 78,
          },
          {
            Zeit: "3 Uhr",
            Datenbanken: 27,
            Projekte: 39,
          },
        ]}
        height="200px"
        syncId="syncedCharts"
      >
        <CartesianChart.Area
          dataKey="Datenbanken"
          unit="%"
        />
        <CartesianChart.Area
          dataKey="Projekte"
          color="palatinate-blue"
          unit="%"
        />
        <CartesianChart.XAxis dataKey="Zeit" />
        <CartesianChart.YAxis domain={[0, 100]} unit=" %" />
        <CartesianChart.Grid />
        <CartesianChart.Tooltip />
      </CartesianChart.Chart>
      <Heading>RAM</Heading>
      <CartesianChart.Chart
        data={[
          {
            Zeit: "0 Uhr",
            Datenbanken: 39,
            Projekte: 27,
          },
          {
            Zeit: "1 Uhr",
            Datenbanken: 30,
            Projekte: 13,
          },
          {
            Zeit: "2 Uhr",
            Datenbanken: 63,
            Projekte: 10,
          },
          {
            Zeit: "3 Uhr",
            Datenbanken: 24,
            Projekte: 40,
          },
        ]}
        syncId="syncedCharts"
      >
        <CartesianChart.Area
          dataKey="Datenbanken"
          unit="%"
        />
        <CartesianChart.Area
          dataKey="Projekte"
          color="palatinate-blue"
          unit="%"
        />
        <CartesianChart.XAxis dataKey="Zeit" />
        <CartesianChart.YAxis domain={[0, 100]} unit=" %" />
        <CartesianChart.Grid />
        <CartesianChart.Legend />
        <CartesianChart.Tooltip />
      </CartesianChart.Chart>
    </Section>
  );
}
```

---

## Mit EmptyView

Der EmptyView wird angezeigt, sobald die Property `data` des Charts entweder ein
leeres Array enthält oder `undefined` ist. Er dient dazu, leere Zustände visuell
zu kennzeichnen und bietet Orientierung bei Ausnahmefällen wie Ladefehlern,
fehlgeschlagenen Datenabfragen oder nicht vorhandenen Ergebnissen.

```tsx
import {
  CartesianChart,
  Flex,
  Heading,
  IconMonitoring,
  IllustratedMessage,
  XAxis,
  YAxis,
} from "@mittwald/flow-react-components";

export default () => {
  const emptyView = (
    <IllustratedMessage>
      <IconMonitoring />
      <Heading>Keine Daten verfügbar</Heading>
    </IllustratedMessage>
  );

  return (
    <Flex direction="row" grow>
      <CartesianChart emptyView={emptyView}>
        <XAxis />
        <YAxis />
      </CartesianChart>
    </Flex>
  );
}
```


## Develop

# Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `data` | `ChartDataValue[]` | - | - |
| `height` | `string` | - | - |
| `emptyView` | `ReactNode` | - | View that is provided when data is empty/undefined |
| `flexGrow` | `boolean` | - | Allow the height controlling container to set flex-grow: 1. Can only be used in combination with `height` |
| `className` | `string` | - | - |
| `syncId` | `string \| number` | - | Charts with the same syncId will synchronize Tooltip and Brush events. @see [Synchronized Charts Example](https://recharts.github.io/en-US/examples/SynchronizedAreaChart/) |
| `syncMethod` | `SyncMethod` | - | Customize how the charts will synchronize tooltips and brushes. `index`: synchronize using the data index in the data array. Index expects that all data has the same length. `value`: synchronize using the data value on categorical axis (categorical: XAxis in horizontal layout, YAxis in vertical layout). function: a custom sync method which receives tick and data as argument and returns an index. @defaultValue index |
| `children` | `ReactNode` | - | - |


## Guidelines

# Grundlagen

## Best practices

Achte bei der Verwendung eines CartesianCharts darauf, dass ...

- die x-Achse immer zeitbasiert ist.
- Dimensionen mit [Categorical Colors](/02-foundations/01-design/02-colors)
  dargestellt werden.
- bei der Area-Darstellung die Areas nach Größe sortiert werden, mit der größten
  Area unten.
- die Anzahl der dargestellten Dimensionen übersichtlich bleibt, um Lesbarkeit
  sicherzustellen.

## Verwendung

Verwende ein CartesianChart, um ...

- Trends von Metriken über längere Zeiträume hinweg zu zeigen.
- den relativen Anteil mehrerer Dimensionen an einem Gesamtwert darzustellen
  (mit Area-Darstellung).
- Veränderungen bei einer oder mehreren Dimensionen miteinander zu vergleichen.

