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

概覽

圖表可以將繪製的值儲存在工作簿儲存格中,或直接作為數值文字常量。
一個IChartSeries 代表一組相關的值,而每個IChartDataPoint 代表該系列中的一個點。
IChartCategory 物件提供系列共用的標籤或分組值。
在使用預設資料建立的圖表中,系列名稱、類別以及點的值皆使用來自圖表工作簿的IChartDataCell 物件。

對於一般的類別圖表,預設工作簿使用第 0 列儲存系列名稱,第 0 欄儲存類別名稱,剩餘的儲存格則存放系列值。
傳遞給IChartDataWorkbook::GetCell 的工作表、列與欄索引是從 0 開始計算的。
此布局在您使用預設資料建立圖表時很有用,但請勿假設每個已存在的圖表都使用此布局。
對於已載入的簡報,在變更工作簿值之前,請先檢查系列、類別與資料點所參照的儲存格。

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

當未設定明確的點或系列填色時,圖表樣式與主題會決定自動外觀。
若同時存在系列與點的格式設定,則以點的格式設定為優先。

chart-series-powerpoint

使用數值文字常量設定系列值

當系列值來自應用程式資料或計算且不需要工作表儲存格參照時,請使用數值文字常量。
在透過set_AsLiteralDouble 為每個點的get_Value 指派回傳值之前,先呼叫set_DataSourceTypeForValues 並傳入DataSourceType::DoubleLiterals。

此集合設定會控制該系列中所有點值的來源類型。
每個點的IBaseChartValue::get_DataSourceType 會回報選取的類型;可透過集合設定變更它。
使用 Worksheet 時,請使用get_AsCell 取得參照的儲存格。
使用 DoubleLiterals 時,請使用get_AsLiteralDouble 或 set_AsLiteralDouble 直接讀寫數字。

下列範例建立一個具有預設系列與類別的直條圖,然後將 10、20 等計算值指派給其第一系列的現有點。它會儲存簡報、重新開啟,並列印儲存的值。

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

點值的來源類型與IChartData::get_DataSourceType 是分開的,後者用來辨識圖表的內部或外部工作簿設定。
僅使用數值文字常量本身不會移除嵌入的工作簿。
在此範例中,工作簿仍可用於類別標籤、系列名稱以及其他系列。
請參閱Chart Workbook 了解工作簿管理。

對於散佈圖和氣泡圖,呼叫set_DataSourceTypeForXValues 與set_DataSourceTypeForYValues 以選擇get_XValue 與get_YValue 的來源。氣泡圖亦使用set_DataSourceTypeForBubbleSizes 取得get_BubbleSize 的來源。於指派數字之前,將每個適用的來源設為 DoubleLiterals,再透過該值的set_AsLiteralDouble 方法寫入。

設定圖表系列重疊

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

常見問題

哪些圖表類型支援資料系列?
所有由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。將值調高會擴大叢之間的間距,調低則會使叢更靠近。