使用 PHP 在演示文稿中自定义图表坐标轴

概述

本文说明如何使用 Aspose.Slides for PHP via Java 自定义图表坐标轴。内容包括计算坐标轴值、交换图表行列、坐标轴可见性、类别标签和刻度间隔、日期类别及其格式、标题旋转、坐标轴位置以及显示单位。

获取图表垂直轴的最大值

创建一个 Presentation 并添加一个使用默认数据的面积图。调用 validateChartLayout 以确保读取计算后的坐标轴值时图表布局是最新的。

读取 getActualMaxValue 与 getActualMinValue 以获取坐标轴上下限,读取 getActualMajorUnit 与 getActualMinorUnit 以获取刻度间隔。getActualMajorUnitScale 和 getActualMinorUnitScale 提供时间单位比例,适用于日期坐标轴。示例将这些值存入局部变量并保存图表。

use aspose\slides\ChartType;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;

$presentation = new Presentation();
try {
    $slide = $presentation->getSlides()->get_Item(0);

    $chart = $slide->getShapes()->addChart(ChartType::Area, 100, 100, 500, 350);
    $chart->validateChartLayout();

    $maxValue = $chart->getAxes()->getVerticalAxis()->getActualMaxValue();
    $minValue = $chart->getAxes()->getVerticalAxis()->getActualMinValue();

    $majorUnit = $chart->getAxes()->getVerticalAxis()->getActualMajorUnit();
    $minorUnit = $chart->getAxes()->getVerticalAxis()->getActualMinorUnit();

    $majorUnitScale = $chart->getAxes()->getVerticalAxis()->getActualMajorUnitScale();
    $minorUnitScale = $chart->getAxes()->getVerticalAxis()->getActualMinorUnitScale();

    $presentation->save("AxisValues_out.pptx", SaveFormat::Pptx);
} finally {
    $presentation->dispose();
}

交换坐标轴之间的数据

使用 switchRowColumn 交换系列和类别在图表数据中的角色。每个原来的类别变为系列,每个原来的系列变为类别。这会改变数据的分组方式,但不会交换水平和垂直坐标轴。示例使用 setRange 将默认数据绑定到 Sheet1!A1:D5(包括标题行和类别列),随后交换行列。它会生成一个包含四个系列和三个类别的图表。

use aspose\slides\ChartType;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;

$presentation = new Presentation();
try {
    $slide = $presentation->getSlides()->get_Item(0);

    $chart = $slide->getShapes()->addChart(ChartType::ClusteredColumn, 100, 100, 400, 300);
    $chart->getChartData()->setRange("Sheet1!A1:D5");
    $chart->getChartData()->switchRowColumn();

    $presentation->save("SwitchChartRowColumns_out.pptx", SaveFormat::Pptx);
} finally {
    $presentation->dispose();
}

为折线图禁用垂直坐标轴

在垂直坐标轴上调用 setVisible 并传入 false 以隐藏坐标轴。示例创建一个使用默认数据的折线图,并在隐藏垂直坐标轴后保存。

use aspose\slides\ChartType;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;

$presentation = new Presentation();
try {
    $slide = $presentation->getSlides()->get_Item(0);

    $chart = $slide->getShapes()->addChart(ChartType::Line, 100, 100, 400, 300);
    $chart->getAxes()->getVerticalAxis()->setVisible(false);

    $presentation->save("HiddenVerticalAxis.pptx", SaveFormat::Pptx);
} finally {
    $presentation->dispose();
}

为折线图禁用水平坐标轴

在水平坐标轴上调用 setVisible 并传入 false 以隐藏坐标轴。示例创建一个使用默认数据的折线图,并在隐藏水平坐标轴后保存。

use aspose\slides\ChartType;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;

$presentation = new Presentation();
try {
    $slide = $presentation->getSlides()->get_Item(0);

    $chart = $slide->getShapes()->addChart(ChartType::Line, 100, 100, 400, 300);
    $chart->getAxes()->getHorizontalAxis()->setVisible(false);

    $presentation->save("HiddenHorizontalAxis.pptx", SaveFormat::Pptx);
} finally {
    $presentation->dispose();
}

