Gestionar series de datos de gráficos en presentaciones en C++
Visión general
Un gráfico puede almacenar sus valores trazados en celdas del libro de trabajo o directamente como literales numéricos. Un IChartSeries representa un conjunto de valores relacionados, y cada IChartDataPoint representa un punto en esa serie. Los objetos IChartCategory proporcionan las etiquetas o valores de agrupamiento compartidos por las series. En los gráficos creados con datos predeterminados, los nombres de serie, categorías y valores de punto utilizan objetos IChartDataCell del libro de trabajo del gráfico.
Para un gráfico de categorías típico, el libro de trabajo predeterminado utiliza la fila 0 para los nombres de serie, la columna 0 para los nombres de categoría y el resto de celdas para los valores de serie. Los índices de hoja de cálculo, fila y columna pasados a IChartDataWorkbook::GetCell son basados en cero. Este diseño es útil cuando crea un gráfico con datos predeterminados, pero no asuma que todos los gráficos existentes lo utilizan. Para una presentación cargada, inspeccione las celdas referenciadas por las series, categorías y puntos de datos antes de modificar los valores del libro de trabajo.
Los ajustes del gráfico tienen tres ámbitos diferentes:
- Configuraciones a nivel de serie, como IChartSeries::get_Format, proporcionan la apariencia predeterminada para todos los puntos de una serie.
- Configuraciones de punto de datos, como IChartDataPoint::get_Format, sobrescriben la apariencia de la serie para un punto.
- Las configuraciones de grupo se aplican a series compatibles que pertenecen al mismo IChartSeriesGroup. Acceda al grupo a través de IChartSeries::get_ParentSeriesGroup cuando necesite establecer opciones como solapamiento o ancho de separación.
Cuando no se define un relleno explícito para el punto o la serie, el estilo y el tema del gráfico determinan la apariencia automática. Cuando están presentes tanto el formato de la serie como el del punto, el formato del punto prevalece para ese punto.

