---
product: "AG Studio"
title: "Combo Charts"
description: "Build combo charts in AG Studio that pair columns with a line, such as revenue and order count: which fields they need and their Format settings."
framework: react
version: "3.1.0"
related:
    - title: "Bar and Column Charts"
      url: "https://www.ag-grid.com/studio/analysts/bar-and-column-charts/"
    - title: "Line and Area Charts"
      url: "https://www.ag-grid.com/studio/analysts/line-and-area-charts/"
    - title: "Scatter Charts"
      url: "https://www.ag-grid.com/studio/analysts/scatter-charts/"
    - title: "Polar Charts"
      url: "https://www.ag-grid.com/studio/analysts/polar-charts/"
    - title: "Proportional Charts"
      url: "https://www.ag-grid.com/studio/analysts/proportional-charts/"
    - title: "Progression Charts"
      url: "https://www.ag-grid.com/studio/analysts/progression-charts/"
    - title: "Hierarchical Charts"
      url: "https://www.ag-grid.com/studio/analysts/hierarchical-charts/"
    - title: "Statistical Charts"
      url: "https://www.ag-grid.com/studio/analysts/statistical-charts/"
llms: "https://www.ag-grid.com/studio/llms.txt"
---

# Combo Charts

Combo Charts pair columns with a line on the same chart. Use them to show a trend alongside the values it relates to, such as revenue as columns and the number of orders as a line.

**Grouped Column / Line Chart** shows adjacent columns for direct comparison across categories, with a line overlaid to trace a trend across the same categories.

**Stacked Column / Line Chart** shows stacked columns for part-to-whole comparison across categories, with a line overlaid to trace a trend across the same categories.

The example below plots monthly revenue for three product lines as columns, with the number of orders as the line, in both variants.

#### Combo

```ts
import {
  AgReportState,
  AgStudioApi,
  AgStudioProperties,
  createStudio,
  enableStudioDevValidations,
} from "ag-studio";
import { getData } from "./data.ts";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableStudioDevValidations();
}

const initialState: AgReportState = {
  pages: [
    {
      id: "page1",
      widgets: {
        "combo-chart-grouped-column-line": {
          type: "combo-chart-grouped-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.month" }],
            valueKey: [
              { id: "sales.bikes", aggregation: "sum" },
              { id: "sales.accessories", aggregation: "sum" },
              { id: "sales.clothing", aggregation: "sum" },
            ],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Grouped Column / Line Chart",
            },
            subtitle: {
              enabled: true,
              text: "Monthly revenue by product line, with the number of orders as a line",
            },
            style: {
              theme: {
                common: {
                  legend: {
                    enabled: true,
                  },
                },
              },
            },
          },
        },
        "combo-chart-stacked-column-line": {
          type: "combo-chart-stacked-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.month" }],
            valueKey: [
              { id: "sales.bikes", aggregation: "sum" },
              { id: "sales.accessories", aggregation: "sum" },
              { id: "sales.clothing", aggregation: "sum" },
            ],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Stacked Column / Line Chart",
            },
            subtitle: {
              enabled: true,
              text: "Monthly revenue by product line, with the number of orders as a line",
            },
            style: {
              theme: {
                common: {
                  legend: {
                    enabled: true,
                  },
                },
              },
            },
          },
        },
      },
      widgetLayout: {
        "combo-chart-grouped-column-line": {
          xTrack: 0,
          yTrack: 0,
          xSpan: 24,
          ySpan: 20,
        },
        "combo-chart-stacked-column-line": {
          xTrack: 0,
          yTrack: 20,
          xSpan: 24,
          ySpan: 20,
        },
      },
    },
  ],
  selectedPageId: "page1",
  panels: {
    filters: {
      collapsed: true,
    },
    data: {
      collapsed: true,
    },
    edit: {
      collapsed: true,
    },
  },
};

const studioProperties: AgStudioProperties = {
  mode: "edit",
  initialState,
  data: getData(),
};

let studioApi: AgStudioApi;

// setup Studio after the page has finished loading
const studioDiv = document.querySelector<HTMLElement>("#myStudio")!;
studioApi = createStudio(studioDiv, studioProperties);
```

