使用 C++ 在簡報中自訂圖表軸

概述

本文說明如何使用 Aspose.Slides for C++ 自訂圖表軸。它涵蓋計算軸值、切換圖表的列與欄、軸可見性、類別標籤與刻度間隔、日期類別與格式設定、標題旋轉、軸定位以及顯示單位。

取得圖表垂直軸的最大值

建立一個Presentation 並加入預設資料的區域圖。 在讀取計算軸值之前,呼叫ValidateChartLayout 以確保圖表版面已更新。

讀取get_ActualMaxValue和get_ActualMinValue以取得軸限值,並使用get_ActualMajorUnit與get_ActualMinorUnit取得刻度間隔。get_ActualMajorUnitScale和get_ActualMinorUnitScale提供時間單位尺度,與日期軸相關。範例將這些值儲存於本機變數,然後儲存圖表。

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

using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;

auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);

auto chart = slide->get_Shapes()->AddChart(ChartType::Area, 100, 100, 500, 350);
chart->ValidateChartLayout();

auto maxValue = chart->get_Axes()->get_VerticalAxis()->get_ActualMaxValue();
auto minValue = chart->get_Axes()->get_VerticalAxis()->get_ActualMinValue();

auto majorUnit = chart->get_Axes()->get_VerticalAxis()->get_ActualMajorUnit();
auto minorUnit = chart->get_Axes()->get_VerticalAxis()->get_ActualMinorUnit();

auto majorUnitScale = chart->get_Axes()->get_VerticalAxis()->get_ActualMajorUnitScale();
auto minorUnitScale = chart->get_Axes()->get_VerticalAxis()->get_ActualMinorUnitScale();

presentation->Save(u"AxisValues_out.pptx", SaveFormat::Pptx);

在軸之間交換資料

使用SwitchRowColumn交換圖表資料中系列與類別的角色。每個原本的類別會變成系列,而每個原本的系列會變成類別。這會改變資料的分組方式;不會交換水平與垂直軸。範例在切換列與欄之前,使用SetRange將預設資料綁定至 Sheet1!A1:D5(包含標頭列與類別欄)。它會儲存一個包含四個系列和三個類別的圖表。

#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 <DOM/Chart/IChartData.h>

using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;

auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);

auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 100, 100, 400, 300);

chart->get_ChartData()->SetRange(u"Sheet1!A1:D5");
chart->get_ChartData()->SwitchRowColumn();

presentation->Save(u"SwitchChartRowColumns_out.pptx", SaveFormat::Pptx);

停用折線圖的垂直軸

在垂直軸上使用set_IsVisible 並設為 false 以隱藏它。範例建立一個預設資料的折線圖,並在垂直軸隱藏的情況下儲存。

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

using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;

auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);

auto chart = slide->get_Shapes()->AddChart(ChartType::Line, 100, 100, 400, 300);
chart->get_Axes()->get_VerticalAxis()->set_IsVisible(false);

presentation->Save(u"HiddenVerticalAxis.pptx", SaveFormat::Pptx);

停用折線圖的水平軸

在水平軸上使用set_IsVisible 並設為 false 以隱藏它。範例建立一個預設資料的折線圖,並在水平軸隱藏的情況下儲存。

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

using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;

auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);

auto chart = slide->get_Shapes()->AddChart(ChartType::Line, 100, 100, 400, 300);
chart->get_Axes()->get_HorizontalAxis()->set_IsVisible(false);

presentation->Save(u"HiddenHorizontalAxis.pptx", SaveFormat::Pptx);

變更類別軸

使用set_CategoryAxisType選擇日期或文字類別軸。此範例需要 ExistingChart.pptx,其中第一張投影片的第一個圖形為圖表,且類別儲存格包含數值型 Excel 日期。它將水平軸變更為日期軸。呼叫set_IsAutomaticMajorUnit 並設為 false、set_MajorUnit 設為 1,以及set_MajorUnitScale 設為 month(月份),即可將主要刻度設為每月一次的間隔。

