在 C++ 簡報中管理圖表資料系列

概觀

圖表將其繪製的資料儲存在圖表資料工作簿中。 IChartSeries 代表一組相關的值,系列中的每個 IChartDataPoint 參考一或多個工作簿儲存格。IChartCategory 物件提供系列共用的標籤或分組值。因此系列名稱、類別與資料點值會連結到 IChartDataCell 物件,而不是僅以顯示文字儲存。

對於一般的類別圖表,預設工作簿使用第 0 列儲存系列名稱,第 0 欄儲存類別名稱,其餘儲存格儲存系列值。傳遞給 IChartDataWorkbook::GetCell 的工作表、列與欄索引皆為零基。此佈局在建立帶有預設資料的圖表時很有用,但請不要假設每個現有圖表都採用此方式。載入簡報後,請在變更工作簿值之前先檢查系列、類別與資料點所參考的儲存格。

圖表設定有三種不同的範圍:

當未明確設定資料點或系列填色時,圖表樣式與佈景主題會決定自動外觀。當系列與資料點同時具有格式設定時,資料點的格式會優先套用於該點。

chart-series-powerpoint

設定圖表系列重疊

IChartSeries::get_Overlap 會回報 2D 圖表中長條或柱狀的重疊程度,範圍為 -100 至 100%。此屬性為唯讀,僅投射父系列群組的設定。呼叫 IChartSeriesGroup::set_Overlap 以更新該群組中所有相容系列。此選項適用於顯示分組長條或柱狀的圖表類型;不會影響組合圖表中不相關的系列群組。

以下範例為包含第一個系列的群組設定重疊:

#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);

// 新圖表包含範例系列、類別和數值。
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();

結果:

The series overlap

變更系列填色

使用 IChartSeries::get_Format 來設定整個系列的預設填色。如果資料點已明確設定填色,其 IChartDataPoint::get_Format 會覆寫該點的系列填色。

以下範例將第一個系列設定為實心藍色填色:

#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();

結果:

The color of the series

變更系列名稱

系列名稱儲存在圖表資料工作簿中,通常顯示於圖例。預設用於叢集柱狀圖的工作簿中,儲存格 B1(第 0 列第 1 欄)包含第一個系列的名稱。以下範例中的具名常數說明此結構:

#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();

您也可以直接更新由 IChartSeries::get_Name 參考的儲存格。此方式避免假設現有圖表的特定列與欄:

#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();

結果:

The series name

建立由多個儲存格組成的系列名稱

當產品名稱與報告期間分別儲存在不同工作簿儲存格時,複合系列名稱非常實用。例如,您可以將 B1 中的 Product A 與 C1 中的 2026 合併為單一系列名稱,同時保留兩部分與來源儲存格的連結。

使用 IChartDataWorkbook::GetCellCollection 取得名稱範圍,然後將該集合傳遞給 IChartSeriesCollection::Add。skipHiddenCells 參數決定是否包括隱藏儲存格:true 為排除,false 為包含。此範例使用 false 以包含名稱範圍內的所有儲存格。

以下範例建立一個僅有一個系列和兩個資料點的簡報。儲存格 B1:C1 提供系列名稱;A2:A3 提供類別標籤;B2:B3 提供數值。

#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);

// 這兩個儲存格提供系列名稱。
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);

// 分別的儲存格提供類別與數值資料點。
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();

產生的系列名稱為 Product A 2026(兩個儲存格值之間有空格)。圖例會將此名稱視為單一條目。以下圖片說明結果:

Column chart with North and South values and the composite series name Product A 2026 in the legend

取得自動系列填色

IChartSeries::GetAutomaticSeriesColor 會依系列索引和圖表樣式計算顏色。這是未明確定義系列填色時使用的顏色。呼叫此方法只會讀取計算出的顏色,不會指派新的填色。

以下範例列印每個預設系列的自動顏色:

#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

具體顏色取決於圖表樣式與佈景主題。

為圖表系列設定反轉填色

對於長條、柱狀與氣泡系列,您可以使用 IChartSeries::set_InvertIfNegative 於負值時顯示不同的填色。將系列的常規填色設定為實心,啟用反轉,並透過 IChartSeries::get_InvertedSolidFillColor 指定負值顏色。負數在工作簿中保持不變,僅改變其顯示顏色。

以下範例以單一系列取代預設圖表資料。工作表第 0 列儲存系列名稱,第 0 欄儲存類別名稱,第 1 欄儲存值:

#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();

結果:

The inverted solid fill color

您也可以對單一資料點啟用反轉,使用 IChartDataPoint::set_InvertIfNegative。下例在系列上停用反轉,僅對選取的資料點啟用,且為該點指派負值以顯示效果:

#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();

清除特定資料點的值

若要讓某個資料點變為空而不移除其他點,將其對應的工作簿儲存格設定為 nullptr。對於柱狀圖,可透過 IChartDataPoint::get_YValue 取得繪製值。資料點仍保留在相同的類別位置,但圖表會依據空值設定將其視為空白。

以下範例僅清除第一個系列的第二個資料點:

#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();

散佈圖使用分別的 X 與 Y 儲存格,氣泡圖亦使用大小儲存格。僅清除您想移除的值所在的儲存格。不要在想保留其他資料點時呼叫 IChartDataPointCollection::Clear,因為該方法會移除整個集合的所有資料點。

控制空儲存格的顯示方式

