mirror of
https://github.com/jmcnamara/libxlsxwriter.git
synced 2026-05-21 06:45:21 -06:00
Added support for custom chart data labels.
This commit is contained in:
parent
eecb22ace1
commit
ca5c2b7cb9
23 changed files with 731 additions and 9 deletions
2
.indent.pro
vendored
2
.indent.pro
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
220
src/chart.c
220
src/chart.c
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
48
test/functional/src/test_chart_data_labels26.c
Normal file
48
test/functional/src/test_chart_data_labels26.c
Normal 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);
|
||||
}
|
||||
48
test/functional/src/test_chart_data_labels27.c
Normal file
48
test/functional/src/test_chart_data_labels27.c
Normal 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);
|
||||
}
|
||||
64
test/functional/src/test_chart_data_labels28.c
Normal file
64
test/functional/src/test_chart_data_labels28.c
Normal 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);
|
||||
}
|
||||
49
test/functional/src/test_chart_data_labels29.c
Normal file
49
test/functional/src/test_chart_data_labels29.c
Normal 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);
|
||||
}
|
||||
49
test/functional/src/test_chart_data_labels30.c
Normal file
49
test/functional/src/test_chart_data_labels30.c
Normal 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);
|
||||
}
|
||||
49
test/functional/src/test_chart_data_labels31.c
Normal file
49
test/functional/src/test_chart_data_labels31.c
Normal 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);
|
||||
}
|
||||
49
test/functional/src/test_chart_data_labels32.c
Normal file
49
test/functional/src/test_chart_data_labels32.c
Normal 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);
|
||||
}
|
||||
49
test/functional/src/test_chart_data_labels33.c
Normal file
49
test/functional/src/test_chart_data_labels33.c
Normal 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);
|
||||
}
|
||||
49
test/functional/src/test_chart_data_labels34.c
Normal file
49
test/functional/src/test_chart_data_labels34.c
Normal 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);
|
||||
}
|
||||
|
|
@ -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')
|
||||
|
|
|
|||
BIN
test/functional/xlsx_files/chart_data_labels26.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_data_labels26.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_data_labels27.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_data_labels27.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_data_labels28.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_data_labels28.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_data_labels29.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_data_labels29.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_data_labels30.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_data_labels30.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_data_labels31.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_data_labels31.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_data_labels32.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_data_labels32.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_data_labels33.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_data_labels33.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_data_labels34.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_data_labels34.xlsx
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue