# Charts

Charts are workbook-local worksheet resources. Use `univer run` to create or maintain them through the Pro Charts facade, then use facade readback to verify command-line results.

For visual verification, open the workbook with `univer view`. `univer run` does not export chart images or perform browser screenshots.

## Core Workflow

Look up the workbook and worksheet, seed or choose a source range, configure a chart builder with `newChart()`, call `build()`, then pass the result to `insertChart(chartInfo)`.

```bash
univer run ./sales.univer --code 'async () => {
  const workbook = univerAPI.getActiveWorkbook();
  const sheet = workbook.getSheetByName("Sheet1");
  if (!sheet) return { success: false, error: "Sheet1 not found" };

  sheet.getRange("A1:C4").setValues([
    ["month", "sales", "cost"],
    ["Jan", 100, 60],
    ["Feb", 120, 70],
    ["Mar", 90, 50]
  ]);

  const chartInfo = sheet
    .newChart()
    .setChartType(univerAPI.Enum.ChartType.Column)
    .addRange("A1:C4")
    .setPosition(1, 4, 0, 0)
    .setWidth(480)
    .setHeight(320)
    .setOptions("title.content", "Quarterly sales")
    .build();

  const chart = await sheet.insertChart(chartInfo);

  return {
    success: true,
    chartId: chart.getChartId(),
    chartCount: sheet.getCharts().length
  };
}'
```

`ChartType.Column` is the common column chart enum value. Other enum values are available from `univerAPI.Enum.ChartType`.

## Chart Type Enum Values

Use `univerAPI.Enum.ChartType.<Name>` with `setChartType()` when building chart metadata.

```javascript
const chartInfo = sheet
  .newChart()
  .setChartType(univerAPI.Enum.ChartType.Column)
  .addRange("A1:C4")
  .build();
```

Available chart type enum values:

| Facade enum value                               | Chart type                                                                                 |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `univerAPI.Enum.ChartType.None`                 | No chart type. This is a sentinel value and should not be used for normal chart insertion. |
| `univerAPI.Enum.ChartType.Line`                 | Line chart                                                                                 |
| `univerAPI.Enum.ChartType.Column`               | Column chart                                                                               |
| `univerAPI.Enum.ChartType.ColumnStacked`        | Stacked column chart                                                                       |
| `univerAPI.Enum.ChartType.ColumnPercentStacked` | Percent stacked column chart                                                               |
| `univerAPI.Enum.ChartType.Bar`                  | Bar chart                                                                                  |
| `univerAPI.Enum.ChartType.BarStacked`           | Stacked bar chart                                                                          |
| `univerAPI.Enum.ChartType.BarPercentStacked`    | Percent stacked bar chart                                                                  |
| `univerAPI.Enum.ChartType.Pie`                  | Pie chart                                                                                  |
| `univerAPI.Enum.ChartType.Doughnut`             | Doughnut chart                                                                             |
| `univerAPI.Enum.ChartType.Area`                 | Area chart                                                                                 |
| `univerAPI.Enum.ChartType.AreaStacked`          | Stacked area chart                                                                         |
| `univerAPI.Enum.ChartType.AreaPercentStacked`   | Percent stacked area chart                                                                 |
| `univerAPI.Enum.ChartType.Radar`                | Radar chart                                                                                |
| `univerAPI.Enum.ChartType.Scatter`              | Scatter chart                                                                              |
| `univerAPI.Enum.ChartType.Combination`          | Combination chart                                                                          |
| `univerAPI.Enum.ChartType.WordCloud`            | Word cloud chart                                                                           |
| `univerAPI.Enum.ChartType.Funnel`               | Funnel chart                                                                               |
| `univerAPI.Enum.ChartType.Bubble`               | Bubble chart                                                                               |
| `univerAPI.Enum.ChartType.Relation`             | Relationship diagram                                                                       |
| `univerAPI.Enum.ChartType.Waterfall`            | Waterfall chart                                                                            |
| `univerAPI.Enum.ChartType.Pareto`               | Pareto chart                                                                               |
| `univerAPI.Enum.ChartType.Sankey`               | Sankey chart                                                                               |
| `univerAPI.Enum.ChartType.Heatmap`              | Heatmap chart                                                                              |
| `univerAPI.Enum.ChartType.Boxplot`              | Box plot chart                                                                             |

