Управление данными серий диаграмм в презентациях с помощью JavaScript
Обзор
Диаграмма хранит свои построенные данные в рабочей книге данных диаграммы. ChartSeries представляет один набор связанных значений, а каждый ChartDataPoint в серии ссылается на одну или несколько ячеек рабочей книги. Объекты ChartCategory предоставляют метки или значения группировки, общие для всех серий. Поэтому имя серии, категории и значения точек связываются с объектами ChartDataCell, а не хранятся только как отображаемый текст.
Для типичной диаграммы категорий рабочая книга по умолчанию использует строку 0 для имён серий, столбец 0 для имён категорий и оставшиеся ячейки — для значений серий. Индексы листа, строки и столбца, передаваемые в ChartDataWorkbook.getCell, начинаются с 0. Такая планировка полезна, когда вы создаёте диаграмму с данными по умолчанию, но не следует полагаться, что каждая существующая диаграмма использует её. Для загруженной презентации проверьте ячейки, на которые ссылаются серии, категории и точки данных, прежде чем изменять значения в рабочей книге.
Настройки диаграммы имеют три разных уровня:
- Настройки уровня серии, такие как ChartSeries.getFormat, задают внешний вид по умолчанию для всех точек в одной серии.
- Настройки отдельной точки, такие как ChartDataPoint.getFormat, переопределяют внешний вид серии для одной точки.
- Групповые настройки применяются к совместимым сериям, принадлежащим одному ChartSeriesGroup. Получить группу можно через ChartSeries.getParentSeriesGroup, когда требуется задать такие параметры, как перекрытие или ширина промежутка.
Если явное заполнение точки или серии не задано, стиль и тема диаграммы определяют автоматический внешний вид. Когда присутствуют как настройки серии, так и точки, приоритет имеет форматирование точки.

