Управление подписями данных диаграмм в презентациях на .NET
Введение
Подписи данных отображают информацию о сериях диаграммы и отдельных точках данных, помогая читателям определять значения и понимать диаграмму. Эта статья объясняет, как форматировать значения, отображать проценты, считывать текст подписи, управлять подписями за пределами максимального значения оси, регулировать расстояние между подписями категориальной оси и позиционировать подписи круговой диаграммы.
Установить точность данных в подписи диаграмм
Используйте NumberFormatOfValues для форматирования значений серии. Этот пример создает линейную диаграмму с данными по умолчанию, выводит её таблицу данных и включает подписи значений для первой серии. Формат #,##0.00 отображает разделитель тысяч и два знака после запятой, не изменяя исходные значения.
using Aspose.Slides;
using Aspose.Slides.Charts;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var chart = slide.Shapes.AddChart(ChartType.Line, 50, 50, 450, 300);
chart.HasDataTable = true;
var series = chart.ChartData.Series[0];
series.NumberFormatOfValues = "#,##0.00";
series.Labels.DefaultDataLabelFormat.ShowValue = true;
presentation.Save("PrecisionOfDatalabels_out.pptx", SaveFormat.Pptx);
Чтобы отформатировать числовые ячейки во встроенной книге диаграммы, смотрите Set Custom Number Formats for Workbook Cells. В этом примере также показано, как подписи значений используют форматы исходных ячеек, сохраняя при этом хранимые числовые значения.
Отображать процент в виде подписей
Для составной столбчатой диаграммы вычислите каждое значение как процент от общей суммы категории и присвойте текст TextFrameForOverriding. Этот пример использует данные диаграммы по умолчанию и отображает проценты с двумя знаками после запятой шрифтом размером 8 пунктов. Категории с нулевой суммой пропускаются, чтобы избежать деления на ноль. При изменении данных диаграммы пересчитайте пользовательский текст подписи.
using System;
using Aspose.Slides;
using Aspose.Slides.Charts;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var chart = slide.Shapes.AddChart(ChartType.StackedColumn, 20, 20, 400, 400);
var categoryTotals = new double[chart.ChartData.Categories.Count];
for (int k = 0; k < chart.ChartData.Categories.Count; k++)
{
for (int i = 0; i < chart.ChartData.Series.Count; i++)
{
var series = chart.ChartData.Series[i];
var pointValue = Convert.ToDouble(series.DataPoints[k].Value.Data);
categoryTotals[k] += pointValue;
}
}
for (int x = 0; x < chart.ChartData.Series.Count; x++)
{
var series = chart.ChartData.Series[x];
series.Labels.DefaultDataLabelFormat.ShowLegendKey = false;
for (int j = 0; j < series.DataPoints.Count; j++)
{
var label = series.DataPoints[j].Label;
if (categoryTotals[j] == 0)
{
continue;
}
var pointValue = Convert.ToDouble(series.DataPoints[j].Value.Data);
var dataPointPercent = (pointValue / categoryTotals[j]) * 100;
var portion = new Portion();
portion.Text = string.Format("{0:F2} %", dataPointPercent);
portion.PortionFormat.FontHeight = 8f;
label.TextFrameForOverriding.Text = "";
var paragraph = label.TextFrameForOverriding.Paragraphs[0];
paragraph.Portions.Add(portion);
label.DataLabelFormat.ShowValue = true;
label.DataLabelFormat.ShowSeriesName = false;
label.DataLabelFormat.ShowPercentage = false;
label.DataLabelFormat.ShowLegendKey = false;
label.DataLabelFormat.ShowCategoryName = false;
label.DataLabelFormat.ShowBubbleSize = false;
}
}
presentation.Save("DisplayPercentageAsLabels_out.pptx", SaveFormat.Pptx);
Установить знак процента в подписях данных диаграммы
Когда значения хранятся в виде дробей, используйте NumberFormat для отображения процентов. Установите IsNumberFormatLinkedToSource в false, чтобы применить формат подписи независимо от исходных ячеек.
Этот пример создает 100% составную столбчатую диаграмму с красными и синими сериями в четырёх категориях. Каждая пара значений в сумме дает 1. Формат подписи 0.0% отображает 0.30 как 30.0%, в то время как вертикальная ось использует два знака после запятой. Обе серии используют белый текст подписи размером 10 пунктов.
using System.Drawing;
using Aspose.Slides;
using Aspose.Slides.Charts;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var chart = slide.Shapes.AddChart(ChartType.PercentsStackedColumn, 20, 20, 500, 400);
chart.Axes.VerticalAxis.IsNumberFormatLinkedToSource = false;
chart.Axes.VerticalAxis.NumberFormat = "0.00%";
chart.ChartData.Series.Clear();
chart.ChartData.Categories.Clear();
var workbook = chart.ChartData.ChartDataWorkbook;
int worksheetIndex = 0;
for (int i = 0; i < 4; i++)
{
var categoryCell = workbook.GetCell(worksheetIndex, i + 1, 0, $"Category {i + 1}");
chart.ChartData.Categories.Add(categoryCell);
}
string[] seriesNames = { "Reds", "Blues" };
Color[] seriesColors = { Color.Red, Color.Blue };
double[,] values = { { 0.30, 0.50, 0.80, 0.65 }, { 0.70, 0.50, 0.20, 0.35 } };
for (int i = 0; i < seriesNames.Length; i++)
{
var seriesCell = workbook.GetCell(worksheetIndex, 0, i + 1, seriesNames[i]);
var series = chart.ChartData.Series.Add(seriesCell, chart.Type);
for (int j = 0; j < 4; j++)
{
var valueCell = workbook.GetCell(worksheetIndex, j + 1, i + 1, values[i, j]);
series.DataPoints.AddDataPointForBarSeries(valueCell);
}
series.Format.Fill.FillType = FillType.Solid;
series.Format.Fill.SolidFillColor.Color = seriesColors[i];
var labelFormat = series.Labels.DefaultDataLabelFormat;
labelFormat.ShowValue = true;
labelFormat.IsNumberFormatLinkedToSource = false;
labelFormat.NumberFormat = "0.0%";
labelFormat.TextFormat.PortionFormat.FontHeight = 10;
labelFormat.TextFormat.PortionFormat.FillFormat.FillType = FillType.Solid;
labelFormat.TextFormat.PortionFormat.FillFormat.SolidFillColor.Color = Color.White;
}
presentation.Save("SetDataLabelsPercentageSign_out.pptx", SaveFormat.Pptx);
Получить фактический текст подписи данных
Используйте GetActualLabelText для получения текста, сформированного настройками подписи данных. Это полезно при извлечении подписей для отчётов, поиске содержания презентаций или проверке сгенерированных диаграмм. В примере ниже стандартный data label format комбинирует название категории, название серии и значение. Одна точка форматирует своё значение как процент, другая использует пользовательский текст из TextFrameForOverriding.
using System;
using Aspose.Slides;
using Aspose.Slides.Charts;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var chart = slide.Shapes.AddChart(ChartType.ClusteredColumn, 20, 20, 500, 300);
chart.ChartData.Series.Clear();
chart.ChartData.Categories.Clear();
var workbook = chart.ChartData.ChartDataWorkbook;
chart.ChartData.Categories.Add(workbook.GetCell(0, 1, 0, "Q1"));
chart.ChartData.Categories.Add(workbook.GetCell(0, 2, 0, "Q2"));
var north = chart.ChartData.Series.Add(workbook.GetCell(0, 0, 1, "North"), chart.Type);
north.DataPoints.AddDataPointForBarSeries(workbook.GetCell(0, 1, 1, 0.25));
north.DataPoints.AddDataPointForBarSeries(workbook.GetCell(0, 2, 1, 0.75));
var south = chart.ChartData.Series.Add(workbook.GetCell(0, 0, 2, "South"), chart.Type);
south.DataPoints.AddDataPointForBarSeries(workbook.GetCell(0, 1, 2, 0.40));
south.DataPoints.AddDataPointForBarSeries(workbook.GetCell(0, 2, 2, 0.60));
foreach (var series in chart.ChartData.Series)
{
var format = series.Labels.DefaultDataLabelFormat;
format.ShowCategoryName = true;
format.ShowSeriesName = true;
format.ShowValue = true;
}
north.Labels[1].DataLabelFormat.IsNumberFormatLinkedToSource = false;
north.Labels[1].DataLabelFormat.NumberFormat = "0%";
south.Labels[0].TextFrameForOverriding.Text = "Reviewed";
foreach (var series in chart.ChartData.Series)
{
foreach (var point in series.DataPoints)
{
var label = point.Label;
if (!label.IsVisible)
{
continue;
}
Console.WriteLine($"Value: {point.Value.Data}; label: {label.GetActualLabelText()}");
}
}
Число, хранящееся в точке данных, остаётся 0.75, даже когда её подпись показывает 75% вместе с названиями категории и серии. Пользовательский текст заменяет сгенерированный текст подписи. GetActualLabelText возвращает полученную строку подписи в обоих случаях. Проверяйте IsVisible отдельно, как показано выше, когда нужно извлекать только видимые подписи.
Управлять подписями данных за пределами максимального значения оси
Когда вы вручную ограничиваете диапазон оси, некоторые точки данных могут превышать её максимум. Используйте ShowDataLabelsOverMaximum для контроля отображения их подписей. Эта настройка меняет видимость подписи; она не меняет диапазон оси и исходные числовые значения.
В примере ниже создаётся 2D сгруппированная столбчатая диаграмма со значениями 60 и 120. Для вертикальной оси устанавливается IsAutomaticMaxValue в false и MaxValue в 100. На первом слайде подписи допускаются за пределами максимума; копия этого слайда отключает их. Оба слайда сохраняются в DataLabelsOverMaximum.pptx.
Включите подписи значений с помощью ShowValue. Настройка уровня диаграммы не включает отображение значений сама по себе и не переопределяет отключённое отображение значений отдельной подписи. Этот пример включает значения для всей серии и использует Position для размещения подписей наружу от каждой колонки.
using Aspose.Slides;
using Aspose.Slides.Charts;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var chart = slide.Shapes.AddChart(ChartType.ClusteredColumn, 50, 50, 600, 400);
chart.HasLegend = false;
chart.ChartData.Series.Clear();
chart.ChartData.Categories.Clear();
var workbook = chart.ChartData.ChartDataWorkbook;
var firstCategory = workbook.GetCell(0, 1, 0, "Within range");
var secondCategory = workbook.GetCell(0, 2, 0, "Above maximum");
chart.ChartData.Categories.Add(firstCategory);
chart.ChartData.Categories.Add(secondCategory);
var seriesName = workbook.GetCell(0, 0, 1, "Values");
var series = chart.ChartData.Series.Add(seriesName, chart.Type);
var firstValue = workbook.GetCell(0, 1, 1, 60);
var secondValue = workbook.GetCell(0, 2, 1, 120);
series.DataPoints.AddDataPointForBarSeries(firstValue);
series.DataPoints.AddDataPointForBarSeries(secondValue);
series.Labels.DefaultDataLabelFormat.ShowValue = true;
series.Labels.DefaultDataLabelFormat.Position = LegendDataLabelPosition.OutsideEnd;
chart.Axes.VerticalAxis.IsAutomaticMaxValue = false;
chart.Axes.VerticalAxis.MaxValue = 100;
chart.ShowDataLabelsOverMaximum = true;
var secondSlide = presentation.Slides.AddClone(slide);
var secondChart = (IChart)secondSlide.Shapes[0];
secondChart.ShowDataLabelsOverMaximum = false;
presentation.Save("DataLabelsOverMaximum.pptx", SaveFormat.Pptx);
Следующие изображения показывают сохранённые слайды, отрисованные в Microsoft PowerPoint. При true подпись 120 видна у верхней границы; при false она скрыта. Подпись 60 остаётся видимой, максимум оси остаётся 100, а вторая точка данных остаётся 120 в обоих случаях.
| ShowDataLabelsOverMaximum = true | ShowDataLabelsOverMaximum = false |
|---|---|
![]() |
![]() |
Chart Type
Этот пример использует 2D столбчатую диаграмму со значительной осью. Диаграммы без значительной оси, такие как круговые и кольцевые, не имеют максимума оси, который можно ограничить таким образом.Установить расстояние подписи от оси
Используйте LabelOffset для управления расстоянием между подписями категориальной оси и самой осью. Значение задаётся в процентах от максимального размера шрифта подписей оси. Этот пример создаёт сгруппированную столбчатую диаграмму и устанавливает смещение подписи горизонтальной оси в 500. Настройка влияет на подписи категориальной оси, а не на подписи, привязанные к отдельным точкам данных.
using Aspose.Slides;
using Aspose.Slides.Charts;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var chart = slide.Shapes.AddChart(ChartType.ClusteredColumn, 20, 20, 500, 300);
chart.Axes.HorizontalAxis.LabelOffset = 500;
presentation.Save("SetCategoryAxisLabelDistance_out.pptx", SaveFormat.Pptx);
Регулировать расположение подписей
На круговой диаграмме отрегулируйте позиции подписей данных, чтобы улучшить интервалы и освободить место для линий‑выноски.
Этот пример отображает значение первой точки данных, размещает её подпись за пределами сектора и регулирует её X и Y смещения. Эти смещения задаются относительно ширины и высоты диаграммы соответственно.
using Aspose.Slides;
using Aspose.Slides.Charts;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var chart = slide.Shapes.AddChart(ChartType.Pie, 50, 50, 200, 200);
var series = chart.ChartData.Series;
var label = series[0].Labels[0];
label.DataLabelFormat.ShowValue = true;
label.DataLabelFormat.Position = LegendDataLabelPosition.OutsideEnd;
label.X = 0.71f;
label.Y = 0.04f;
presentation.Save("presentation.pptx", SaveFormat.Pptx);

