使用 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_IsPlotOrderReversed 可以反转类别坐标轴或数值坐标轴。例如,水平条形图可以按照工作表中相同的顺序从上到下显示项目阶段:计划、开发、测试。反转坐标轴会改变绘制方向,但不会对工作簿数据进行排序或重新排列。相比之下, SwitchRowColumn 交换的是系列与类别的角色。
下面的示例创建了一个包含三个阶段和一个系列的水平条形图。它保存了三张幻灯片:正常顺序、类别反转、数值反转。每个副本使用相同的数据集,并且每张副本仅反转一个坐标轴。
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IAxesManager.h>
#include <DOM/Chart/IAxis.h>
#include <DOM/Chart/CrossesType.h>
#include <DOM/Chart/IChartData.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 <Export/SaveFormat.h>
#include <system/object_ext.h>
#include <array>
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::ClusteredBar, 50, 40, 620, 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::ClusteredBar);
auto stages = std::array<System::String, 3>{u"Planning", u"Development", u"Testing"};
auto values = std::array<int, 3>{10, 30, 20};
for (auto i = 0; i < stages.size(); i++)
{
auto categoryCell = workbook->GetCell(0, i + 1, 0, System::ObjectExt::Box(stages[i]));
chart->get_ChartData()->get_Categories()->Add(categoryCell);
auto valueCell = workbook->GetCell(0, i + 1, 1, System::ObjectExt::Box(values[i]));
series->get_DataPoints()->AddDataPointForBarSeries(valueCell);
}
// 幻灯片 2:在顶部显示第一个类别。
auto categorySlide = presentation->get_Slides()->AddClone(slide);
auto categoryChart = System::ExplicitCast<IChart>(categorySlide->get_Shape(0));
categoryChart->get_Axes()->get_VerticalAxis()->set_IsPlotOrderReversed(true);
// 保持水平数值坐标轴在底部。
categoryChart->get_Axes()->get_VerticalAxis()->set_CrossType(CrossesType::Maximum);
// 幻灯片 3:仅反转水平数值刻度。
auto valueSlide = presentation->get_Slides()->AddClone(slide);
auto valueChart = System::ExplicitCast<IChart>(valueSlide->get_Shape(0));
valueChart->get_Axes()->get_HorizontalAxis()->set_IsPlotOrderReversed(true);
presentation->Save(u"ReversedAxes.pptx", SaveFormat::Pptx);
反转坐标轴还可以将垂直坐标轴移动到图表另一侧。set_CrossType 控制另一坐标轴在被配置坐标轴上的交叉位置。在第 2 张幻灯片中,将其设置为 Maximum,使反转后的类别坐标轴保持水平数值坐标轴在底部。若需指定具体交叉点,请使用 set_CrossAt。在改变方向时请检查交叉设置,尤其是图表已经设置了自定义交叉点的情况。调用 set_IsPlotOrderReversed 并传入 false 可以恢复正常绘制方向;交叉设置是独立的。
| 正常顺序(幻灯片 1) | 类别反转(幻灯片 2) | 数值反转(幻灯片 3) |
|---|---|---|
![]() |
![]() |
![]() |
| 类别从底部向顶部递增;数值从左向右递增。 | 计划、开发、测试从上到下递增。数值及工作表行顺序保持不变。 | 类别保持正常顺序;数值从右向左递增。类别坐标轴在右侧零点交叉。 |
为折线图禁用垂直坐标轴
在垂直坐标轴上调用 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 设为月份,便可将主要刻度设置为一个月的间隔。
#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): 在此渲染中,每隔一个类别标签会显示一次,并换行成两行。自动结果会随图表大小、字体和渲染器而变化。

手动间隔(幻灯片 2): 每隔三个标签显示一行,而刻度线仍然在每个类别间隔处。所有 24 列(包括未显示标签的列)均保持可见且数值相同。第 3 张幻灯片恢复了上图的自动外观。

选择正确的坐标轴和间隔
对文本类别坐标轴(如柱形图、折线图、面积图或条形图的类别坐标轴)使用此类别计数间隔。对于柱形图,它是水平坐标轴;对于水平条形图,类别坐标轴是垂直的,因此请将这些设置应用到 get_VerticalAxis。在具有系列坐标轴的图表中,刻度线间隔同样适用于该坐标轴。
请勿使用类别标签间隔来设置数值坐标轴的数值刻度。在数值坐标轴上, set_MajorUnit 指定数值差异,例如 10 表示在轴起点为 0 时产生 0、10、20… 的刻度。类别标签间隔 3 仅计数类别位置,与数据值无关。散点图和气泡图使用数值坐标轴而非文本类别坐标轴。对于日期坐标轴,请参阅 更改类别坐标轴 中的基于时间的主要单位和比例设置。
设置类别坐标轴值的日期格式
示例用四个年度数值替换默认图表数据。日期以 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);
配置对数数值坐标轴
当正数值跨越多个数量级时,对数数值坐标轴非常有用。例如,某服务在五个时间段内的请求数分别为 10、100、1,000、10,000、100,000。在线性刻度下,小数值会聚集在接近零的位置。对数刻度使它们的相对增长更易比较:相等的距离代表相等的比例而非相等的差值。
在数值坐标轴上调用 set_IsLogarithmic 并传入 true,再使用 set_LogBase 选择基数。此操作仅改变现有数值的显示方式,不会更改数据或添加对数趋势线。趋势线是对数据进行拟合的独立功能。
选择数值坐标轴和基数
对于折线图或柱形图,数值坐标轴为 get_VerticalAxis。对于水平条形图,则为 get_HorizontalAxis。散点图和气泡图有两个数值坐标轴,可为 X 值选择水平坐标轴,为 Y 值选择垂直坐标轴,或两者皆设。请勿在类别坐标轴上使用对数刻度。
默认的对数基数是 10。对于 PPTX 图表,基数范围为 2 到 1000(含),也支持小数基数如 2.5。使用基数 10 时,10、100、1,000、10,000 等幂次等间距分布。
比较线性和对数刻度
下面的独立示例在第 1 张幻灯片上创建一个折线图并绘制五个请求计数,然后克隆该幻灯片并在第 2 张上启用基数为 10 的对数数值坐标轴。两张幻灯片保留相同的数据。
#include <DOM/Presentation.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/IShapeCollection.h>
#include <DOM/IChart.h>
#include <DOM/Chart/ChartType.h>
#include <DOM/Chart/IAxesManager.h>
#include <DOM/Chart/IAxis.h>
#include <DOM/Chart/IChartData.h>
#include <DOM/Chart/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 <Export/SaveFormat.h>
#include <system/object_ext.h>
#include <array>
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, 30, 40, 660, 200);
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::Line);
auto values = std::array<double, 5>{10, 100, 1000, 10000, 100000};
for (auto i = 0; i < values.size(); i++)
{
auto categoryName = System::String::Format(u"Period {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(values[i]));
series->get_DataPoints()->AddDataPointForLineSeries(valueCell);
}
// 保持第一张幻灯片线性,仅更改副本的数值轴刻度。
auto logarithmicSlide = presentation->get_Slides()->AddClone(slide);
auto logarithmicChart = System::ExplicitCast<IChart>(logarithmicSlide->get_Shape(0));
auto valueAxis = logarithmicChart->get_Axes()->get_VerticalAxis();
valueAxis->set_IsLogarithmic(true);
valueAxis->set_LogBase(10);
presentation->Save(u"LogarithmicAxis.pptx", SaveFormat::Pptx);
线性刻度(幻灯片 1): 相等的垂直距离代表请求计数的相等差值。最大值主导图表,导致较小的值难以辨认。

对数刻度(幻灯片 2): 相等的垂直距离代表相等的比例。每个时期的请求数是前一个时期的十倍,因此在基数为 10 的刻度上点形成一条直线。坐标轴标签仍显示原始请求计数。

处理零值和负值
对数刻度仅能显示严格正数。在启用之前请检查数据。如果零值或负值具有实际意义,请保持线性刻度或单独展示这些值。如果在分析中可以排除这些值,请说明原因。不要悄悄将它们替换为小的正数,因为这会改变数据含义。对数坐标轴的手动最小值或最大值也必须为正数。
常见问题
如何设置坐标轴交叉点的数值(坐标轴交叉)?
使用 set_CrossType 选择交叉行为。若需指定数值交叉点,请使用 set_CrossAt。这些设置可以将坐标轴交叉点移动到合适的基线位置。
如何相对于坐标轴定位刻度标签?
使用 set_TickLabelPosition 并传入 TickLabelPositionType 的值:Low、High、NextTo 或 None。若要控制刻度线本身,请使用 set_MajorTickMark 或 set_MinorTickMark;这些与标签定位是分离的。