## Chart Facade Enum Examples

The chart facade also exposes option enums through `univerAPI.Enum`. Use these with specialized builder methods or `setOptions(path, value)`.

```javascript
const chartInfo = sheet
  .newChart()
  .asLineChart()
  .addRange("A1:D6")
  .setPosition(1, 4, 0, 0)
  .setOptions("title.position", univerAPI.Enum.TitlePositionEnum.Top)
  .setOptions("legend.position", univerAPI.Enum.LegendPositionEnum.Right)
  .setOptions("legend.selectMode", univerAPI.Enum.SelectModeEnum.Multiple)
  .setXAxisTextStyle({
    content: "Month",
    axisAlignment: univerAPI.Enum.AxisAlignEnum.End
  })
  .setAxisPointerStyle({
    indicatorLineType: univerAPI.Enum.ChartBorderDashType.Dashed,
    indicatorLineColor: "#1677ff",
    indicatorLabelColor: "#e6f4ff",
    indicatorLabelTextColor: "#0958d9"
  })
  .setDataPointShape(univerAPI.Enum.LinePointShape.Circle)
  .build();
```

Common chart facade enums:

| Facade enum                          | Example values                                                                                                                                                                                                 | Typical use                                                                                  |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `univerAPI.Enum.LegendPositionEnum`  | `Top`, `Bottom`, `Left`, `Right`, `Hide`                                                                                                                                                                       | `setOptions("legend.position", value)`                                                       |
| `univerAPI.Enum.SelectModeEnum`      | `Single`, `Multiple`, `Close`                                                                                                                                                                                  | `setOptions("legend.selectMode", value)`                                                     |
| `univerAPI.Enum.TitlePositionEnum`   | `Top`, `Bottom`, `Left`, `Right`, `Hide`                                                                                                                                                                       | `setOptions("title.position", value)`                                                        |
| `univerAPI.Enum.AxisAlignEnum`       | `Start`, `Center`, `End`                                                                                                                                                                                       | `setXAxisTextStyle({ axisAlignment: value })`, `setYAxisTextStyle({ axisAlignment: value })` |
| `univerAPI.Enum.ChartBorderDashType` | `Solid`, `Dashed`, `Dotted`                                                                                                                                                                                    | `setAxisPointerStyle({ indicatorLineType: value })`, series border `dashType`                |
| `univerAPI.Enum.LinePointShape`      | `Circle`, `Square`, `Triangle`, `Diamond`, `Rect`, `RoundRect`, `Pin`, `Arrow`, `None`, `EmptyCircle`, `EmptySquare`, `EmptyTriangle`, `EmptyDiamond`, `EmptyRect`, `EmptyRoundRect`, `EmptyPin`, `EmptyArrow` | `setDataPointShape(value)`                                                                   |
| `univerAPI.Enum.RadarShape`          | `Polygon`, `Circle`                                                                                                                                                                                            | `asRadarChart().setShape(value)`                                                             |

## Chart Builder

`sheet.newChart()` returns the shared chart builder. The builder only prepares chart metadata. `build()` does not draw anything by itself; insert a new chart with `insertChart(chartInfo)` or update an existing chart with `updateChart(chartInfo)`.

Core builder methods:

- `getChartType()` returns the chart type currently configured on the builder.
- `setChartType(univerAPI.Enum.ChartType.Column)` chooses the chart type.
- `addRange("A1:C4")` binds the source range. A sheet-qualified range can target another sheet.
- `clearRange()` removes the current source range from the builder.
- `setPosition(row, column, rowOffset, columnOffset)` anchors the chart to the grid.
- `setAbsolutePosition(x, y)` places the chart by absolute canvas coordinates.
- `setWidth(width)` and `setHeight(height)` set the rendered chart size.
- `setTransposeRowsAndColumns(true)` swaps the category and series orientation.
- `build()` returns chart metadata for `insertChart(chartInfo)` or `updateChart(chartInfo)`.

Option and style methods:

- `setOptions(path, value)` sets a nested chart option such as `title.content`, `title.position`, `legend.position`, or `legend.selectMode`. Use an empty path, `setOptions("", options)`, to merge a root options object.
- `setTheme(themeName)` applies a registered chart theme.
- `setXAxisTitle(title)`, `setYAxisTitle(title)`, and `setRightYAxisTitle(title)` set axis title text.
- `setXAxisTextStyle(style)`, `setYAxisTextStyle(style)`, and `setRightYAxisTextStyle(style)` set axis title text style. Use `axisAlignment: univerAPI.Enum.AxisAlignEnum.End` for axis-title alignment.
- `setInvalidValueStrategy(univerAPI.Enum.InvalidValueType.Zero)` controls how line-like charts handle invalid values. Common values are `Zero`, `Break`, and `Link`.
- `setAxisPointerStyle(style)` configures axis pointer labels and line style. Use `univerAPI.Enum.ChartBorderDashType` for `indicatorLineType`.
- `setAllSeriesStyle(style)` applies style defaults across all series.
- `setSeriesStyle(index, style)` applies style to one series. Use `chart.getSeriesData()` readback to find stable series indexes when updating an existing chart.

Specialized builder entrypoints:

- `asLineChart()` returns a `LineChartBuilder`.
- `asPieChart()` returns a `PieChartBuilder`.
- `asRadarChart()` returns a `RadarChartBuilder`.

Line chart builder methods:

- `setLineStyle("line" | "smooth" | "step")` controls line interpolation.
- `setDataPointShape(univerAPI.Enum.LinePointShape.Circle)` sets the marker shape.
- `setDataPointColor(color)` sets marker color.
- `setDataPointSize(size)` sets marker size.

Pie chart builder methods:

- `setDoughnutHole(value)` sets the center hole size from `0` to `1`.
- `setBorderColor(color)` sets pie border color.
- `setHasPaddingAngle(true)` enables slice padding.
- `setIsHalfPie(true)` renders a half pie.
- `setRosePie(true)` renders a rose pie.
- `setShowLabelLine(true)` toggles label leader lines.

Radar chart builder methods:

- `setShape(univerAPI.Enum.RadarShape.Polygon)` sets the radar shape. Common values are `Polygon` and `Circle`.
- `setFill(true)` fills the radar area.

## Source Data Shapes

Most charts accept a category-plus-series range such as `month, sales, cost`, where the first column supplies category labels and the remaining columns supply numeric series.

Some chart types require stricter source shapes:

- Relation charts require a node/type matrix. Use headers like `node, type, Alpha, Beta, Gamma`, then one row per node. The first column names the row node, the second column assigns that node to a type/category, and the remaining columns form the numeric relation matrix. For `N` nodes, the range must have `N` data rows and `N + 2` columns.
- Sankey charts require a source/target/value edge list. Use headers like `source, target, value`, then one row per edge. The third column must contain numeric weights. Avoid reverse edges such as `A -> B` and `B -> A` in the same source; circular Sankey data is treated as invalid for rendering.
- Bubble charts need numeric x, y, and size columns. A practical minimum is `x, y, size`; optional label or series columns can be selected through chart context when supported.
- Heatmap charts use the first column as y-axis labels, the remaining headers as x-axis labels, and the remaining cells as numeric heat values.

Examples:

```javascript
sheet.getRange("A1:E4").setValues([
  ["node", "type", "Alpha", "Beta", "Gamma"],
  ["Alpha", "Organic", 0, 12, 8],
  ["Beta", "Organic", 12, 0, 18],
  ["Gamma", "Paid", 8, 18, 0]
]);

await sheet.insertChart(
  sheet
    .newChart()
    .setChartType(univerAPI.Enum.ChartType.Relation)
    .addRange("A1:E4")
    .setPosition(1, 6, 0, 0)
    .build()
);
```

```javascript
sheet.getRange("A1:C6").setValues([
  ["source", "target", "value"],
  ["Visit", "Signup", 80],
  ["Signup", "Trial", 45],
  ["Trial", "Paid", 22],
  ["Visit", "Docs", 30],
  ["Docs", "Signup", 18]
]);

await sheet.insertChart(
  sheet
    .newChart()
    .setChartType(univerAPI.Enum.ChartType.Sankey)
    .addRange("A1:C6")
    .setPosition(1, 6, 0, 0)
    .build()
);
```