Форматировать линии-выноски
Когда подписи круговой диаграммы находятся за пределами своих секторов, линии‑выноски помогают читателю сопоставить каждое значение с соответствующим сектором. Контрастный цвет и слегка утолщённая линия делают такие соединения легче воспринимаемыми, а прозрачность и пунктирный стиль сохраняют линии незаметными.
Используйте LeaderLinesFormat для форматирования линий‑выноски на уровне коллекции подписей серии. Параметры в series.Labels.LeaderLinesFormat.Line применяются к всей коллекции, а не к отдельной подписи.
Этот пример создаёт круговую диаграмму с данными по умолчанию, выводит значения за пределами секторов и включает ShowLeaderLines. Он перемещает две подписи дальше от их секторов с помощью смещений X и Y, выраженных в долях ширины и высоты диаграммы. Входная презентация не требуется.
Линия имеет FillFormat со сплошным синим цветом и альфа‑значением 191 из 255, что даёт примерно 25% прозрачности. Width задаёт толщину в 2 пункта, а DashStyle делает линию пунктирной.
using System.Drawing;
using Aspose.Slides;
using Aspose.Slides.Charts;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var chart = slide.Shapes.AddChart(ChartType.Pie, 80, 50, 560, 400);
chart.HasLegend = false;
var series = chart.ChartData.Series[0];
var labelFormat = series.Labels.DefaultDataLabelFormat;
labelFormat.ShowValue = true;
labelFormat.Position = LegendDataLabelPosition.OutsideEnd;
labelFormat.ShowLeaderLines = true;
// Переместить две подписи дальше от их секторов.
series.Labels[0].X = 0.10f;
series.Labels[0].Y = -0.05f;
series.Labels[1].X = -0.10f;
series.Labels[1].Y = 0.05f;
var line = series.Labels.LeaderLinesFormat.Line;
line.FillFormat.FillType = FillType.Solid;
line.FillFormat.SolidFillColor.Color = Color.FromArgb(191, 30, 90, 160);
line.Width = 2;
line.DashStyle = LineDashStyle.Dash;
presentation.Save("FormattedLeaderLines.pptx", SaveFormat.Pptx);
Включение линий‑выноски не гарантирует появление линии для каждой подписи. Видимость зависит от расположения подписи и поведения компоновки диаграммы. В этом примере две сдвинутые подписи имеют видимые линии‑выноски; подписи, оставшиеся близко к своим секторам, их не требуют.
Следующее изображение показывает сохранённый FormattedLeaderLines.pptx, отрисованный с помощью Aspose.Slides:

