mirror of
https://github.com/jmcnamara/libxlsxwriter.git
synced 2026-05-15 14:15:54 -06:00
Add chart major and minor units.
This commit is contained in:
parent
8ded7269c7
commit
0edc678e85
9 changed files with 238 additions and 10 deletions
BIN
docs/images/chart_set_major_units.png
Normal file
BIN
docs/images/chart_set_major_units.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
|
|
@ -689,10 +689,17 @@ typedef struct lxw_chart_axis {
|
|||
uint8_t label_position;
|
||||
uint8_t hidden;
|
||||
uint8_t reverse;
|
||||
|
||||
uint8_t has_min;
|
||||
uint8_t has_max;
|
||||
double min;
|
||||
uint8_t has_max;
|
||||
double max;
|
||||
|
||||
uint8_t has_major_unit;
|
||||
double major_unit;
|
||||
uint8_t has_minor_unit;
|
||||
double minor_unit;
|
||||
|
||||
uint16_t log_base;
|
||||
|
||||
} lxw_chart_axis;
|
||||
|
|
@ -1522,6 +1529,48 @@ void chart_axis_set_max(lxw_chart_axis *axis, double max);
|
|||
*/
|
||||
void chart_axis_set_log_base(lxw_chart_axis *axis, uint16_t log_base);
|
||||
|
||||
/**
|
||||
* @brief Set the increment of the major units in the axis.
|
||||
*
|
||||
* @param axis A pointer to a chart #lxw_chart_axis object.
|
||||
* @param unit The increment of the major units.
|
||||
*
|
||||
* Set the increment of the major units in the axis range.
|
||||
*
|
||||
* @code
|
||||
* // Turn on the minor gridline (it is off by default).
|
||||
* chart_axis_minor_gridlines_set_visible(chart->y_axis, LXW_TRUE);
|
||||
*
|
||||
* chart_axis_set_major_unit(chart->y_axis, 4);
|
||||
* chart_axis_set_minor_unit(chart->y_axis, 2);
|
||||
* @endcode
|
||||
*
|
||||
* @image html chart_set_major_units.png
|
||||
*
|
||||
* **Axis types**: This function is applicable to value and date axes only.
|
||||
* See @ref ww_charts_axes.
|
||||
*/
|
||||
void chart_axis_set_major_unit(lxw_chart_axis *axis, double unit);
|
||||
|
||||
/**
|
||||
* @brief Set the increment of the minor units in the axis.
|
||||
*
|
||||
* @param axis A pointer to a chart #lxw_chart_axis object.
|
||||
* @param unit The increment of the minor units.
|
||||
*
|
||||
* Set the increment of the minor units in the axis range.
|
||||
*
|
||||
* @code
|
||||
* chart_axis_set_minor_unit(chart->y_axis, 2);
|
||||
* @endcode
|
||||
*
|
||||
* See the image above
|
||||
*
|
||||
* **Axis types**: This function is applicable to value and date axes only.
|
||||
* See @ref ww_charts_axes.
|
||||
*/
|
||||
void chart_axis_set_minor_unit(lxw_chart_axis *axis, double unit);
|
||||
|
||||
/**
|
||||
* @brief Turn on/off the major gridlines for an axis.
|
||||
*
|
||||
|
|
|
|||
92
src/chart.c
92
src/chart.c
|
|
@ -2320,32 +2320,70 @@ _chart_write_auto(lxw_chart *self)
|
|||
* Write the <c:lblAlgn> element.
|
||||
*/
|
||||
STATIC void
|
||||
_chart_write_lbl_algn(lxw_chart *self)
|
||||
_chart_write_label_align(lxw_chart *self)
|
||||
{
|
||||
struct xml_attribute_list attributes;
|
||||
struct xml_attribute *attribute;
|
||||
char val[] = "ctr";
|
||||
|
||||
LXW_INIT_ATTRIBUTES();
|
||||
LXW_PUSH_ATTRIBUTES_STR("val", val);
|
||||
LXW_PUSH_ATTRIBUTES_STR("val", "ctr");
|
||||
|
||||
lxw_xml_empty_tag(self->file, "c:lblAlgn", &attributes);
|
||||
|
||||
LXW_FREE_ATTRIBUTES();
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the <c:majorUnit> element.
|
||||
*/
|
||||
STATIC void
|
||||
_chart_write_major_unit(lxw_chart *self, lxw_chart_axis *axis)
|
||||
{
|
||||
struct xml_attribute_list attributes;
|
||||
struct xml_attribute *attribute;
|
||||
|
||||
if (!axis->has_major_unit)
|
||||
return;
|
||||
|
||||
LXW_INIT_ATTRIBUTES();
|
||||
LXW_PUSH_ATTRIBUTES_DBL("val", axis->major_unit);
|
||||
|
||||
lxw_xml_empty_tag(self->file, "c:majorUnit", &attributes);
|
||||
|
||||
LXW_FREE_ATTRIBUTES();
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the <c:minorUnit> element.
|
||||
*/
|
||||
STATIC void
|
||||
_chart_write_minor_unit(lxw_chart *self, lxw_chart_axis *axis)
|
||||
{
|
||||
struct xml_attribute_list attributes;
|
||||
struct xml_attribute *attribute;
|
||||
|
||||
if (!axis->has_minor_unit)
|
||||
return;
|
||||
|
||||
LXW_INIT_ATTRIBUTES();
|
||||
LXW_PUSH_ATTRIBUTES_DBL("val", axis->minor_unit);
|
||||
|
||||
lxw_xml_empty_tag(self->file, "c:minorUnit", &attributes);
|
||||
|
||||
LXW_FREE_ATTRIBUTES();
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the <c:lblOffset> element.
|
||||
*/
|
||||
STATIC void
|
||||
_chart_write_lbl_offset(lxw_chart *self)
|
||||
_chart_write_label_offset(lxw_chart *self)
|
||||
{
|
||||
struct xml_attribute_list attributes;
|
||||
struct xml_attribute *attribute;
|
||||
char val[] = "100";
|
||||
|
||||
LXW_INIT_ATTRIBUTES();
|
||||
LXW_PUSH_ATTRIBUTES_STR("val", val);
|
||||
LXW_PUSH_ATTRIBUTES_STR("val", "100");
|
||||
|
||||
lxw_xml_empty_tag(self->file, "c:lblOffset", &attributes);
|
||||
|
||||
|
|
@ -2753,10 +2791,10 @@ _chart_write_cat_axis(lxw_chart *self)
|
|||
_chart_write_auto(self);
|
||||
|
||||
/* Write the c:lblAlgn element. */
|
||||
_chart_write_lbl_algn(self);
|
||||
_chart_write_label_align(self);
|
||||
|
||||
/* Write the c:lblOffset element. */
|
||||
_chart_write_lbl_offset(self);
|
||||
_chart_write_label_offset(self);
|
||||
|
||||
lxw_xml_end_tag(self->file, "c:catAx");
|
||||
}
|
||||
|
|
@ -2822,6 +2860,12 @@ _chart_write_val_axis(lxw_chart *self)
|
|||
/* Write the c:crossBetween element. */
|
||||
_chart_write_cross_between(self, self->x_axis->position_axis);
|
||||
|
||||
/* Write the c:majorUnit element. */
|
||||
_chart_write_major_unit(self, self->y_axis);
|
||||
|
||||
/* Write the c:minorUnit element. */
|
||||
_chart_write_minor_unit(self, self->y_axis);
|
||||
|
||||
lxw_xml_end_tag(self->file, "c:valAx");
|
||||
}
|
||||
|
||||
|
|
@ -2886,6 +2930,12 @@ _chart_write_cat_val_axis(lxw_chart *self)
|
|||
/* Write the c:crossBetween element. */
|
||||
_chart_write_cross_between(self, self->y_axis->position_axis);
|
||||
|
||||
/* Write the c:majorUnit element. */
|
||||
_chart_write_major_unit(self, self->x_axis);
|
||||
|
||||
/* Write the c:minorUnit element. */
|
||||
_chart_write_minor_unit(self, self->x_axis);
|
||||
|
||||
lxw_xml_end_tag(self->file, "c:valAx");
|
||||
}
|
||||
|
||||
|
|
@ -3543,7 +3593,7 @@ lxw_chart_add_data_cache(lxw_series_range *range, uint8_t *data,
|
|||
/* Initialize the series range data cache. */
|
||||
for (i = 0; i < rows; i++) {
|
||||
data_point = calloc(1, sizeof(struct lxw_series_data_point));
|
||||
RETURN_ON_MEM_ERROR(data_point, LXW_ERROR_MEMORY_MALLOC_FAILED);
|
||||
RETURN_ON_MEM_ERROR(data_point, LXW_ERROR_MEMORY_MALLOC_FAILED);
|
||||
STAILQ_INSERT_TAIL(range->data_cache, data_point, list_pointers);
|
||||
data_point->number = data[i * cols + col];
|
||||
}
|
||||
|
|
@ -3998,6 +4048,30 @@ chart_axis_set_log_base(lxw_chart_axis *axis, uint16_t log_base)
|
|||
axis->log_base = log_base;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set major unit for a value axis.
|
||||
*/
|
||||
void
|
||||
chart_axis_set_major_unit(lxw_chart_axis *axis, double unit)
|
||||
{
|
||||
LXW_WARN_VALUE_AND_DATE_AXIS_ONLY("chart_axis_set_major_unit");
|
||||
|
||||
axis->has_major_unit = LXW_TRUE;
|
||||
axis->major_unit = unit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set minor unit for a value axis.
|
||||
*/
|
||||
void
|
||||
chart_axis_set_minor_unit(lxw_chart_axis *axis, double unit)
|
||||
{
|
||||
LXW_WARN_VALUE_AND_DATE_AXIS_ONLY("chart_axis_set_minor_unit");
|
||||
|
||||
axis->has_minor_unit = LXW_TRUE;
|
||||
axis->minor_unit = unit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the axis major gridlines on/off.
|
||||
*/
|
||||
|
|
|
|||
45
test/functional/src/test_chart_axis15.c
Normal file
45
test/functional/src/test_chart_axis15.c
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*****************************************************************************
|
||||
* 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_axis15.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 = 45705856;
|
||||
chart->axis_id_2 = 54518528;
|
||||
|
||||
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_major_unit(chart->y_axis, 2);
|
||||
chart_axis_set_minor_unit(chart->y_axis, 0.4);
|
||||
|
||||
worksheet_insert_chart(worksheet, CELL("E9"), chart);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
||||
55
test/functional/src/test_chart_scatter06.c
Normal file
55
test/functional/src/test_chart_scatter06.c
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*****************************************************************************
|
||||
* 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_scatter06.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_SCATTER);
|
||||
|
||||
/* For testing, copy the randomly generated axis ids in the target file. */
|
||||
chart->axis_id_1 = 57708544;
|
||||
chart->axis_id_2 = 44297600;
|
||||
|
||||
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,
|
||||
"=Sheet1!$A$1:$A$5",
|
||||
"=Sheet1!$B$1:$B$5"
|
||||
);
|
||||
|
||||
chart_add_series(chart,
|
||||
"=Sheet1!$A$1:$A$5",
|
||||
"=Sheet1!$C$1:$C$5"
|
||||
);
|
||||
|
||||
chart_axis_set_major_unit(chart->x_axis, 3);
|
||||
chart_axis_set_minor_unit(chart->x_axis, 1);
|
||||
|
||||
chart_axis_set_major_unit(chart->y_axis, 4);
|
||||
chart_axis_set_minor_unit(chart->y_axis, 2);
|
||||
|
||||
|
||||
worksheet_insert_chart(worksheet, CELL("E9"), chart);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
||||
|
|
@ -53,6 +53,9 @@ class TestCompareXLSXFiles(base_test_class.XLSXBaseTest):
|
|||
# def test_chart_axis14(self):
|
||||
# self.run_exe_test('test_chart_axis14')
|
||||
|
||||
def test_chart_axis15(self):
|
||||
self.run_exe_test('test_chart_axis15')
|
||||
|
||||
def test_chart_axis17(self):
|
||||
self.run_exe_test('test_chart_axis17')
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ class TestCompareXLSXFiles(base_test_class.XLSXBaseTest):
|
|||
def test_chart_scatter05(self):
|
||||
self.run_exe_test('test_chart_scatter05')
|
||||
|
||||
def test_chart_scatter06(self):
|
||||
self.run_exe_test('test_chart_scatter06')
|
||||
|
||||
def test_chart_scatter12(self):
|
||||
self.run_exe_test('test_chart_scatter12')
|
||||
|
|
|
|||
BIN
test/functional/xlsx_files/chart_axis15.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_axis15.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/chart_scatter06.xlsx
Normal file
BIN
test/functional/xlsx_files/chart_scatter06.xlsx
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue