¿Para qué sirve un gráfico de columnas?
Los gráficos de columnas son ideales para comparar valores entre diferentes categorías o mostrar datos discretos. Cada columna representa un valor asociado a una categoría, con la altura indicando la magnitud. Son úteles para:
- Comparar desempeños (ej.: ventas por mes).
- Destacar diferencias entre grupos (ej.: ingresos por región).
- Presentar datos estáticos o puntuales (ej.: puntajes de un equipo).

Crear un column chart básico
Aquí hay un ejemplo simple para mostrar datos de ventas anuales.
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Column Chart básico')),
body: Center(
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
series: <ColumnSeries<SalesData, String>>[
ColumnSeries<SalesData, String>(
dataSource: [
SalesData('Ene', 35),
SalesData('Feb', 28),
SalesData('Mar', 34),
SalesData('Abr', 32),
SalesData('May', 40),
],
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
),
],
),
),
),
);
}
}
class SalesData {
SalesData(this.month, this.sales);
final String month;
final double sales;
}
Elementos clave para un gráfico de columnas en Flutter:
- SfCartesianChart: Contenedor principal para todos los gráficos cartesianos (columnas, líneas, etc.).
- primaryXAxis: Define el eje horizontal. Sin esto, el gráfico no puede interpretar los datos X (aqui, CategoryAxis para meses en texto).
- series: Lista de series a mostrar.
- ColumnSeries: Especifica que el gráfico es de tipo columna.
- dataSource: Datos en forma de lista de objetos, que proporcionan los puntos a mostrar.
- xValueMapper y yValueMapper: Conectan los datos con los ejes X (categorías) y Y (valores). Sin estos mapeos, el gráfico no puede asociar los datos con los ejes.
Agregar varias columnas al gráfico
Se puede hacer el gráfico más potente agregando varias series de datos para comparar categorías. Con syncfusion_flutter_charts, simplemente agregue múltiples ColumnSeries a la lista series de SfCartesianChart. Cada serie puede tener sus propios datos, colores y leyendas. Por defecto, las columnas de diferentes series se colocan una al lado de la otra gracias a la propiedad enableSideBySideSeriesPlacement.
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final TooltipBehavior _tooltip = TooltipBehavior(enable: true);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Column Chart con varias columnas')),
body: SfCartesianChart(
title: ChartTitle(text: 'Ventas por región (2025)'),
legend: Legend(isVisible: true),
tooltipBehavior: _tooltip,
primaryXAxis: CategoryAxis(
title: AxisTitle(text: 'Mes'),
),
primaryYAxis: NumericAxis(
title: AxisTitle(text: 'Ventas (k€)')
),
series: <ColumnSeries<SalesData, String>>[
ColumnSeries<SalesData, String>(
name: 'Región A',
dataSource: [
SalesData('Ene', 35),
SalesData('Feb', 28),
SalesData('Mar', 34),
SalesData('Abr', 32),
SalesData('May', 40),
],
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
color: Colors.blue,
),
ColumnSeries<SalesData, String>(
name: 'Región B',
dataSource: [
SalesData('Ene', 25),
SalesData('Feb', 30),
SalesData('Mar', 27),
SalesData('Abr', 35),
SalesData('May', 38),
],
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
color: Colors.red,
),
],
),
),
);
}
}
class SalesData {
SalesData(this.month, this.sales);
final String month;
final double sales;
}