Establecer valores de serie usando literales numéricos
Use literales numéricos cuando los valores de serie provengan de datos de la aplicación o de cálculos y no necesiten referencias a celdas de hoja de cálculo. Llame a set_DataSourceTypeForValues con DataSourceType::DoubleLiterals antes de asignar el valor devuelto por cada get_Value del punto mediante set_AsLiteralDouble.
La configuración de la colección controla el tipo de origen de todos los valores de punto en esa serie. El método IBaseChartValue::get_DataSourceType de cada punto informa el tipo seleccionado; cámbielo mediante la configuración de la colección. Con Worksheet, utilice get_AsCell para acceder a la celda referenciada. Con DoubleLiterals, utilice get_AsLiteralDouble o set_AsLiteralDouble para leer o escribir el número directamente.
El siguiente ejemplo crea un gráfico de columnas con series y categorías predeterminadas, luego asigna valores calculados de 10, 20, etc., a los puntos existentes de su primera serie. Guarda la presentación, la vuelve a abrir y muestra los valores almacenados.
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/DataSourceType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartDataPoint.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IDoubleChartValue.h>
#include <DOM/IChart.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <system/console.h>
#include <system/object_ext.h>
#include <system/shared_ptr.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);
auto series = chart->get_ChartData()->get_Series()->idx_get(0);
series->get_DataPoints()->set_DataSourceTypeForValues(DataSourceType::DoubleLiterals);
for (auto i = 0; i < series->get_DataPoints()->get_Count(); i++)
{
series->get_DataPoints()->idx_get(i)->get_Value()->set_AsLiteralDouble((i + 1) * 10);
}
presentation->Save(u"numeric_literals.pptx", SaveFormat::Pptx);
presentation->Dispose();
auto reopenedPresentation = MakeObject<Presentation>(u"numeric_literals.pptx");
auto reopenedSlide = reopenedPresentation->get_Slide(0);
auto reopenedChart = ExplicitCast<IChart>(reopenedSlide->get_Shape(0));
auto reopenedSeries = reopenedChart->get_ChartData()->get_Series()->idx_get(0);
for (auto i = 0; i < reopenedSeries->get_DataPoints()->get_Count(); i++)
{
auto point = reopenedSeries->get_DataPoints()->idx_get(i);
Console::WriteLine(point->get_Value()->get_AsLiteralDouble());
}
reopenedPresentation->Dispose();
El tipo de origen del valor del punto es independiente de IChartData::get_DataSourceType, que identifica la configuración del libro de trabajo interno o externo del gráfico. Usar literales numéricos no elimina, por sí mismo, el libro de trabajo incrustado. En este ejemplo, el libro de trabajo sigue disponible para las etiquetas de categoría, los nombres de serie y las demás series. Consulte Libro de trabajo del gráfico para la gestión del libro de trabajo.
Para los gráficos de dispersión y burbujas, llame a set_DataSourceTypeForXValues y set_DataSourceTypeForYValues para elegir los orígenes de get_XValue y get_YValue. Los gráficos de burbujas también usan set_DataSourceTypeForBubbleSizes para get_BubbleSize. Asigne cada origen aplicable a DoubleLiterals antes de asignar números mediante el método set_AsLiteralDouble de ese valor.
Establecer el solapamiento de la serie del gráfico
IChartSeries::get_Overlap informa cuánto se solapan las barras o columnas en un gráfico 2D, de -100 a 100 por ciento. Es una proyección de solo lectura del ajuste en el grupo de series padre. Llame a IChartSeriesGroup::set_Overlap para actualizar cada serie compatible en ese grupo. Esta opción se aplica a los tipos de gráfico que muestran barras o columnas agrupadas; no afecta a los grupos de series no relacionados en un gráfico combinado.
El siguiente ejemplo establece el solapamiento para el grupo que contiene la primera serie:
#include <cstdint>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeriesGroup.h>
#include <DOM/IChart.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <system/shared_ptr.h>
using Aspose::Slides::Charts::ChartType;
using Aspose::Slides::Export::SaveFormat;
using Aspose::Slides::Presentation;
const int firstSlideIndex = 0;
const int firstSeriesIndex = 0;
const int8_t overlapPercent = 30;
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(firstSlideIndex);
// El nuevo gráfico contiene series de muestra, categorías y valores.
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 20.0f, 20.0f, 500.0f, 200.0f);
auto seriesCollection = chart->get_ChartData()->get_Series();
auto series = seriesCollection->idx_get(firstSeriesIndex);
series->get_ParentSeriesGroup()->set_Overlap(overlapPercent);
presentation->Save(u"series_overlap.pptx", SaveFormat::Pptx);
presentation->Dispose();

Cambiar el color de relleno de la serie
Utilice IChartSeries::get_Format para establecer el relleno predeterminado de una serie completa. Si un punto ya tiene un relleno explícito, su configuración IChartDataPoint::get_Format sobrescribe el relleno de la serie para ese punto.
El siguiente ejemplo aplica un relleno sólido azul a la primera serie:
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IFormat.h>
#include <DOM/FillType.h>
#include <DOM/IChart.h>
#include <DOM/IColorFormat.h>
#include <DOM/IFillFormat.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
#include <system/shared_ptr.h>
using Aspose::Slides::Charts::ChartType;
using Aspose::Slides::Export::SaveFormat;
using Aspose::Slides::FillType;
using Aspose::Slides::Presentation;
using System::Drawing::Color;
const int firstSlideIndex = 0;
const int firstSeriesIndex = 0;
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(firstSlideIndex);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 20.0f, 20.0f, 500.0f, 200.0f);
auto seriesCollection = chart->get_ChartData()->get_Series();
auto series = seriesCollection->idx_get(firstSeriesIndex);
auto seriesColor = Color::get_Blue();
series->get_Format()->get_Fill()->set_FillType(FillType::Solid);
series->get_Format()->get_Fill()->get_SolidFillColor()->set_Color(seriesColor);
presentation->Save(u"series_color.pptx", SaveFormat::Pptx);
presentation->Dispose();

