Gestionar etiquetas de datos de gráficos en presentaciones usando C++
Introducción
Las etiquetas de datos muestran información sobre las series de gráficos y los puntos de datos individuales, ayudando a los lectores a identificar valores y comprender el gráfico. Este artículo explica cómo formatear valores, mostrar porcentajes, leer el texto de las etiquetas, controlar las etiquetas más allá del máximo del eje, ajustar el espacio entre etiquetas del eje de categorías y posicionar las etiquetas de los gráficos de sectores.
Establecer la precisión de los datos en las etiquetas de datos del gráfico
Utilice set_NumberFormatOfValues para formatear los valores de la serie. Este ejemplo crea un gráfico de líneas con datos predeterminados, muestra su tabla de datos y habilita las etiquetas de valor para la primera serie. El formato #,##0.00 muestra un separador de miles y dos decimales sin cambiar los valores subyacentes.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IDataLabelCollection.h>
#include <DOM/Chart/IDataLabelFormat.h>
#include <Export/SaveFormat.h>
#include <system/smart_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::Line, 50, 50, 450, 300);
chart->set_HasDataTable(true);
auto series = chart->get_ChartData()->get_Series()->idx_get(0);
series->set_NumberFormatOfValues(u"#,##0.00");
series->get_Labels()->get_DefaultDataLabelFormat()->set_ShowValue(true);
presentation->Save(u"PrecisionOfDatalabels_out.pptx", SaveFormat::Pptx);
Para formatear las celdas numéricas en el libro de trabajo incrustado en un gráfico, consulte Establecer formatos numéricos personalizados para celdas de libro de trabajo. Ese ejemplo también muestra etiquetas de valor que siguen los formatos de sus celdas de origen mientras preservan los valores numéricos almacenados.
Mostrar porcentaje como etiquetas
Para un gráfico de columnas apiladas, calcule cada valor como un porcentaje del total de su categoría y asigne el texto al marco de texto devuelto por get_TextFrameForOverriding. Este ejemplo usa los datos predeterminados del gráfico y muestra porcentajes con dos decimales en una fuente de 8 puntos. Las categorías con un total de cero se omiten para evitar divisiones por cero. Recalcule el texto personalizado de la etiqueta si los datos del gráfico cambian.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartCategoryCollection.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <DOM/Chart/IChartDataPoint.h>
#include <DOM/Chart/IDoubleChartValue.h>
#include <DOM/Chart/IDataLabel.h>
#include <DOM/Chart/IDataLabelCollection.h>
#include <DOM/Chart/IDataLabelFormat.h>
#include <DOM/Portion.h>
#include <DOM/IPortionFormat.h>
#include <DOM/ITextFrame.h>
#include <DOM/IParagraph.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/IPortionCollection.h>
#include <system/convert.h>
#include <vector>
#include <Export/SaveFormat.h>
#include <system/smart_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::StackedColumn, 20, 20, 400, 400);
auto categoryTotals = std::vector<double>(chart->get_ChartData()->get_Categories()->get_Count(), 0.0);
for (auto k = 0; k < chart->get_ChartData()->get_Categories()->get_Count(); k++)
{
for (auto i = 0; i < chart->get_ChartData()->get_Series()->get_Count(); i++)
{
auto series = chart->get_ChartData()->get_Series()->idx_get(i);
auto pointValue = Convert::ToDouble(series->get_DataPoint(k)->get_Value()->get_Data());
categoryTotals[k] += pointValue;
}
}
for (auto x = 0; x < chart->get_ChartData()->get_Series()->get_Count(); x++)
{
auto series = chart->get_ChartData()->get_Series()->idx_get(x);
series->get_Labels()->get_DefaultDataLabelFormat()->set_ShowLegendKey(false);
for (auto j = 0; j < series->get_DataPoints()->get_Count(); j++)
{
auto label = series->get_DataPoint(j)->get_Label();
if (categoryTotals[j] == 0)
{
continue;
}
auto pointValue = Convert::ToDouble(series->get_DataPoint(j)->get_Value()->get_Data());
auto dataPointPercent = (pointValue / categoryTotals[j]) * 100;
auto portion = MakeObject<Portion>();
portion->set_Text(String::Format(u"{0:F2} %", dataPointPercent));
portion->get_PortionFormat()->set_FontHeight(8.0f);
label->get_TextFrameForOverriding()->set_Text(u"");
auto paragraph = label->get_TextFrameForOverriding()->get_Paragraphs()->idx_get(0);
paragraph->get_Portions()->Add(portion);
label->get_DataLabelFormat()->set_ShowValue(true);
label->get_DataLabelFormat()->set_ShowSeriesName(false);
label->get_DataLabelFormat()->set_ShowPercentage(false);
label->get_DataLabelFormat()->set_ShowLegendKey(false);
label->get_DataLabelFormat()->set_ShowCategoryName(false);
label->get_DataLabelFormat()->set_ShowBubbleSize(false);
}
}
presentation->Save(u"DisplayPercentageAsLabels_out.pptx", SaveFormat::Pptx);
Establecer el signo de porcentaje con las etiquetas de datos del gráfico
Cuando los valores se almacenan como fracciones, utilice set_NumberFormat para mostrar porcentajes. Pase false a set_IsNumberFormatLinkedToSource para aplicar el formato de la etiqueta de forma independiente de las celdas de origen.
Este ejemplo crea un gráfico de columnas apiladas al 100 % con series roja y azul en cuatro categorías. Cada par de valores suma 1. El formato de etiqueta 0.0% muestra 0.30 como 30.0 %, mientras que el eje vertical usa dos decimales. Ambas series utilizan texto de etiqueta blanco de 10 puntos.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IAxesManager.h>
#include <DOM/Chart/IAxis.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartCategoryCollection.h>
#include <DOM/Chart/IChartDataWorkbook.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <DOM/Chart/IFormat.h>
#include <DOM/Chart/IDataLabelCollection.h>
#include <DOM/Chart/IDataLabelFormat.h>
#include <DOM/Chart/IChartTextFormat.h>
#include <DOM/Chart/IChartPortionFormat.h>
#include <DOM/FillType.h>
#include <DOM/IFillFormat.h>
#include <DOM/IColorFormat.h>
#include <drawing/color.h>
#include <system/object_ext.h>
#include <Export/SaveFormat.h>
#include <system/smart_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::Drawing;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::PercentsStackedColumn, 20, 20, 500, 400);
chart->get_Axes()->get_VerticalAxis()->set_IsNumberFormatLinkedToSource(false);
chart->get_Axes()->get_VerticalAxis()->set_NumberFormat(u"0.00%");
chart->get_ChartData()->get_Series()->Clear();
chart->get_ChartData()->get_Categories()->Clear();
auto workbook = chart->get_ChartData()->get_ChartDataWorkbook();
auto worksheetIndex = 0;
for (auto i = 0; i < 4; i++)
{
auto categoryCell = workbook->GetCell(worksheetIndex, i + 1, 0, ObjectExt::Box(String::Format(u"Category {0}", i + 1)));
chart->get_ChartData()->get_Categories()->Add(categoryCell);
}
String seriesNames[] = { u"Reds", u"Blues" };
Color seriesColors[] = { Color::get_Red(), Color::get_Blue() };
double values[2][4] = { { 0.30, 0.50, 0.80, 0.65 }, { 0.70, 0.50, 0.20, 0.35 } };
for (auto i = 0; i < 2; i++)
{
auto seriesCell = workbook->GetCell(worksheetIndex, 0, i + 1, ObjectExt::Box(seriesNames[i]));
auto series = chart->get_ChartData()->get_Series()->Add(seriesCell, chart->get_Type());
for (auto j = 0; j < 4; j++)
{
auto valueCell = workbook->GetCell(worksheetIndex, j + 1, i + 1, ObjectExt::Box(values[i][j]));
series->get_DataPoints()->AddDataPointForBarSeries(valueCell);
}
series->get_Format()->get_Fill()->set_FillType(FillType::Solid);
series->get_Format()->get_Fill()->get_SolidFillColor()->set_Color(seriesColors[i]);
auto labelFormat = series->get_Labels()->get_DefaultDataLabelFormat();
labelFormat->set_ShowValue(true);
labelFormat->set_IsNumberFormatLinkedToSource(false);
labelFormat->set_NumberFormat(u"0.0%");
labelFormat->get_TextFormat()->get_PortionFormat()->set_FontHeight(10);
labelFormat->get_TextFormat()->get_PortionFormat()->get_FillFormat()->set_FillType(FillType::Solid);
labelFormat->get_TextFormat()->get_PortionFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_White());
}
presentation->Save(u"SetDataLabelsPercentageSign_out.pptx", SaveFormat::Pptx);
Leer el texto real de las etiquetas de datos
Utilice GetActualLabelText para obtener el texto generado por la configuración de una etiqueta de datos. Esto es útil al extraer etiquetas para informes, buscar contenido en presentaciones o validar gráficos generados. En el ejemplo siguiente, el formato de etiqueta de datos predeterminado combina el nombre de cada categoría, el nombre de la serie y el valor. Un punto formatea su valor como porcentaje, y otro usa texto personalizado de get_TextFrameForOverriding.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartCategoryCollection.h>
#include <DOM/Chart/IChartDataWorkbook.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <DOM/Chart/IChartDataPoint.h>
#include <DOM/Chart/IDoubleChartValue.h>
#include <DOM/Chart/IDataLabel.h>
#include <DOM/Chart/IDataLabelCollection.h>
#include <DOM/Chart/IDataLabelFormat.h>
#include <DOM/ITextFrame.h>
#include <system/console.h>
#include <system/object_ext.h>
#include <system/smart_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 20, 20, 500, 300);
chart->get_ChartData()->get_Series()->Clear();
chart->get_ChartData()->get_Categories()->Clear();
auto workbook = chart->get_ChartData()->get_ChartDataWorkbook();
auto firstCategoryCell = workbook->GetCell(0, 1, 0, ObjectExt::Box<String>(u"Q1"));
chart->get_ChartData()->get_Categories()->Add(firstCategoryCell);
auto secondCategoryCell = workbook->GetCell(0, 2, 0, ObjectExt::Box<String>(u"Q2"));
chart->get_ChartData()->get_Categories()->Add(secondCategoryCell);
auto northSeriesCell = workbook->GetCell(0, 0, 1, ObjectExt::Box<String>(u"North"));
auto north = chart->get_ChartData()->get_Series()->Add(northSeriesCell, chart->get_Type());
auto northFirstValueCell = workbook->GetCell(0, 1, 1, ObjectExt::Box(0.25));
north->get_DataPoints()->AddDataPointForBarSeries(northFirstValueCell);
auto northSecondValueCell = workbook->GetCell(0, 2, 1, ObjectExt::Box(0.75));
north->get_DataPoints()->AddDataPointForBarSeries(northSecondValueCell);
auto southSeriesCell = workbook->GetCell(0, 0, 2, ObjectExt::Box<String>(u"South"));
auto south = chart->get_ChartData()->get_Series()->Add(southSeriesCell, chart->get_Type());
auto southFirstValueCell = workbook->GetCell(0, 1, 2, ObjectExt::Box(0.40));
south->get_DataPoints()->AddDataPointForBarSeries(southFirstValueCell);
auto southSecondValueCell = workbook->GetCell(0, 2, 2, ObjectExt::Box(0.60));
south->get_DataPoints()->AddDataPointForBarSeries(southSecondValueCell);
for (auto i = 0; i < chart->get_ChartData()->get_Series()->get_Count(); i++)
{
auto series = chart->get_ChartData()->get_Series()->idx_get(i);
auto format = series->get_Labels()->get_DefaultDataLabelFormat();
format->set_ShowCategoryName(true);
format->set_ShowSeriesName(true);
format->set_ShowValue(true);
}
north->get_Label(1)->get_DataLabelFormat()->set_IsNumberFormatLinkedToSource(false);
north->get_Label(1)->get_DataLabelFormat()->set_NumberFormat(u"0%");
south->get_Label(0)->get_TextFrameForOverriding()->set_Text(u"Reviewed");
for (auto i = 0; i < chart->get_ChartData()->get_Series()->get_Count(); i++)
{
auto series = chart->get_ChartData()->get_Series()->idx_get(i);
for (auto j = 0; j < series->get_DataPoints()->get_Count(); j++)
{
auto point = series->get_DataPoint(j);
auto label = point->get_Label();
if (!label->get_IsVisible())
{
continue;
}
Console::WriteLine(String::Format(u"Value: {0}; label: {1}", point->get_Value()->get_Data(), label->GetActualLabelText()));
}
}
El número almacenado en un punto de datos sigue siendo 0.75, incluso cuando su etiqueta muestra 75 % junto con los nombres de categoría y serie. El texto personalizado reemplaza el texto de etiqueta generado. GetActualLabelText devuelve la cadena de etiqueta resultante en ambos casos. Compruebe get_IsVisible por separado, como se muestra arriba, cuando desee extraer solo las etiquetas visibles.
Controlar las etiquetas de datos más allá del máximo del eje
Cuando limita manualmente el rango de un eje, algunos puntos de datos pueden superar su máximo. Utilice set_ShowDataLabelsOverMaximum para controlar si se muestran sus etiquetas de datos. Esta configuración cambia la visibilidad de las etiquetas; no modifica el rango del eje ni los valores subyacentes de los datos.
El ejemplo siguiente crea un gráfico de columnas agrupadas 2D con valores de 60 y 120. Establece set_IsAutomaticMaxValue a false y set_MaxValue a 100 en el eje vertical. La primera diapositiva permite etiquetas más allá del máximo; una copia de esa diapositiva las desactiva. Ambas diapositivas se guardan en DataLabelsOverMaximum.pptx.
Habilite las etiquetas de valor con set_ShowValue. La configuración a nivel de gráfico no habilita la visualización de valores por sí sola ni sobrescribe la visualización desactivada de un valor en una etiqueta individual. Este ejemplo habilita los valores para toda la serie y usa set_Position para colocar las etiquetas en el extremo exterior de cada columna.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IAxesManager.h>
#include <DOM/Chart/IAxis.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartCategoryCollection.h>
#include <DOM/Chart/IChartDataWorkbook.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <DOM/Chart/IDataLabelCollection.h>
#include <DOM/Chart/IDataLabelFormat.h>
#include <DOM/Chart/LegendDataLabelPosition.h>
#include <Export/SaveFormat.h>
#include <system/object_ext.h>
#include <system/smart_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 50, 50, 600, 400);
chart->set_HasLegend(false);
chart->get_ChartData()->get_Series()->Clear();
chart->get_ChartData()->get_Categories()->Clear();
auto workbook = chart->get_ChartData()->get_ChartDataWorkbook();
auto firstCategory = workbook->GetCell(0, 1, 0, ObjectExt::Box<String>(u"Within range"));
auto secondCategory = workbook->GetCell(0, 2, 0, ObjectExt::Box<String>(u"Above maximum"));
chart->get_ChartData()->get_Categories()->Add(firstCategory);
chart->get_ChartData()->get_Categories()->Add(secondCategory);
auto seriesName = workbook->GetCell(0, 0, 1, ObjectExt::Box<String>(u"Values"));
auto series = chart->get_ChartData()->get_Series()->Add(seriesName, chart->get_Type());
auto firstValue = workbook->GetCell(0, 1, 1, ObjectExt::Box(60));
auto secondValue = workbook->GetCell(0, 2, 1, ObjectExt::Box(120));
series->get_DataPoints()->AddDataPointForBarSeries(firstValue);
series->get_DataPoints()->AddDataPointForBarSeries(secondValue);
series->get_Labels()->get_DefaultDataLabelFormat()->set_ShowValue(true);
series->get_Labels()->get_DefaultDataLabelFormat()->set_Position(LegendDataLabelPosition::OutsideEnd);
chart->get_Axes()->get_VerticalAxis()->set_IsAutomaticMaxValue(false);
chart->get_Axes()->get_VerticalAxis()->set_MaxValue(100);
chart->set_ShowDataLabelsOverMaximum(true);
auto secondSlide = presentation->get_Slides()->AddClone(slide);
auto secondChart = ExplicitCast<IChart>(secondSlide->get_Shape(0));
secondChart->set_ShowDataLabelsOverMaximum(false);
presentation->Save(u"DataLabelsOverMaximum.pptx", SaveFormat::Pptx);
Las siguientes imágenes muestran las diapositivas guardadas renderizadas por Microsoft PowerPoint. Con true, la etiqueta 120 es visible en el límite superior; con false, está oculta. La etiqueta 60 sigue visible, el máximo del eje permanece en 100, y el segundo punto de datos sigue siendo 120 en ambos casos.
| ShowDataLabelsOverMaximum = true | ShowDataLabelsOverMaximum = false |
|---|---|
![]() |
![]() |
Chart Type
Este ejemplo usa un gráfico de columnas 2D con un eje de valores. Los gráficos sin eje de valores, como los gráficos de sectores y de anillo, no tienen un máximo de eje que limitar de esta manera.Establecer la distancia de la etiqueta respecto a un eje
Utilice set_LabelOffset para controlar la distancia entre las etiquetas del eje de categorías y el eje. El valor es un porcentaje del tamaño máximo de fuente de las etiquetas del eje. Este ejemplo crea un gráfico de columnas agrupadas y establece el desplazamiento de etiqueta del eje horizontal a 500. Esta configuración afecta a las etiquetas del eje de categorías más que a las etiquetas vinculadas a puntos de datos individuales.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IAxesManager.h>
#include <DOM/Chart/IAxis.h>
#include <Export/SaveFormat.h>
#include <system/smart_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 20, 20, 500, 300);
chart->get_Axes()->get_HorizontalAxis()->set_LabelOffset(500);
presentation->Save(u"SetCategoryAxisLabelDistance_out.pptx", SaveFormat::Pptx);
Ajustar la ubicación de la etiqueta
En un gráfico de sectores, ajuste las posiciones de las etiquetas de datos para mejorar el espaciado y dejar espacio para las líneas guía.
Este ejemplo muestra el valor del primer punto de datos, coloca su etiqueta fuera de la porción y utiliza set_X y set_Y para ajustar sus desplazamientos. Estos desplazamientos son relativos al ancho y la altura del gráfico, respectivamente.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IDataLabel.h>
#include <DOM/Chart/IDataLabelFormat.h>
#include <DOM/Chart/LegendDataLabelPosition.h>
#include <Export/SaveFormat.h>
#include <system/smart_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::Pie, 50, 50, 200, 200);
auto series = chart->get_ChartData()->get_Series();
auto label = series->idx_get(0)->get_Label(0);
label->get_DataLabelFormat()->set_ShowValue(true);
label->get_DataLabelFormat()->set_Position(LegendDataLabelPosition::OutsideEnd);
label->set_X(0.71f);
label->set_Y(0.04f);
presentation->Save(u"presentation.pptx", SaveFormat::Pptx);

