Mixed Charts
ApexCharts lets you combine multiple chart types in a single canvas by assigning a type property to each series individually. A mixed chart (sometimes called a combo chart) is useful whenever you need to compare two or more series that have different value scales, or where a different visual encoding makes a series easier to read alongside the others. For example, displaying monthly revenue as columns and a moving average as a line lets the viewer distinguish the raw figures from the trend at a glance.
How Mixed Charts Work
The key to a mixed chart is the per-series type field. Each object in the series array can declare its own rendering type. The chart-level chart.type sets the base renderer and should be set to 'line' when you are mixing any combination of line, column, and area series.
series: [
{ name: 'Revenue', type: 'column', data: [...] },
{ name: 'Trend', type: 'line', data: [...] },
]
Without the per-series type, every series inherits the chart-level type and renders the same way. Adding type to individual series overrides that default for each series independently.
Complete Example: Line and Column
The example below combines a column series (blog traffic) with a line series (social media referrals). Because the two datasets live on different scales, the chart uses two y-axes: one on the left for the column series and a second on the right for the line.
var options = {
series: [
{
name: 'Website Blog',
type: 'column',
data: [440, 505, 414, 671, 227, 413, 201, 352, 752, 320, 257, 160],
},
{
name: 'Social Media',
type: 'line',
data: [23, 42, 35, 27, 43, 22, 17, 31, 22, 22, 12, 16],
},
],
chart: {
height: 350,
type: 'line',
},
stroke: {
width: [0, 4],
},
dataLabels: {
enabled: true,
enabledOnSeries: [1],
},
labels: [
'01 Jan 2024', '02 Jan 2024', '03 Jan 2024', '04 Jan 2024',
'05 Jan 2024', '06 Jan 2024', '07 Jan 2024', '08 Jan 2024',
'09 Jan 2024', '10 Jan 2024', '11 Jan 2024', '12 Jan 2024',
],
yaxis: [
{
title: { text: 'Website Blog' },
},
{
opposite: true,
title: { text: 'Social Media' },
},
],
};
var chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
Why stroke.width is an array
The stroke.width option accepts a single number or an array. When you pass an array, each element corresponds to the series at the same index. Column series do not use a stroke to draw the bar body, so setting stroke.width[0] to 0 prevents a spurious outline from appearing around the bars. The line series at index 1 gets stroke.width[1] = 4, which controls the line thickness.
If you set stroke: { width: 4 } globally instead, ApexCharts applies a 4-pixel stroke to the column series too, drawing a visible border around every bar. That is rarely the intended behavior in a mixed chart.
Dual Y-Axis for Different Scales
Mixed charts frequently pair datasets that use incompatible units or have very different magnitudes. Plotting social media counts (tens) on the same axis as blog views (hundreds) would compress the line into a nearly flat band at the bottom of the chart, making it unreadable.
The solution is a second y-axis. Set yaxis to an array with one configuration object per axis. The second entry must include opposite: true to render it on the right side of the chart.
yaxis: [
{
// Left axis for the column series
title: { text: 'Website Blog' },
min: 0,
},
{
// Right axis for the line series
opposite: true,
title: { text: 'Social Media' },
min: 0,
},
],
ApexCharts automatically assigns series to axes by position: the first series in the series array uses the first entry in yaxis, the second series uses the second entry. If you have more series than axis definitions, the extra series fall back to the first axis.
You can also bind a series to a specific axis explicitly using seriesName on the y-axis object:
yaxis: [
{
seriesName: 'Website Blog',
title: { text: 'Website Blog' },
},
{
seriesName: 'Social Media',
opposite: true,
title: { text: 'Social Media' },
},
],
This approach is more explicit and avoids surprises when series order changes later.
Controlling Data Labels Per Series
dataLabels.enabled: true turns on labels for every series. In a line-and-column chart this creates visual clutter because both the bars and the line dots get labelled. Use dataLabels.enabledOnSeries to whitelist only the series indexes that should show labels.
dataLabels: {
enabled: true,
enabledOnSeries: [1], // only the line series (index 1) gets labels
},
The array contains zero-based series indexes. To show labels on both series write enabledOnSeries: [0, 1]. To show them only on the column series write enabledOnSeries: [0].
Example: Line and Area
Area and line pairings work well when you want to show both a filled region (for volume or cumulative data) and a precise trend line without fill. The chart-level type stays 'line'; the area series declares type: 'area' individually.
var options = {
series: [
{
name: 'Income',
type: 'area',
data: [44, 55, 57, 56, 61, 58, 63, 60, 66, 72, 68, 74],
},
{
name: 'Cashflow',
type: 'line',
data: [17, 21, 25, 18, 31, 22, 14, 27, 33, 29, 24, 30],
},
],
chart: {
height: 350,
type: 'line',
},
stroke: {
curve: 'smooth',
width: [2, 3],
},
fill: {
type: ['gradient', 'solid'],
opacity: [0.3, 1],
},
dataLabels: {
enabled: false,
},
labels: [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
],
yaxis: [
{ title: { text: 'Income' } },
{ opposite: true, title: { text: 'Cashflow' } },
],
};
var chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
The fill.type array mirrors the same index-based convention as stroke.width. Setting fill.type[0] to 'gradient' and fill.opacity[0] to 0.3 gives the area series a translucent gradient beneath the curve. The line series at index 1 uses a solid fill at full opacity, which for a line series only affects the marker fill.
Three-Series Combination: Line, Column, and Area
You can combine all three types in one chart. Extend the series array and keep the parallel arrays (stroke.width, fill.type) in the same series order.
var options = {
series: [
{
name: 'Revenue',
type: 'column',
data: [320, 400, 370, 420, 390, 450, 500, 480, 510, 530, 490, 560],
},
{
name: 'Forecast',
type: 'area',
data: [310, 390, 360, 415, 385, 440, 490, 470, 505, 520, 480, 550],
},
{
name: 'Target',
type: 'line',
data: [350, 350, 400, 400, 420, 420, 480, 480, 500, 500, 520, 520],
},
],
chart: {
height: 350,
type: 'line',
},
stroke: {
width: [0, 2, 3],
},
fill: {
opacity: [1, 0.25, 1],
},
dataLabels: {
enabled: false,
},
labels: [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
],
};
var chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
Index 0 is the column series (stroke.width: 0, full opacity). Index 1 is the area series (stroke.width: 2, 25% opacity fill). Index 2 is the line series (stroke.width: 3, full opacity). The pattern generalizes: add a series, add the corresponding element to each parallel array.
Supported Type Combinations
ApexCharts supports mixed charts for its axis-based (Cartesian) chart types. The following per-series types can be freely combined:
'line''column''area''scatter'(overlaid on any axis chart)
Candlestick and boxplot series can also be combined with 'line' overlays.
You cannot mix axis-based types with non-axis types such as 'pie', 'donut', 'radialBar', or 'polarArea'. Those types use polar coordinates and cannot share a canvas with Cartesian series. Attempting to do so will cause the per-series type to be ignored, and all series will fall back to the chart-level type.
Scatter series are particularly useful as an overlay because they render individual point markers without connecting lines, making them suitable for highlighting specific events or outliers on an existing line or column chart.
Quick Reference: Per-Series Options
| Option | Purpose |
|---|---|
series[n].type | Sets the chart type for a single series |
stroke.width | Array controlling line thickness per series; set to 0 for column series |
dataLabels.enabledOnSeries | Array of series indexes where data labels are shown |
yaxis | Array of y-axis configurations; second entry uses opposite: true for a right-side axis |
fill.type | Array controlling fill style ('solid', 'gradient', 'pattern') per series |
fill.opacity | Array controlling fill opacity per series |
Live Demos
Runnable mixed chart demos are available at /javascript-chart-demos/mixed-charts/. The gallery includes the line-column combo, the line-area combo, and a scatter overlay example.