Cambiar el nombre de la serie
El nombre de una serie se almacena en el libro de datos del gráfico y normalmente se muestra en la leyenda. En el libro de trabajo predeterminado creado para un gráfico de columnas agrupadas, la celda B1 está en la fila 0, columna 1 y contiene el nombre de la primera serie. Las constantes con nombre en el siguiente ejemplo hacen explícita esa estructura:
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartDataWorkbook.h>
#include <DOM/IChart.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <system/object_ext.h>
#include <system/shared_ptr.h>
#include <system/string.h>
using Aspose::Slides::Charts::ChartType;
using Aspose::Slides::Export::SaveFormat;
using Aspose::Slides::Presentation;
using System::ObjectExt;
using System::String;
const int firstSlideIndex = 0;
const int worksheetIndex = 0;
const int seriesNameRowIndex = 0;
const int firstSeriesColumnIndex = 1;
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(firstSlideIndex);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 20.0f, 20.0f, 500.0f, 200.0f);
auto workbook = chart->get_ChartData()->get_ChartDataWorkbook();
auto seriesNameCell = workbook->GetCell(worksheetIndex, seriesNameRowIndex, firstSeriesColumnIndex);
auto seriesName = ObjectExt::Box<String>(u"Revenue");
seriesNameCell->set_Value(seriesName);
presentation->Save(u"series_name.pptx", SaveFormat::Pptx);
presentation->Dispose();
También puede actualizar la celda ya referenciada por IChartSeries::get_Name. Este enfoque evita suponer una fila y columna específicas en un gráfico existente:
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartCellCollection.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IStringChartValue.h>
#include <DOM/IChart.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <system/object_ext.h>
#include <system/shared_ptr.h>
#include <system/string.h>
using Aspose::Slides::Charts::ChartType;
using Aspose::Slides::Export::SaveFormat;
using Aspose::Slides::Presentation;
using System::ObjectExt;
using System::String;
const int firstSlideIndex = 0;
const int firstSeriesIndex = 0;
const int firstNameCellIndex = 0;
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(firstSlideIndex);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 20.0f, 20.0f, 500.0f, 200.0f);
auto seriesCollection = chart->get_ChartData()->get_Series();
auto series = seriesCollection->idx_get(firstSeriesIndex);
auto seriesNameCells = series->get_Name()->get_AsCells();
auto seriesNameCell = seriesNameCells->idx_get(firstNameCellIndex);
auto seriesName = ObjectExt::Box<String>(u"Revenue");
seriesNameCell->set_Value(seriesName);
presentation->Save(u"series_name.pptx", SaveFormat::Pptx);
presentation->Dispose();