Formatear líneas guía
Cuando las etiquetas de un gráfico de sectores se sitúan fuera de sus porciones, las líneas guía ayudan a los lectores a asociar cada valor con la porción correspondiente. Un color contrastante y una línea ligeramente más gruesa pueden facilitar seguir estas conexiones, mientras que la transparencia y un estilo punteado mantienen las líneas visualmente discretas.
Utilice get_LeaderLinesFormat para formatear las líneas guía a nivel de la colección de etiquetas de datos de la serie. Los ajustes en series->get_Labels()->get_LeaderLinesFormat()->get_Line() se aplican a la colección, en lugar de a una etiqueta individual.
Este ejemplo crea un gráfico de sectores con datos predeterminados, muestra los valores fuera de las porciones y habilita líneas guía con set_ShowLeaderLines. Mueve dos etiquetas más lejos de sus porciones usando desplazamientos set_X y set_Y, expresados como fracciones del ancho y la altura del gráfico. No se requiere una presentación de entrada.
El formato de relleno devuelto por get_FillFormat se utiliza para establecer un color azul sólido con un valor alfa de 191 de 255, lo que brinda aproximadamente un 25 % de transparencia. set_Width establece el grosor en 2 puntos, y set_DashStyle hace que la línea sea punteada.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IDataLabel.h>
#include <DOM/Chart/IDataLabelCollection.h>
#include <DOM/Chart/IDataLabelFormat.h>
#include <DOM/Chart/IChartLinesFormat.h>
#include <DOM/Chart/LegendDataLabelPosition.h>
#include <DOM/ILineFormat.h>
#include <DOM/ILineFillFormat.h>
#include <DOM/IColorFormat.h>
#include <DOM/FillType.h>
#include <DOM/LineDashStyle.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
#include <system/smart_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::Drawing;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::Pie, 80, 50, 560, 400);
chart->set_HasLegend(false);
auto series = chart->get_ChartData()->get_Series()->idx_get(0);
auto labelFormat = series->get_Labels()->get_DefaultDataLabelFormat();
labelFormat->set_ShowValue(true);
labelFormat->set_Position(LegendDataLabelPosition::OutsideEnd);
labelFormat->set_ShowLeaderLines(true);
// Mover dos etiquetas más lejos de sus porciones.
series->get_Label(0)->set_X(0.10f);
series->get_Label(0)->set_Y(-0.05f);
series->get_Label(1)->set_X(-0.10f);
series->get_Label(1)->set_Y(0.05f);
auto line = series->get_Labels()->get_LeaderLinesFormat()->get_Line();
line->get_FillFormat()->set_FillType(FillType::Solid);
line->get_FillFormat()->get_SolidFillColor()->set_Color(Color::FromArgb(191, 30, 90, 160));
line->set_Width(2);
line->set_DashStyle(LineDashStyle::Dash);
presentation->Save(u"FormattedLeaderLines.pptx", SaveFormat::Pptx);
Activar las líneas guía no garantiza que aparezca una línea para cada etiqueta. La visibilidad depende de la ubicación de la etiqueta y del comportamiento de diseño del gráfico. En este ejemplo, las dos etiquetas desplazadas tienen líneas guía visibles; las etiquetas que permanecen cercanas a sus porciones no las necesitan.
La siguiente imagen muestra el archivo FormattedLeaderLines.pptx guardado renderizado con Aspose.Slides:

Añadir varias filas de etiquetas de datos encima de un gráfico de columnas
Este ejemplo crea un gráfico de columnas con dos filas de etiquetas de datos encima del área de trazado. La Serie A muestra las columnas visibles, mientras que las Series B y C proporcionan las etiquetas adicionales. Sus columnas se ocultan eliminando el relleno y el contorno. El método set_Overlap alinea las tres series en los mismos centros de categoría.
Los ajustes de get_PlotArea reservan espacio para las filas de etiquetas. Después de que ValidateChartLayout calcula las posiciones predeterminadas, set_X y set_Y conservan la alineación horizontal y aplican desplazamientos verticales para organizar las etiquetas en dos filas. Los números siguen siendo etiquetas de datos vinculadas a los valores de la serie; solo los encabezados de fila son formas de texto independientes.
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartCategoryCollection.h>
#include <DOM/Chart/IChartDataWorkbook.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <DOM/Chart/IChartDataPoint.h>
#include <DOM/Chart/IChartSeriesGroup.h>
#include <DOM/Chart/IFormat.h>
#include <DOM/Chart/IDataLabelCollection.h>
#include <DOM/Chart/IDataLabelFormat.h>
#include <DOM/Chart/IDataLabel.h>
#include <DOM/Chart/IChartTextFormat.h>
#include <DOM/Chart/IChartPortionFormat.h>
#include <DOM/Chart/LegendDataLabelPosition.h>
#include <DOM/Chart/IAxesManager.h>
#include <DOM/Chart/IAxis.h>
#include <DOM/Chart/IChartPlotArea.h>
#include <DOM/Chart/LayoutTargetType.h>
#include <DOM/FillType.h>
#include <DOM/IFillFormat.h>
#include <DOM/ILineFormat.h>
#include <DOM/IColorFormat.h>
#include <DOM/ShapeType.h>
#include <DOM/IAutoShape.h>
#include <DOM/ITextFrame.h>
#include <DOM/ITextFrameFormat.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/IParagraph.h>
#include <DOM/IPortionCollection.h>
#include <DOM/IPortion.h>
#include <DOM/IPortionFormat.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
#include <system/object_ext.h>
#include <system/smart_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::Drawing;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 40, 40, 640, 200);
chart->set_HasTitle(false);
chart->set_HasLegend(false);
chart->get_TextFormat()->get_PortionFormat()->set_FontHeight(12);
chart->get_ChartData()->get_Series()->Clear();
chart->get_ChartData()->get_Categories()->Clear();
auto workbook = chart->get_ChartData()->get_ChartDataWorkbook();
workbook->Clear(0);
String categories[] = { u"North", u"South", u"East", u"West" };
String seriesNames[] = { u"Series A", u"Series B", u"Series C" };
double seriesValues[3][4] = {
{ 35, 42, 28, 47 },
{ 22, 31, 19, 26 },
{ 12, 16, 14, 18 }
};
for (auto categoryIndex = 0; categoryIndex < 4; categoryIndex++)
{
auto categoryCell = workbook->GetCell(0, categoryIndex + 1, 0, ObjectExt::Box(categories[categoryIndex]));
chart->get_ChartData()->get_Categories()->Add(categoryCell);
}
for (auto seriesIndex = 0; seriesIndex < 3; seriesIndex++)
{
auto seriesCell = workbook->GetCell(0, 0, seriesIndex + 1, ObjectExt::Box(seriesNames[seriesIndex]));
auto series = chart->get_ChartData()->get_Series()->Add(seriesCell, ChartType::ClusteredColumn);
for (auto categoryIndex = 0; categoryIndex < 4; categoryIndex++)
{
auto valueCell = workbook->GetCell(0, categoryIndex + 1, seriesIndex + 1, ObjectExt::Box(seriesValues[seriesIndex][categoryIndex]));
series->get_DataPoints()->AddDataPointForBarSeries(valueCell);
}
if (seriesIndex > 0)
{
// Ocultar las columnas de B y C, pero mantener sus etiquetas de datos.
series->get_Format()->get_Fill()->set_FillType(FillType::NoFill);
series->get_Format()->get_Line()->get_FillFormat()->set_FillType(FillType::NoFill);
auto labelFormat = series->get_Labels()->get_DefaultDataLabelFormat();
labelFormat->set_ShowValue(true);
labelFormat->get_TextFormat()->get_PortionFormat()->set_FontHeight(12);
auto labelFill = labelFormat->get_TextFormat()->get_PortionFormat()->get_FillFormat();
labelFill->set_FillType(FillType::Solid);
labelFill->get_SolidFillColor()->set_Color(Color::get_Black());
labelFormat->set_Position(LegendDataLabelPosition::InsideBase);
}
}
// Alinear las tres series con los mismos centros de categoría.
chart->get_ChartData()->get_Series()->idx_get(0)->get_ParentSeriesGroup()->set_Overlap(100);
// Usar menos líneas de cuadrícula para este ejemplo compacto.
chart->get_Axes()->get_VerticalAxis()->set_IsAutomaticMajorUnit(false);
chart->get_Axes()->get_VerticalAxis()->set_MajorUnit(10);
// Reservar espacio encima del área de trazado para dos filas de etiquetas de datos.
chart->get_PlotArea()->set_LayoutTargetType(LayoutTargetType::Inner);
chart->get_PlotArea()->set_X(0.15f);
chart->get_PlotArea()->set_Y(0.32f);
chart->get_PlotArea()->set_Width(0.80f);
chart->get_PlotArea()->set_Height(0.48f);
chart->ValidateChartLayout();
for (auto seriesIndex = 1; seriesIndex < 3; seriesIndex++)
{
auto series = chart->get_ChartData()->get_Series()->idx_get(seriesIndex);
auto rowTop = seriesIndex == 1 ? 0.15f : 0.03f;
for (auto categoryIndex = 0; categoryIndex < 4; categoryIndex++)
{
auto dataLabel = series->get_DataPoint(categoryIndex)->get_Label();
// Mantener la posición horizontal predeterminada. Y es un desplazamiento desde
// la posición predeterminada de la etiqueta, expresado como una fracción de la altura del gráfico.
dataLabel->set_X(0);
dataLabel->set_Y(rowTop - dataLabel->get_ActualY() / chart->get_Height());
}
// Solo el encabezado de fila es una forma de texto separada.
auto rowHeading = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, chart->get_X(), chart->get_Y() + rowTop * chart->get_Height(), 85, 18);
rowHeading->get_FillFormat()->set_FillType(FillType::NoFill);
rowHeading->get_LineFormat()->get_FillFormat()->set_FillType(FillType::NoFill);
rowHeading->AddTextFrame(seriesNames[seriesIndex]);
rowHeading->get_TextFrame()->get_TextFrameFormat()->set_MarginTop(0);
rowHeading->get_TextFrame()->get_TextFrameFormat()->set_MarginBottom(0);
auto headingFormat = rowHeading->get_TextFrame()->get_Paragraphs()->idx_get(0)->get_Portions()->idx_get(0)->get_PortionFormat();
headingFormat->set_FontHeight(12);
headingFormat->get_FillFormat()->set_FillType(FillType::Solid);
headingFormat->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Black());
}
presentation->Save(u"multiple-rows-of-labels.pptx", SaveFormat::Pptx);

Preguntas frecuentes
¿Cómo puedo evitar que las etiquetas de datos se superpongan en gráficos densos?
Combine la colocación automática de etiquetas, líneas guía y reducción del tamaño de la fuente; si es necesario, oculte algunos campos (por ejemplo, la categoría) o muestre etiquetas solo para valores extremos o puntos clave.
¿Cómo puedo desactivar las etiquetas solo para valores cero, negativos o vacíos?
Filtre los puntos de datos antes de habilitar las etiquetas y desactive la visualización para valores de 0, valores negativos o valores ausentes según una regla definida.
¿Cómo puedo garantizar un estilo de etiqueta coherente al exportar a PDF/imágenes?
Establezca explícitamente la familia y el tamaño de la fuente y verifique que la fuente esté disponible en el entorno de renderizado para evitar sustituciones.