## Specialized Builders

`newChart()` returns the shared builder. Convert it to a specialized builder when you need chart-type-specific options:

- `asLineChart()` returns a `LineChartBuilder`.
- `asPieChart()` returns a `PieChartBuilder`.
- `asRadarChart()` returns a `RadarChartBuilder`.

Line chart options:

```javascript
const chartInfo = sheet
  .newChart()
  .asLineChart()
  .addRange("A1:D6")
  .setPosition(1, 4, 0, 0)
  .setLineStyle("step")
  .setDataPointShape(univerAPI.Enum.LinePointShape.Circle)
  .setDataPointColor("#ff0000")
  .setDataPointSize(10)
  .build();

await sheet.insertChart(chartInfo);
```

Pie chart options:

```javascript
const chartInfo = sheet
  .newChart()
  .asPieChart()
  .addRange("A1:B6")
  .setPosition(1, 4, 0, 0)
  .setDoughnutHole(0.5)
  .setBorderColor("#ff0000")
  .setHasPaddingAngle(true)
  .setIsHalfPie(false)
  .setRosePie(false)
  .setShowLabelLine(true)
  .build();

await sheet.insertChart(chartInfo);
```

Radar chart options:

```javascript
const chartInfo = sheet
  .newChart()
  .asRadarChart()
  .addRange("A1:D6")
  .setPosition(1, 4, 0, 0)
  .setShape(univerAPI.Enum.RadarShape.Polygon)
  .setFill(true)
  .build();

await sheet.insertChart(chartInfo);
```

## Readback And Maintenance

Use public facade APIs for stable command-line verification:

```javascript
const charts = sheet.getCharts();
const chart = charts[0];

return {
  chartId: chart.getChartId(),
  source: chart.getRange(),
  categoryData: chart.getCategoryData(),
  seriesData: chart.getSeriesData()
};
```

## Update Chart Source Range

To change the source range, call `updateRange()` with a public range descriptor.

```bash
univer run ./sales.univer --code 'async () => {
  const workbook = univerAPI.getActiveWorkbook();
  const sheet = workbook.getSheetByName("Sheet1");
  if (!sheet) return { success: false, error: "Sheet1 not found" };

  const [chart] = sheet.getCharts();
  if (!chart) return { success: false, error: "No chart found" };

  sheet.getRange("A1:D4").setValues([
    ["month", "sales", "cost", "profit"],
    ["Jan", 100, 60, 40],
    ["Feb", 120, 70, 50],
    ["Mar", 90, 50, 40]
  ]);

  const updated = await chart.updateRange({
    rangeInfo: {
      range: sheet.getRange("A1:D4").getRange(),
      unitId: workbook.getId(),
      subUnitId: sheet.getSheetId()
    },
    isRowDirection: true
  });
  const source = chart.getRange();

  return {
    success: true,
    updated,
    chartId: chart.getChartId(),
    sourceRange: source?.rangeInfo?.range
  };
}'
```

## Remove Chart

To remove a chart, pass the facade chart object back to the worksheet.

```bash
univer run ./sales.univer --code 'async () => {
  const workbook = univerAPI.getActiveWorkbook();
  const sheet = workbook.getSheetByName("Sheet1");
  if (!sheet) return { success: false, error: "Sheet1 not found" };

  const [chart] = sheet.getCharts();
  if (!chart) {
    return {
      success: true,
      removed: false,
      remaining: 0
    };
  }

  const removed = await sheet.removeChart(chart);

  return {
    success: true,
    removed,
    remaining: sheet.getCharts().length
  };
}'
```

## Headless And Viewer Boundary

Headless `univer run` scripts should verify charts by reading facade state: `getCharts()`, `getChartId()`, `getRange()`, `getSeriesData()`, and `getCategoryData()`.

Browser rendering belongs to `univer view`, where the readonly workbook viewer loads chart UI plugins and paints the visible chart surface.