Crear una serie con un nombre a partir de varias celdas
Un nombre de serie compuesto es útil cuando el nombre de un producto y el período de informe están almacenados en celdas de libro de trabajo distintas. Por ejemplo, puede combinar Product A en B1 y 2026 en C1 en un único nombre de serie manteniendo ambas partes vinculadas a sus celdas origen.
Utilice IChartDataWorkbook::GetCellCollection para obtener el rango de nombre, luego pase esa colección a IChartSeriesCollection::Add. El argumento skipHiddenCells controla si se incluyen celdas ocultas: true las excluye, mientras que false las incluye. Este ejemplo usa false para incluir todas las celdas del rango de nombre.
El siguiente ejemplo crea una presentación con una serie y dos puntos de datos. Las celdas B1:C1 proporcionan solo el nombre de la serie; A2:A3 suministran las etiquetas de categoría, y B2:B3 los valores numéricos.
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartCategoryCollection.h>
#include <DOM/Chart/IChartCellCollection.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <DOM/Chart/IChartDataWorkbook.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/IChart.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <system/object_ext.h>
#include <system/shared_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;
using System::ObjectExt;
using System::String;
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 50.0f, 50.0f, 620.0f, 180.0f);
auto chartData = chart->get_ChartData();
chartData->get_Series()->Clear();
chartData->get_Categories()->Clear();
chart->set_HasLegend(true);
auto workbook = chartData->get_ChartDataWorkbook();
workbook->Clear(0);
// Estas dos celdas suministran el nombre de la serie.
auto productName = ObjectExt::Box<String>(u"Product A");
auto reportingPeriod = ObjectExt::Box<String>(u"2026");
workbook->GetCell(0, 0, 1, productName);
workbook->GetCell(0, 0, 2, reportingPeriod);
auto nameCells = workbook->GetCellCollection(u"Sheet1!$B$1:$C$1", false);
auto series = chartData->get_Series()->Add(nameCells, ChartType::ClusteredColumn);
// Celdas separadas suministran las categorías y los puntos de datos numéricos.
auto northLabel = ObjectExt::Box<String>(u"North");
auto southLabel = ObjectExt::Box<String>(u"South");
auto northCategory = workbook->GetCell(0, 1, 0, northLabel);
auto southCategory = workbook->GetCell(0, 2, 0, southLabel);
chartData->get_Categories()->Add(northCategory);
chartData->get_Categories()->Add(southCategory);
auto northAmount = ObjectExt::Box<int>(120);
auto southAmount = ObjectExt::Box<int>(150);
auto northValue = workbook->GetCell(0, 1, 1, northAmount);
auto southValue = workbook->GetCell(0, 2, 1, southAmount);
series->get_DataPoints()->AddDataPointForBarSeries(northValue);
series->get_DataPoints()->AddDataPointForBarSeries(southValue);
presentation->Save(u"composite_series_name.pptx", SaveFormat::Pptx);
presentation->Dispose();
El nombre de serie resultante es Product A 2026, con un espacio entre los dos valores de celda. La leyenda lo muestra como una única entrada para ambas columnas. La imagen a continuación ilustra el resultado:

Obtener el color de relleno automático de la serie
IChartSeries::GetAutomaticSeriesColor devuelve el color calculado a partir del índice de la serie y el estilo del gráfico. Este es el color utilizado cuando el relleno de la serie no ha sido definido explícitamente. Llamar al método lee el color calculado; no asigna un nuevo relleno.
El siguiente ejemplo muestra el color automático de cada serie predeterminada:
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/IChart.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <drawing/color.h>
#include <system/console.h>
#include <system/shared_ptr.h>
#include <system/string.h>
using Aspose::Slides::Charts::ChartType;
using Aspose::Slides::Presentation;
using System::Console;
using System::String;
const int firstSlideIndex = 0;
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(firstSlideIndex);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 20.0f, 20.0f, 500.0f, 200.0f);
auto seriesCollection = chart->get_ChartData()->get_Series();
const int seriesCount = seriesCollection->get_Count();
for (int seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++)
{
auto series = seriesCollection->idx_get(seriesIndex);
auto automaticColor = series->GetAutomaticSeriesColor();
auto colorName = automaticColor.get_Name();
auto outputLine = String::Format(u"Series {0}: {1}", seriesIndex, colorName);
Console::WriteLine(outputLine);
}
presentation->Dispose();
Series 0: ff4f81bd
Series 1: ffc0504d
Series 2: ff9bbb59
Los colores exactos dependen del estilo y del tema del gráfico.
Establecer color de relleno invertido para una serie de gráfico
Para series de barras, columnas y burbujas, IChartSeries::set_InvertIfNegative puede mostrar valores negativos con un relleno diferente. Establezca el relleno regular de la serie como sólido, habilite la inversión y asigna el color de valor negativo mediante IChartSeries::get_InvertedSolidFillColor. Los números negativos permanecen sin cambios en el libro de trabajo; solo cambia su color de visualización.
El siguiente ejemplo reemplaza los datos predeterminados del gráfico con una serie. La fila 0 de la hoja de cálculo contiene el nombre de la serie, la columna 0 contiene los nombres de categoría y la columna 1 contiene los valores:
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartCategoryCollection.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <DOM/Chart/IChartDataWorkbook.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IFormat.h>
#include <DOM/FillType.h>
#include <DOM/IChart.h>
#include <DOM/IColorFormat.h>
#include <DOM/IFillFormat.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
#include <system/object_ext.h>
#include <system/shared_ptr.h>
#include <system/string.h>
using Aspose::Slides::Charts::ChartType;
using Aspose::Slides::Export::SaveFormat;
using Aspose::Slides::FillType;
using Aspose::Slides::Presentation;
using System::Drawing::Color;
using System::ObjectExt;
using System::String;
const int firstSlideIndex = 0;
const int worksheetIndex = 0;
const int headerRowIndex = 0;
const int categoryColumnIndex = 0;
const int firstSeriesColumnIndex = 1;
const int firstDataRowIndex = 1;
const int categoryCount = 3;
const String categoryNames[] = {u"Category 1", u"Category 2", u"Category 3"};
const int seriesValues[] = {-20, 50, -30};
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(firstSlideIndex);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 20.0f, 20.0f, 500.0f, 200.0f);
auto chartData = chart->get_ChartData();
auto workbook = chartData->get_ChartDataWorkbook();
auto seriesCollection = chartData->get_Series();
seriesCollection->Clear();
chartData->get_Categories()->Clear();
auto seriesName = ObjectExt::Box<String>(u"Series 1");
auto seriesNameCell = workbook->GetCell(worksheetIndex, headerRowIndex, firstSeriesColumnIndex, seriesName);
auto chartType = chart->get_Type();
auto series = seriesCollection->Add(seriesNameCell, chartType);
for (int categoryIndex = 0; categoryIndex < categoryCount; categoryIndex++)
{
const int dataRowIndex = firstDataRowIndex + categoryIndex;
auto categoryName = categoryNames[categoryIndex];
const int seriesValue = seriesValues[categoryIndex];
auto boxedCategoryName = ObjectExt::Box<String>(categoryName);
auto categoryCell = workbook->GetCell(worksheetIndex, dataRowIndex, categoryColumnIndex, boxedCategoryName);
chartData->get_Categories()->Add(categoryCell);
auto boxedSeriesValue = ObjectExt::Box<int>(seriesValue);
auto valueCell = workbook->GetCell(worksheetIndex, dataRowIndex, firstSeriesColumnIndex, boxedSeriesValue);
series->get_DataPoints()->AddDataPointForBarSeries(valueCell);
}
auto automaticSeriesColor = series->GetAutomaticSeriesColor();
auto invertedSeriesColor = Color::get_Red();
series->get_Format()->get_Fill()->set_FillType(FillType::Solid);
series->get_Format()->get_Fill()->get_SolidFillColor()->set_Color(automaticSeriesColor);
series->set_InvertIfNegative(true);
series->get_InvertedSolidFillColor()->set_Color(invertedSeriesColor);
presentation->Save(u"inverted_solid_fill_color.pptx", SaveFormat::Pptx);
presentation->Dispose();

