Added support for custom chart data labels.

This commit is contained in:
John McNamara 2020-08-01 01:28:29 +01:00
parent eecb22ace1
commit ca5c2b7cb9
23 changed files with 731 additions and 9 deletions

2
.indent.pro vendored
View file

@ -57,6 +57,8 @@
-T lxw_chart_axis_tick_position
-T lxw_chart_axis_type
-T lxw_chart_blank
-T lxw_chart_custom_label
-T lxw_chart_data_label
-T lxw_chart_error_bar_axis
-T lxw_chart_error_bar_cap
-T lxw_chart_error_bar_direction

View file

@ -787,6 +787,29 @@ typedef struct lxw_chart_point {
} lxw_chart_point;
typedef struct lxw_chart_data_label {
char *value;
uint8_t delete;
lxw_chart_font *font;
} lxw_chart_data_label;
/* Internal version of lxw_chart_data_label with more metadata. */
typedef struct lxw_chart_custom_label {
char *value;
uint8_t delete;
lxw_chart_font *font;
/* We use a range to hold the label formula properties even though it
* will only have 1 point in order to re-use similar functions.*/
lxw_series_range *range;
struct lxw_series_data_point data_point;
} lxw_chart_custom_label;
/**
* @brief Define how blank values are displayed in a chart.
*/
@ -916,7 +939,9 @@ typedef struct lxw_chart_series {
lxw_chart_pattern *pattern;
lxw_chart_marker *marker;
lxw_chart_point *points;
lxw_chart_custom_label *data_labels;
uint16_t point_count;
uint16_t data_label_count;
uint8_t smooth;
uint8_t invert_if_negative;
@ -1659,6 +1684,9 @@ void chart_series_set_labels_options(lxw_chart_series *series,
uint8_t show_name, uint8_t show_category,
uint8_t show_value);
lxw_error chart_series_set_labels_custom(lxw_chart_series *series, lxw_chart_data_label
*data_labels[]);
/**
* @brief Set the separator for the data label captions.
*

View file

@ -82,6 +82,23 @@ _chart_free_font(lxw_chart_font *font)
free(font);
}
STATIC void
_chart_free_data_labels(lxw_chart_series *series)
{
uint16_t index;
for (index = 0; index < series->data_label_count; index++) {
lxw_chart_custom_label *data_label = &series->data_labels[index];
free(data_label->value);
_chart_free_range(data_label->range);
_chart_free_font(data_label->font);
}
series->data_label_count = 0;
free(series->data_labels);
}
/*
* Free a series object.
*/
@ -109,6 +126,7 @@ _chart_series_free(lxw_chart_series *series)
_chart_free_range(series->values);
_chart_free_range(series->title.range);
_chart_free_points(series);
_chart_free_data_labels(series);
if (series->x_error_bars) {
free(series->x_error_bars->line);
@ -1067,12 +1085,14 @@ _chart_write_a_p_pie(lxw_chart *self, lxw_chart_font *font)
* Write the <a:p> element.
*/
STATIC void
_chart_write_a_p_rich(lxw_chart *self, char *name, lxw_chart_font *font)
_chart_write_a_p_rich(lxw_chart *self, char *name, lxw_chart_font *font,
uint8_t is_data_label)
{
lxw_xml_start_tag(self->file, "a:p", NULL);
/* Write the a:pPr element. */
_chart_write_a_p_pr_rich(self, font);
if (!is_data_label)
_chart_write_a_p_pr_rich(self, font);
/* Write the a:r element. */
_chart_write_a_r(self, name, font);
@ -1454,8 +1474,8 @@ _chart_write_axis_font(lxw_chart *self, lxw_chart_font *font)
* Write the <c:rich> element.
*/
STATIC void
_chart_write_rich(lxw_chart *self, char *name, uint8_t is_horizontal,
lxw_chart_font *font)
_chart_write_rich(lxw_chart *self, char *name, lxw_chart_font *font,
uint8_t is_horizontal, uint8_t is_data_label)
{
int32_t rotation = 0;
@ -1471,7 +1491,7 @@ _chart_write_rich(lxw_chart *self, char *name, uint8_t is_horizontal,
_chart_write_a_lst_style(self);
/* Write the a:p element. */
_chart_write_a_p_rich(self, name, font);
_chart_write_a_p_rich(self, name, font, is_data_label);
lxw_xml_end_tag(self->file, "c:rich");
}
@ -1487,7 +1507,7 @@ _chart_write_tx_rich(lxw_chart *self, char *name, uint8_t is_horizontal,
lxw_xml_start_tag(self->file, "c:tx", NULL);
/* Write the c:rich element. */
_chart_write_rich(self, name, is_horizontal, font);
_chart_write_rich(self, name, font, is_horizontal, LXW_FALSE);
lxw_xml_end_tag(self->file, "c:tx");
}
@ -2256,6 +2276,110 @@ _chart_write_label_num_fmt(lxw_chart *self, char *format)
LXW_FREE_ATTRIBUTES();
}
/*
* Write parts of the <c:dLbl> elements for formula custom labels.
*/
STATIC void
_chart_write_custom_label_formula(lxw_chart *self, lxw_chart_series *series,
lxw_chart_custom_label *data_label)
{
lxw_xml_empty_tag(self->file, "c:layout", NULL);
lxw_xml_start_tag(self->file, "c:tx", NULL);
_chart_write_str_ref(self, data_label->range);
lxw_xml_end_tag(self->file, "c:tx");
if (data_label->font) {
lxw_xml_empty_tag(self->file, "c:spPr", NULL);
_chart_write_tx_pr(self, LXW_FALSE, data_label->font);
}
/* Write the c:showVal element. */
if (series->show_labels_value)
_chart_write_show_val(self);
/* Write the c:showCatName element. */
if (series->show_labels_category)
_chart_write_show_cat_name(self);
/* Write the c:showSerName element. */
if (series->show_labels_name)
_chart_write_show_ser_name(self);
}
/*
* Write parts of the <c:dLbl> elements for string custom labels.
*/
STATIC void
_chart_write_custom_label_str(lxw_chart *self, lxw_chart_series *series,
lxw_chart_custom_label *data_label)
{
lxw_xml_empty_tag(self->file, "c:layout", NULL);
lxw_xml_start_tag(self->file, "c:tx", NULL);
/* Write the c:rich element. */
_chart_write_rich(self, data_label->value, data_label->font,
LXW_FALSE, LXW_TRUE);
lxw_xml_end_tag(self->file, "c:tx");
/* Write the c:showVal element. */
if (series->show_labels_value)
_chart_write_show_val(self);
/* Write the c:showCatName element. */
if (series->show_labels_category)
_chart_write_show_cat_name(self);
/* Write the c:showSerName element. */
if (series->show_labels_name)
_chart_write_show_ser_name(self);
}
/*
* Write the <c:dLbl> elements for custom labels.
*/
STATIC void
_chart_write_custom_labels(lxw_chart *self, lxw_chart_series *series)
{
uint16_t index = 0;
for (index = 0; index < series->data_label_count; index++) {
lxw_chart_custom_label *data_label = &series->data_labels[index];
if (!data_label->value && !data_label->range && !data_label->delete
&& !data_label->font) {
continue;
}
lxw_xml_start_tag(self->file, "c:dLbl", NULL);
/* Write the c:idx element. */
_chart_write_idx(self, index);
if (data_label->delete) {
/* Write the c:delete element. */
_chart_write_delete(self);
}
else if (data_label->value) {
_chart_write_custom_label_str(self, series, data_label);
}
else if (data_label->range) {
_chart_write_custom_label_formula(self, series, data_label);
}
else if (data_label->font) {
lxw_xml_empty_tag(self->file, "c:spPr", NULL);
_chart_write_tx_pr(self, LXW_FALSE, data_label->font);
}
lxw_xml_end_tag(self->file, "c:dLbl");
}
}
/*
* Write the <c:dLbls> element.
*/
@ -2267,6 +2391,9 @@ _chart_write_d_lbls(lxw_chart *self, lxw_chart_series *series)
lxw_xml_start_tag(self->file, "c:dLbls", NULL);
if (series->data_labels)
_chart_write_custom_labels(self, series);
/* Write the c:numFmt element. */
if (series->label_num_format)
_chart_write_label_num_fmt(self, series->label_num_format);
@ -3557,7 +3684,7 @@ _chart_write_legend_entry(lxw_chart *self, uint16_t index)
/* Write the c:idx element. */
_chart_write_idx(self, self->delete_series[index]);
/* Write the c:delete element. */
/* Write the c:dst_label element. */
_chart_write_delete(self);
lxw_xml_end_tag(self->file, "c:legendEntry");
@ -4999,7 +5126,7 @@ lxw_chart_add_data_cache(lxw_series_range *range, uint8_t *data,
}
/*
* Insert an image into the worksheet.
* Add a series to the chart.
*/
lxw_chart_series *
chart_add_series(lxw_chart *self, const char *categories, const char *values)
@ -5306,7 +5433,7 @@ chart_series_set_marker_pattern(lxw_chart_series *series,
}
/*
* Store the horizontal page breaks on a worksheet.
* Store the points for a chart.
*/
lxw_error
chart_series_set_points(lxw_chart_series *series, lxw_chart_point *points[])
@ -5375,6 +5502,81 @@ chart_series_set_labels_options(lxw_chart_series *series, uint8_t show_name,
series->show_labels_value = show_value;
}
/*
* Store the custom data_labels for a chart.
*/
lxw_error
chart_series_set_labels_custom(lxw_chart_series *series,
lxw_chart_data_label *data_labels[])
{
uint16_t i = 0;
uint16_t data_label_count = 0;
if (data_labels == NULL)
return LXW_ERROR_NULL_PARAMETER_IGNORED;
while (data_labels[data_label_count])
data_label_count++;
if (data_label_count == 0)
return LXW_ERROR_NULL_PARAMETER_IGNORED;
series->has_labels = LXW_TRUE;
/* Set the Value label type if no other type is set. */
if (!series->show_labels_name && !series->show_labels_category
&& !series->show_labels_value) {
series->show_labels_value = LXW_TRUE;
}
/* Free any existing resource. */
_chart_free_data_labels(series);
series->data_labels = calloc(data_label_count,
sizeof(lxw_chart_custom_label));
RETURN_ON_MEM_ERROR(series->data_labels, LXW_ERROR_MEMORY_MALLOC_FAILED);
/* Copy the user data into the array of new structs. The struct types
* are different since the internal version has more fields. */
for (i = 0; i < data_label_count; i++) {
lxw_chart_data_label *user_data_label = data_labels[i];
lxw_chart_custom_label *data_label = &series->data_labels[i];
char *src_value = user_data_label->value;
data_label->delete = user_data_label->delete;
data_label->font = _chart_convert_font_args(user_data_label->font);
if (src_value) {
if (*src_value == '=') {
/* The value is a formula. Handle like other chart ranges. */
data_label->range = calloc(1, sizeof(lxw_series_range));
GOTO_LABEL_ON_MEM_ERROR(data_label->range, mem_error);
data_label->range->formula = lxw_strdup(src_value + 1);
/* Add the formula to the data cache to allow value to be looked
* up and filled in when the file is closed. */
if (_chart_init_data_cache(data_label->range) != LXW_NO_ERROR)
goto mem_error;
}
else {
/* The value is a simple string. */
data_label->value = lxw_strdup(src_value);
}
}
}
series->data_label_count = data_label_count;
return LXW_NO_ERROR;
mem_error:
_chart_free_data_labels(series);
return LXW_ERROR_MEMORY_MALLOC_FAILED;
}
/*
* Set the data labels separator for a series.
*/

View file

@ -879,6 +879,9 @@ _populate_range_dimensions(lxw_workbook *self, lxw_series_range *range)
STATIC void
_populate_range(lxw_workbook *self, lxw_series_range *range)
{
if (!range)
return;
_populate_range_dimensions(self, range);
_populate_range_data_cache(self, range);
}
@ -892,6 +895,7 @@ _add_chart_cache_data(lxw_workbook *self)
{
lxw_chart *chart;
lxw_chart_series *series;
uint16_t i;
STAILQ_FOREACH(chart, self->ordered_charts, ordered_list_pointers) {
@ -906,6 +910,11 @@ _add_chart_cache_data(lxw_workbook *self)
_populate_range(self, series->categories);
_populate_range(self, series->values);
_populate_range(self, series->title.range);
for (i = 0; i < series->data_label_count; i++) {
lxw_chart_custom_label *data_label = &series->data_labels[i];
_populate_range(self, data_label->range);
}
}
}
}

View file

@ -0,0 +1,48 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = workbook_new("test_chart_data_labels26.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
/* For testing, copy the randomly generated axis ids in the target file. */
chart->axis_id_1 = 48514944;
chart->axis_id_2 = 48516480;
uint8_t data[5][4] = {
{1, 2, 3, 10},
{2, 4, 6, 20},
{3, 6, 9, 30},
{4, 8, 12, 40},
{5, 10, 15, 50}
};
int row, col;
for (row = 0; row < 5; row++)
for (col = 0; col < 4; col++)
worksheet_write_number(worksheet, row, col, data[row][col], NULL);
lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
lxw_chart_data_label data_label1 = {.value = "33"};
lxw_chart_data_label *data_labels[] = {&data_label1, NULL};
chart_series_set_labels_custom(series, data_labels);
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View file

@ -0,0 +1,48 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = workbook_new("test_chart_data_labels27.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
/* For testing, copy the randomly generated axis ids in the target file. */
chart->axis_id_1 = 48514944;
chart->axis_id_2 = 48516480;
uint8_t data[5][4] = {
{1, 2, 3, 10},
{2, 4, 6, 20},
{3, 6, 9, 30},
{4, 8, 12, 40},
{5, 10, 15, 50}
};
int row, col;
for (row = 0; row < 5; row++)
for (col = 0; col < 4; col++)
worksheet_write_number(worksheet, row, col, data[row][col], NULL);
lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
lxw_chart_data_label data_label1 = {.value = "=Sheet1!$D$1"};
lxw_chart_data_label *data_labels[] = {&data_label1, NULL};
chart_series_set_labels_custom(series, data_labels);
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View file

@ -0,0 +1,64 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = workbook_new("test_chart_data_labels28.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
/* For testing, copy the randomly generated axis ids in the target file. */
chart->axis_id_1 = 48514944;
chart->axis_id_2 = 48516480;
uint8_t data[5][3] = {
{1, 2, 3},
{2, 4, 6},
{3, 6, 9},
{4, 8, 12},
{5, 10, 15}
};
int row, col;
for (row = 0; row < 5; row++)
for (col = 0; col < 3; col++)
worksheet_write_number(worksheet, row, col, data[row][col], NULL);
worksheet_write_string(worksheet, CELL("D1"), "foo" , NULL);
worksheet_write_string(worksheet, CELL("D2"), "bar" , NULL);
lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
lxw_chart_data_label data_label1 = {.value = "123"};
lxw_chart_data_label data_label2 = {.value = "abc"};
lxw_chart_data_label data_label3 = {0};
lxw_chart_data_label data_label4 = {.value = "=Sheet1!$D$1"};
lxw_chart_data_label data_label5 = {.value = "=Sheet1!$D$2"};
lxw_chart_data_label *data_labels[] = {
&data_label1,
&data_label2,
&data_label3,
&data_label4,
&data_label5,
NULL
};
chart_series_set_labels_custom(series, data_labels);
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View file

@ -0,0 +1,49 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = workbook_new("test_chart_data_labels29.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
/* For testing, copy the randomly generated axis ids in the target file. */
chart->axis_id_1 = 67858816;
chart->axis_id_2 = 67863296;
uint8_t data[5][3] = {
{1, 2, 3},
{2, 4, 6},
{3, 6, 9},
{4, 8, 12},
{5, 10, 15}
};
int row, col;
for (row = 0; row < 5; row++)
for (col = 0; col < 3; col++)
worksheet_write_number(worksheet, row, col, data[row][col], NULL);
lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
lxw_chart_data_label data_label1 = {.delete = LXW_TRUE};
lxw_chart_data_label *data_labels[] = {&data_label1, NULL};
chart_series_set_labels_custom(series, data_labels);
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View file

@ -0,0 +1,49 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = workbook_new("test_chart_data_labels30.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
/* For testing, copy the randomly generated axis ids in the target file. */
chart->axis_id_1 = 67858816;
chart->axis_id_2 = 67863296;
uint8_t data[5][3] = {
{1, 2, 3},
{2, 4, 6},
{3, 6, 9},
{4, 8, 12},
{5, 10, 15}
};
int row, col;
for (row = 0; row < 5; row++)
for (col = 0; col < 3; col++)
worksheet_write_number(worksheet, row, col, data[row][col], NULL);
lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
lxw_chart_data_label data_label1 = {.delete = LXW_TRUE};
lxw_chart_data_label data_label2 = {0};
lxw_chart_data_label *data_labels[] = {&data_label1, &data_label2, &data_label1, &data_label2, &data_label1, NULL};
chart_series_set_labels_custom(series, data_labels);
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View file

@ -0,0 +1,49 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = workbook_new("test_chart_data_labels31.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
/* For testing, copy the randomly generated axis ids in the target file. */
chart->axis_id_1 = 71248896;
chart->axis_id_2 = 71373568;
uint8_t data[5][4] = {
{1, 2, 3, 10},
{2, 4, 6, 20},
{3, 6, 9, 30},
{4, 8, 12, 40},
{5, 10, 15, 50}
};
int row, col;
for (row = 0; row < 5; row++)
for (col = 0; col < 4; col++)
worksheet_write_number(worksheet, row, col, data[row][col], NULL);
lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
lxw_chart_data_label data_label1 = {.value = "33"};
lxw_chart_data_label *data_labels[] = {&data_label1, NULL};
chart_series_set_labels_custom(series, data_labels);
chart_series_set_labels_options(series, LXW_TRUE, LXW_TRUE, LXW_TRUE);
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View file

@ -0,0 +1,49 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = workbook_new("test_chart_data_labels32.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
/* For testing, copy the randomly generated axis ids in the target file. */
chart->axis_id_1 = 71374336;
chart->axis_id_2 = 71414144;
uint8_t data[5][4] = {
{1, 2, 3, 10},
{2, 4, 6, 20},
{3, 6, 9, 30},
{4, 8, 12, 40},
{5, 10, 15, 50}
};
int row, col;
for (row = 0; row < 5; row++)
for (col = 0; col < 4; col++)
worksheet_write_number(worksheet, row, col, data[row][col], NULL);
lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
lxw_chart_font font1 = {.bold = LXW_TRUE, .italic = LXW_TRUE, .color = LXW_COLOR_RED, .baseline = -1};
lxw_chart_data_label data_label1 = {.value = "33", .font = &font1};
lxw_chart_data_label *data_labels[] = {&data_label1, NULL};
chart_series_set_labels_custom(series, data_labels);
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View file

@ -0,0 +1,49 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = workbook_new("test_chart_data_labels33.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
/* For testing, copy the randomly generated axis ids in the target file. */
chart->axis_id_1 = 65546112;
chart->axis_id_2 = 70217728;
uint8_t data[5][4] = {
{1, 2, 3, 10},
{2, 4, 6, 20},
{3, 6, 9, 30},
{4, 8, 12, 40},
{5, 10, 15, 50}
};
int row, col;
for (row = 0; row < 5; row++)
for (col = 0; col < 4; col++)
worksheet_write_number(worksheet, row, col, data[row][col], NULL);
lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
lxw_chart_font font1 = {.bold = LXW_TRUE, .italic = LXW_TRUE, .baseline = -1};
lxw_chart_data_label data_label1 = {.font = &font1};
lxw_chart_data_label *data_labels[] = {&data_label1, NULL};
chart_series_set_labels_custom(series, data_labels);
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View file

@ -0,0 +1,49 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2020, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = workbook_new("test_chart_data_labels34.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN);
/* For testing, copy the randomly generated axis ids in the target file. */
chart->axis_id_1 = 48497792;
chart->axis_id_2 = 48499712;
uint8_t data[5][4] = {
{1, 2, 3, 10},
{2, 4, 6, 20},
{3, 6, 9, 30},
{4, 8, 12, 40},
{5, 10, 15, 50}
};
int row, col;
for (row = 0; row < 5; row++)
for (col = 0; col < 4; col++)
worksheet_write_number(worksheet, row, col, data[row][col], NULL);
lxw_chart_series *series = chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
lxw_chart_font font1 = {.bold = LXW_TRUE, .italic = LXW_TRUE, .color = LXW_COLOR_RED, .baseline = -1};
lxw_chart_data_label data_label1 = {. value = "=Sheet1!$D$1", .font = &font1};
lxw_chart_data_label *data_labels[] = {&data_label1, NULL};
chart_series_set_labels_custom(series, data_labels);
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View file

@ -86,3 +86,30 @@ class TestCompareXLSXFiles(base_test_class.XLSXBaseTest):
def test_chart_data_labels25(self):
self.run_exe_test('test_chart_data_labels25')
def test_chart_data_labels26(self):
self.run_exe_test('test_chart_data_labels26')
def test_chart_data_labels27(self):
self.run_exe_test('test_chart_data_labels27')
def test_chart_data_labels28(self):
self.run_exe_test('test_chart_data_labels28')
def test_chart_data_labels29(self):
self.run_exe_test('test_chart_data_labels29')
def test_chart_data_labels30(self):
self.run_exe_test('test_chart_data_labels30')
def test_chart_data_labels31(self):
self.run_exe_test('test_chart_data_labels31')
def test_chart_data_labels32(self):
self.run_exe_test('test_chart_data_labels32')
def test_chart_data_labels33(self):
self.run_exe_test('test_chart_data_labels33')
def test_chart_data_labels34(self):
self.run_exe_test('test_chart_data_labels34')

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.