diff --git a/docs/images/chart_axis_set_fill.png b/docs/images/chart_axis_set_fill.png new file mode 100644 index 00000000..f57906cc Binary files /dev/null and b/docs/images/chart_axis_set_fill.png differ diff --git a/docs/images/chart_axis_set_line.png b/docs/images/chart_axis_set_line.png new file mode 100644 index 00000000..ce5ebd9a Binary files /dev/null and b/docs/images/chart_axis_set_line.png differ diff --git a/docs/images/chart_fill1.png b/docs/images/chart_fill1.png new file mode 100644 index 00000000..9007c435 Binary files /dev/null and b/docs/images/chart_fill1.png differ diff --git a/docs/images/chart_fill2.png b/docs/images/chart_fill2.png new file mode 100644 index 00000000..357c5f34 Binary files /dev/null and b/docs/images/chart_fill2.png differ diff --git a/docs/images/chart_fill3.png b/docs/images/chart_fill3.png new file mode 100644 index 00000000..e7d629c4 Binary files /dev/null and b/docs/images/chart_fill3.png differ diff --git a/docs/images/chart_fill4.png b/docs/images/chart_fill4.png new file mode 100644 index 00000000..b24e293f Binary files /dev/null and b/docs/images/chart_fill4.png differ diff --git a/docs/images/chart_fonts.png b/docs/images/chart_fonts.png index b9e1bef4..cdae281f 100644 Binary files a/docs/images/chart_fonts.png and b/docs/images/chart_fonts.png differ diff --git a/docs/images/chart_formatting4.png b/docs/images/chart_formatting4.png new file mode 100644 index 00000000..c45d6781 Binary files /dev/null and b/docs/images/chart_formatting4.png differ diff --git a/docs/images/chart_formatting5.png b/docs/images/chart_formatting5.png new file mode 100644 index 00000000..000645b5 Binary files /dev/null and b/docs/images/chart_formatting5.png differ diff --git a/docs/images/chart_formatting_multiple.png b/docs/images/chart_formatting_multiple.png new file mode 100644 index 00000000..44d66db7 Binary files /dev/null and b/docs/images/chart_formatting_multiple.png differ diff --git a/docs/images/chart_formatting_width.png b/docs/images/chart_formatting_width.png new file mode 100644 index 00000000..e350be4f Binary files /dev/null and b/docs/images/chart_formatting_width.png differ diff --git a/docs/images/chart_series_set_fill.png b/docs/images/chart_series_set_fill.png new file mode 100644 index 00000000..c39ec7fd Binary files /dev/null and b/docs/images/chart_series_set_fill.png differ diff --git a/docs/images/chart_series_set_line.png b/docs/images/chart_series_set_line.png new file mode 100644 index 00000000..5dd7e12d Binary files /dev/null and b/docs/images/chart_series_set_line.png differ diff --git a/docs/src/working_with_charts.dox b/docs/src/working_with_charts.dox index 6071a998..97be78e6 100644 --- a/docs/src/working_with_charts.dox +++ b/docs/src/working_with_charts.dox @@ -6,6 +6,15 @@ This section explains how to work with some of the options and features of @ref chart.h "The Chart object". +The majority of the examples in this section are based on a variation of the following program: + +@dontinclude chart_working_with_example.c +@skip main +@until } + +@image html chart_working.png + + @section ww_charts_axes Chart Value and Category Axes @@ -20,12 +29,24 @@ are displayed according to their value. Excel treats these two types of axis differently and exposes different properties for each. -As such some of the `libxlsxwriter` axis properties can be set for a value +As such, some of the `libxlsxwriter` axis properties can be set for a value axis, some can be set for a category axis and some properties can be set for both. The documentation calls out the type of axis to which functions apply. -@section chart_fonts Working with Chart Fonts +@section chart_formatting Chart Formatting + +The following chart formatting properties can be set for any chart object that +they apply to (and that are supported by libxlsxwriter) such as chart lines, +column fill areas and other chart elements: + +- Font +- Line/Border +- Fill + +These properties are explained in the subsections below. + +@subsection chart_fonts Chart formatting: Fonts Font properties can be set for several chart objects such as chart titles, axis labels, and axis numbering. @@ -86,14 +107,15 @@ deg: This is useful for displaying axis data such as dates in a more compact format. -__color__: Set the font color property. Can be a color index, a color name or -HTML style RGB color, See @ref working_with_colors : +__color__: Set the font color property. It can be a HTML style RGB color or a +limited number of named colors (see @ref working_with_colors for more +information): @code lxw_chart_font font = {.color = LXW_COLOR_BLUE}; @endcode -Here is a longer example of several chart formats: +Here is a longer example with several chart formats: @dontinclude chart_fonts.c @@ -103,16 +125,172 @@ Here is a longer example of several chart formats: @image html chart_fonts.png +@subsection chart_lines Chart formatting: Line + +The line format is used to specify properties of line objects that appear in a +chart such as a plotted line on a chart or a border. + +A chart line #lxw_chart_line struct with default properties is: + +@code + lxw_chart_line line = {.none = LXW_FALSE, + .color = LXW_COLOR_BLACK, + .width = 2.25, + .dash_type = LXW_CHART_LINE_DASH_SOLID}; +@endcode + +The `none` member is uses to turn the line off (it is always on by default +except in Scatter charts). This is useful if you wish to plot a series with +markers (not supported yet) but without a line or a column fill without a +border. + +The `color` member sets the color of the line. It can be a HTML style RGB +color or a limited number of named colors (see @ref working_with_colors for +more information): + +@code + lxw_chart_line line = {.color = 0xFF9900}; + + chart_series_set_line(series, &line); +@endcode + +@image html chart_formatting4.png + + +The `width` member sets the width of the line. It should be specified in +increments of 0.25 of a point as in Excel: + +@code + lxw_chart_line line = {.width = 4.25}; + + chart_series_set_line(series, &line); +@endcode + +@image html chart_formatting_width.png + + +The `dash_type` member sets the dash style of the line: + +@code + lxw_chart_line line = {.dash_type = LXW_CHART_LINE_DASH_DASH_DOT}; + + chart_series_set_line(series, &line); +@endcode + +@image html chart_formatting5.png + +The following #lxw_chart_line_dash_type values are available. They are shown +in the order that they appear in the Excel dialog: + + Define | Excel name + ------------------------------------- | ------------------ + LXW_CHART_LINE_DASH_SOLID | Solid + LXW_CHART_LINE_DASH_ROUND_DOT | Round Dot + LXW_CHART_LINE_DASH_SQUARE_DOT | Square Dot + LXW_CHART_LINE_DASH_DASH | Dash + LXW_CHART_LINE_DASH_DASH_DOT | Dash Dot + LXW_CHART_LINE_DASH_LONG_DASH | Long Dash + LXW_CHART_LINE_DASH_LONG_DASH_DOT | Long Dash Dot + LXW_CHART_LINE_DASH_LONG_DASH_DOT_DOT | Long Dash Dot Dot + +The default line style is `#LXW_CHART_LINE_DASH_SOLID`. + +More than one line property can be specified at a time: + +@code + lxw_chart_line line = {.color = LXW_COLOR_RED, + .width = 1.25, + .dash_type = LXW_CHART_LINE_DASH_SQUARE_DOT}; +@endcode + +@image html chart_formatting_multiple.png + + +@subsection chart_borders Chart formatting: Border + +In Excel chart formatting the `border` property is a synonym for `line` when +the object being formatting also has a `fill` property. + +Anywhere you see `border` in an Excel chart dialog you can use the equivalent +libxlsxwriter `line` function. + + +@subsection chart_fills Chart formatting: Fill + +The fill format is used to specify properties of chart objects that internal +boundaries such as a column chart. + + +A chart fill #lxw_chart_fill struct with default properties is: + +@code + lxw_chart_fill fill = {.none = LXW_FALSE, + .color = LXW_COLOR_BLACK, + .transparency = 0}; +@endcode + + +The none property is used to turn the fill property off (it is generally on by +default): + +@code + lxw_chart_line line = {.color = LXW_COLOR_BLACK}; + lxw_chart_fill fill = {.none = LXW_TRUE}; + + chart_series_set_line(series, &line); + chart_series_set_fill(series, &fill); +@endcode + +@image html chart_fill1.png + +The `color` member sets the color of the fill area. It can be a HTML style RGB +color or a limited number of named colors, (see @ref working_with_colors for +more information): + +@code + lxw_chart_fill fill = {.color = 0xFF9900}; + + chart_series_set_fill(series, &fill); +@endcode + +@image html chart_fill2.png + +The `transparency` member sets the transparency of the solid fill color in the +integer range 1 - 100: + +@code + lxw_chart_fill fill = {.color = LXW_COLOR_YELLOW, + .transparency = 50}; + + chart_series_set_fill(series, &fill); +@endcode + +@image html chart_fill3.png + +The `fill` format is generally used in conjunction with a border which can be +set via the `line` format: + +@code + lxw_chart_line line = {.color = LXW_COLOR_BLACK}; + lxw_chart_fill fill = {.color = LXW_COLOR_RED}; + + chart_series_set_line(series, &line); + chart_series_set_fill(series, &fill); +@endcode + +@image html chart_fill4.png + + @section ww_charts_limitations Chart Limitations The following chart features aren't currently supported in libxlsxwriter but -will be in time: +will be in time. See the [GitHub Chart Feature Request][1]. + +[1]: https://github.com/jmcnamara/libxlsxwriter/issues/51 -- Chart formatting (in progress). - Chart markers. - Secondary axis. - Combined charts. -- Chart legend formatting. - Chart area and plot area formatting. - Chart tables. - Up down lines. diff --git a/docs/src/working_with_colors.dox b/docs/src/working_with_colors.dox index 657bd47b..c1c8f0b8 100644 --- a/docs/src/working_with_colors.dox +++ b/docs/src/working_with_colors.dox @@ -18,8 +18,8 @@ The color names and corresponding RRGGBB value are shown below: Color | Define | Value - -------- | --------------------- | --------- - Black | #LXW_COLOR_BLACK | `0x000000` + -------- | --------------------- | ------------------ + Black | #LXW_COLOR_BLACK | `0x1000000` (note) Blue | #LXW_COLOR_BLUE | `0x0000FF` Brown | #LXW_COLOR_BROWN | `0x800000` Cyan | #LXW_COLOR_CYAN | `0x00FFFF` @@ -37,6 +37,10 @@ The color names and corresponding RRGGBB value are shown below: Yellow | #LXW_COLOR_YELLOW | `0xFFFF00` +@note Black in Html is actually `0x000000` but `#LXW_COLOR_BLACK` is defined +as 0x1000000 to avoid confusion with an undefined or Zero color value. It is +converted to the correct Html code internally. + Next: @ref working_with_dates */ diff --git a/examples/chart_fonts.c b/examples/chart_fonts.c index aa5e76d7..475e6514 100644 --- a/examples/chart_fonts.c +++ b/examples/chart_fonts.c @@ -8,23 +8,6 @@ #include "xlsxwriter.h" -/* Write some data to the worksheet. */ -void write_worksheet_data(lxw_worksheet *worksheet) { - - uint8_t data[5][3] = { - /* Three columns of data. */ - {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); -} /* Create a worksheet with a chart. */ int main() { @@ -33,17 +16,18 @@ int main() { lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); /* Write some data for the chart. */ - write_worksheet_data(worksheet); + worksheet_write_number(worksheet, 0, 0, 10, NULL); + worksheet_write_number(worksheet, 1, 0, 40, NULL); + worksheet_write_number(worksheet, 2, 0, 50, NULL); + worksheet_write_number(worksheet, 3, 0, 20, NULL); + worksheet_write_number(worksheet, 4, 0, 10, NULL); + worksheet_write_number(worksheet, 5, 0, 50, NULL); /* Create a chart object. */ - lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_COLUMN); + lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE); - /* Configure the chart. In simplest case we just add some value data - * series. The NULL categories will default to 1 to 5 like in Excel. - */ - 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"); + /* Configure the chart. */ + chart_add_series(chart, NULL, "Sheet1!$A$1:$A$6"); /* Create some fonts to use in the chart. */ lxw_chart_font font1 = {.name = "Calibri", .color = LXW_COLOR_BLUE}; @@ -70,13 +54,12 @@ int main() { chart_axis_set_name_font(chart->x_axis, &font4); chart_axis_set_num_font(chart->x_axis, &font5); - /* Display the chart legend at the bottom of the chart. */ chart_legend_set_position(chart, LXW_CHART_LEGEND_BOTTOM); chart_legend_set_font(chart, &font6); /* Insert the chart into the worksheet. */ - worksheet_insert_chart(worksheet, CELL("E9"), chart); + worksheet_insert_chart(worksheet, CELL("C1"), chart); return workbook_close(workbook); } diff --git a/examples/chart_working_with_example.c b/examples/chart_working_with_example.c new file mode 100644 index 00000000..3f5e7827 --- /dev/null +++ b/examples/chart_working_with_example.c @@ -0,0 +1,38 @@ +/* + * An example of a simple Excel chart using the libxlsxwriter library. This + * example is used in the "Working with Charts" section of the docs. + * + * Copyright 2014-2017, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + + +/* Create a worksheet with a chart. */ +int main() { + + lxw_workbook *workbook = new_workbook("chart_line.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + lxw_chart *chart; + lxw_chart_series *series; + + /* Write some data for the chart. */ + worksheet_write_number(worksheet, 0, 0, 10, NULL); + worksheet_write_number(worksheet, 1, 0, 40, NULL); + worksheet_write_number(worksheet, 2, 0, 50, NULL); + worksheet_write_number(worksheet, 3, 0, 20, NULL); + worksheet_write_number(worksheet, 4, 0, 10, NULL); + worksheet_write_number(worksheet, 5, 0, 50, NULL); + + /* Create a chart object. */ + chart = workbook_add_chart(workbook, LXW_CHART_LINE); + + /* Configure the chart. */ + series = chart_add_series(chart, NULL, "Sheet1!$A$1:$A$6"); + + /* Insert the chart into the worksheet. */ + worksheet_insert_chart(worksheet, CELL("C1"), chart); + + return workbook_close(workbook); +} diff --git a/include/xlsxwriter/chart.h b/include/xlsxwriter/chart.h index 275473e3..165a1410 100644 --- a/include/xlsxwriter/chart.h +++ b/include/xlsxwriter/chart.h @@ -174,19 +174,42 @@ typedef enum lxw_chart_legend_position { LXW_CHART_LEGEND_OVERLAY_LEFT } lxw_chart_legend_position; -/** Chart line dash types. */ +/** @brief Chart line dash types. + * + * The dash types are shown in the order that they appear in the Excel dialog. + * See @ref chart_lines. + */ typedef enum lxw_chart_line_dash_type { + + /** Solid. */ LXW_CHART_LINE_DASH_SOLID = 0, + + /** Round Dot. */ LXW_CHART_LINE_DASH_ROUND_DOT, + + /** Square Dot. */ LXW_CHART_LINE_DASH_SQUARE_DOT, + + /** Dash. */ LXW_CHART_LINE_DASH_DASH, + + /** Dash Dot. */ LXW_CHART_LINE_DASH_DASH_DOT, + + /** Long Dash. */ LXW_CHART_LINE_DASH_LONG_DASH, + + /** Long Dash Dot. */ LXW_CHART_LINE_DASH_LONG_DASH_DOT, + + /** Long Dash Dot Dot. */ LXW_CHART_LINE_DASH_LONG_DASH_DOT_DOT, + + /* These aren't available in the dialog but are used by Excel. */ LXW_CHART_LINE_DASH_DOT, LXW_CHART_LINE_DASH_SYSTEM_DASH_DOT, LXW_CHART_LINE_DASH_SYSTEM_DASH_DOT_DOT + } lxw_chart_liLINE_ne_dash_type; enum lxw_chart_subtype { @@ -240,22 +263,50 @@ typedef struct lxw_series_data_point { } lxw_series_data_point; +/** + * @brief Struct to represent a chart line. + * + * See @ref chart_lines. + */ typedef struct lxw_chart_line { + /** The chart font color. See @ref working_with_colors. */ lxw_color_t color; + + /** Turn off/hide line. Set to 0 or 1.*/ uint8_t none; + + /** Width of the line in increments of 0.25. Default is 2.25. */ float width; + + /** The line dash type. See #lxw_chart_line_dash_type. */ uint8_t dash_type; + + /* Transparency for lines isn't generally useful. Undocumented for now. */ uint8_t transparency; + + /* Members for internal use only. */ uint8_t has_color; } lxw_chart_line; +/** + * @brief Struct to represent a chart line. + * + * See @ref chart_fills. + */ typedef struct lxw_chart_fill { + /** The chart font color. See @ref working_with_colors. */ lxw_color_t color; + + /** Turn off/hide line. Set to 0 or 1.*/ uint8_t none; + + /** Set the transparency of the fill. 0 - 100. Default 0. */ uint8_t transparency; + + /* Members for internal use only. */ uint8_t has_color; } lxw_chart_fill; @@ -288,6 +339,7 @@ typedef struct lxw_chart_font { /** The chart font color. See @ref working_with_colors. */ lxw_color_t color; + /* Members for internal use only. */ uint8_t pitch_family; uint8_t charset; int8_t baseline; @@ -635,9 +687,50 @@ void chart_series_set_name(lxw_chart_series *series, const char *name); void chart_series_set_name_range(lxw_chart_series *series, const char *sheetname, lxw_row_t row, lxw_col_t col); - +/** + * @brief Set the line properties for a chart series. + * + * @param series A series object created via `chart_add_series()`. + * @param line A #lxw_chart_line struct. + * + * Set the line/border properties of a chart series: + * + * @code + * lxw_chart_line line = {.color = LXW_COLOR_RED}; + * + * chart_series_set_line(series1, &line); + * chart_series_set_line(series2, &line); + * chart_series_set_line(series3, &line); + * @endcode + * + * @image html chart_series_set_line.png + * + * For more information see @ref chart_lines. + */ void chart_series_set_line(lxw_chart_series *series, lxw_chart_line *line); +/** + * @brief Set the fill properties for a chart series. + * + * @param series A series object created via `chart_add_series()`. + * @param fill A #lxw_chart_fill struct. + * + * Set the fill properties of a chart series: + * + * @code + * lxw_chart_fill fill1 = {.color = LXW_COLOR_RED}; + * lxw_chart_fill fill2 = {.color = LXW_COLOR_YELLOW}; + * lxw_chart_fill fill3 = {.color = LXW_COLOR_GREEN}; + * + * chart_series_set_fill(series1, &fill1); + * chart_series_set_fill(series2, &fill2); + * chart_series_set_fill(series3, &fill3); + * @endcode + * + * @image html chart_series_set_fill.png + * + * For more information see @ref chart_fills. + */ void chart_series_set_fill(lxw_chart_series *series, lxw_chart_fill *fill); /** @@ -692,10 +785,10 @@ void chart_axis_set_name_range(lxw_chart_axis *axis, const char *sheetname, lxw_row_t row, lxw_col_t col); /** - * @brief Set the font properties for a chart axis name. + * @brief Set the font properties for a chart axis name. * - * @param axis A pointer to a chart #lxw_chart_axis object. - * @param font A pointer to a chart #lxw_chart_font font struct. + * @param axis A pointer to a chart #lxw_chart_axis object. + * @param font A pointer to a chart #lxw_chart_font font struct. * * The `%chart_axis_set_name_font()` function is used to set the font of an * axis name: @@ -714,10 +807,10 @@ void chart_axis_set_name_range(lxw_chart_axis *axis, const char *sheetname, void chart_axis_set_name_font(lxw_chart_axis *axis, lxw_chart_font *font); /** - * @brief Set the font properties for the numbers of a chart axis. + * @brief Set the font properties for the numbers of a chart axis. * - * @param axis A pointer to a chart #lxw_chart_axis object. - * @param font A pointer to a chart #lxw_chart_font font struct. + * @param axis A pointer to a chart #lxw_chart_axis object. + * @param font A pointer to a chart #lxw_chart_font font struct. * * The `%chart_axis_set_num_font()` function is used to set the font of the * numbers on an axis: @@ -734,8 +827,45 @@ void chart_axis_set_name_font(lxw_chart_axis *axis, lxw_chart_font *font); */ void chart_axis_set_num_font(lxw_chart_axis *axis, lxw_chart_font *font); +/** + * @brief Set the line properties for a chart axis. + * + * @param axis A pointer to a chart #lxw_chart_axis object. + * @param line A #lxw_chart_line struct. + * + * Set the line properties of a chart axis: + * + * @code + * // Hide the Y axis. + * lxw_chart_line line = {.none = LXW_TRUE}; + * + * chart_axis_set_line(chart->y_axis, &line); + * @endcode + * + * @image html chart_axis_set_line.png + * + * For more information see @ref chart_lines. + */ void chart_axis_set_line(lxw_chart_axis *axis, lxw_chart_line *line); +/** + * @brief Set the fill properties for a chart axis. + * + * @param axis A pointer to a chart #lxw_chart_axis object. + * @param fill A #lxw_chart_fill struct. + * + * Set the fill properties of a chart axis: + * + * @code + * lxw_chart_fill fill = {.color = LXW_COLOR_YELLOW}; + * + * chart_axis_set_fill(chart->y_axis, &fill); + * @endcode + * + * @image html chart_axis_set_fill.png + * + * For more information see @ref chart_fills. + */ void chart_axis_set_fill(lxw_chart_axis *axis, lxw_chart_fill *fill); /** diff --git a/include/xlsxwriter/format.h b/include/xlsxwriter/format.h index 993cab03..41e07fbc 100644 --- a/include/xlsxwriter/format.h +++ b/include/xlsxwriter/format.h @@ -166,7 +166,7 @@ enum lxw_format_diagonal_types { /** Predefined values for common colors. */ enum lxw_defined_colors { /** Black */ - LXW_COLOR_BLACK = 0x000000, + LXW_COLOR_BLACK = 0x1000000, /** Blue */ LXW_COLOR_BLUE = 0x0000FF, diff --git a/test/functional/src/test_chart_axis35.c b/test/functional/src/test_chart_axis35.c index 7f585ef1..f914a75d 100644 --- a/test/functional/src/test_chart_axis35.c +++ b/test/functional/src/test_chart_axis35.c @@ -37,6 +37,7 @@ int main() { chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5"); lxw_chart_line line = {.none = LXW_TRUE}; + chart_axis_set_line(chart->y_axis, &line); worksheet_insert_chart(worksheet, CELL("E9"), chart); diff --git a/test/functional/src/test_chart_axis36.c b/test/functional/src/test_chart_axis36.c index a0c393d0..6444c4d0 100644 --- a/test/functional/src/test_chart_axis36.c +++ b/test/functional/src/test_chart_axis36.c @@ -37,8 +37,8 @@ int main() { chart_add_series(chart, NULL, "=Sheet1!$C$1:$C$5"); lxw_chart_line line = {.none = LXW_TRUE}; - chart_axis_set_line(chart->x_axis, &line); + chart_axis_set_line(chart->x_axis, &line); worksheet_insert_chart(worksheet, CELL("E9"), chart); diff --git a/test/functional/src/test_chart_format01.c b/test/functional/src/test_chart_format01.c index 35bb6272..7149086d 100644 --- a/test/functional/src/test_chart_format01.c +++ b/test/functional/src/test_chart_format01.c @@ -32,12 +32,12 @@ int main() { for (col = 0; col < 3; col++) worksheet_write_number(worksheet, row, col, data[row][col], NULL); - chart_add_series(chart, + chart_add_series(chart, "=Sheet1!$A$1:$A$5", "=Sheet1!$B$1:$B$5" ); - chart_add_series(chart, + chart_add_series(chart, "=Sheet1!$A$1:$A$5", "=Sheet1!$C$1:$C$5" );