更改类别坐标轴

使用 setCategoryAxisType 选择日期或文本类别坐标轴。此示例需要 ExistingChart.pptx,其中第一张幻灯片的第一形状是图表,类别单元格包含 Excel 数字日期值。它将水平坐标轴改为日期坐标轴。将 setAutomaticMajorUnit 设为 false,setMajorUnit 设为 1,并使用 setMajorUnitScale 并传入 TimeUnitType::Months,可使主刻度以一个月为间隔。

use aspose\slides\CategoryAxisType;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
use aspose\slides\TimeUnitType;

$presentation = new Presentation("ExistingChart.pptx");
try {
    $slide = $presentation->getSlides()->get_Item(0);

    $chart = $slide->getShapes()->get_Item(0);
    $chart->getAxes()->getHorizontalAxis()->setCategoryAxisType(CategoryAxisType::Date);
    $chart->getAxes()->getHorizontalAxis()->setAutomaticMajorUnit(false);
    $chart->getAxes()->getHorizontalAxis()->setMajorUnit(1);
    $chart->getAxes()->getHorizontalAxis()->setMajorUnitScale(TimeUnitType::Months);

    $presentation->save("ChangeChartCategoryAxis_out.pptx", SaveFormat::Pptx);
} finally {
    $presentation->dispose();
}

控制类别坐标轴标签间隔

当图表拥有大量类别时,可在不删除类别或数据点的前提下降低可见坐标轴标签的数量。调用 setAutomaticTickLabelSpacing 并设为 false,随后将期望的类别间隔传给 setTickLabelSpacing。对于保持正常顺序的文本类别,计数从第一个类别开始:

Interval 示例中显示的标签
1 类别 1, 类别 2, 类别 3, … 类别 24
2 类别 1, 类别 3, 类别 5, … 类别 23
3 类别 1, 类别 4, 类别 7, … 类别 22

间隔为 3 时,每三个标签显示一次,中间的两个标签被隐藏。它不会删除相应的列。自动间隔会根据可用空间选择间隔;并不一定会显示每个标签。

刻度线有独立的控制方式。调用 setAutomaticTickMarksSpacing 并设为 false,再使用 setTickMarksSpacing 设置其间隔。例如,1 表示在每个类别间隔处保留刻度线,而标签仅每三个类别显示一次。使用 setMajorTickMark 设置可见样式,以便看到效果。再次将任一自动间隔设置器设为 true,即可让图表重新选择该间隔。

下面的独立示例创建 24 个类别和一个系列,然后在 CategoryAxisIntervals.pptx 中保存三张幻灯片:自动间隔、手动标签间隔(刻度线独立)以及恢复自动间隔。两个副本保留原始图表数据,无需输入演示文稿。水平标签文本使得密度差异易于观察。

use aspose\slides\CategoryAxisType;
use aspose\slides\ChartType;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
use aspose\slides\TickMarkType;