[Live example: Combo](https://www.ag-grid.com/studio/examples/combo-charts/combo/typescript/)

## Setup

| Slot | Required | Accepts | What it does |
| --- | --- | --- | --- |
| X Axis | Yes | One category | Draws one category along the axis for each value of the field. |
| Y Axis (Column) | Yes | One or more numeric fields | Draws the columns, plotted against the left axis. Each field adds a series of columns. |
| Y Axis (Line) | Yes | One or more numeric fields | Draws the lines, plotted against a second axis on the right. Each field adds a line. |
| Legend | No | One category | Splits the columns into one series per value of the field. The lines are not split. |
| Tooltip | No | Any fields | Shows the fields in the tooltip without plotting them. |

The line has its own axis, so the columns and the line can show values of different sizes or units. When the first field on an axis is formatted as a percentage, that axis shows percentages.

### Legend

A Legend splits each column field into a series for each value of a category, while the line still shows one total for each category.

The example below has Region in the Legend slot and Orders in the Y Axis (Line) slot of every chart. The left column has one field, Revenue, in the Y Axis (Column) slot, so each quarter has one column series per region. The right column adds Profit, so each region has a series for each field. The top row is Grouped and the bottom row is Stacked, where each field has its own stack.

#### Legend

```ts
import {
  AgReportState,
  AgStudioApi,
  AgStudioProperties,
  createStudio,
  enableStudioDevValidations,
} from "ag-studio";
import { getData } from "./data.ts";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableStudioDevValidations();
}

const initialState: AgReportState = {
  pages: [
    {
      id: "page1",
      widgets: {
        "grouped-one": {
          type: "combo-chart-grouped-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.quarter" }],
            valueKey: [{ id: "sales.revenue", aggregation: "sum" }],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            legendKey: [{ id: "sales.region" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Grouped: Revenue",
            },
            subtitle: {
              enabled: true,
              text: "Region in the Legend slot, Orders as the line",
            },
            style: {
              theme: {
                common: {
                  legend: {
                    enabled: true,
                    position: "right",
                  },
                },
              },
            },
          },
        },
        "grouped-two": {
          type: "combo-chart-grouped-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.quarter" }],
            valueKey: [
              { id: "sales.revenue", aggregation: "sum" },
              { id: "sales.profit", aggregation: "sum" },
            ],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            legendKey: [{ id: "sales.region" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Grouped: Revenue and Profit",
            },
            subtitle: {
              enabled: true,
              text: "Region in the Legend slot, Orders as the line",
            },
            style: {
              theme: {
                common: {
                  legend: {
                    enabled: true,
                    position: "right",
                  },
                },
              },
            },
          },
        },
        "stacked-one": {
          type: "combo-chart-stacked-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.quarter" }],
            valueKey: [{ id: "sales.revenue", aggregation: "sum" }],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            legendKey: [{ id: "sales.region" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Stacked: Revenue",
            },
            subtitle: {
              enabled: true,
              text: "Region in the Legend slot, Orders as the line",
            },
            style: {
              theme: {
                common: {
                  legend: {
                    enabled: true,
                    position: "right",
                  },
                },
              },
            },
          },
        },
        "stacked-two": {
          type: "combo-chart-stacked-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.quarter" }],
            valueKey: [
              { id: "sales.revenue", aggregation: "sum" },
              { id: "sales.profit", aggregation: "sum" },
            ],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            legendKey: [{ id: "sales.region" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Stacked: Revenue and Profit",
            },
            subtitle: {
              enabled: true,
              text: "Region in the Legend slot, Orders as the line",
            },
            style: {
              theme: {
                common: {
                  legend: {
                    enabled: true,
                    position: "right",
                  },
                },
              },
            },
          },
        },
      },
      widgetLayout: {
        "grouped-one": { xTrack: 0, yTrack: 0, xSpan: 10, ySpan: 22 },
        "grouped-two": { xTrack: 10, yTrack: 0, xSpan: 14, ySpan: 22 },
        "stacked-one": { xTrack: 0, yTrack: 22, xSpan: 10, ySpan: 22 },
        "stacked-two": { xTrack: 10, yTrack: 22, xSpan: 14, ySpan: 22 },
      },
    },
  ],
  selectedPageId: "page1",
  panels: {
    filters: {
      collapsed: true,
    },
    data: {
      collapsed: true,
    },
    edit: {
      collapsed: true,
    },
  },
};

const studioProperties: AgStudioProperties = {
  mode: "edit",
  initialState,
  data: getData(),
};

let studioApi: AgStudioApi;

// setup Studio after the page has finished loading
const studioDiv = document.querySelector<HTMLElement>("#myStudio")!;
studioApi = createStudio(studioDiv, studioProperties);
```

[Live example: Legend](https://www.ag-grid.com/studio/examples/combo-charts/combo-legend/typescript/)

### Tooltip

Fields in the Tooltip slot appear in the tooltip when you hover over a column, but are not plotted. Use the slot for context that would clutter the chart, such as the returns behind each month's revenue.

In the example below, the columns show monthly revenue and the line shows orders, and the Setup tab is open beside the chart. Hover over a column to see its Returns and Refunds, which are in the Tooltip slot.

#### Tooltip

```ts
import {
  AgReportState,
  AgStudioApi,
  AgStudioProperties,
  createStudio,
  enableStudioDevValidations,
} from "ag-studio";
import { getData } from "./data.ts";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableStudioDevValidations();
}

const initialState: AgReportState = {
  pages: [
    {
      id: "page1",
      widgets: {
        "revenue-and-orders": {
          type: "combo-chart-grouped-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.month" }],
            valueKey: [{ id: "sales.revenue", aggregation: "sum" }],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            tooltipKey: [
              { id: "sales.returns", aggregation: "sum" },
              { id: "sales.refunds", aggregation: "sum" },
            ],
          },
          format: {
            title: {
              enabled: true,
              text: "Revenue and Orders by Month",
            },
            style: {
              theme: {
                common: {
                  legend: {
                    enabled: true,
                  },
                },
              },
            },
          },
        },
      },
      widgetLayout: {
        "revenue-and-orders": { xTrack: 0, yTrack: 0, xSpan: 24, ySpan: 24 },
      },
      selection: { type: "widget", id: "revenue-and-orders" },
    },
  ],
  selectedPageId: "page1",
};

const studioProperties: AgStudioProperties = {
  mode: "edit",
  initialState,
  panels: {
    edit: {
      right: ["edit"],
    },
  },
  data: getData(),
};

let studioApi: AgStudioApi;

// setup Studio after the page has finished loading
const studioDiv = document.querySelector<HTMLElement>("#myStudio")!;
studioApi = createStudio(studioDiv, studioProperties);
```

[Live example: Tooltip](https://www.ag-grid.com/studio/examples/combo-charts/combo-tooltip/typescript/)

## Format

Combo Charts have these settings of their own on the Format tab, beside the title, axis and appearance settings every chart has. Your developer can change the defaults shown.

| Setting | Where | Default | What it does |
| --- | --- | --- | --- |
| Legend | Elements | Off | Shows the legend. **Position** places it around the chart, at the bottom by default. |
| Markers (Line) | Elements | On | Draws a marker at each point on the line. **Shape** and **Size** change the marker. |
| Data Labels (Line) | Elements | Off | Shows the value of each point on the line. **Font** and **Color** change the label text. |
| Segment Borders | Elements | Off | Draws a border around each column and segment. **Width** and **Color** change the border. |

The line's axis has its own **Y Axis (Line)** section, with the same settings as the **Y Axis (Column)** section, and it sits on the right by default.

The example below changes one setting from its default in each chart, over the same data.

#### Format

```ts
import {
  AgReportState,
  AgStudioApi,
  AgStudioProperties,
  createStudio,
  enableStudioDevValidations,
} from "ag-studio";
import { getData } from "./data.ts";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableStudioDevValidations();
}

const initialState: AgReportState = {
  pages: [
    {
      id: "page1",
      widgets: {
        "data-labels": {
          type: "combo-chart-grouped-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.month" }],
            valueKey: [
              { id: "sales.bikes", aggregation: "sum" },
              { id: "sales.accessories", aggregation: "sum" },
            ],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Data Labels (Line)",
            },
            subtitle: {
              enabled: true,
              text: "Elements > Data Labels (Line) on",
            },
            style: {
              theme: {
                line: {
                  series: {
                    label: {
                      enabled: true,
                    },
                  },
                },
                common: {
                  legend: {
                    enabled: true,
                  },
                },
              },
            },
          },
        },
        "markers-off": {
          type: "combo-chart-grouped-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.month" }],
            valueKey: [
              { id: "sales.bikes", aggregation: "sum" },
              { id: "sales.accessories", aggregation: "sum" },
            ],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Markers (Line) Off",
            },
            subtitle: {
              enabled: true,
              text: "Elements > Markers (Line) off",
            },
            style: {
              theme: {
                line: {
                  series: {
                    marker: {
                      enabled: false,
                    },
                  },
                },
                common: {
                  legend: {
                    enabled: true,
                  },
                },
              },
            },
          },
        },
        "segment-borders": {
          type: "combo-chart-stacked-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.month" }],
            valueKey: [
              { id: "sales.bikes", aggregation: "sum" },
              { id: "sales.accessories", aggregation: "sum" },
            ],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Segment Borders",
            },
            subtitle: {
              enabled: true,
              text: "Elements > Segment Borders on, Width 2",
            },
            style: {
              custom: {
                seriesStroke: {
                  enabled: true,
                  strokeWidth: 2,
                },
              },
              theme: {
                common: {
                  legend: {
                    enabled: true,
                  },
                },
              },
            },
          },
        },
        "legend-position": {
          type: "combo-chart-grouped-column-line",
          dataMapping: {
            categoryKey: [{ id: "sales.month" }],
            valueKey: [
              { id: "sales.bikes", aggregation: "sum" },
              { id: "sales.accessories", aggregation: "sum" },
            ],
            secondaryValueKey: [{ id: "sales.orders", aggregation: "sum" }],
            tooltipKey: [],
          },
          format: {
            title: {
              enabled: true,
              text: "Legend Position",
            },
            subtitle: {
              enabled: true,
              text: "Elements > Legend > Position Right",
            },
            style: {
              theme: {
                common: {
                  legend: {
                    enabled: true,
                    position: "right",
                  },
                },
              },
            },
          },
        },
      },
      widgetLayout: {
        "data-labels": { xTrack: 0, yTrack: 0, xSpan: 12, ySpan: 22 },
        "markers-off": { xTrack: 12, yTrack: 0, xSpan: 12, ySpan: 22 },
        "segment-borders": { xTrack: 0, yTrack: 22, xSpan: 12, ySpan: 22 },
        "legend-position": { xTrack: 12, yTrack: 22, xSpan: 12, ySpan: 22 },
      },
    },
  ],
  selectedPageId: "page1",
  panels: {
    filters: {
      collapsed: true,
    },
    data: {
      collapsed: true,
    },
    edit: {
      collapsed: true,
    },
  },
};

const studioProperties: AgStudioProperties = {
  mode: "edit",
  initialState,
  data: getData(),
};

let studioApi: AgStudioApi;

// setup Studio after the page has finished loading
const studioDiv = document.querySelector<HTMLElement>("#myStudio")!;
studioApi = createStudio(studioDiv, studioProperties);
```

[Live example: Format](https://www.ag-grid.com/studio/examples/combo-charts/combo-format/typescript/)