Puede habilitar la inversión para un punto mediante IChartDataPoint::set_InvertIfNegative. En el siguiente ejemplo, la inversión está deshabilitada para la serie y habilitada solo para el punto seleccionado. Al punto también se le asigna un valor negativo para que el efecto sea visible:
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartDataPoint.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IDoubleChartValue.h>
#include <DOM/Chart/IFormat.h>
#include <DOM/FillType.h>
#include <DOM/IChart.h>
#include <DOM/IColorFormat.h>
#include <DOM/IFillFormat.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
#include <system/object_ext.h>
#include <system/shared_ptr.h>
using Aspose::Slides::Charts::ChartType;
using Aspose::Slides::Export::SaveFormat;
using Aspose::Slides::FillType;
using Aspose::Slides::Presentation;
using System::Drawing::Color;
using System::ObjectExt;
const int firstSlideIndex = 0;
const int firstSeriesIndex = 0;
const int targetDataPointIndex = 2;
const int negativeValue = -30;
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(firstSlideIndex);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 20.0f, 20.0f, 500.0f, 200.0f);
auto seriesCollection = chart->get_ChartData()->get_Series();
auto series = seriesCollection->idx_get(firstSeriesIndex);
auto automaticSeriesColor = series->GetAutomaticSeriesColor();
auto invertedSeriesColor = Color::get_Red();
series->get_Format()->get_Fill()->set_FillType(FillType::Solid);
series->get_Format()->get_Fill()->get_SolidFillColor()->set_Color(automaticSeriesColor);
series->get_InvertedSolidFillColor()->set_Color(invertedSeriesColor);
series->set_InvertIfNegative(false);
auto dataPoint = series->get_DataPoint(targetDataPointIndex);
auto boxedNegativeValue = ObjectExt::Box<int>(negativeValue);
dataPoint->get_YValue()->get_AsCell()->set_Value(boxedNegativeValue);
dataPoint->set_InvertIfNegative(true);
presentation->Save(u"data_point_invert_color_if_negative.pptx", SaveFormat::Pptx);
presentation->Dispose();
Borrar el valor de un punto de datos específico
Para dejar un punto vacío sin eliminar los demás puntos, establezca su celda de libro de trabajo subyacente a nullptr. En un gráfico de columnas, el valor trazado está disponible a través de IChartDataPoint::get_YValue. El punto de datos permanece en la misma posición de categoría, pero el gráfico trata su valor como vacío según la configuración de valores en blanco del gráfico.
El siguiente ejemplo borra solo el segundo punto de la primera serie:
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartDataPoint.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IDoubleChartValue.h>
#include <DOM/IChart.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <system/shared_ptr.h>
using Aspose::Slides::Charts::ChartType;
using Aspose::Slides::Export::SaveFormat;
using Aspose::Slides::Presentation;
const int firstSlideIndex = 0;
const int firstSeriesIndex = 0;
const int targetDataPointIndex = 1;
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(firstSlideIndex);
auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 20.0f, 20.0f, 500.0f, 200.0f);
auto seriesCollection = chart->get_ChartData()->get_Series();
auto series = seriesCollection->idx_get(firstSeriesIndex);
auto dataPoint = series->get_DataPoint(targetDataPointIndex);
dataPoint->get_YValue()->get_AsCell()->set_Value(nullptr);
presentation->Save(u"clear_data_point_value.pptx", SaveFormat::Pptx);
presentation->Dispose();
Los gráficos de dispersión utilizan celdas X e Y separadas, y los gráficos de burbujas también usan una celda de tamaño. Borre solo la celda que representa el valor que desea eliminar. No llame a IChartDataPointCollection::Clear cuando desee conservar los demás puntos, ya que ese método elimina todos los puntos de datos de la colección.
Controlar la visualización de celdas vacías
Las celdas ocultas que contienen valores son un caso distinto de las celdas vacías. Para incluir o excluir datos de filas y columnas ocultas de la hoja de cálculo, consulte Incluir datos de filas y columnas ocultas.
Una celda de libro de trabajo vacía representa datos ausentes; una celda que contiene 0 representa un valor numérico conocido. Llame a IChartDataCell::set_Value con nullptr para vaciar una celda. Un cero numérico sigue siendo cero independientemente de la configuración de celdas en blanco.
Utilice IChart::set_DisplayBlanksAs para elegir cómo muestra el gráfico las celdas vacías. Esta configuración se aplica a todo el gráfico. Cambia la forma en que se trazan los vacíos, sin rellenar la celda vacía del libro de trabajo con cero o un valor interpolado.
El siguiente ejemplo autónomo crea un gráfico de líneas con una serie, borra el valor del Día 3 y guarda el mismo gráfico con cada modo. No se necesita archivo de entrada. El IChartDataWorkbook utiliza la hoja 0, la columna 0 para las etiquetas de categoría y la columna 1 para los valores; la fila 0 contiene el nombre de la serie. Los datos finales son 10, 20, vacío, 30, 40.
#include <array>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/DisplayBlanksAsType.h>
#include <DOM/Chart/IChartCategoryCollection.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <DOM/Chart/IChartDataWorkbook.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/IChart.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <system/object_ext.h>
#include <system/shared_ptr.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;
using System::ObjectExt;
using System::String;
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto chart = slide->get_Shapes()->AddChart(ChartType::LineWithMarkers, 40.0f, 40.0f, 640.0f, 400.0f);
auto chartData = chart->get_ChartData();
auto workbook = chartData->get_ChartDataWorkbook();
chartData->get_Series()->Clear();
chartData->get_Categories()->Clear();
auto seriesName = ObjectExt::Box<String>(u"Measurements");
auto seriesNameCell = workbook->GetCell(0, 0, 1, seriesName);
auto series = chartData->get_Series()->Add(seriesNameCell, chart->get_Type());
auto values = std::array<int, 5>{10, 20, 25, 30, 40};
for (auto i = 0; i < values.size(); i++)
{
auto categoryName = String::Format(u"Day {0}", i + 1);
auto boxedCategoryName = ObjectExt::Box<String>(categoryName);
auto categoryCell = workbook->GetCell(0, i + 1, 0, boxedCategoryName);
chartData->get_Categories()->Add(categoryCell);
auto boxedValue = ObjectExt::Box<int>(values[i]);
auto valueCell = workbook->GetCell(0, i + 1, 1, boxedValue);
series->get_DataPoints()->AddDataPointForLineSeries(valueCell);
}
// Dejar el Día 3 realmente vacío, manteniendo su categoría y punto de datos.
workbook->GetCell(0, 3, 1)->set_Value(nullptr);
auto modes = std::array<DisplayBlanksAsType, 3>{DisplayBlanksAsType::Gap, DisplayBlanksAsType::Zero, DisplayBlanksAsType::Span};
for (auto mode : modes)
{
chart->set_DisplayBlanksAs(mode);
auto outputPath = String::Format(u"empty_cells_{0}.pptx", mode);
presentation->Save(outputPath, SaveFormat::Pptx);
}
presentation->Dispose();
Cada archivo de salida almacena el modo asignado antes de guardar: empty_cells_Gap.pptx, empty_cells_Zero.pptx y empty_cells_Span.pptx. Para guardar solo una versión, asigne el modo deseado y guarde la presentación una sola vez en lugar de iterar sobre los modos.
La comparación a continuación muestra los mismos datos en los tres archivos. El Día 3 está vacío en el libro de trabajo en todos los casos:

El efecto visible depende del tipo de gráfico. Un gráfico de líneas hace que los tres modos sean fáciles de comparar. Los gráficos de barras y columnas no tienen línea para conectar una categoría ausente, por lo que Span no puede producir el segmento de conexión mostrado arriba; una columna ausente y una columna de altura cero pueden parecer similares. Del mismo modo, un gráfico de dispersión solo con marcadores no tiene línea de conexión. No espere tres resultados distintos para cada tipo de gráfico; verifique la salida para el tipo que utilice.
Establecer el ancho de separación de la serie
El ancho de separación es el espacio entre grupos adyacentes de barras o columnas, expresado como un porcentaje del ancho de la barra o columna. Al igual que el solapamiento, pertenece al grupo de series padre más que a una sola serie. Llame a IChartSeriesGroup::set_GapWidth una vez para el grupo. Un valor mayor crea más espacio entre los grupos; un valor menor los vuelve más densos.
El siguiente ejemplo cambia el ancho de separación y guarda solo la presentación final:
#include <cstdint>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeriesGroup.h>
#include <DOM/IChart.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/Presentation.h>
#include <Export/SaveFormat.h>
#include <system/shared_ptr.h>
using Aspose::Slides::Charts::ChartType;
using Aspose::Slides::Export::SaveFormat;
using Aspose::Slides::Presentation;
const int firstSlideIndex = 0;
const int firstSeriesIndex = 0;
const uint16_t gapWidthPercent = 30;
auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(firstSlideIndex);
auto chart = slide->get_Shapes()->AddChart(ChartType::StackedColumn, 20.0f, 20.0f, 500.0f, 200.0f);
auto seriesCollection = chart->get_ChartData()->get_Series();
auto series = seriesCollection->idx_get(firstSeriesIndex);
series->get_ParentSeriesGroup()->set_GapWidth(gapWidthPercent);
presentation->Save(u"gap_width_30.pptx", SaveFormat::Pptx);
presentation->Dispose();

