# `Noora.Chart`

A powerful charting component powered by ECharts.

## Example

```elixir
<.chart
  id="revenue-chart"
  type="line"
  series={[10, 20, 30, 40]}
  labels={["Q1", "Q2", "Q3", "Q4"]}
  title="Quarterly Revenue"
/>
```

## Custom formatters

For labels, we offer several built-in formatters:

- `formatSeconds`: Formats seconds into human readable time (e.g., "30s", "2m 30s", "1h 5m")
- `formatMilliseconds`: Formats milliseconds into human readable time
- `formatHours`: Formats hours into human readable time (e.g., "30m", "2h 30m", "1d 5h")
- `formatBytes`: Formats bytes into human readable size (e.g., "1.5 KB", "2 MB", "1 GB")
- `formatMbps`: Formats bytes/second into human readable throughput in megabits per second (e.g., "1.0 Mbps", "10.0 Mbps")
- `toLocaleDate`: Formats dates into locale-specific format
- `firstAndLastDate`: Renders the first and last label only as dates. This is useful for time series charts.

If this does not match your use case, you can also pass a completely custom formatter. This expects a global `nooraChartFormatters` object
with a function named after the formatter you want to use. For example, if you want to use a "first label only" formatter, you can define
a function named `firstLabelOnly` in the `nooraChartFormatters` object as such:

```js
nooraChartFormatters = {
  firstLabelOnly: (el) => (value, index) => {
    if (index === 0) {
      return value;
    }
  }
};
```

You can use these function-based formatters in your chart configuration as such:

```elixir
%{
  extra_options: %{
    xAxis: %{
      axisLabel: %{
        formatter: "fn:firstLabelOnly"
      }
    }
  }
```

# `chart`

## Attributes

* `id` (`:string`) (required) - The ID used for the chart container.
* `type` (`:string`) - The type of chart to render. Defaults to "bar".
  Available types: bar, line, pie, scatter, radar

  Defaults to `"bar"`. Must be one of `"bar"`, `"line"`, `"pie"`, `"scatter"`, or `"radar"`.
* `series` (`:any`) - The series data for the chart. Structure depends on chart type:

  For bar/line charts:
    - A list of values: [10, 20, 30]
    - A list of maps with names: [%{name: "Series 1", values: [10, 20, 30]}]
    - A list of series with different types: [%{name: "Bar", type: "bar", values: [10, 20, 30]}, %{name: "Line", type: "line", values: [5, 15, 25]}]
    - A list of time series: [%{name: "Series 1", data: [["2024-01-01", 10], ["2024-01-02", 20]]}]

  For pie charts:
    - A list of maps with name and value: [%{name: "A", value: 10}, %{name: "B", value: 20}]

  For scatter charts:
    - A list of [x, y] points: [[10, 20], [30, 40]]
    - A list of maps with series: [%{name: "Series 1", data: [[10, 20], [30, 40]]}]

  Defaults to `nil`.
* `labels` (`:list`) - Category labels for the x-axis (for bar/line charts) or data point names (for pie charts).
  Example: ["Jan", "Feb", "Mar"]

  Defaults to `[]`.
* `title` (`:string`) - Main title for the chart. Defaults to `nil`.
* `subtitle` (`:string`) - Subtitle shown below the main title. Defaults to `nil`.
* `show_legend` (`:boolean`) - Whether to show the chart legend. Defaults to `true`.
* `legend_position` (`:string`) - Position of the legend. Options: "top", "bottom", "left", "right". Defaults to `"top"`. Must be one of `"top"`, `"bottom"`, `"left"`, or `"right"`.
* `colors` (`:list`) - Custom colors for data series.

  The given items can either be a hex string, such as "#4C9AFF", or a CSS variable, prefixed with `var:`, but omitting the `--` prefix,
  such as `chart-primary`.
  The CSS variable is expected to be on the `:root` element, so the variable would be defined as such:

  ```css
  :root {
    --chart-primary: #4C9AFF;
  }
  ```

  In addition, the color setting supports the `light-dark()` function, which can be used to automatically resolve the appropriate color
  based on the the color scheme. That way, the variable can be defined as such:

  ```css
  :root {
    --chart-primary: light-dark(#4C9AFF, #36B37E);
  }
  ```

  Example: ["#4C9AFF", "#36B37E", "#FF5630", "#FFAB00", "#6554C0"]

  Defaults to `["var:noora-chart-primary", "var:noora-chart-secondary", "var:noora-chart-tertiary", "var:noora-chart-quaternary"]`.
* `stacked` (`:boolean`) - For bar/line charts, whether series should be stacked. Defaults to `false`.
* `show_values` (`:boolean`) - Whether to show data values directly on the chart. Defaults to `false`.
* `smooth` (`:any`) - For line charts, whether to use smooth curves instead of straight lines.
  Can be a boolean or a number between 0 and 1 to control the smoothing amount.

  Defaults to `false`.
* `donut` (`:boolean`) - For pie charts, whether to render as a donut chart. Defaults to `false`.
* `donut_radius` (`:list`) - For donut charts, the inner and outer radius. Default: ["50%", "70%"]. Defaults to `["50%", "70%"]`.
* `x_axis_name` (`:string`) - Name for the X axis. Example: "Month". Defaults to `nil`.
* `y_axis_name` (`:string`) - Name for the Y axis. Example: "Revenue ($)". Defaults to `nil`.
* `x_axis_min` (`:integer`) - Minimum value for the X axis. Example: 0. Defaults to `nil`.
* `x_axis_max` (`:integer`) - Maximum value for the X axis. Example: 100. Defaults to `nil`.
* `y_axis_min` (`:integer`) - Minimum value for the Y axis. Example: 0. Defaults to `nil`.
* `y_axis_max` (`:integer`) - Maximum value for the Y axis. Example: 100. Defaults to `nil`.
* `grid_lines` (`:boolean`) - Whether to show grid lines on the chart. Defaults to `true`.
* `horizontal` (`:boolean`) - Whether to display a horizontal bar chart (with category axis on y-axis). Defaults to `false`.
* `bar_width` (`:integer`) - Width of bars in bar charts (in pixels). Defaults to `nil`.
* `bar_radius` (`:integer`) - Border radius of bars in bar charts (in pixels). Defaults to `nil`.
* `extra_options` (`:map`) - Additional ECharts options for advanced customization.
  These will be deeply merged with options generated from other attributes.

  Defaults to `%{}`.
* Global attributes are accepted. Additional HTML attributes to add to the container div.

---

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