# `PhiaUi.Components.Chart`
[🔗](https://github.com/charlenopires/PhiaUI/blob/v0.1.17/lib/phia_ui/components/data/chart.ex#L1)

Chart integration component powered by the `PhiaChart` vanilla JS hook.

`phia_chart/1` renders a container `<div>` wired to the `PhiaChart` hook,
which initialises **Apache ECharts** (or **Chart.js** as a fallback) in the
browser. Chart options and series data are passed as JSON via `data-config`
and `data-series` HTML attributes — the component itself is pure server-side
HEEx with zero client-side Elixir knowledge.

## Architecture

The hook detects which library is loaded:

    window.echarts   → uses Apache ECharts
    window.Chart     → falls back to Chart.js

Chart configuration is split into two attributes:

- `data-config` — ECharts option object (axes, tooltip, series type). Built
  server-side from `:type` and `:labels` by `build_config/2`.
- `data-series` — array of series objects `[%{name: ..., data: [...]}]`.
  Passed as-is via `Jason.encode!/1`.

This split allows the hook to merge updated series data without replacing
the entire chart configuration on `push_event`.

## Chart types

| `:type`  | ECharts series type | Notes                                      |
|----------|---------------------|--------------------------------------------|
| `:line`  | `"line"`            | Standard line chart                        |
| `:bar`   | `"bar"`             | Vertical bar / column chart                |
| `:area`  | `"line"` + area     | Line chart with `areaStyle: {}` fill       |
| `:pie`   | `"pie"`             | Pie/donut; labels become data point names  |

## Basic example

    <.phia_chart
      id="revenue-chart"
      type={:area}
      title="Monthly Revenue"
      description="Last 12 months"
      series={[%{name: "MRR", data: [10_000, 12_500, 11_800, 14_200, 15_600]}]}
      labels={["Jan", "Feb", "Mar", "Apr", "May"]}
      height="350px"
    />

## Without ChartShell wrapper

Omit `:title` and `:description` to render only the raw chart canvas, useful
when embedding inside an existing card or layout:

    <.phia_chart
      id="sparkline"
      type={:line}
      series={[%{name: "Sessions", data: @daily_sessions}]}
      labels={@day_labels}
      height="80px"
      class="w-full"
    />

## Multiple series

    <.phia_chart
      id="acquisition-chart"
      type={:bar}
      title="User Acquisition"
      series={[
        %{name: "Organic",  data: [120, 145, 132, 178, 201]},
        %{name: "Paid",     data: [80,  95,  110, 88,  130]},
        %{name: "Referral", data: [30,  28,  45,  52,  40]}
      ]}
      labels={["Jan", "Feb", "Mar", "Apr", "May"]}
      height="400px"
    />

## Pie chart

For pie charts, `labels` become the data point names and `series` should
provide a single series whose `data` values correspond positionally to labels:

    <.phia_chart
      id="traffic-sources"
      type={:pie}
      title="Traffic Sources"
      series={[%{name: "Sources", data: [45, 30, 15, 10]}]}
      labels={["Organic", "Direct", "Referral", "Social"]}
      height="300px"
    />

## Live updates via push_event

Send updated series data from the server without a full re-render. The hook
listens for `"update-chart-{id}"` events:

    # In your LiveView handle_info or handle_event:
    socket = push_event(socket, "update-chart-revenue-chart", %{
      series: [%{name: "MRR", data: [50_000, 55_000, 62_000]}]
    })

The hook calls `chart.setOption/1` with a merge, so static configuration
(colors, axis formatting, tooltip) is preserved.

## Dark mode

PhiaChart listens for the `phia:theme-changed` custom DOM event (fired by
the `PhiaDarkMode` hook). When the event fires, the hook re-initialises the
chart with ECharts' dark theme applied automatically.

## Setup

1. Copy the hook with `mix phia.add chart` (or copy manually from
   `priv/templates/js/hooks/chart.js`).

2. Register the hook in your `app.js`:

       import PhiaChart from "./hooks/chart"
       let liveSocket = new LiveSocket("/live", Socket, {
         hooks: { PhiaChart }
       })

3. Install ECharts (recommended):

       npm install echarts

   Or load from CDN in `root.html.heex`:

       <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>

# `phia_chart`

Renders a chart container wired to the `PhiaChart` hook.

If `:title` is provided, the chart is wrapped in a `chart_shell/1` card.
Otherwise, the raw `<div phx-hook="PhiaChart">` is rendered directly.

Chart options are encoded to JSON at render time via `Jason.encode!/1` and
stored in `data-config` and `data-series` attributes. The hook reads these
attributes on mount to initialise the chart.

## Example (with card shell)

    <.phia_chart
      id="mrr"
      type={:area}
      title="MRR"
      series={[%{name: "Revenue", data: @mrr_data}]}
      labels={@month_labels}
      height="350px"
    />

## Example (raw canvas)

    <.phia_chart
      id="sparkline-mrr"
      type={:line}
      series={[%{name: "MRR", data: @sparkline}]}
      labels={@sparkline_labels}
      height="60px"
    />

## Attributes

* `id` (`:string`) (required) - Unique element ID for the chart container. Also used as the suffix for
  `push_event` targeting: to update this chart from the server, send
  `push_event(socket, "update-chart-{id}", %{series: [...]})`.

* `type` (`:atom`) - Chart type. Controls the ECharts series type and the base config generated
  by `build_config/2`. See the module docs for the full type matrix.

  Defaults to `:line`. Must be one of `:line`, `:bar`, `:pie`, or `:area`.
* `series` (`:list`) - List of series maps. Each map must have at least a `"data"` key (list of
  values). A `"name"` key is recommended for tooltips and legends:

      [%{name: "Revenue", data: [100, 200, 150]},
       %{name: "Costs",   data: [80, 120, 90]}]

  For pie charts, `data` values correspond positionally to `labels`.

  Defaults to `[]`.
* `labels` (`:list`) - X-axis category labels (or pie slice names for `:pie` charts). Must match
  the length of each series' `data` list:

      labels={["Jan", "Feb", "Mar", "Apr", "May"]}

  Defaults to `[]`.
* `height` (`:string`) - CSS height of the chart container. Accepts any CSS length: `"300px"`,
  `"20rem"`, `"50vh"`. The chart hook reads this from the container's
  computed style to size the ECharts instance correctly.

  Defaults to `"300px"`.
* `title` (`:string`) - When provided, wraps the chart in a `chart_shell/1` card with this title
  in the header. When `nil`, renders only the raw chart canvas (no card wrapper).

  Defaults to `nil`.
* `description` (`:string`) - Optional description shown in the `chart_shell` header below the title.
  Only relevant when `:title` is also provided. Ignored when `:title` is nil.

  Defaults to `nil`.
* `class` (`:string`) - Additional CSS classes for the chart container. Defaults to `nil`.
* Global attributes are accepted. HTML attributes forwarded to the chart container or card element.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