¿Cómo personalizar tu gráfico de columnas?
syncfusion_flutter_charts ofrece numerosas opciones para personalizar un Column Chart. Aquí tienes una lista detallada con ejemplos.
Cambiar la apariencia de las columnas
Puedes modificar el color, el ancho y el borde de las columnas:
- color: Define el color de relleno de las columnas. Acepta un Color (por ejemplo: Colors.teal, Color.fromRGBO(255, 0, 0, 1)).
- width: Controla el ancho relativo de las columnas en el espacio asignado a cada categoría. Valor entre 0 y 1 (1 = ancho completo, 0.5 = mitad del espacio).
- borderWidth: Grosor del borde alrededor de las columnas, en píxeles (por ejemplo: 2.0). Por defecto, 0 (sin borde).
- borderColor: Color del borde. Requiere borderWidth > 0 para ser visible.
ColumnSeries<SalesData, String>(
dataSource: /* ... */,
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
color: Colors.teal,
width: 0.8, // 80% del espacio disponible por columna
borderWidth: 2,
borderColor: Colors.black,
),
Agregar esquinas redondeadas
borderRadius redondea las esquinas superiores de las columnas gracias al widget BorderRadius.
ColumnSeries<SalesData, String>(
dataSource: /* ... */,
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
borderRadius: BorderRadius.circular(5), // Esquinas redondeadas de 5 píxeles
),
Columnas multicolores
Utiliza pointColorMapper para asignar un color diferente a cada columna:
class SalesData {
SalesData(this.month, this.sales, this.color);
final String month;
final double sales;
final Color color;
}
ColumnSeries<SalesData, String>(
dataSource: [
SalesData('Ene', 35, Colors.red),
SalesData('Feb', 28, Colors.green),
SalesData('Mar', 34, Colors.blue),
SalesData('Abr', 32, Colors.yellow),
SalesData('May', 40, Colors.purple),
],
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
pointColorMapper: (SalesData sales, _) => sales.color,
),
Agregar varias columnas al gráfico
El widget SfCartesianChart te permite mostrar varias series de datos para comparar categorías, cada una con sus colores y leyendas.
Para ello, utiliza la propiedad enableSideBySideSeriesPlacement que permite colocar las columnas lado a lado cuando tiene un valor de true, y se superponen cuando tiene un valor de false.
SfCartesianChart(
title: ChartTitle(text: 'Ventas por región (2025)'),
legend: Legend(isVisible: true),
primaryXAxis: CategoryAxis(title: AxisTitle(text: 'Mes')),
primaryYAxis: NumericAxis(title: AxisTitle(text: 'Ventas (k€)')),
series: <ColumnSeries<SalesData, String>>[
ColumnSeries<SalesData, String>(
name: 'Región A', // Nombre en la leyenda
dataSource: [
SalesData('Ene', 35),
SalesData('Feb', 28),
SalesData('Mar', 34),
],
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
color: Colors.blue,
),
ColumnSeries<SalesData, String>(
name: 'Región B',
dataSource: [
SalesData('Ene', 25),
SalesData('Feb', 30),
SalesData('Mar', 27),
],
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
color: Colors.red,
),
],
),
Agregar etiquetas de datos
Con dataLabelSettings, muestra los valores de tus columnas directamente encima:
- isVisible: true para mostrar las etiquetas, false para ocultarlas.
- labelAlignment: Posición de la etiqueta (ChartDataLabelAlignment.top, middle, bottom, etc.).
- textStyle: Estilo del texto (por ejemplo: TextStyle(fontSize: 12, color: Colors.black)).
ColumnSeries<SalesData, String>(
dataSource: /* ... */,
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
dataLabelSettings: DataLabelSettings(
isVisible: true,
labelAlignment: ChartDataLabelAlignment.top,
textStyle: TextStyle(fontSize: 12, color: Colors.black),
),
),
Personalizar los ejes
Puedes personalizar los ejes de tu grafico, con las propriedades siguentes :
- primaryXAxis: Define el tipo del eje horizontal. Por ejemplo, CategoryAxis (categorías textuales), NumericAxis (números), etc.
- title: Añade un título mediante AxisTitle(text: ‘Mes’).
- primaryYAxis: Eje vertical. Generalmente NumericAxis para las columnas.
- title: Título del eje Y.
- minimum: Valor mínimo (por ejemplo: 0).
- maximum: Valor máximo (por ejemplo: 50).
- interval: Espaciado entre las marcas (por ejemplo: 10).
SfCartesianChart(
primaryXAxis: CategoryAxis(
title: AxisTitle(text: 'Mes'), // Título del eje X
),
primaryYAxis: NumericAxis(
title: AxisTitle(text: 'Ventas (k€)'), // Título del eje Y
minimum: 0, // Comienza en 0
maximum: 50, // Termina en 50
interval: 10, // Marcas cada 10 k€
),
series: /* ... */,
),
Cuidado, las posibilidades de personalización no son las mismas según el tipo de eje. Aquí están las diferentes variantes que puedes usar:
Tipo | Datos adaptados | Ejemplo de uso |
---|---|---|
NumericAxis | Números continuos | Años, cantidades |
CategoryAxis | Categorías textuales | Meses, nombres de productos |
DateTimeAxis | Fechas/horas continuas | Ventas por día |
DateTimeCategoryAxis | Fechas discretas | Primeros días de los meses |
LogarithmicAxis | Datos exponenciales | Crecimiento logarítmico |
Agregar un título y una leyenda
También puedes añadir un título y una leyenda a tu gráfico, gracias a las siguientes propiedades:
- title: Título global del gráfico mediante ChartTitle.
- legend: Muestra una leyenda para identificar las series.
SfCartesianChart(
title: ChartTitle(text: 'Ventas mensuales 2025'), // Título del gráfico
legend: Legend(isVisible: true), // Leyenda visible
series: /* ... */,
),
Activar las interacciones
Puedes mostrar burbujas informativas en tus columnas gracias a la propiedad tooltipBehavior. Para ello, deberás crear un widget de tipo TooltipBehavior, que contenga los siguientes elementos:
- enable: true para activar.
- color: Color de fondo (por ejemplo: Colors.grey).
- textStyle: Estilo del texto en la burbuja.
class MyApp extends StatelessWidget {
final TooltipBehavior _tooltip = TooltipBehavior(
enable: true, // Activa los tooltips
color: Colors.grey[800], // Fondo gris oscuro
textStyle: TextStyle(color: Colors.white), // Texto blanco
);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SfCartesianChart(
tooltipBehavior: _tooltip,
series: /* ... */,
),
),
);
}
}
Agregar un segundo eje Y con la propiedad axes
Cuando tus líneas representan datos con unidades o escalas diferentes (por ejemplo: ventas en k€ y tasa de crecimiento en %), un solo eje Y puede hacer que el gráfico sea ilegible. Con la propiedad axes de SfCartesianChart, puedes añadir un segundo eje de ordenadas (o más), y luego asociarlo a una serie mediante yAxisName.
Aquí tienes un ejemplo donde una columna muestra las ventas (k€) y otra la tasa de crecimiento (%):
SfCartesianChart(
title: ChartTitle(text: 'Ventas por región (2025)'),
legend: Legend(
isVisible: true), // Activa la leyenda para identificar las columnas
tooltipBehavior: _tooltip,
primaryXAxis: CategoryAxis(
title: AxisTitle(text: 'Mes'),
),
primaryYAxis: NumericAxis(
title: AxisTitle(text: 'Ventas (k€)'),
minimum: 20,
maximum: 50,
),
axes: <ChartAxis>[
// Agrega los ejes adicionales
NumericAxis(
name: 'secondYAxis', // Nombre único para este eje
title: AxisTitle(text: 'Tasa de crecimiento (%)'),
minimum: 0,
maximum: 10,
opposedPosition: true, // Coloca el eje a la derecha
),
],
series: <ColumnSeries<SalesData, String>>[
// Primera serie: Región A
ColumnSeries<SalesData, String>(
dataSource: [
SalesData('Ene', 35),
SalesData('Feb', 28),
SalesData('Mar', 34),
SalesData('Abr', 32),
SalesData('May', 40),
],
dataLabelSettings: DataLabelSettings(
isVisible: true,
labelAlignment: ChartDataLabelAlignment.top,
textStyle: TextStyle(fontSize: 12, color: Colors.black),
),
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
color: Colors.blue, // Color de las columnas
width: 0.8,
),
ColumnSeries<SalesData, String>(
yAxisName: 'secondYAxis',
dataSource: [
SalesData('Ene', 0.5),
SalesData('Feb', 1),
SalesData('Mar', 3),
SalesData('Abr', 1.5),
SalesData('May', 4),
],
dataLabelSettings: DataLabelSettings(
isVisible: true,
labelAlignment: ChartDataLabelAlignment.top,
textStyle: TextStyle(fontSize: 12, color: Colors.black),
),
xValueMapper: (SalesData sales, _) => sales.month,
yValueMapper: (SalesData sales, _) => sales.sales,
color: Colors.red, // Color de las columnas
width: 0.8,
),
],
),

Modificar la duración de la animación
Por último, puedes gestionar la duración de la animación de entrada de tu gráfico de columnas con animationDuration (en milisegundos):
LineSeries<SalesData, double>(
dataSource: /* ... */,
xValueMapper: (SalesData sales, _) => sales.year,
yValueMapper: (SalesData sales, _) => sales.sales,
animationDuration: 5000, // 5 segundos
),