Добавить несколько строк подписей над столбчатой диаграммой
Этот пример создаёт столбчатую диаграмму с двумя строками подписей над областью построения. Серия A отображает видимые столбцы, тогда как серии B и C предоставляют дополнительные подписи. Их столбцы скрыты удалением заливки и контура. Свойство Overlap выравнивает все три серии по центрам категорий.
Настройки PlotArea резервируют место для строк подписей. После того как ValidateChartLayout вычислит позиции по умолчанию, X и Y сохраняют горизонтальное выравнивание и применяют вертикальные смещения для размещения подписей в две строки. Числа остаются подписью данных, связанной со значениями серии; только заголовки строк выступают отдельными текстовыми объектами.
using System.Drawing;
using Aspose.Slides;
using Aspose.Slides.Charts;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var chart = slide.Shapes.AddChart(ChartType.ClusteredColumn, 40, 40, 640, 200);
chart.HasTitle = false;
chart.HasLegend = false;
chart.TextFormat.PortionFormat.FontHeight = 12;
chart.ChartData.Series.Clear();
chart.ChartData.Categories.Clear();
var workbook = chart.ChartData.ChartDataWorkbook;
workbook.Clear(0);
string[] categories = { "North", "South", "East", "West" };
string[] seriesNames = { "Series A", "Series B", "Series C" };
double[,] seriesValues = {
{ 35, 42, 28, 47 },
{ 22, 31, 19, 26 },
{ 12, 16, 14, 18 }
};
for (int categoryIndex = 0; categoryIndex < categories.Length; categoryIndex++)
{
var categoryCell = workbook.GetCell(0, categoryIndex + 1, 0, categories[categoryIndex]);
chart.ChartData.Categories.Add(categoryCell);
}
for (int seriesIndex = 0; seriesIndex < seriesNames.Length; seriesIndex++)
{
var seriesCell = workbook.GetCell(0, 0, seriesIndex + 1, seriesNames[seriesIndex]);
var series = chart.ChartData.Series.Add(seriesCell, ChartType.ClusteredColumn);
for (int categoryIndex = 0; categoryIndex < categories.Length; categoryIndex++)
{
var valueCell = workbook.GetCell(0, categoryIndex + 1, seriesIndex + 1, seriesValues[seriesIndex, categoryIndex]);
series.DataPoints.AddDataPointForBarSeries(valueCell);
}
if (seriesIndex > 0)
{
// Скрыть столбцы B и C, но оставить их подписи данных.
series.Format.Fill.FillType = FillType.NoFill;
series.Format.Line.FillFormat.FillType = FillType.NoFill;
var labelFormat = series.Labels.DefaultDataLabelFormat;
labelFormat.ShowValue = true;
labelFormat.TextFormat.PortionFormat.FontHeight = 12;
var labelFill = labelFormat.TextFormat.PortionFormat.FillFormat;
labelFill.FillType = FillType.Solid;
labelFill.SolidFillColor.Color = Color.Black;
labelFormat.Position = LegendDataLabelPosition.InsideBase;
}
}
// Выравнивание всех трех серий по одинаковым центрам категорий.
chart.ChartData.Series[0].ParentSeriesGroup.Overlap = 100;
// Использовать меньше линий сетки для этого компактного примера.
chart.Axes.VerticalAxis.IsAutomaticMajorUnit = false;
chart.Axes.VerticalAxis.MajorUnit = 10;
// Зарезервировать место над областью построения для двух рядов подписей данных.
chart.PlotArea.LayoutTargetType = LayoutTargetType.Inner;
chart.PlotArea.X = 0.15f;
chart.PlotArea.Y = 0.32f;
chart.PlotArea.Width = 0.80f;
chart.PlotArea.Height = 0.48f;
chart.ValidateChartLayout();
for (int seriesIndex = 1; seriesIndex < seriesNames.Length; seriesIndex++)
{
var series = chart.ChartData.Series[seriesIndex];
float rowTop = seriesIndex == 1 ? 0.15f : 0.03f;
for (int categoryIndex = 0; categoryIndex < categories.Length; categoryIndex++)
{
var dataLabel = series.DataPoints[categoryIndex].Label;
// Сохранить позицию по горизонтали по умолчанию. Y – смещение от
// позиции подписи по умолчанию, выраженное в долях высоты диаграммы.
dataLabel.X = 0;
dataLabel.Y = rowTop - dataLabel.ActualY / chart.Height;
}
// Только заголовок строки является отдельной текстовой фигурой.
var rowHeading = slide.Shapes.AddAutoShape(ShapeType.Rectangle, chart.X, chart.Y + rowTop * chart.Height, 85, 18);
rowHeading.FillFormat.FillType = FillType.NoFill;
rowHeading.LineFormat.FillFormat.FillType = FillType.NoFill;
rowHeading.AddTextFrame(seriesNames[seriesIndex]);
rowHeading.TextFrame.TextFrameFormat.MarginTop = 0;
rowHeading.TextFrame.TextFrameFormat.MarginBottom = 0;
var headingFormat = rowHeading.TextFrame.Paragraphs[0].Portions[0].PortionFormat;
headingFormat.FontHeight = 12;
headingFormat.FillFormat.FillType = FillType.Solid;
headingFormat.FillFormat.SolidFillColor.Color = Color.Black;
}
presentation.Save("multiple-rows-of-labels.pptx", SaveFormat.Pptx);

FAQ
Как предотвратить наложение подписей данных на плотных диаграммах?
Комбинируйте автоматическое размещение подписей, линии‑выноски и уменьшение размера шрифта; при необходимости скрывайте некоторые поля (например, категорию) или отображайте подписи только для экстремальных или ключевых точек.
Как отключить подписи только для нулевых, отрицательных или пустых значений?
Отфильтруйте точки данных перед включением подписей и выключите отображение для значений 0, отрицательных или отсутствующих значений в соответствии с заданным правилом.
Как обеспечить согласованный стиль подписи при экспорте в PDF/изображения?
Явно задайте семейство шрифта и размер, а также проверьте, что шрифт доступен в среде рендеринга, чтобы избежать подстановки.