#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 <DOM/Chart/CategoryAxisType.h>
#include <DOM/Chart/TimeUnitType.h>
#include <system/object_ext.h>

using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;

auto presentation = System::MakeObject<Presentation>(u"ExistingChart.pptx");
auto slide = presentation->get_Slide(0);

auto chart = System::ExplicitCast<IChart>(slide->get_Shape(0));
chart->get_Axes()->get_HorizontalAxis()->set_CategoryAxisType(CategoryAxisType::Date);
chart->get_Axes()->get_HorizontalAxis()->set_IsAutomaticMajorUnit(false);
chart->get_Axes()->get_HorizontalAxis()->set_MajorUnit(1);
chart->get_Axes()->get_HorizontalAxis()->set_MajorUnitScale(TimeUnitType::Months);

presentation->Save(u"ChangeChartCategoryAxis_out.pptx", SaveFormat::Pptx);

控制類別軸標籤間隔

當圖表擁有許多類別時,可減少可見的軸標籤數量,而不必移除類別或資料點。使用set_IsAutomaticTickLabelSpacing 並設為 false,接著使用set_TickLabelSpacing 設定想要的類別間隔。對於以正常順序排列的文字類別,計數從第一個類別開始:

間隔 範例顯示的標籤
1 Category 1, Category 2, Category 3, … Category 24
2 Category 1, Category 3, Category 5, … Category 23
3 Category 1, Category 4, Category 7, … Category 22

間隔為 3 時,會每三個標籤顯示一次,兩個標籤會被隱藏。它不會移除相對應的欄位。自動間距會根據可用空間選擇間隔;未必會顯示所有標籤。刻度線有獨立的控制。使用set_IsAutomaticTickMarksSpacing 並設為 false,再使用set_TickMarksSpacing 來設定其間隔。例如,1 會在每個類別間隔保留刻度線,而標籤僅每三個類別顯示一次。使用set_MajorTickMark 設為可見樣式,以便觀察結果。將任一自動間距屬性重新設為 true,即可讓圖表再次自行選擇間隔。以下獨立範例建立 24 個類別和一個系列,然後在 CategoryAxisIntervals.pptx 中儲存三張投影片:自動間距、具有獨立刻度線的手動標籤間距、以及恢復自動間距。兩個副本保留原始圖表資料。無需輸入投影片。水平標籤文字使密度差異一目了然。

#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 <DOM/Chart/IChartData.h>
#include <DOM/Chart/CategoryAxisType.h>
#include <DOM/Chart/TickMarkType.h>
#include <DOM/Chart/IChartTextFormat.h>
#include <DOM/Chart/IChartTextBlockFormat.h>
#include <DOM/Chart/IChartPortionFormat.h>
#include <DOM/Chart/IChartDataWorkbook.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartCategoryCollection.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <system/object_ext.h>
#include <DOM/ISlideCollection.h>

using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;

auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);

auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 30, 40, 660, 320);

chart->set_HasLegend(false);
chart->get_ChartData()->get_Categories()->Clear();
chart->get_ChartData()->get_Series()->Clear();

auto workbook = chart->get_ChartData()->get_ChartDataWorkbook();
workbook->Clear(0);

auto series = chart->get_ChartData()->get_Series()->Add(ChartType::ClusteredColumn);
for (auto i = 0; i < 24; i++)
{
    auto categoryName = System::String::Format(u"Category {0}", i + 1);
    auto categoryCell = workbook->GetCell(0, i + 1, 0, System::ObjectExt::Box(categoryName));
    chart->get_ChartData()->get_Categories()->Add(categoryCell);
    auto valueCell = workbook->GetCell(0, i + 1, 1, System::ObjectExt::Box(10 + i % 6 * 5));
    series->get_DataPoints()->AddDataPointForBarSeries(valueCell);
}

