mirror of
https://github.com/jmcnamara/libxlsxwriter
synced 2025-03-28 21:13:14 +00:00
Added handling of blank data in charts.
This commit is contained in:
parent
8f930ac6dc
commit
bcc3945565
1
.indent.pro
vendored
1
.indent.pro
vendored
@ -53,6 +53,7 @@
|
||||
-T lxw_chart_axis_label_position
|
||||
-T lxw_chart_axis_tick_mark
|
||||
-T lxw_chart_axis_tick_position
|
||||
-T lxw_chart_blank
|
||||
-T lxw_chart_fill
|
||||
-T lxw_chart_font
|
||||
-T lxw_chart_gridline
|
||||
|
@ -514,6 +514,21 @@ typedef enum lxw_chart_axis_tick_mark {
|
||||
LXW_CHART_AXIS_TICK_MARK_CROSSING
|
||||
} lxw_chart_tick_mark;
|
||||
|
||||
/**
|
||||
* @brief Define how blank values are displayed in a chart.
|
||||
*/
|
||||
typedef enum lxw_chart_blank {
|
||||
|
||||
/** Show empty chart cells as gaps in the data. The default. */
|
||||
LXW_CHART_BLANKS_AS_GAP,
|
||||
|
||||
/** Show empty chart cells as zeros. */
|
||||
LXW_CHART_BLANKS_AS_ZERO,
|
||||
|
||||
/** Show empty chart cells as connected. Only for charts with lines. */
|
||||
LXW_CHART_BLANKS_AS_CONNECTED
|
||||
} lxw_chart_blank;
|
||||
|
||||
enum lxw_chart_position {
|
||||
LXW_CHART_AXIS_RIGHT,
|
||||
LXW_CHART_AXIS_LEFT,
|
||||
@ -884,6 +899,9 @@ typedef struct lxw_chart {
|
||||
uint8_t has_table_legend_keys;
|
||||
lxw_chart_font *table_font;
|
||||
|
||||
uint8_t show_blanks_as;
|
||||
uint8_t show_hidden_data;
|
||||
|
||||
STAILQ_ENTRY (lxw_chart) ordered_list_pointers;
|
||||
STAILQ_ENTRY (lxw_chart) list_pointers;
|
||||
|
||||
@ -2545,6 +2563,42 @@ void chart_set_series_overlap(lxw_chart *chart, int8_t overlap);
|
||||
*/
|
||||
void chart_set_series_gap(lxw_chart *chart, uint16_t gap);
|
||||
|
||||
/**
|
||||
* @brief Set the option for displaying blank data in a chart.
|
||||
*
|
||||
* @param chart Pointer to a lxw_chart instance to be configured.
|
||||
* @param option The display option. A #lxw_chart_blank option.
|
||||
*
|
||||
* The `%chart_show_blanks_as()` function controls how blank data is displayed
|
||||
* in a chart:
|
||||
*
|
||||
* @code
|
||||
* chart_show_blanks_as(chart, LXW_CHART_BLANKS_AS_CONNECTED);
|
||||
* @endcode
|
||||
*
|
||||
* The `option` parameter can have one of the following values:
|
||||
*
|
||||
* - #LXW_CHART_BLANKS_AS_GAP: Show empty chart cells as gaps in the data.
|
||||
* This is the default option for Excel charts.
|
||||
* - #LXW_CHART_BLANKS_AS_ZERO: Show empty chart cells as zeros.
|
||||
* - #LXW_CHART_BLANKS_AS_CONNECTED: Show empty chart cells as connected.
|
||||
* Only for charts with lines.
|
||||
*/
|
||||
void chart_show_blanks_as(lxw_chart *chart, uint8_t option);
|
||||
|
||||
/**
|
||||
* @brief Display data on charts from hidden rows or columns.
|
||||
*
|
||||
* @param chart Pointer to a lxw_chart instance to be configured.
|
||||
*
|
||||
* Display data that is in hidden rows or columns on the chart:
|
||||
*
|
||||
* @code
|
||||
* chart_show_hidden_data(chart);
|
||||
* @endcode
|
||||
*/
|
||||
void chart_show_hidden_data(lxw_chart *chart);
|
||||
|
||||
/**
|
||||
* @brief Set the Pie/Doughnut chart rotation.
|
||||
*
|
||||
|
49
src/chart.c
49
src/chart.c
@ -2934,6 +2934,9 @@ _chart_write_plot_vis_only(lxw_chart *self)
|
||||
struct xml_attribute_list attributes;
|
||||
struct xml_attribute *attribute;
|
||||
|
||||
if (self->show_hidden_data)
|
||||
return;
|
||||
|
||||
LXW_INIT_ATTRIBUTES();
|
||||
LXW_PUSH_ATTRIBUTES_STR("val", "1");
|
||||
|
||||
@ -3043,6 +3046,31 @@ _chart_write_gap_width(lxw_chart *self, uint16_t gap)
|
||||
LXW_FREE_ATTRIBUTES();
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the <c:dispBlanksAs> element.
|
||||
*/
|
||||
STATIC void
|
||||
_chart_write_disp_blanks_as(lxw_chart *self)
|
||||
{
|
||||
struct xml_attribute_list attributes;
|
||||
struct xml_attribute *attribute;
|
||||
|
||||
if (self->show_blanks_as != LXW_CHART_BLANKS_AS_ZERO
|
||||
&& self->show_blanks_as != LXW_CHART_BLANKS_AS_CONNECTED)
|
||||
return;
|
||||
|
||||
LXW_INIT_ATTRIBUTES();
|
||||
|
||||
if (self->show_blanks_as == LXW_CHART_BLANKS_AS_ZERO)
|
||||
LXW_PUSH_ATTRIBUTES_STR("val", "zero");
|
||||
else
|
||||
LXW_PUSH_ATTRIBUTES_STR("val", "span");
|
||||
|
||||
lxw_xml_empty_tag(self->file, "c:dispBlanksAs", &attributes);
|
||||
|
||||
LXW_FREE_ATTRIBUTES();
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the <c:showHorzBorder> element.
|
||||
*/
|
||||
@ -3841,6 +3869,9 @@ _chart_write_chart(lxw_chart *self)
|
||||
/* Write the c:plotVisOnly element. */
|
||||
_chart_write_plot_vis_only(self);
|
||||
|
||||
/* Write the c:dispBlanksAs element. */
|
||||
_chart_write_disp_blanks_as(self);
|
||||
|
||||
lxw_xml_end_tag(self->file, "c:chart");
|
||||
}
|
||||
|
||||
@ -5129,6 +5160,24 @@ chart_set_series_overlap(lxw_chart *self, int8_t overlap)
|
||||
overlap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the option for displaying blank data in a chart.
|
||||
*/
|
||||
void
|
||||
chart_show_blanks_as(lxw_chart *self, uint8_t option)
|
||||
{
|
||||
self->show_blanks_as = option;
|
||||
}
|
||||
|
||||
/*
|
||||
* Display data on charts from hidden rows or columns.
|
||||
*/
|
||||
void
|
||||
chart_show_hidden_data(lxw_chart *self)
|
||||
{
|
||||
self->show_hidden_data = LXW_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the Bar/Column gap for all data series.
|
||||
*/
|
||||
|
44
test/functional/src/test_chart_blank01.c
Normal file
44
test/functional/src/test_chart_blank01.c
Normal file
@ -0,0 +1,44 @@
|
||||
/*****************************************************************************
|
||||
* Test cases for libxlsxwriter.
|
||||
*
|
||||
* Test to compare output against Excel files.
|
||||
*
|
||||
* Copyright 2014-2017, John McNamara, jmcnamara@cpan.org
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = new_workbook("test_chart_blank01.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
|
||||
|
||||
/* For testing, copy the randomly generated axis ids in the target file. */
|
||||
chart->axis_id_1 = 45705856;
|
||||
chart->axis_id_2 = 45843584;
|
||||
|
||||
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);
|
||||
|
||||
chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
|
||||
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
|
||||
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
|
||||
|
||||
chart_show_blanks_as(chart, LXW_CHART_BLANKS_AS_GAP);
|
||||
|
||||
worksheet_insert_chart(worksheet, CELL("E9"), chart);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
44
test/functional/src/test_chart_blank02.c
Normal file
44
test/functional/src/test_chart_blank02.c
Normal file
@ -0,0 +1,44 @@
|
||||
/*****************************************************************************
|
||||
* Test cases for libxlsxwriter.
|
||||
*
|
||||
* Test to compare output against Excel files.
|
||||
*
|
||||
* Copyright 2014-2017, John McNamara, jmcnamara@cpan.org
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = new_workbook("test_chart_blank02.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
|
||||
|
||||
/* For testing, copy the randomly generated axis ids in the target file. */
|
||||
chart->axis_id_1 = 44253568;
|
||||
chart->axis_id_2 = 44269952;
|
||||
|
||||
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);
|
||||
|
||||
chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
|
||||
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
|
||||
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
|
||||
|
||||
chart_show_blanks_as(chart, LXW_CHART_BLANKS_AS_ZERO);
|
||||
|
||||
worksheet_insert_chart(worksheet, CELL("E9"), chart);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
44
test/functional/src/test_chart_blank03.c
Normal file
44
test/functional/src/test_chart_blank03.c
Normal file
@ -0,0 +1,44 @@
|
||||
/*****************************************************************************
|
||||
* Test cases for libxlsxwriter.
|
||||
*
|
||||
* Test to compare output against Excel files.
|
||||
*
|
||||
* Copyright 2014-2017, John McNamara, jmcnamara@cpan.org
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = new_workbook("test_chart_blank03.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
|
||||
|
||||
/* For testing, copy the randomly generated axis ids in the target file. */
|
||||
chart->axis_id_1 = 44253568;
|
||||
chart->axis_id_2 = 44269952;
|
||||
|
||||
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);
|
||||
|
||||
chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
|
||||
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
|
||||
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
|
||||
|
||||
chart_show_blanks_as(chart, LXW_CHART_BLANKS_AS_CONNECTED);
|
||||
|
||||
worksheet_insert_chart(worksheet, CELL("E9"), chart);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
53
test/functional/src/test_chart_blank04.c
Normal file
53
test/functional/src/test_chart_blank04.c
Normal file
@ -0,0 +1,53 @@
|
||||
/*****************************************************************************
|
||||
* Test cases for libxlsxwriter.
|
||||
*
|
||||
* Test to compare output against Excel files.
|
||||
*
|
||||
* Copyright 2014-2017, John McNamara, jmcnamara@cpan.org
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = new_workbook("test_chart_blank04.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
|
||||
|
||||
/* For testing, copy the randomly generated axis ids in the target file. */
|
||||
chart->axis_id_1 = 42268928;
|
||||
chart->axis_id_2 = 42990208;
|
||||
|
||||
/* Leave some blanks in the default test data. */
|
||||
|
||||
worksheet_write_number(worksheet, 0, 0, 1, NULL);
|
||||
worksheet_write_number(worksheet, 1, 0, 2, NULL);
|
||||
|
||||
worksheet_write_number(worksheet, 3, 0, 4, NULL);
|
||||
worksheet_write_number(worksheet, 4, 0, 5, NULL);
|
||||
|
||||
worksheet_write_number(worksheet, 0, 1, 2, NULL);
|
||||
worksheet_write_number(worksheet, 1, 1, 4, NULL);
|
||||
|
||||
worksheet_write_number(worksheet, 3, 1, 8, NULL);
|
||||
worksheet_write_number(worksheet, 4, 1, 10, NULL);
|
||||
|
||||
worksheet_write_number(worksheet, 0, 2, 3, NULL);
|
||||
worksheet_write_number(worksheet, 1, 2, 6, NULL);
|
||||
|
||||
worksheet_write_number(worksheet, 3, 2, 12, NULL);
|
||||
worksheet_write_number(worksheet, 4, 2, 15, NULL);
|
||||
|
||||
|
||||
|
||||
chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
|
||||
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
|
||||
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
|
||||
|
||||
chart_show_blanks_as(chart, LXW_CHART_BLANKS_AS_CONNECTED);
|
||||
|
||||
worksheet_insert_chart(worksheet, CELL("E9"), chart);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
44
test/functional/src/test_chart_blank06.c
Normal file
44
test/functional/src/test_chart_blank06.c
Normal file
@ -0,0 +1,44 @@
|
||||
/*****************************************************************************
|
||||
* Test cases for libxlsxwriter.
|
||||
*
|
||||
* Test to compare output against Excel files.
|
||||
*
|
||||
* Copyright 2014-2017, John McNamara, jmcnamara@cpan.org
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xlsxwriter.h"
|
||||
|
||||
int main() {
|
||||
|
||||
lxw_workbook *workbook = new_workbook("test_chart_blank06.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
|
||||
|
||||
/* For testing, copy the randomly generated axis ids in the target file. */
|
||||
chart->axis_id_1 = 42270080;
|
||||
chart->axis_id_2 = 42990208;
|
||||
|
||||
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);
|
||||
|
||||
chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");
|
||||
chart_add_series(chart, NULL, "=Sheet1!$B$1:$B$5");
|
||||
chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5");
|
||||
|
||||
chart_show_hidden_data(chart);
|
||||
|
||||
worksheet_insert_chart(worksheet, CELL("E9"), chart);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
33
test/functional/test_chart_blank.py
Normal file
33
test/functional/test_chart_blank.py
Normal file
@ -0,0 +1,33 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Tests for libxlsxwriter.
|
||||
#
|
||||
# Copyright 2014-2017, John McNamara, jmcnamara@cpan.org
|
||||
#
|
||||
|
||||
import base_test_class
|
||||
|
||||
class TestCompareXLSXFiles(base_test_class.XLSXBaseTest):
|
||||
"""
|
||||
Test file created with libxlsxwriter against a file created by Excel.
|
||||
|
||||
"""
|
||||
|
||||
def test_chart_blank01(self):
|
||||
self.run_exe_test('test_chart_blank01')
|
||||
|
||||
def test_chart_blank02(self):
|
||||
self.run_exe_test('test_chart_blank02')
|
||||
|
||||
def test_chart_blank03(self):
|
||||
self.run_exe_test('test_chart_blank03')
|
||||
|
||||
def test_chart_blank04(self):
|
||||
self.run_exe_test('test_chart_blank04')
|
||||
|
||||
# Chartsheet.
|
||||
# def test_chart_blank05(self):
|
||||
# self.run_exe_test('test_chart_blank05')
|
||||
|
||||
def test_chart_blank06(self):
|
||||
self.run_exe_test('test_chart_blank06')
|
BIN
test/functional/xlsx_files/chart_blank01.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_blank01.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_blank02.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_blank02.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_blank03.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_blank03.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_blank04.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_blank04.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_blank06.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_blank06.xlsx
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user