Форматирование диаграмм презентаций в Java
Обзор
Эта статья объясняет, как форматировать диаграммы в презентациях PowerPoint с использованием Aspose.Slides. Она показывает, как настраивать ключевые элементы диаграммы, такие как оси, линии сетки, заголовки, легенды, область построения и заполнения стен, чтобы улучшить внешний вид и читаемость данных диаграммы.
Также демонстрируется, как задавать свойства шрифта для текста диаграммы, применять предустановленные числовые форматы к данным диаграммы и включать скруглённые углы области диаграммы. Вместе эти примеры показывают, как управлять как визуальным стилем, так и представлением данных диаграмм в презентации.
Форматирование элементов диаграммы
Используйте IChart для форматирования заголовков диаграмм, осей, линий сетки, легенд и области построения. Этот пример создает линейную диаграмму с маркерами и данными по умолчанию, затем применяет отдельные текстовые и линейные стили к её оси значений и оси категорий. Размеры шрифтов и толщины линий задаются в пунктах; подписи категорий повёрнуты на 45 градусов.
Ось значений использует setNumberFormat независимо от исходных ячеек. Ее масштаб проходит от -2 до 15 с основными интервалами 2 и вспомогательными интервалами 0.5. Пример также комбинирует процентное форматирование с setDisplayUnit, установленным в тысячах, поэтому адаптируйте эти настройки к смыслу и масштабу ваших данных. Легенда остаётся вне области построения, потому что setOverlay вызывается с false. Заполнение задней стены и пола настраивается через getBackWall и getFloor, но эти поверхности видимы только в 3D‑диаграммах.
import com.aspose.slides.*;
import java.awt.Color;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IChart chart = slide.getShapes().addChart(ChartType.LineWithMarkers, 50, 50, 500, 400);
chart.setTitle(true);
chart.getChartTitle().addTextFrameForOverriding("");
IPortion chartTitle = chart.getChartTitle().getTextFrameForOverriding().getParagraphs().get_Item(0).getPortions().get_Item(0);
chartTitle.setText("Sample Chart");
chartTitle.getPortionFormat().getFillFormat().setFillType(FillType.Solid);
chartTitle.getPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.GRAY);
chartTitle.getPortionFormat().setFontHeight(20);
chartTitle.getPortionFormat().setFontBold(NullableBool.True);
chartTitle.getPortionFormat().setFontItalic(NullableBool.True);
chart.getAxes().getVerticalAxis().getMajorGridLinesFormat().getLine().getFillFormat().setFillType(FillType.Solid);
chart.getAxes().getVerticalAxis().getMajorGridLinesFormat().getLine().getFillFormat().getSolidFillColor().setColor(Color.BLUE);
chart.getAxes().getVerticalAxis().getMajorGridLinesFormat().getLine().setWidth(5);
chart.getAxes().getVerticalAxis().getMajorGridLinesFormat().getLine().setDashStyle(LineDashStyle.DashDot);
chart.getAxes().getVerticalAxis().getMinorGridLinesFormat().getLine().getFillFormat().setFillType(FillType.Solid);
chart.getAxes().getVerticalAxis().getMinorGridLinesFormat().getLine().getFillFormat().getSolidFillColor().setColor(Color.RED);
chart.getAxes().getVerticalAxis().getMinorGridLinesFormat().getLine().setWidth(3);
chart.getAxes().getVerticalAxis().setNumberFormatLinkedToSource(false);
chart.getAxes().getVerticalAxis().setDisplayUnit(DisplayUnitType.Thousands);
chart.getAxes().getVerticalAxis().setNumberFormat("0.0%");
chart.getAxes().getVerticalAxis().setAutomaticMajorUnit(false);
chart.getAxes().getVerticalAxis().setAutomaticMaxValue(false);
chart.getAxes().getVerticalAxis().setAutomaticMinorUnit(false);
chart.getAxes().getVerticalAxis().setAutomaticMinValue(false);
chart.getAxes().getVerticalAxis().setMaxValue(15f);
chart.getAxes().getVerticalAxis().setMinValue(-2f);
chart.getAxes().getVerticalAxis().setMinorUnit(0.5f);
chart.getAxes().getVerticalAxis().setMajorUnit(2.0f);
IChartPortionFormat valueAxisText = chart.getAxes().getVerticalAxis().getTextFormat().getPortionFormat();
valueAxisText.setFontBold(NullableBool.True);
valueAxisText.setFontHeight(16);
valueAxisText.setFontItalic(NullableBool.True);
valueAxisText.getFillFormat().setFillType(FillType.Solid);
valueAxisText.getFillFormat().getSolidFillColor().setPresetColor(PresetColor.DarkGreen);
valueAxisText.setLatinFont(new FontData("Times New Roman"));
chart.getAxes().getVerticalAxis().setTitle(true);
chart.getAxes().getVerticalAxis().getTitle().addTextFrameForOverriding("");
IPortion valueAxisTitle = chart.getAxes().getVerticalAxis().getTitle().getTextFrameForOverriding().getParagraphs().get_Item(0).getPortions().get_Item(0);
valueAxisTitle.setText("Primary Axis");
valueAxisTitle.getPortionFormat().getFillFormat().setFillType(FillType.Solid);
valueAxisTitle.getPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.GRAY);
valueAxisTitle.getPortionFormat().setFontHeight(20);
valueAxisTitle.getPortionFormat().setFontBold(NullableBool.True);
valueAxisTitle.getPortionFormat().setFontItalic(NullableBool.True);
chart.getAxes().getHorizontalAxis().getMajorGridLinesFormat().getLine().getFillFormat().setFillType(FillType.Solid);
chart.getAxes().getHorizontalAxis().getMajorGridLinesFormat().getLine().getFillFormat().getSolidFillColor().setColor(new Color(0, 128, 0));
chart.getAxes().getHorizontalAxis().getMajorGridLinesFormat().getLine().setWidth(5);
chart.getAxes().getHorizontalAxis().getMinorGridLinesFormat().getLine().getFillFormat().setFillType(FillType.Solid);
chart.getAxes().getHorizontalAxis().getMinorGridLinesFormat().getLine().getFillFormat().getSolidFillColor().setColor(Color.YELLOW);
chart.getAxes().getHorizontalAxis().getMinorGridLinesFormat().getLine().setWidth(3);
IChartPortionFormat categoryAxisText = chart.getAxes().getHorizontalAxis().getTextFormat().getPortionFormat();
categoryAxisText.setFontBold(NullableBool.True);
categoryAxisText.setFontHeight(16);
categoryAxisText.setFontItalic(NullableBool.True);
categoryAxisText.getFillFormat().setFillType(FillType.Solid);
categoryAxisText.getFillFormat().getSolidFillColor().setColor(Color.BLUE);
categoryAxisText.setLatinFont(new FontData("Arial"));
chart.getAxes().getHorizontalAxis().setTitle(true);
chart.getAxes().getHorizontalAxis().getTitle().addTextFrameForOverriding("");
IPortion categoryAxisTitle = chart.getAxes().getHorizontalAxis().getTitle().getTextFrameForOverriding().getParagraphs().get_Item(0).getPortions().get_Item(0);
categoryAxisTitle.setText("Sample Category");
categoryAxisTitle.getPortionFormat().getFillFormat().setFillType(FillType.Solid);
categoryAxisTitle.getPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.GRAY);
categoryAxisTitle.getPortionFormat().setFontHeight(20);
categoryAxisTitle.getPortionFormat().setFontBold(NullableBool.True);
categoryAxisTitle.getPortionFormat().setFontItalic(NullableBool.True);
chart.getAxes().getHorizontalAxis().setTickLabelPosition(TickLabelPositionType.Low);
chart.getAxes().getHorizontalAxis().setTickLabelRotationAngle(45);
IChartPortionFormat legendText = chart.getLegend().getTextFormat().getPortionFormat();
legendText.setFontBold(NullableBool.True);
legendText.setFontHeight(16);
legendText.setFontItalic(NullableBool.True);
legendText.getFillFormat().setFillType(FillType.Solid);
legendText.getFillFormat().getSolidFillColor().setPresetColor(PresetColor.DarkRed);
chart.getLegend().setOverlay(false);
chart.getBackWall().setThickness(1);
chart.getBackWall().getFormat().getFill().setFillType(FillType.Solid);
chart.getBackWall().getFormat().getFill().getSolidFillColor().setColor(new Color(255, 165, 0));
chart.getFloor().getFormat().getFill().setFillType(FillType.Solid);
chart.getFloor().getFormat().getFill().getSolidFillColor().setColor(Color.RED);
chart.getPlotArea().getFormat().getFill().setFillType(FillType.Solid);
chart.getPlotArea().getFormat().getFill().getSolidFillColor().setPresetColor(PresetColor.LightCyan);
presentation.save("FormattedChart_out.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Установка свойств шрифта для диаграммы
Задайте размер шрифта по умолчанию для текста диаграммы через Chart.getTextFormat. Пример создаёт сгруппированную столбцовую диаграмму с 20‑пунктовым шрифтом и включает подписи значений для первой серии через setShowValue. Текстовые элементы с собственными явными настройками шрифта могут переопределять значение по умолчанию диаграммы.
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IChart chart = slide.getShapes().addChart(ChartType.ClusteredColumn, 100, 100, 500, 400);
chart.getTextFormat().getPortionFormat().setFontHeight(20);
chart.getChartData().getSeries().get_Item(0).getLabels().getDefaultDataLabelFormat().setShowValue(true);
presentation.save("FontPropertiesForChart.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Установка числового формата
Используйте IChartDataCell.setPresetNumberFormat для применения встроенного числового формата к ячейкам рабочей книги диаграммы. Этот пример создаёт сгруппированную столбцовую диаграмму с данными по умолчанию, поддерживаемыми ячейками, и применяет индекс формата 10 (0.00%) к каждой ячейке значений серии. Это меняет отображение значений в рабочей книге без изменения самих чисел; например, 0.25 отображается как 25.00 %. Форматы осей и подписей данных можно настраивать отдельно.
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IChart chart = slide.getShapes().addChart(ChartType.ClusteredColumn, 50, 50, 500, 400);
IChartSeriesCollection series = chart.getChartData().getSeries();
for (IChartSeries chartSeries : series)
{
for (IChartDataPoint dataPoint : chartSeries.getDataPoints())
{
dataPoint.getValue().getAsCell().setPresetNumberFormat((byte) 10); // 0.00%
}
}
presentation.save("PresetNumberFormat_out.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Следующая таблица перечисляет встроенные индексы числовых форматов с типичными форматами Excel для локали английский (США). Точные строковые форматы и их отображение могут различаться в зависимости от приложения и локали, особенно для валют и дат. Некоторые форматы Excel также отличаются от значений по умолчанию в стандарте OOXML, как описано в Microsoft’s number format implementation notes.
| Индекс | Формат |
|---|---|
| 0 | General |
| 1 | 0 |
| 2 | 0.00 |
| 3 | #,##0 |
| 4 | #,##0.00 |
| 5 | "$"#,##0_);("$"#,##0) |
| 6 | "$"#,##0_);[Red]("$"#,##0) |
| 7 | "$"#,##0.00_);("$"#,##0.00) |
| 8 | "$"#,##0.00_);[Red]("$"#,##0.00) |
| 9 | 0% |
| 10 | 0.00% |
| 11 | 0.00E+00 |
| 12 | # ?/? |
| 13 | # ??/?? |
| 14 | m/d/yyyy |
| 15 | d-mmm-yy |
| 16 | d-mmm |
| 17 | mmm-yy |
| 18 | h:mm AM/PM |
| 19 | h:mm:ss AM/PM |
| 20 | h:mm |
| 21 | h:mm:ss |
| 22 | m/d/yyyy h:mm |
| 37 | #,##0_);(#,##0) |
| 38 | #,##0_);[Red](#,##0) |
| 39 | #,##0.00_);(#,##0.00) |
| 40 | #,##0.00_);[Red](#,##0.00) |
| 41 | _(* #,##0_);_(* (#,##0);_(* "-"_);_(@_) |
| 42 | _("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_) |
| 43 | _(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_) |
| 44 | _("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_) |
| 45 | mm:ss |
| 46 | [h]:mm:ss |
| 47 | mm:ss.0 |
| 48 | ##0.0E+0 |
| 49 | @ |
Установка скругленных границ области диаграммы
Вызовите IChart.setRoundedCorners с true, чтобы скруглить углы области диаграммы. Пример создаёт сгруппированную столбцовую диаграмму и использует getLineFormat для установки сплошного серого контура и одиночного стиля линии перед сохранением презентации.
import com.aspose.slides.*;
import java.awt.Color;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IChart chart = slide.getShapes().addChart(ChartType.ClusteredColumn, 20, 100, 600, 400);
chart.getLineFormat().getFillFormat().setFillType(FillType.Solid);
chart.getLineFormat().getFillFormat().getSolidFillColor().setColor(Color.GRAY);
chart.getLineFormat().setStyle(LineStyle.Single);
chart.setRoundedCorners(true);
presentation.save("out.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Редактирование существующих аннотаций диаграммы
Диаграмма может содержать пользовательские фигуры, например текстовую аннотацию, объясняющую статус отчёта. Доступ к этим фигурам осуществляется через IChart.getUserShapes, также перечисленную под Chart.getUserShapes в справочнике API диаграмм. Коллекция, возвращаемая getShapes, содержит принадлежащие диаграмме фигуры.
Обычный текстовый блок, размещённый поверх диаграммы, принадлежит слайду, даже если выглядит как часть диаграммы. Итерация через Slide.getShapes находит диаграмму и обычные фигуры слайда, но не перечисляет отдельные фигуры внутри диаграммы. Заголовки диаграмм и подписи данных являются отдельными элементами диаграммы, а не пользовательскими аннотациями в этой коллекции.
Скачайте chart-annotations.pptx и поместите его в рабочий каталог приложения. На первом слайде находится диаграмма с разъединённой аннотацией «Preliminary results», принадлежащей диаграмме линией и обычным текстовым блоком слайда «Slide overlay». Пример находит первую диаграмму на этом слайде и меняет аннотацию на «Final results», когда отчёт готов к публикации. Он проверяет, что коллекция не пуста, и редактирует только IAutoShape с ненулевым текстовым фреймом, возвращаемым getTextFrame, содержащим ожидаемый текст.
import com.aspose.slides.*;
Presentation presentation = new Presentation("chart-annotations.pptx");
try {
ISlide slide = presentation.getSlides().get_Item(0);
IChart chart = null;
for (IShape shape : slide.getShapes()) {
if (shape instanceof IChart) {
chart = (IChart) shape;
break;
}
}
if (chart == null || chart.getUserShapes().getShapes().size() == 0) {
System.out.println("No chart or chart-owned shapes found.");
return;
}
boolean updated = false;
for (IShape shape : chart.getUserShapes().getShapes()) {
if (shape instanceof IAutoShape) {
IAutoShape annotation = (IAutoShape) shape;
if (annotation.getTextFrame() != null && "Preliminary results".equals(annotation.getTextFrame().getText())) {
annotation.getTextFrame().setText("Final results");
updated = true;
break;
}
}
}
if (updated) {
presentation.save("chart-annotations-updated.pptx", SaveFormat.Pptx);
} else {
System.out.println("No matching text annotation found.");
}
} finally {
presentation.dispose();
}
Линия и текстовый блок слайда остаются без изменений. Ниже показаны входное изображение и сохранённый, повторно открытый результат:
| До редактирования | После редактирования |
|---|---|
![]() |
![]() |
Note
Пример проверяет только фигуры верхнего уровня, принадлежащие диаграмме. Если аннотация находится внутри IGroupShape, также проверьте коллекцию getShapes этой группы. Выполняйте эту проверку рекурсивно для вложенных групп, применяя те же проверки текста к их дочерним фигурам. Сама группа является контейнером; не рассматривайте её как текстовый блок.FAQ
Могу ли я установить полупрозрачные заливки для столбцов/областей, сохранив границы непрозрачными?
Да. Прозрачность заливки и контур настраиваются отдельно. Это полезно для повышения читаемости сетки и данных в плотных визуализациях.
Как поступить с подписями данных, когда они перекрываются?
Уменьшите размер шрифта, отключите необязательные компоненты подписи (например, категории), скорректируйте позицию подписи, выводите подписи только для выбранных точек при необходимости или переключите формат на «значение + легенда».
Можно ли применять градиентные или шаблонные заливки к сериям?
Да. Для серий поддерживаются сплошные, градиентные и шаблонные заливки. На практике используйте градиенты умеренно и избегайте комбинаций, снижающих контраст с сеткой и текстом.