auto axis = chart->get_Axes()->get_HorizontalAxis();
axis->set_CategoryAxisType(CategoryAxisType::Text);
axis->get_TextFormat()->get_TextBlockFormat()->set_RotationAngle(0);
axis->get_TextFormat()->get_PortionFormat()->set_FontHeight(12);
axis->set_MajorTickMark(TickMarkType::Outside);
axis->set_IsAutomaticTickLabelSpacing(true);
axis->set_IsAutomaticTickMarksSpacing(true);

// 投影片 2:顯示每三個標籤,但對每個類別保留刻度標記。
auto manualSlide = presentation->get_Slides()->AddClone(slide);
auto manualChart = System::ExplicitCast<IChart>(manualSlide->get_Shape(0));
auto manualAxis = manualChart->get_Axes()->get_HorizontalAxis();
manualAxis->set_IsAutomaticTickLabelSpacing(false);
manualAxis->set_TickLabelSpacing(3);
manualAxis->set_IsAutomaticTickMarksSpacing(false);
manualAxis->set_TickMarksSpacing(1);

// 投影片 3:讓圖表再次自行選擇兩個間隔。
auto restoredSlide = presentation->get_Slides()->AddClone(manualSlide);
auto restoredChart = System::ExplicitCast<IChart>(restoredSlide->get_Shape(0));
restoredChart->get_Axes()->get_HorizontalAxis()->set_IsAutomaticTickLabelSpacing(true);
restoredChart->get_Axes()->get_HorizontalAxis()->set_IsAutomaticTickMarksSpacing(true);

presentation->Save(u"CategoryAxisIntervals.pptx", SaveFormat::Pptx);

自動間距(投影片 1): 在此呈現中,每兩個類別標籤顯示一次,且會換成兩行。自動結果會因圖表大小、字型與渲染器而有所不同。

自動類別標籤間距(顯示全部 24 欄)

手動間距(投影片 2): 每三個標籤顯示於一行,同時刻度線仍保留在每個類別間隔。所有 24 欄(包括未顯示標籤的欄位)仍以相同數值可見。投影片 3 復原上述的自動外觀。

手動類別標籤間隔三(顯示全部 24 欄)

選擇正確的軸與間隔

對文字類別軸(例如柱狀圖、折線圖、區域圖或長條圖的類別軸)使用此類別計數間隔。在柱狀圖中,它是水平軸。於水平長條圖中,類別軸為垂直軸,故將此設定套用至get_VerticalAxis。刻度間距同樣適用於具有系列軸的圖表之系列軸。請勿使用類別標籤間隔來設定值軸的數值刻度。在值軸上,set_MajorUnit 指定數值差距:例如,主要單位為 10 時,若軸從零開始,則會在 0、10、20 等處產生刻度。類別標籤間隔 3 則是計算類別位置,與其資料值無關。散佈圖與氣泡圖使用值軸而非文字類別軸。對於日期軸,請使用基於時間的主要單位與尺度,如Change a Category Axis 中所述。

設定類別軸值的日期格式

此範例將預設圖表資料取代為四個年度值。日期以 OLE Automation 序號儲存在第一個工作表(索引 0)中。使用set_CategoryAxisType選取日期軸,並以set_IsNumberFormatLinkedToSource 停用來源連結的格式,接著以set_NumberFormat 指定 yyyy,使類別標籤能獨立於儲存格格式顯示四位數年份。

#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 <DOM/Chart/IChartData.h>
#include <DOM/Chart/CategoryAxisType.h>
#include <DOM/Chart/IChartDataWorkbook.h>
#include <DOM/Chart/IChartDataCell.h>
#include <DOM/Chart/IChartCategoryCollection.h>
#include <DOM/Chart/IChartSeriesCollection.h>
#include <DOM/Chart/IChartSeries.h>
#include <DOM/Chart/IChartDataPointCollection.h>
#include <system/object_ext.h>
#include <system/date_time.h>

using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;

auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);

auto chart = slide->get_Shapes()->AddChart(ChartType::Line, 50, 50, 450, 300);

