Added 'min' crossing option to chart axes.

Add option to set a chart crossing to 'min' as well as the existing
'max' option. The 'min' option isn't available in the Excel interface
but can be enabled via VBA.
This commit is contained in:
John McNamara 2021-03-26 17:01:00 +00:00
parent eefa0200ca
commit 83550882c6
7 changed files with 135 additions and 5 deletions

View File

@ -1072,6 +1072,7 @@ typedef struct lxw_chart_axis {
uint8_t display_units_visible;
uint8_t has_crossing;
uint8_t crossing_min;
uint8_t crossing_max;
double crossing;
@ -2700,6 +2701,26 @@ void chart_axis_set_crossing(lxw_chart_axis *axis, double value);
*/
void chart_axis_set_crossing_max(lxw_chart_axis *axis);
/**
* @brief Set the opposite axis crossing position as the axis minimum.
*
* @param axis A pointer to a chart #lxw_chart_axis object.
*
* Set the position that the opposite axis will cross as the axis minimum.
* The default axis crossing position is generally the axis minimum so this
* function can be used to reverse the location of the axes without reversing
* the number sequence:
*
* @code
* chart_axis_set_crossing_min(chart->x_axis);
* chart_axis_set_crossing_min(chart->y_axis);
* @endcode
*
* **Axis types**: This function is applicable to to all axes types.
* See @ref ww_charts_axes.
*/
void chart_axis_set_crossing_min(lxw_chart_axis *axis);
/**
* @brief Turn off/hide an axis.
*

View File

@ -3318,7 +3318,9 @@ _chart_write_crosses(lxw_chart *self, lxw_chart_axis *axis)
LXW_INIT_ATTRIBUTES();
if (axis->crossing_max)
if (axis->crossing_min)
LXW_PUSH_ATTRIBUTES_STR("val", "min");
else if (axis->crossing_max)
LXW_PUSH_ATTRIBUTES_STR("val", "max");
else
LXW_PUSH_ATTRIBUTES_STR("val", "autoZero");
@ -4261,7 +4263,8 @@ _chart_write_cat_axis(lxw_chart *self)
_chart_write_cross_axis(self, self->axis_id_2);
/* Write the c:crosses element. */
if (!self->y_axis->has_crossing || self->y_axis->crossing_max)
if (!self->y_axis->has_crossing || self->y_axis->crossing_min
|| self->y_axis->crossing_max)
_chart_write_crosses(self, self->y_axis);
else
_chart_write_crosses_at(self, self->y_axis);
@ -4342,7 +4345,8 @@ _chart_write_val_axis(lxw_chart *self)
_chart_write_cross_axis(self, self->axis_id_1);
/* Write the c:crosses element. */
if (!self->x_axis->has_crossing || self->x_axis->crossing_max)
if (!self->x_axis->has_crossing || self->x_axis->crossing_min
|| self->x_axis->crossing_max)
_chart_write_crosses(self, self->x_axis);
else
_chart_write_crosses_at(self, self->x_axis);
@ -4420,7 +4424,8 @@ _chart_write_cat_val_axis(lxw_chart *self)
_chart_write_cross_axis(self, self->axis_id_2);
/* Write the c:crosses element. */
if (!self->y_axis->has_crossing || self->y_axis->crossing_max)
if (!self->y_axis->has_crossing || self->y_axis->crossing_min
|| self->y_axis->crossing_max)
_chart_write_crosses(self, self->y_axis);
else
_chart_write_crosses_at(self, self->y_axis);
@ -6139,7 +6144,17 @@ chart_axis_set_crossing(lxw_chart_axis *axis, double value)
}
/*
* Set the axis crossing position as the max possible value.
* Set the axis crossing position as the minimum possible value.
*/
void
chart_axis_set_crossing_min(lxw_chart_axis *axis)
{
axis->has_crossing = LXW_TRUE;
axis->crossing_min = LXW_TRUE;
}
/*
* Set the axis crossing position as the maximum possible value.
*/
void
chart_axis_set_crossing_max(lxw_chart_axis *axis)

View File

@ -0,0 +1,44 @@
/*****************************************************************************
* 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_crossing05.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 = 55948032;
chart->axis_id_2 = 55950336;
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_axis_set_crossing_min(chart->x_axis);
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View File

@ -0,0 +1,44 @@
/*****************************************************************************
* 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_crossing06.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 = 72794880;
chart->axis_id_2 = 72796416;
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_axis_set_crossing_min(chart->y_axis);
worksheet_insert_chart(worksheet, CELL("E9"), chart);
return workbook_close(workbook);
}

View File

@ -24,3 +24,9 @@ class TestCompareXLSXFiles(base_test_class.XLSXBaseTest):
def test_chart_crossing04(self):
self.run_exe_test('test_chart_crossing04')
def test_chart_crossing05(self):
self.run_exe_test('test_chart_crossing05')
def test_chart_crossing06(self):
self.run_exe_test('test_chart_crossing06')

Binary file not shown.

Binary file not shown.