$presentation = new Presentation();
try {
    $slide = $presentation->getSlides()->get_Item(0);

    $chart = $slide->getShapes()->addChart(ChartType::ClusteredColumn, 30, 40, 660, 320);

    $chart->setLegend(false);
    $chart->getChartData()->getCategories()->clear();
    $chart->getChartData()->getSeries()->clear();

    $workbook = $chart->getChartData()->getChartDataWorkbook();
    $workbook->clear(0);

    $series = $chart->getChartData()->getSeries()->add(ChartType::ClusteredColumn);
    for ($i = 0; $i < 24; $i++) {
        $categoryCell = $workbook->getCell(0, $i + 1, 0, "Category " . ($i + 1));
        $chart->getChartData()->getCategories()->add($categoryCell);
        $valueCell = $workbook->getCell(0, $i + 1, 1, 10 + $i % 6 * 5);
        $series->getDataPoints()->addDataPointForBarSeries($valueCell);
    }

    $axis = $chart->getAxes()->getHorizontalAxis();
    $axis->setCategoryAxisType(CategoryAxisType::Text);
    $axis->getTextFormat()->getTextBlockFormat()->setRotationAngle(0);
    $axis->getTextFormat()->getPortionFormat()->setFontHeight(12);
    $axis->setMajorTickMark(TickMarkType::Outside);
    $axis->setAutomaticTickLabelSpacing(true);
    $axis->setAutomaticTickMarksSpacing(true);

    // 幻灯片 2:每三个标签显示一次,但为每个类别保留刻度标记。
    $manualSlide = $presentation->getSlides()->addClone($slide);
    $manualChart = $manualSlide->getShapes()->get_Item(0);
    $manualAxis = $manualChart->getAxes()->getHorizontalAxis();
    $manualAxis->setAutomaticTickLabelSpacing(false);
    $manualAxis->setTickLabelSpacing(3);
    $manualAxis->setAutomaticTickMarksSpacing(false);
    $manualAxis->setTickMarksSpacing(1);

    // 幻灯片 3:让图表再次自动选择标签和刻度间隔。
    $restoredSlide = $presentation->getSlides()->addClone($manualSlide);
    $restoredChart = $restoredSlide->getShapes()->get_Item(0);
    $restoredChart->getAxes()->getHorizontalAxis()->setAutomaticTickLabelSpacing(true);
    $restoredChart->getAxes()->getHorizontalAxis()->setAutomaticTickMarksSpacing(true);

    $presentation->save("CategoryAxisIntervals.pptx", SaveFormat::Pptx);
} finally {
    $presentation->dispose();
}

自动间隔(第 1 张幻灯片): 在此渲染中,每隔一个类别标签会显示一次,并换行成两行。自动结果会随图表大小、字体和渲染器而变化。

Automatic category label spacing with all 24 columns visible

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

Manual category label interval of three with all 24 columns visible

选择正确的坐标轴和间隔

对文本类别坐标轴(例如柱形图、折线图、面积图或条形图的类别坐标轴)使用此类别计数间隔。在柱形图中,它是水平坐标轴;在水平条形图中,类别坐标轴是垂直的,因此将这些设置应用于 getVerticalAxis 返回的坐标轴。刻度间隔同样适用于具有系列坐标轴的图表。

不要使用类别标签间隔来设定数值坐标轴的数值刻度。在数值坐标轴上,setMajorUnit 指定数值差异:例如,将主单位设为 10 会在 0、10、20 等位置生成刻度(前提是坐标轴从零开始)。而类别标签间隔 3 则仅计数类别位置,忽略其数据值。散点图和气泡图使用数值坐标轴而非文本类别坐标轴。对于日期坐标轴,请参考 更改类别坐标轴 中的基于时间的主单位和比例设置。

为类别坐标轴的值设置日期格式

示例使用四个年度值替换默认图表数据。日期作为 OLE Automation 序列号存放在第一个工作表(索引 0)中,计算方式为自 1899 年 12 月 30 日起的天数。使用 setCategoryAxisType 并传入 CategoryAxisType::Date,调用 setNumberFormatLinkedToSource 并设为 false,再将 yyyy 传给 setNumberFormat,即可使类别标签独立于单元格格式而显示四位数年份。

use aspose\slides\CategoryAxisType;
use aspose\slides\ChartType;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;