chart->get_ChartData()->get_Categories()->Clear();
chart->get_ChartData()->get_Series()->Clear();

auto workbook = chart->get_ChartData()->get_ChartDataWorkbook();
workbook->Clear(0);

auto series = chart->get_ChartData()->get_Series()->Add(ChartType::Line);
for (auto i = 0; i < 4; i++)
{
    auto date = System::DateTime(2015 + i, 1, 1);
    auto categoryCell = workbook->GetCell(0, i + 1, 0, System::ObjectExt::Box(date.ToOADate()));
    chart->get_ChartData()->get_Categories()->Add(categoryCell);

    auto valueCell = workbook->GetCell(0, i + 1, 1, System::ObjectExt::Box(i + 1));
    series->get_DataPoints()->AddDataPointForLineSeries(valueCell);
}

chart->get_Axes()->get_HorizontalAxis()->set_CategoryAxisType(CategoryAxisType::Date);
chart->get_Axes()->get_HorizontalAxis()->set_IsNumberFormatLinkedToSource(false);
chart->get_Axes()->get_HorizontalAxis()->set_NumberFormat(u"yyyy");

presentation->Save(u"DateAxisFormat.pptx", SaveFormat::Pptx);

設定圖表軸標題的旋轉角度

使用set_HasTitle 啟用垂直軸標題,提供標題文字,並以set_RotationAngle 旋轉標題。角度以度為單位;此範例將柱狀圖的值軸標題旋轉 90 度後儲存。

#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 <DOM/Chart/IChartTextFormat.h>
#include <DOM/Chart/IChartTextBlockFormat.h>
#include <DOM/Chart/IChartTitle.h>

using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;

auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);

auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 50, 50, 450, 300);
chart->get_Axes()->get_VerticalAxis()->set_HasTitle(true);
chart->get_Axes()->get_VerticalAxis()->get_Title()->AddTextFrameForOverriding(u"Value");
chart->get_Axes()->get_VerticalAxis()->get_Title()->get_TextFormat()->get_TextBlockFormat()->set_RotationAngle(90);

presentation->Save(u"RotatedAxisTitle.pptx", SaveFormat::Pptx);

設定類別或值軸的位置

使用set_AxisBetweenCategories 控制值軸在類別軸之間的交叉位置,是在類別之間還是於類別刻度標記處。此屬性適用於類別軸。範例在柱狀圖的水平類別軸上將其設定為 true,並儲存結果。

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

using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;

auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);

auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 50, 50, 450, 300);
chart->get_Axes()->get_HorizontalAxis()->set_AxisBetweenCategories(true);

presentation->Save(u"AxisBetweenCategories.pptx", SaveFormat::Pptx);

設定圖表值軸的顯示單位

使用set_DisplayUnit 於值軸上縮放標籤而不變更底層資料。將DisplayUnitType 設為 Millions 時,60,000,000 會顯示為 60。此範例建立柱狀圖,並將百萬顯示單位套用至其垂直軸。

#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 <DOM/Chart/DisplayUnitType.h>

using namespace Aspose::Slides;
using namespace Aspose::Slides::Charts;
using namespace Aspose::Slides::Export;

auto presentation = System::MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);

auto chart = slide->get_Shapes()->AddChart(ChartType::ClusteredColumn, 50, 50, 450, 300);
chart->get_Axes()->get_VerticalAxis()->set_DisplayUnit(DisplayUnitType::Millions);

presentation->Save(u"Result.pptx", SaveFormat::Pptx);

常見問題

如何設定軸交叉的值(軸交叉點)?

使用set_CrossType選取交叉行為。若要指定數值型的交叉點,請使用set_CrossAt。這些設定可讓您將軸交叉移至適當的基線。

如何相對於軸定位刻度標籤?

使用set_TickLabelPosition 並從TickLabelPositionType 中選擇 Low、High、NextTo 或 None。若要控制刻度線本身,請使用set_MajorTickMark 或set_MinorTickMark;這與標籤位置是分開的設定。