隱藏且含有值的儲存格屬於與空儲存格不同的情況。若要包含或排除來自隱藏工作表列與欄的資料,請參閱 Include Data from Hidden Rows and Columns。

空的工作簿儲存格代表缺少資料;儲存格內的 0 代表已知的數值。呼叫 IChartDataCell::set_Value 並傳入 nullptr 可將儲存格設為空。數值零仍會保持為零,無論空儲存格設定為何。

使用 IChart::set_DisplayBlanksAs 來選擇圖表如何顯示空儲存格。此設定套用於整個圖表,會改變空白的繪製方式,但不會將空的工作簿儲存格填入零或插值值。

以下自包含範例建立一個單系列折線圖,清除第 3 天的值,並以三種模式分別儲存同一圖表。此範例不需要輸入檔案。IChartDataWorkbook 使用工作表 0,第 0 欄作為類別標籤,第 1 欄作為值;第 0 列保存系列名稱。最終資料為 10, 20, empty, 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);
}

// 將第 3 天真正留空,同時保留其類別與資料點。
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();

每個輸出檔案在儲存前皆已設定相應的模式:empty_cells_Gap.pptx、empty_cells_Zero.pptx、empty_cells_Span.pptx。若只需一個版本,只需設定所需模式並儲存一次即可,無需逐一迭代。

下圖比較三個檔案的相同資料。第 3 天在工作簿中皆為空:

Line charts with identical data: Gap breaks the line at Day 3, Zero drops the line to zero, and Span connects Day 2 to Day 4.

可見效果取決於圖表類型。折線圖最能直觀比較三種模式。長條與柱狀圖沒有連線可跨過缺少的類別,因此 Span 無法產生如上所示的連接段落;缺少的柱狀與零高度柱狀亦可能看起來相似。同樣地,僅有標記的散佈圖也沒有連線。不要期望每種圖表類型都有三種明顯不同的結果;請依您使用的圖表類型檢查輸出。

設定系列間距寬度

間距寬度是相鄰長條或柱狀叢集之間的空間,表示為長條或柱狀寬度的百分比。與重疊類似,此設定屬於父系列群組,而非單一系列。請對群組呼叫一次 IChartSeriesGroup::set_GapWidth。較大的數值會在叢集之間產生更多空間,較小的數值則使叢集更緊密。

以下範例變更間距寬度,並僅儲存最終簡報:

#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();

結果:

The gap width

FAQ

哪些圖表類型支援資料系列?

所有由 ChartType 列舉的圖表類型皆使用圖表資料,但其系列的值結構與設定並不完全相同。例如,類別圖表使用類別與值,散佈圖使用 X 與 Y 值,氣泡圖則額外加入氣泡大小。請使用與系列類型相符的資料點建立方法。重疊與間距寬度等選項僅適用於相容的長條或柱狀群組。

什麼是圖表系列群組?

IChartSeriesGroup 包含共享群組層級繪製設定的相容系列。組合圖表可包含多個群組,因此透過某個系列取得的群組設定不一定會影響圖表中所有系列。

新建立的圖表是否包含預設資料?

是的。預設情況下,IShapeCollection::AddChart 會建立示範系列、類別與值。您可以編輯這些儲存格,或在加入完全自訂的資料集之前先清除系列與類別集合。亦有載入項可建立不含預設資料的圖表。

圖表物件如何與工作簿儲存格連結?

系列名稱、類別標籤與資料點值皆參考 IChartDataWorkbook 中的儲存格。變更被參考的儲存格即會更新對應的圖表元素。建構自訂資料時,請確保類別列與系列值列對齊,使每個資料點都繪製在正確的類別下。

如何只清除單一資料點而不是整個系列?

將相關的值儲存格設定為 nullptr,即可保留該點的類別位置且將其視為空點。僅在想要移除該系列所有資料點時才呼叫 IChartDataPointCollection::Clear。若同時移除類別,請同步更新所有系列,使其值仍與類別集合對齊。

空點如何顯示?

顯示結果取決於圖表類型與 IChart::get_DisplayBlanksAs。支援的圖表可將空白顯示為間隙、零值或連接相鄰點。請選擇最能表達缺失資料意義的設定。完整範例與視覺比較請參閱 Control the Display of Empty Cells。

負值的格式如何設定?

對於支援的長條、柱狀與氣泡系列,呼叫 IChartSeries::set_InvertIfNegative 並透過 IChartSeries::get_InvertedSolidFillColor 設定顏色。您也可以使用 IChartDataPoint::set_InvertIfNegative 為個別資料點覆寫此行為。這些方法僅影響格式,不會改變儲存的數值。

當系列與資料點同時設定格式時,哪個會優先?

明確的資料點格式會優先套用於該點。其他資料點則繼續使用明確的系列格式,若系列格式未定義則使用自動的圖表樣式與佈景主題。群組設定(例如重疊與間距寬度)屬於版面配置,並非資料點層級的格式覆寫。

圖表可容納的系列數量有上限嗎?

Aspose.Slides 本身未設定固定的系列數量上限。實務上,簡報檔案的限制、可用記憶體、渲染時間以及圖表可讀性會共同決定實際可接受的上限。

如果柱狀圖的柱子太靠近或太分散,我該怎麼調整?

對相應的父系列群組呼叫 IChartSeriesGroup::set_GapWidth。增大數值會擴大叢集之間的間距,減小則使叢集更緊密。