$presentation = new Presentation();
try {
    $slide = $presentation->getSlides()->get_Item(0);

    $chart = $slide->getShapes()->addChart(ChartType::Line, 50, 50, 450, 300);

    $chart->getChartData()->getCategories()->clear();
    $chart->getChartData()->getSeries()->clear();

    $workbook = $chart->getChartData()->getChartDataWorkbook();
    $workbook->clear(0);

    $baseDate = gmmktime(0, 0, 0, 12, 30, 1899);

    $series = $chart->getChartData()->getSeries()->add(ChartType::Line);
    for ($i = 0; $i < 4; $i++) {
        $date = gmmktime(0, 0, 0, 1, 1, 2015 + $i);
        $serialDate = ($date - $baseDate) / 86400;
        $categoryCell = $workbook->getCell(0, $i + 1, 0, $serialDate);
        $chart->getChartData()->getCategories()->add($categoryCell);

        $valueCell = $workbook->getCell(0, $i + 1, 1, $i + 1);
        $series->getDataPoints()->addDataPointForLineSeries($valueCell);
    }

    $chart->getAxes()->getHorizontalAxis()->setCategoryAxisType(CategoryAxisType::Date);
    $chart->getAxes()->getHorizontalAxis()->setNumberFormatLinkedToSource(false);
    $chart->getAxes()->getHorizontalAxis()->setNumberFormat("yyyy");

    $presentation->save("DateAxisFormat.pptx", SaveFormat::Pptx);
} finally {
    $presentation->dispose();
}

为图表坐标轴标题设置旋转角度

在垂直坐标轴上调用 setTitle 并传入 true,提供标题文本,然后使用 setRotationAngle 进行旋转。角度以度数计;本示例将柱形图的数值轴标题旋转 90 度后保存。

use aspose\slides\ChartType;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;

$presentation = new Presentation();
try {
    $slide = $presentation->getSlides()->get_Item(0);

    $chart = $slide->getShapes()->addChart(ChartType::ClusteredColumn, 50, 50, 450, 300);
    $chart->getAxes()->getVerticalAxis()->setTitle(true);
    $chart->getAxes()->getVerticalAxis()->getTitle()->addTextFrameForOverriding("Value");
    $chart->getAxes()->getVerticalAxis()->getTitle()->getTextFormat()->getTextBlockFormat()->setRotationAngle(90);

    $presentation->save("RotatedAxisTitle.pptx", SaveFormat::Pptx);
} finally {
    $presentation->dispose();
}

在类别轴或数值轴上设置坐标轴位置

使用 setAxisBetweenCategories 控制数值轴是跨越类别之间还是跨越类别刻度线。此设置适用于类别坐标轴。示例在柱形图的水平类别坐标轴上将其设为 true 并保存结果。

use aspose\slides\ChartType;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;

$presentation = new Presentation();
try {
    $slide = $presentation->getSlides()->get_Item(0);

    $chart = $slide->getShapes()->addChart(ChartType::ClusteredColumn, 50, 50, 450, 300);
    $chart->getAxes()->getHorizontalAxis()->setAxisBetweenCategories(true);

    $presentation->save("AxisBetweenCategories.pptx", SaveFormat::Pptx);
} finally {
    $presentation->dispose();
}

在图表数值轴上设置显示单位

使用 setDisplayUnit 可在不更改底层数据的前提下缩放数值轴标签。将 DisplayUnitType 设为 Millions,则 60,000,000 将显示为 60。示例创建一个柱形图,并将其垂直轴的显示单位设为百万。

use aspose\slides\ChartType;
use aspose\slides\DisplayUnitType;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;

$presentation = new Presentation();
try {
    $slide = $presentation->getSlides()->get_Item(0);

    $chart = $slide->getShapes()->addChart(ChartType::ClusteredColumn, 50, 50, 450, 300);
    $chart->getAxes()->getVerticalAxis()->setDisplayUnit(DisplayUnitType::Millions);

    $presentation->save("Result.pptx", SaveFormat::Pptx);
} finally {
    $presentation->dispose();
}

常见问题解答

如何设置一个坐标轴穿过另一坐标轴的数值(轴交叉)?

使用 setCrossType 选择交叉行为。若要指定数值交叉点,使用 setCrossAt。这些设置可将轴交叉点移动到合适的基准线。

如何相对于坐标轴定位刻度标签?

调用 setTickLabelPosition 并使用 TickLabelPositionType 的 Low、High、NextTo 或 None。若要控制刻度线本身,使用 setMajorTickMark 或 setMinorTickMark,它们与标签定位分离。