Preguntas frecuentes
¿Qué tipos de gráfico admiten series de datos?
Todos los tipos de gráfico representados por la enumeración ChartType utilizan datos de gráfico, pero sus series no comparten la misma estructura de valores ni la misma configuración. Por ejemplo, los gráficos de categorías usan categorías y valores, los gráficos de dispersión usan valores X e Y, y los gráficos de burbujas añaden tamaños de burbuja. Use el método de creación de puntos de datos que coincida con el tipo de serie. Opciones como solapamiento y ancho de separación se aplican solo a grupos de barras o columnas compatibles.
¿Qué es un grupo de series de gráfico?
Un IChartSeriesGroup contiene series compatibles que comparten configuraciones de trazado a nivel de grupo. Un gráfico combinado puede contener más de un grupo, por lo que cambiar el grupo alcanzado a través de una serie no cambia necesariamente todas las series del gráfico.
¿Un gráfico recién creado contiene datos predeterminados?
Sí. Por defecto, IShapeCollection::AddChart crea series de muestra, categorías y valores. Puede editar esas celdas o vaciar tanto las colecciones de series como de categorías antes de añadir un conjunto de datos completamente personalizado. También existe una sobrecarga que puede crear un gráfico sin datos predeterminados.
¿Cómo se conectan los objetos del gráfico a las celdas del libro de trabajo?
Los nombres de serie, etiquetas de categoría y valores de puntos de datos hacen referencia a celdas en un IChartDataWorkbook. Cambiar una celda referenciada actualiza el elemento del gráfico correspondiente. Cuando crea datos personalizados, mantenga alineadas las filas de categorías y las filas de valores de serie para que cada punto se trace bajo la categoría prevista.
¿Cómo borro un punto en lugar de toda la serie?
Establezca la celda de valor correspondiente a nullptr para mantener la posición de categoría del punto como un punto vacío. Llame a IChartDataPointCollection::Clear solo cuando pretenda eliminar todos los puntos de esa serie. Si también elimina categorías, actualice cada serie para que sus valores sigan alineados con la colección de categorías.
¿Cómo se muestran los puntos vacíos?
El resultado depende del tipo de gráfico y de IChart::get_DisplayBlanksAs. Los gráficos compatibles pueden mostrar los vacíos como huecos, como valores cero o conectando los puntos vecinos. Elija la configuración que coincida con el significado de los datos ausentes en su presentación. Consulte Controlar la visualización de celdas vacías para un ejemplo completo y una comparación visual.
¿Cómo se formatean los valores negativos?
Para series de barras, columnas y burbujas compatibles, llame a IChartSeries::set_InvertIfNegative y establezca el color a través de IChartSeries::get_InvertedSolidFillColor. Puede sobrescribir el comportamiento para un punto individual con IChartDataPoint::set_InvertIfNegative. Estos métodos afectan al formato, no a los valores numéricos almacenados.
¿Qué formato prevalece cuando tanto una serie como un punto están formateados?
El formato explícito del punto de datos prevalece para ese punto. Los demás puntos continúan usando el formato explícito de la serie o, cuando no se define el formato de la serie, el estilo y tema automático del gráfico. Las configuraciones de grupo, como solapamiento y ancho de separación, controlan el diseño y no son sobrescrituras de formato a nivel de punto.
¿Existe un límite en la cantidad de series que puede contener un gráfico?
Aspose.Slides no impone un límite fijo separado para la cantidad de series. En la práctica, las limitaciones del archivo de presentación, la memoria disponible, el tiempo de renderizado y la legibilidad del gráfico determinan un límite práctico.
¿Qué debo cambiar cuando las columnas están demasiado juntas o demasiado separadas?
Llame a IChartSeriesGroup::set_GapWidth en el grupo de series padre apropiado. Aumente el valor para ensanchar el espacio entre los grupos, o disminúyalo para acercar los grupos.