Установка перекрытия серий диаграммы
ChartSeries.getOverlap сообщает, насколько столбцы или полосы перекрываются в 2D‑диаграмме, от ‑100 до 100 процентов. Это только чтение проекции настройки родительской группы серий. Чтобы изменить перекрытие для всех совместимых серий в группе, используйте ChartSeriesGroup.setOverlap. Эта опция применяется к типам диаграмм, показывающим сгруппированные полосы или столбцы; она не влияет на несвязанные группы серий в комбинированной диаграмме.
Следующий пример задаёт перекрытие для группы, содержащей первую серию:
const aspose = {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const firstSlideIndex = 0;
const firstSeriesIndex = 0;
const overlapPercent = java.newByte(30);
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(firstSlideIndex);
// Новая диаграмма содержит примерные серии, категории и значения.
const chart = slide.getShapes().addChart(aspose.slides.ChartType.ClusteredColumn, 20, 20, 500, 200);
const series = chart.getChartData().getSeries().get_Item(firstSeriesIndex);
series.getParentSeriesGroup().setOverlap(overlapPercent);
presentation.save("series_overlap.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Результат:

Изменение цвета заливки серии
Используйте ChartSeries.getFormat, чтобы задать заливку по умолчанию для всей серии. Если у точки уже задана явная заливка, её настройка ChartDataPoint.getFormat переопределит заливку серии для этой точки.
Следующий пример применяет сплошную синюю заливку к первой серии:
const aspose = {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const firstSlideIndex = 0;
const firstSeriesIndex = 0;
const solidFillType = java.newByte(aspose.slides.FillType.Solid);
const blueColor = java.getStaticFieldValue("java.awt.Color", "BLUE");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(firstSlideIndex);
const chart = slide.getShapes().addChart(aspose.slides.ChartType.ClusteredColumn, 20, 20, 500, 200);
const series = chart.getChartData().getSeries().get_Item(firstSeriesIndex);
series.getFormat().getFill().setFillType(solidFillType);
series.getFormat().getFill().getSolidFillColor().setColor(blueColor);
presentation.save("series_color.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Результат:

Изменение имени серии
Имя серии хранится в рабочей книге данных диаграммы и обычно отображается в легенде. В рабочей книге по умолчанию, созданной для сгруппированной столбчатой диаграммы, ячейка B1 находится в строке 0, столбце 1 и содержит имя первой серии. Именованные константы в следующем примере делают эту структуру явной:
const aspose = {};
aspose.slides = require("aspose.slides.via.java");
const firstSlideIndex = 0;
const worksheetIndex = 0;
const seriesNameRowIndex = 0;
const firstSeriesColumnIndex = 1;
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(firstSlideIndex);
const chart = slide.getShapes().addChart(aspose.slides.ChartType.ClusteredColumn, 20, 20, 500, 200);
const workbook = chart.getChartData().getChartDataWorkbook();
const seriesNameCell = workbook.getCell(worksheetIndex, seriesNameRowIndex, firstSeriesColumnIndex);
seriesNameCell.setValue("Revenue");
presentation.save("series_name.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Вы также можете обновить уже используемую ячейку через ChartSeries.getName. Такой подход избавляет от предположений о конкретных строках и столбцах в существующей диаграмме:
const aspose = {};
aspose.slides = require("aspose.slides.via.java");
const firstSlideIndex = 0;
const firstSeriesIndex = 0;
const firstNameCellIndex = 0;
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(firstSlideIndex);
const chart = slide.getShapes().addChart(aspose.slides.ChartType.ClusteredColumn, 20, 20, 500, 200);
const series = chart.getChartData().getSeries().get_Item(firstSeriesIndex);
const seriesNameCell = series.getName().getAsCells().get_Item(firstNameCellIndex);
seriesNameCell.setValue("Revenue");
presentation.save("series_name.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Результат:

Получение автоматически рассчитываемого цвета заливки серии
ChartSeries.getAutomaticSeriesColor возвращает цвет, вычисленный из индекса серии и стиля диаграммы. Это цвет, используемый, когда заливка серии не определена явно. Вызов метода лишь читает рассчитанный цвет; он не задаёт новую заливку.
Следующий пример выводит автоматический цвет каждой серии по умолчанию:
const aspose = {};
aspose.slides = require("aspose.slides.via.java");
const firstSlideIndex = 0;
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(firstSlideIndex);
const chart = slide.getShapes().addChart(aspose.slides.ChartType.ClusteredColumn, 20, 20, 500, 200);
const seriesCount = chart.getChartData().getSeries().size();
for (let seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++) {
const series = chart.getChartData().getSeries().get_Item(seriesIndex);
const automaticColor = series.getAutomaticSeriesColor();
const automaticColorText = automaticColor.toString();
console.log("Series " + seriesIndex + ": " + automaticColorText);
}
} finally {
presentation.dispose();
}
Пример вывода для стиля диаграммы по умолчанию:
Series 0: java.awt.Color[r=79,g=129,b=189]
Series 1: java.awt.Color[r=192,g=80,b=77]
Series 2: java.awt.Color[r=155,g=187,b=89]
Точные цвета зависят от стиля и темы диаграммы.
Установка инвертированного цвета заливки для серии
Для столбцов, полос и «пузырьковых» серий ChartSeries.setInvertIfNegative может отображать отрицательные значения другой заливкой. Задайте обычную заливку серии как сплошную, включите инверсию и укажите цвет отрицательного значения через ChartSeries.getInvertedSolidFillColor. Отрицательные числа в рабочей книге остаются без изменений; меняется только их отображаемый цвет.
Следующий пример заменяет данные по умолчанию одной серией. Строка 0 листа содержит имя серии, столбец 0 — имена категорий, столбец 1 — значения:
const aspose = {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const firstSlideIndex = 0;
const worksheetIndex = 0;
const headerRowIndex = 0;
const categoryColumnIndex = 0;
const firstSeriesColumnIndex = 1;
const firstDataRowIndex = 1;
const solidFillType = java.newByte(aspose.slides.FillType.Solid);
const redColor = java.getStaticFieldValue("java.awt.Color", "RED");
const categoryNames = ["Category 1", "Category 2", "Category 3"];
const seriesValues = [-20, 50, -30];
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(firstSlideIndex);
const chart = slide.getShapes().addChart(aspose.slides.ChartType.ClusteredColumn, 20, 20, 500, 200);
const chartData = chart.getChartData();
const workbook = chartData.getChartDataWorkbook();
chartData.getSeries().clear();
chartData.getCategories().clear();
const seriesNameCell = workbook.getCell(worksheetIndex, headerRowIndex, firstSeriesColumnIndex, "Series 1");
const chartType = chart.getType();
const series = chartData.getSeries().add(seriesNameCell, chartType);
for (let categoryIndex = 0; categoryIndex < categoryNames.length; categoryIndex++) {
const dataRowIndex = firstDataRowIndex + categoryIndex;
const categoryName = categoryNames[categoryIndex];
const seriesValue = seriesValues[categoryIndex];
const categoryCell = workbook.getCell(worksheetIndex, dataRowIndex, categoryColumnIndex, categoryName);
chartData.getCategories().add(categoryCell);
const valueCell = workbook.getCell(worksheetIndex, dataRowIndex, firstSeriesColumnIndex, seriesValue);
series.getDataPoints().addDataPointForBarSeries(valueCell);
}
const automaticSeriesColor = series.getAutomaticSeriesColor();
series.getFormat().getFill().setFillType(solidFillType);
series.getFormat().getFill().getSolidFillColor().setColor(automaticSeriesColor);
series.setInvertIfNegative(true);
series.getInvertedSolidFillColor().setColor(redColor);
presentation.save("inverted_solid_fill_color.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Результат:

Инверсию для отдельной точки можно включить через ChartDataPoint.setInvertIfNegative. В следующем примере инверсия отключена для серии и включена только для выбранной точки. Точке также присвоено отрицательное значение, чтобы эффект был виден:
const aspose = {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const firstSlideIndex = 0;
const firstSeriesIndex = 0;
const targetDataPointIndex = 2;
const negativeValue = -30;
const solidFillType = java.newByte(aspose.slides.FillType.Solid);
const redColor = java.getStaticFieldValue("java.awt.Color", "RED");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(firstSlideIndex);
const chart = slide.getShapes().addChart(aspose.slides.ChartType.ClusteredColumn, 20, 20, 500, 200);
const series = chart.getChartData().getSeries().get_Item(firstSeriesIndex);
const automaticSeriesColor = series.getAutomaticSeriesColor();
series.getFormat().getFill().setFillType(solidFillType);
series.getFormat().getFill().getSolidFillColor().setColor(automaticSeriesColor);
series.getInvertedSolidFillColor().setColor(redColor);
series.setInvertIfNegative(false);
const dataPoint = series.getDataPoints().get_Item(targetDataPointIndex);
dataPoint.getValue().getAsCell().setValue(negativeValue);
dataPoint.setInvertIfNegative(true);
presentation.save("data_point_invert_color_if_negative.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Очистка значения конкретной точки данных
Чтобы сделать одну точку пустой, не удаляя остальные, задайте её ячейке в рабочей книге значение null. Для столбчатой диаграммы построенное значение доступно через ChartDataPoint.getValue. Точка остаётся на той же позиции категории, но диаграмма рассматривает её значение как пустое в соответствии с настройками отображения пустых значений.
Следующий пример очищает только вторую точку в первой серии:
const aspose = {};
aspose.slides = require("aspose.slides.via.java");
const firstSlideIndex = 0;
const firstSeriesIndex = 0;
const targetDataPointIndex = 1;
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(firstSlideIndex);
const chart = slide.getShapes().addChart(aspose.slides.ChartType.ClusteredColumn, 20, 20, 500, 200);
const series = chart.getChartData().getSeries().get_Item(firstSeriesIndex);
const dataPoint = series.getDataPoints().get_Item(targetDataPointIndex);
dataPoint.getValue().getAsCell().setValue(null);
presentation.save("clear_data_point_value.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Диаграммы разброса используют отдельные ячейки X и Y, а «пузырьковые» диаграммы также используют ячейку размера. Очищайте только ту ячейку, которая представляет значение, которое вы хотите убрать. Не вызывайте ChartDataPointCollection.clear, когда нужно сохранить остальные точки, поскольку этот метод удаляет все точки из коллекции.
Установка ширины промежутка между сериями
Ширина промежутка — это пространство между соседними кластерами столбцов или полос, выраженное в процентах от их ширины. Как и перекрытие, она принадлежит родительской группе серий, а не отдельной серии. Вызовите ChartSeriesGroup.setGapWidth один раз для группы. Большее значение увеличивает расстояние между кластерами; меньшее — делает их плотнее.
Следующий пример меняет ширину промежутка и сохраняет только итоговую презентацию:
const aspose = {};
aspose.slides = require("aspose.slides.via.java");
const firstSlideIndex = 0;
const firstSeriesIndex = 0;
const gapWidthPercent = 30;
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(firstSlideIndex);
const chart = slide.getShapes().addChart(aspose.slides.ChartType.StackedColumn, 20, 20, 500, 200);
const series = chart.getChartData().getSeries().get_Item(firstSeriesIndex);
series.getParentSeriesGroup().setGapWidth(gapWidthPercent);
presentation.save("gap_width_30.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Результат:

FAQ
Какие типы диаграмм поддерживают серии данных?
Все типы диаграмм, перечисленные в ChartType, используют данные диаграммы, но их серии не всегда имеют одинаковую структуру значений или настройки. Например, категориальные диаграммы используют категории и значения, диаграммы разброса — X и Y, а «пузырьковые» добавляют размеры пузырей. Используйте метод создания точек данных, соответствующий типу серии. Параметры, такие как перекрытие и ширина промежутка, применимы только к совместимым группам столбцов или полос.
Что такое группа серий диаграммы?
ChartSeriesGroup содержит совместимые серии, делящие групповые настройки построения. Комбинированная диаграмма может иметь более одной группы, поэтому изменение группы, полученной через одну серию, не обязательно изменит все серии в диаграмме.
Создаётся ли в новой диаграмме набор данных по умолчанию?
Да. По умолчанию ShapeCollection.addChart создаёт образцы серий, категорий и значений. Их ячейки можно редактировать или очистить коллекции серий и категорий перед добавлением полностью пользовательского набора данных. Существует перегрузка, позволяющая создать диаграмму без данных по умолчанию.
Как объекты диаграммы связаны с ячейками рабочей книги?
Имена серий, метки категорий и значения точек данных ссылаются на ячейки в ChartDataWorkbook. Изменение связанной ячейки обновляет соответствующий элемент диаграммы. При построении пользовательских данных поддерживайте согласованность строк категорий и строк значений серий, чтобы каждая точка отображалась под нужной категорией.
Как очистить одну точку, а не всю серию?
Задайте соответствующей ячейке значение null, чтобы точка осталась на своей позиции как пустая. Используйте ChartDataPointCollection.clear только когда требуется удалить все точки из серии.
Как отображаются пустые точки?
Результат зависит от типа диаграммы и настройки, заданной через Chart.setDisplayBlanksAs. Поддерживаемые варианты: отображать пустоты как разрывы, как нули или соединять соседние точки. Выберите параметр, соответствующий смыслу отсутствующих данных в вашей презентации.
Как форматируются отрицательные значения?
Для поддерживаемых столбцов, полос и «пузырьковых» серий вызовите ChartSeries.setInvertIfNegative и задайте цвет, возвращаемый ChartSeries.getInvertedSolidFillColor. Поведение для отдельной точки можно переопределить с помощью ChartDataPoint.setInvertIfNegative. Эти методы влияют только на визуальное форматирование, а не на хранимые числовые значения.
Какой формат имеет приоритет, когда форматированы и серия, и точка?
Явное форматирование отдельной точки имеет приоритет для этой точки. Другие точки продолжают использовать явный формат серии или, если формат серии не задан, автоматический стиль и тему диаграммы. Групповые настройки, такие как перекрытие и ширина промежутка, управляют расположением и не переопределяют точечное форматирование.
Есть ли ограничение на количество серий в диаграмме?
Aspose.Slides не накладывает отдельного фиксированного ограничения на количество серий. На практике ограничения задаются ограничениями файлов презентации, доступной памятью, временем рендеринга и читаемостью диаграммы.
Что менять, если столбцы находятся слишком близко или слишком далеко друг от друга?
Вызовите ChartSeriesGroup.setGapWidth у соответствующей родительской группы серий. Увеличьте значение, чтобы расширить пространство между кластерами, или уменьшите его, чтобы сблизить их.