diff --git a/dev/release/fix_example_docs.pl b/dev/release/fix_example_docs.pl
index 4884ebbd..2baf1785 100644
--- a/dev/release/fix_example_docs.pl
+++ b/dev/release/fix_example_docs.pl
@@ -59,6 +59,7 @@ my @examples = (
[ 'chart_clustered.c', 'Examples of clustered category chart' ],
[ 'chart_data_table.c', 'Examples of charts with data tables' ],
[ 'chart_data_tools.c', 'Examples of charts data tools' ],
+ [ 'chart_data_labels.c', 'Examples of charts data labels' ],
[ 'chart_fonts.c', 'Examples of using charts fonts' ],
[ 'chart_pattern.c', 'Examples of using charts patterns' ],
[ 'chart_styles.c', 'Examples of built-in charts styles' ],
diff --git a/docs/images/chart_labels1.png b/docs/images/chart_data_labels1.png
similarity index 100%
rename from docs/images/chart_labels1.png
rename to docs/images/chart_data_labels1.png
diff --git a/docs/images/chart_data_labels11.png b/docs/images/chart_data_labels11.png
new file mode 100644
index 00000000..065c31ff
Binary files /dev/null and b/docs/images/chart_data_labels11.png differ
diff --git a/docs/images/chart_data_labels12.png b/docs/images/chart_data_labels12.png
new file mode 100644
index 00000000..a3a683f5
Binary files /dev/null and b/docs/images/chart_data_labels12.png differ
diff --git a/docs/images/chart_data_labels13.png b/docs/images/chart_data_labels13.png
new file mode 100644
index 00000000..ea96a4d0
Binary files /dev/null and b/docs/images/chart_data_labels13.png differ
diff --git a/docs/images/chart_data_labels14.png b/docs/images/chart_data_labels14.png
new file mode 100644
index 00000000..f0bfb1d4
Binary files /dev/null and b/docs/images/chart_data_labels14.png differ
diff --git a/docs/images/chart_data_labels15.png b/docs/images/chart_data_labels15.png
new file mode 100644
index 00000000..d1cf8d24
Binary files /dev/null and b/docs/images/chart_data_labels15.png differ
diff --git a/docs/images/chart_data_labels16.png b/docs/images/chart_data_labels16.png
new file mode 100644
index 00000000..a294081b
Binary files /dev/null and b/docs/images/chart_data_labels16.png differ
diff --git a/docs/images/chart_data_labels17.png b/docs/images/chart_data_labels17.png
new file mode 100644
index 00000000..a79869be
Binary files /dev/null and b/docs/images/chart_data_labels17.png differ
diff --git a/docs/images/chart_data_labels18.png b/docs/images/chart_data_labels18.png
new file mode 100644
index 00000000..07bf15a3
Binary files /dev/null and b/docs/images/chart_data_labels18.png differ
diff --git a/docs/images/chart_data_labels19.png b/docs/images/chart_data_labels19.png
new file mode 100644
index 00000000..cc023834
Binary files /dev/null and b/docs/images/chart_data_labels19.png differ
diff --git a/docs/images/chart_labels2.png b/docs/images/chart_data_labels2.png
similarity index 100%
rename from docs/images/chart_labels2.png
rename to docs/images/chart_data_labels2.png
diff --git a/docs/images/chart_data_labels20.png b/docs/images/chart_data_labels20.png
new file mode 100644
index 00000000..7419abf4
Binary files /dev/null and b/docs/images/chart_data_labels20.png differ
diff --git a/docs/images/chart_data_labels21.png b/docs/images/chart_data_labels21.png
new file mode 100644
index 00000000..36e7466c
Binary files /dev/null and b/docs/images/chart_data_labels21.png differ
diff --git a/docs/images/chart_labels3.png b/docs/images/chart_data_labels3.png
similarity index 100%
rename from docs/images/chart_labels3.png
rename to docs/images/chart_data_labels3.png
diff --git a/docs/images/chart_labels4.png b/docs/images/chart_data_labels4.png
similarity index 100%
rename from docs/images/chart_labels4.png
rename to docs/images/chart_data_labels4.png
diff --git a/docs/images/chart_labels5.png b/docs/images/chart_data_labels5.png
similarity index 100%
rename from docs/images/chart_labels5.png
rename to docs/images/chart_data_labels5.png
diff --git a/docs/images/chart_labels6.png b/docs/images/chart_data_labels6.png
similarity index 100%
rename from docs/images/chart_labels6.png
rename to docs/images/chart_data_labels6.png
diff --git a/docs/images/chart_labels7.png b/docs/images/chart_data_labels7.png
similarity index 100%
rename from docs/images/chart_labels7.png
rename to docs/images/chart_data_labels7.png
diff --git a/docs/images/chart_labels8.png b/docs/images/chart_data_labels8.png
similarity index 100%
rename from docs/images/chart_labels8.png
rename to docs/images/chart_data_labels8.png
diff --git a/docs/images/chart_labels9.png b/docs/images/chart_data_labels9.png
similarity index 100%
rename from docs/images/chart_labels9.png
rename to docs/images/chart_data_labels9.png
diff --git a/docs/src/examples.dox b/docs/src/examples.dox
index f36ef3ab..5e485cc5 100644
--- a/docs/src/examples.dox
+++ b/docs/src/examples.dox
@@ -859,7 +859,7 @@ Chart 2 is a column chart with default data table with legend keys:
@ref chart_data_table.c "<< chart_data_table.c" |
- @ref chart_fonts.c "chart_fonts.c >>" |
+ @ref chart_data_labels.c "chart_data_labels.c >>" |
@@ -892,11 +892,51 @@ Chart 7: chart with a trendline.
-@example chart_fonts.c
+@example chart_data_labels.c
@ref chart_data_tools.c "<< chart_data_tools.c" |
+ @ref chart_fonts.c "chart_fonts.c >>" |
+
+
+
+A demo of an various Excel chart data label features that are available via a
+libxlsxwriter chart, including custom data labels.
+
+Chart 1: chart with standard data labels.
+@image html chart_data_labels11.png
+
+Chart 2: chart with Category and Value data labels.
+@image html chart_data_labels12.png
+
+Chart 3: chart with data labels with a user defined font.
+@image html chart_data_labels13.png
+
+Chart 4: chart with custom string data labels.
+@image html chart_data_labels14.png
+
+Chart 5: chart with custom data labels referenced from worksheet cells.
+@image html chart_data_labels15.png
+
+Chart 6: chart with a mix of custom and default labels. The items inialised
+with '{0}' and items without a custom label (points 5 and 6 which come after
+NULL) will get the default value. We also set a font for the custom items as
+an extra example.
+@image html chart_data_labels16.png
+
+Chart 7: chart with some deleted custom labels and defaults.
+@image html chart_data_labels17.png
+
+
+
+
+
+@example chart_fonts.c
+
+
+
+ @ref chart_data_labels.c "<< chart_data_labels.c" |
@ref chart_pattern.c "chart_pattern.c >>" |
diff --git a/docs/src/examples.txt b/docs/src/examples.txt
index f19a26b2..e90fe6de 100644
--- a/docs/src/examples.txt
+++ b/docs/src/examples.txt
@@ -457,6 +457,37 @@ Chart 7: chart with a trendline.
@image html chart_data_tools9.png
+##############################################################
+@example chart_data_labels.c
+
+A demo of an various Excel chart data label features that are available via a
+libxlsxwriter chart, including custom data labels.
+
+Chart 1: chart with standard data labels.
+@image html chart_data_labels11.png
+
+Chart 2: chart with Category and Value data labels.
+@image html chart_data_labels12.png
+
+Chart 3: chart with data labels with a user defined font.
+@image html chart_data_labels13.png
+
+Chart 4: chart with custom string data labels.
+@image html chart_data_labels14.png
+
+Chart 5: chart with custom data labels referenced from worksheet cells.
+@image html chart_data_labels15.png
+
+Chart 6: chart with a mix of custom and default labels. The items inialised
+with '{0}' and items without a custom label (points 5 and 6 which come after
+NULL) will get the default value. We also set a font for the custom items as
+an extra example.
+@image html chart_data_labels16.png
+
+Chart 7: chart with some deleted custom labels and defaults.
+@image html chart_data_labels17.png
+
+
##############################################################
@example chart_fonts.c
diff --git a/docs/src/working_with_charts.dox b/docs/src/working_with_charts.dox
index 19d33992..4bd9e7e2 100644
--- a/docs/src/working_with_charts.dox
+++ b/docs/src/working_with_charts.dox
@@ -514,11 +514,11 @@ for a chart series:
chart_series_set_labels(series);
@endcode
-@image html chart_labels1.png
+@image html chart_data_labels1.png
By default data labels are displayed in Excel with only the values shown:
-@image html chart_labels2.png
+@image html chart_data_labels2.png
However, it is possible to configure other display options, as shown
in the functions below.
@@ -531,7 +531,7 @@ parameters that are displayed in the series data label:
chart_series_set_labels_options(series, LXW_TRUE, LXW_TRUE, LXW_TRUE);
@endcode
-@image html chart_labels3.png
+@image html chart_data_labels3.png
The `chart_series_set_labels_separator()` function is used to change the
separator between multiple data label items. The default options is a comma
@@ -552,7 +552,7 @@ For example:
chart_series_set_labels_separator(series, LXW_CHART_LABEL_SEPARATOR_NEWLINE);
@endcode
-@image html chart_labels4.png
+@image html chart_data_labels4.png
The `chart_series_set_labels_position()` function sets the position of
the labels in the data series:
@@ -562,7 +562,7 @@ the labels in the data series:
chart_series_set_labels_position(series, LXW_CHART_LABEL_POSITION_ABOVE);
@endcode
-@image html chart_labels5.png
+@image html chart_data_labels5.png
In Excel the allowable data label positions vary for different chart
types. The allowable, and default, positions are:
@@ -603,7 +603,7 @@ legend key for a data series:
chart_series_set_labels_legend(series);
@endcode
-@image html chart_labels6.png
+@image html chart_data_labels6.png
The `chart_series_set_labels_percentage()` function is used to turn on
the display of data labels as a percentage for a series. It is mainly
@@ -615,7 +615,7 @@ used for pie charts:
chart_series_set_labels_percentage(series);
@endcode
-@image html chart_labels7.png
+@image html chart_data_labels7.png
The `chart_series_set_labels_num_format()` function is used to set the
number format for data labels:
@@ -625,7 +625,7 @@ number format for data labels:
chart_series_set_labels_num_format(series, "$0.00");
@endcode
-@image html chart_labels8.png
+@image html chart_data_labels8.png
The number format is similar to the Worksheet Cell Format num_format,
see `format_set_num_format()`.
@@ -640,10 +640,171 @@ for data labels:
chart_series_set_labels_font(series, &font);
@endcode
-@image html chart_labels9.png
+@image html chart_data_labels9.png
For more information see @ref chart_fonts below.
+@subsection chart_custom_labels Custom Chart Data Labels
+
+The `chart_series_set_labels_custom()` function is used to set the properties
+of individual data labels in a series. The most common use for this is to set
+custom text or number labels:
+
+@code
+ // Add the series data labels.
+ chart_series_set_labels(series);
+
+ // Create some custom labels.
+ lxw_chart_data_label data_label1 = {.value = "Jan"};
+ lxw_chart_data_label data_label2 = {.value = "Feb"};
+ lxw_chart_data_label data_label3 = {.value = "Mar"};
+ lxw_chart_data_label data_label4 = {.value = "Apr"};
+ lxw_chart_data_label data_label5 = {.value = "May"};
+ lxw_chart_data_label data_label6 = {.value = "Jun"};
+
+ // Create an array of label pointers. NULL indicates the end of the array.
+ lxw_chart_data_label *data_labels[] = {
+ &data_label1,
+ &data_label2,
+ &data_label3,
+ &data_label4,
+ &data_label5,
+ &data_label6,
+ NULL
+ };
+
+ // Set the custom labels.
+ chart_series_set_labels_custom(series, data_labels);
+@endcode
+
+@image html chart_data_labels18.png
+
+As shown in the previous example the `chart_series_set_labels_custom()`
+function takes a pointer to an array of #lxw_chart_data_label pointers. The
+list should be `NULL` terminated. Any #lxw_chart_data_label items set to a
+default initialization or omitted from the list will be assigned the default
+data label value:
+
+@code
+ // Add the series data labels.
+ chart_series_set_labels(series);
+
+ // Create some custom labels.
+ lxw_chart_data_label default_label = {0};
+ lxw_chart_data_label data_label2 = {.value = "Feb"};
+ lxw_chart_data_label data_label3 = {.value = "Mar"};
+ lxw_chart_data_label data_label4 = {.value = "Apr"};
+
+
+ // Create an array of label pointers. NULL indicates the end of the array.
+ lxw_chart_data_label *data_labels[] = {
+ &default_label,
+ &data_label2,
+ &data_label3,
+ &data_label4,
+ NULL
+ };
+
+ // Set the custom labels.
+ chart_series_set_labels_custom(series, data_labels);
+@endcode
+
+@image html chart_data_labels19.png
+
+The `value` element in the #lxw_chart_data_label struct should be a string, a
+number as a string, or formula string that refers to a cell from which the
+value will be taken:
+
+@code
+ // Add the series data labels.
+ chart_series_set_labels(series);
+
+ // Create some custom labels.
+ lxw_chart_data_label data_label1 = {.value = "=Sheet1!$C$1"};
+ lxw_chart_data_label data_label2 = {.value = "=Sheet1!$C$2"};
+ lxw_chart_data_label data_label3 = {.value = "=Sheet1!$C$3"};
+ lxw_chart_data_label data_label4 = {.value = "=Sheet1!$C$4"};
+ lxw_chart_data_label data_label5 = {.value = "=Sheet1!$C$5"};
+ lxw_chart_data_label data_label6 = {.value = "=Sheet1!$C$6"};
+
+ // Create an array of label pointers. NULL indicates the end of the array.
+ lxw_chart_data_label *data_labels[] = {
+ &data_label1,
+ &data_label2,
+ &data_label3,
+ &data_label4,
+ &data_label5,
+ &data_label6,
+ NULL
+ };
+
+ // Set the custom labels.
+ chart_series_set_labels_custom(series, data_labels);
+@endcode
+
+The `font` element in the #lxw_chart_data_label struct can be used to set the
+font for the label in the data series (see @ref chart_fonts):
+
+@code
+ lxw_chart_font font = {.color = LXW_COLOR_RED};
+
+ // Add the series data labels.
+ chart_series_set_labels(series);
+
+ // Create some custom labels.
+ lxw_chart_data_label data_label1 = {.value = "=Sheet1!$C$1", .font = &font};
+ lxw_chart_data_label data_label2 = {.value = "=Sheet1!$C$2", .font = &font};
+ lxw_chart_data_label data_label3 = {.value = "=Sheet1!$C$3", .font = &font};
+ lxw_chart_data_label data_label4 = {.value = "=Sheet1!$C$4", .font = &font};
+ lxw_chart_data_label data_label5 = {.value = "=Sheet1!$C$5", .font = &font};
+ lxw_chart_data_label data_label6 = {.value = "=Sheet1!$C$6", .font = &font};
+
+ // Create an array of label pointers. NULL indicates the end of the array.
+ lxw_chart_data_label *data_labels[] = {
+ &data_label1,
+ &data_label2,
+ &data_label3,
+ &data_label4,
+ &data_label5,
+ &data_label6,
+ NULL
+ };
+
+ // Set the custom labels.
+ chart_series_set_labels_custom(series, data_labels);
+@endcode
+
+@image html chart_data_labels20.png
+
+The `delete` element in the #lxw_chart_data_label struct can be used to delete
+labels in a series. This can be useful if you want to highlight one or more
+cells in the series, for example the maximum and the minimum:
+
+@code
+ // Add the series data labels.
+ chart_series_set_labels(series);
+
+ // Create some custom labels.
+ lxw_chart_data_label delete = {.delete = LXW_TRUE};
+ lxw_chart_data_label keep = {.delete = LXW_FALSE};
+
+ // Create an array of label pointers. NULL indicates the end of the array.
+ lxw_chart_data_label *data_labels[] = {
+ &delete,
+ &keep,
+ &delete,
+ &delete,
+ &keep,
+ &delete,
+ NULL
+ };
+
+ // Set the custom labels.
+ chart_series_set_labels_custom(series, data_labels);
+@endcode
+
+@image html chart_data_labels21.png
+
@section chart_formatting Chart Formatting
diff --git a/examples/chart_data_labels.c b/examples/chart_data_labels.c
new file mode 100644
index 00000000..aca40274
--- /dev/null
+++ b/examples/chart_data_labels.c
@@ -0,0 +1,304 @@
+/*
+ * A demo of an various Excel chart data label features that are available via
+ * a libxlsxwriter chart.
+ *
+ * Copyright 2014-2020, John McNamara, jmcnamara@cpan.org
+ *
+ */
+
+#include "xlsxwriter.h"
+
+/*
+ * Create a worksheet with examples charts.
+ */
+int main() {
+
+ lxw_workbook *workbook = workbook_new("chart_data_labels.xlsx");
+ lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
+
+ /* Add a bold format to use to highlight the header cells. */
+ lxw_format *bold = workbook_add_format(workbook);
+ format_set_bold(bold);
+
+ /* Some chart positioning options. */
+ lxw_chart_options options = {.x_offset = 25, .y_offset = 10};
+
+ /* Write some data for the chart. */
+ worksheet_write_string(worksheet, 0, 0, "Number", bold);
+ worksheet_write_number(worksheet, 1, 0, 2, NULL);
+ worksheet_write_number(worksheet, 2, 0, 3, NULL);
+ worksheet_write_number(worksheet, 3, 0, 4, NULL);
+ worksheet_write_number(worksheet, 4, 0, 5, NULL);
+ worksheet_write_number(worksheet, 5, 0, 6, NULL);
+ worksheet_write_number(worksheet, 6, 0, 7, NULL);
+
+ worksheet_write_string(worksheet, 0, 1, "Data", bold);
+ worksheet_write_number(worksheet, 1, 1, 20, NULL);
+ worksheet_write_number(worksheet, 2, 1, 10, NULL);
+ worksheet_write_number(worksheet, 3, 1, 20, NULL);
+ worksheet_write_number(worksheet, 4, 1, 30, NULL);
+ worksheet_write_number(worksheet, 5, 1, 40, NULL);
+ worksheet_write_number(worksheet, 6, 1, 30, NULL);
+
+ worksheet_write_string(worksheet, 0, 2, "Text", bold);
+ worksheet_write_string(worksheet, 1, 2, "Jan", NULL);
+ worksheet_write_string(worksheet, 2, 2, "Feb", NULL);
+ worksheet_write_string(worksheet, 3, 2, "Mar", NULL);
+ worksheet_write_string(worksheet, 4, 2, "Apr", NULL);
+ worksheet_write_string(worksheet, 5, 2, "May", NULL);
+ worksheet_write_string(worksheet, 6, 2, "Jun", NULL);
+
+
+ /*
+ * Chart 1. Example with standard data labels.
+ */
+ lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
+
+ /* Add a chart title. */
+ chart_title_set_name(chart, "Chart with standard data labels");
+
+ /* Add a data series to the chart. */
+ lxw_chart_series *series = chart_add_series(chart, "=Sheet1!$A$2:$A$7",
+ "=Sheet1!$B$2:$B$7");
+
+ /* Add the series data labels. */
+ chart_series_set_labels(series);
+
+ /* Turn off the legend. */
+ chart_legend_set_position(chart, LXW_CHART_LEGEND_NONE);
+
+ /* Insert the chart into the worksheet. */
+ worksheet_insert_chart_opt(worksheet, CELL("D2"), chart, &options);
+
+
+ /*
+ * Chart 2. Example with value and category data labels.
+ */
+ chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
+
+ /* Add a chart title. */
+ chart_title_set_name(chart, "Category and Value data labels");
+
+ /* Add a data series to the chart. */
+ series = chart_add_series(chart, "=Sheet1!$A$2:$A$7",
+ "=Sheet1!$B$2:$B$7");
+
+ /* Add the series data labels. */
+ chart_series_set_labels(series);
+
+ /* Turn on Value and Category labels. */
+ chart_series_set_labels_options(series, LXW_FALSE, LXW_TRUE, LXW_TRUE);
+
+ /* Turn off the legend. */
+ chart_legend_set_position(chart, LXW_CHART_LEGEND_NONE);
+
+ /* Insert the chart into the worksheet. */
+ worksheet_insert_chart_opt(worksheet, CELL("D18"), chart, &options);
+
+
+ /*
+ * Chart 3. Example with standard data labels with different font.
+ */
+ chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
+
+ /* Add a chart title. */
+ chart_title_set_name(chart, "Data labels with user defined font");
+
+ /* Add a data series to the chart. */
+ series = chart_add_series(chart, "=Sheet1!$A$2:$A$7",
+ "=Sheet1!$B$2:$B$7");
+
+ /* Add the series data labels. */
+ chart_series_set_labels(series);
+
+ lxw_chart_font font1 = {.bold = LXW_TRUE, .color = LXW_COLOR_RED, .rotation = -30};
+ chart_series_set_labels_font(series, &font1);
+
+ /* Turn off the legend. */
+ chart_legend_set_position(chart, LXW_CHART_LEGEND_NONE);
+
+ /* Insert the chart into the worksheet. */
+ worksheet_insert_chart_opt(worksheet, CELL("D34"), chart, &options);
+
+
+ /*
+ * Chart 4.Example with custom string data labels.
+ */
+ chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
+
+ /* Add a chart title. */
+ chart_title_set_name(chart, "Chart with custom string data labels");
+
+ /* Add a data series to the chart. */
+ series = chart_add_series(chart, "=Sheet1!$A$2:$A$7",
+ "=Sheet1!$B$2:$B$7");
+
+ /* Add the series data labels. */
+ chart_series_set_labels(series);
+
+ /* Create some custom labels. */
+ lxw_chart_data_label data_label41 = {.value = "Amy"};
+ lxw_chart_data_label data_label42 = {.value = "Bea"};
+ lxw_chart_data_label data_label43 = {.value = "Eva"};
+ lxw_chart_data_label data_label44 = {.value = "Fay"};
+ lxw_chart_data_label data_label45 = {.value = "Liv"};
+ lxw_chart_data_label data_label46 = {.value = "Una"};
+
+ /* Create an array of label pointers. NULL indicates the end of the array. */
+ lxw_chart_data_label *data_labels4[] = {
+ &data_label41,
+ &data_label42,
+ &data_label43,
+ &data_label44,
+ &data_label45,
+ &data_label46,
+ NULL
+ };
+
+ /* Set the custom labels. */
+ chart_series_set_labels_custom(series, data_labels4);
+
+ /* Turn off the legend. */
+ chart_legend_set_position(chart, LXW_CHART_LEGEND_NONE);
+
+ /* Insert the chart into the worksheet. */
+ worksheet_insert_chart_opt(worksheet, CELL("D50"), chart, &options);
+
+
+ /*
+ * Chart 5. Example with custom data labels from cells.
+ */
+ chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
+
+ /* Add a chart title. */
+ chart_title_set_name(chart, "Chart with custom data labels from cells");
+
+ /* Add a data series to the chart. */
+ series = chart_add_series(chart, "=Sheet1!$A$2:$A$7",
+ "=Sheet1!$B$2:$B$7");
+
+ /* Add the series data labels. */
+ chart_series_set_labels(series);
+
+ /* Create some custom labels. */
+ lxw_chart_data_label data_label51 = {.value = "=Sheet1!$C$2"};
+ lxw_chart_data_label data_label52 = {.value = "=Sheet1!$C$3"};
+ lxw_chart_data_label data_label53 = {.value = "=Sheet1!$C$4"};
+ lxw_chart_data_label data_label54 = {.value = "=Sheet1!$C$5"};
+ lxw_chart_data_label data_label55 = {.value = "=Sheet1!$C$6"};
+ lxw_chart_data_label data_label56 = {.value = "=Sheet1!$C$7"};
+
+ /* Create an array of label pointers. NULL indicates the end of the array. */
+ lxw_chart_data_label *data_labels5[] = {
+ &data_label51,
+ &data_label52,
+ &data_label53,
+ &data_label54,
+ &data_label55,
+ &data_label56,
+ NULL
+ };
+
+ /* Set the custom labels. */
+ chart_series_set_labels_custom(series, data_labels5);
+
+ /* Turn off the legend. */
+ chart_legend_set_position(chart, LXW_CHART_LEGEND_NONE);
+
+ /* Insert the chart into the worksheet. */
+ worksheet_insert_chart_opt(worksheet, CELL("D66"), chart, &options);
+
+
+ /*
+ * Chart 6. Example with custom and default data labels.
+ */
+ chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
+
+ /* Add a chart title. */
+ chart_title_set_name(chart, "Mixed custom and default data labels");
+
+ /* Add a data series to the chart. */
+ series = chart_add_series(chart, "=Sheet1!$A$2:$A$7",
+ "=Sheet1!$B$2:$B$7");
+
+ lxw_chart_font font2 = {.color = LXW_COLOR_RED};
+
+ /* Add the series data labels. */
+ chart_series_set_labels(series);
+
+ /* Create some custom labels. */
+
+ /* The following is used to get a mix of default and custom labels. The
+ * items initialized with '{0}' and items without a custom label (points 5
+ * and 6 which come after NULL) will get the default value. We also set a
+ * font for the custom items as an extra example.
+ */
+ lxw_chart_data_label data_label61 = {.value = "=Sheet1!$C$2", .font = &font2};
+ lxw_chart_data_label data_label62 = {0};
+ lxw_chart_data_label data_label63 = {.value = "=Sheet1!$C$4", .font = &font2};
+ lxw_chart_data_label data_label64 = {.value = "=Sheet1!$C$5", .font = &font2};
+
+ /* Create an array of label pointers. NULL indicates the end of the array. */
+ lxw_chart_data_label *data_labels6[] = {
+ &data_label61,
+ &data_label62,
+ &data_label63,
+ &data_label64,
+ NULL
+ };
+
+ /* Set the custom labels. */
+ chart_series_set_labels_custom(series, data_labels6);
+
+ /* Turn off the legend. */
+ chart_legend_set_position(chart, LXW_CHART_LEGEND_NONE);
+
+ /* Insert the chart into the worksheet. */
+ worksheet_insert_chart_opt(worksheet, CELL("D82"), chart, &options);
+
+
+ /*
+ * Chart 7. Example with deleted custom data labels.
+ */
+ chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
+
+ /* Add a chart title. */
+ chart_title_set_name(chart, "Chart with deleted data labels");
+
+ /* Add a data series to the chart. */
+ series = chart_add_series(chart, "=Sheet1!$A$2:$A$7",
+ "=Sheet1!$B$2:$B$7");
+
+ /* Add the series data labels. */
+ chart_series_set_labels(series);
+
+ /* Create some custom labels. */
+ lxw_chart_data_label delete = {.delete = LXW_TRUE};
+ lxw_chart_data_label keep = {.delete = LXW_FALSE};
+
+ /* An initialized struct like this would also work: */
+ /* lxw_chart_data_label keep = {0}; */
+
+ /* Create an array of label pointers. NULL indicates the end of the array. */
+ lxw_chart_data_label *data_labels7[] = {
+ &delete,
+ &keep,
+ &delete,
+ &delete,
+ &keep,
+ &delete,
+ NULL
+ };
+
+ /* Set the custom labels. */
+ chart_series_set_labels_custom(series, data_labels7);
+
+ /* Turn off the legend. */
+ chart_legend_set_position(chart, LXW_CHART_LEGEND_NONE);
+
+ /* Insert the chart into the worksheet. */
+ worksheet_insert_chart_opt(worksheet, CELL("D98"), chart, &options);
+
+
+ return workbook_close(workbook);
+}
diff --git a/include/xlsxwriter/chart.h b/include/xlsxwriter/chart.h
index 67e929dd..e30e55f9 100644
--- a/include/xlsxwriter/chart.h
+++ b/include/xlsxwriter/chart.h
@@ -787,10 +787,23 @@ typedef struct lxw_chart_point {
} lxw_chart_point;
+/**
+ * @brief Struct to represent an Excel chart data label.
+ *
+ * The lxw_chart_data_label struct is used to represent a data label in a
+ * chart series so that custom properties can be set for it.
+ */
typedef struct lxw_chart_data_label {
+ /** The string or formula value for the data label. See
+ * @ref chart_custom_labels. */
char *value;
+
+ /** Option to delete/hide the data label from the chart series.
+ * See @ref chart_custom_labels. */
uint8_t delete;
+
+ /** The font properties for the chart data label. @ref chart_fonts. */
lxw_chart_font *font;
} lxw_chart_data_label;
@@ -1647,11 +1660,11 @@ void chart_series_set_smooth(lxw_chart_series *series, uint8_t smooth);
* chart_series_set_labels(series);
* @endcode
*
- * @image html chart_labels1.png
+ * @image html chart_data_labels1.png
*
* By default data labels are displayed in Excel with only the values shown:
*
- * @image html chart_labels2.png
+ * @image html chart_data_labels2.png
*
* However, it is possible to configure other display options, as shown
* in the functions below.
@@ -1676,7 +1689,7 @@ void chart_series_set_labels(lxw_chart_series *series);
* chart_series_set_labels_options(series, LXW_TRUE, LXW_TRUE, LXW_TRUE);
* @endcode
*
- * @image html chart_labels3.png
+ * @image html chart_data_labels3.png
*
* For more information see @ref chart_labels.
*/
@@ -1684,6 +1697,60 @@ void chart_series_set_labels_options(lxw_chart_series *series,
uint8_t show_name, uint8_t show_category,
uint8_t show_value);
+/** @brief Set the properties for data labels in a series.
+*
+* @param series A series object created via `chart_add_series()`.
+* @param data_labels An NULL terminated array of #lxw_chart_data_label pointers.
+*
+* @return A #lxw_error.
+*
+* The `%chart_series_set_labels_custom()` function is used to set the properties
+* for data labels in a series. It can also be used to delete individual data
+* labels in a series.
+*
+* In general properties are set for all the data labels in a chart
+* series. However, it is also possible to set properties for individual data
+* labels in a series using `%chart_series_set_labels_custom()`.
+*
+* The `%chart_series_set_labels_custom()` function takes a pointer to an array
+* of #lxw_chart_data_label pointers. The list should be `NULL` terminated:
+*
+* @code
+* // Add the series data labels.
+* chart_series_set_labels(series);
+*
+* // Create some custom labels.
+* lxw_chart_data_label data_label1 = {.value = "Jan"};
+* lxw_chart_data_label data_label2 = {.value = "Feb"};
+* lxw_chart_data_label data_label3 = {.value = "Mar"};
+* lxw_chart_data_label data_label4 = {.value = "Apr"};
+* lxw_chart_data_label data_label5 = {.value = "May"};
+* lxw_chart_data_label data_label6 = {.value = "Jun"};
+*
+* // Create an array of label pointers. NULL indicates the end of the array.
+* lxw_chart_data_label *data_labels[] = {
+* &data_label1,
+* &data_label2,
+* &data_label3,
+* &data_label4,
+* &data_label5,
+* &data_label6,
+* NULL
+* };
+*
+* // Set the custom labels.
+* chart_series_set_labels_custom(series, data_labels);
+* @endcode
+*
+* @image html chart_data_labels18.png
+*
+* @note The array of #lxw_chart_point pointers should be NULL terminated as
+* shown in the example. Any #lxw_chart_data_label items set to a default
+* initialization or omitted from the list will be assigned the default data
+* label value.
+*
+* For more details see @ref chart_custom_labels.
+*/
lxw_error chart_series_set_labels_custom(lxw_chart_series *series, lxw_chart_data_label
*data_labels[]);
@@ -1713,7 +1780,7 @@ lxw_error chart_series_set_labels_custom(lxw_chart_series *series, lxw_chart_dat
* chart_series_set_labels_separator(series, LXW_CHART_LABEL_SEPARATOR_NEWLINE);
* @endcode
*
- * @image html chart_labels4.png
+ * @image html chart_data_labels4.png
*
* For more information see @ref chart_labels.
*/
@@ -1734,7 +1801,7 @@ void chart_series_set_labels_separator(lxw_chart_series *series,
* chart_series_set_labels_position(series, LXW_CHART_LABEL_POSITION_ABOVE);
* @endcode
*
- * @image html chart_labels5.png
+ * @image html chart_data_labels5.png
*
* In Excel the allowable data label positions vary for different chart
* types. The allowable, and default, positions are:
@@ -1794,7 +1861,7 @@ void chart_series_set_labels_leader_line(lxw_chart_series *series);
* chart_series_set_labels_legend(series);
* @endcode
*
- * @image html chart_labels6.png
+ * @image html chart_data_labels6.png
*
* For more information see @ref chart_labels.
*/
@@ -1815,7 +1882,7 @@ void chart_series_set_labels_legend(lxw_chart_series *series);
* chart_series_set_labels_percentage(series);
* @endcode
*
- * @image html chart_labels7.png
+ * @image html chart_data_labels7.png
*
* For more information see @ref chart_labels.
*/
@@ -1835,7 +1902,7 @@ void chart_series_set_labels_percentage(lxw_chart_series *series);
* chart_series_set_labels_num_format(series, "$0.00");
* @endcode
*
- * @image html chart_labels8.png
+ * @image html chart_data_labels8.png
*
* The number format is similar to the Worksheet Cell Format num_format,
* see `format_set_num_format()`.
@@ -1862,7 +1929,7 @@ void chart_series_set_labels_num_format(lxw_chart_series *series,
* chart_series_set_labels_font(series, &font);
* @endcode
*
- * @image html chart_labels9.png
+ * @image html chart_data_labels9.png
*
* For more information see @ref chart_fonts and @ref chart_labels.
*