Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/api/enum/XlChartType.rst
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,24 @@ XY_SCATTER_SMOOTH

XY_SCATTER_SMOOTH_NO_MARKERS
Scatter with Smoothed Lines and No Data Markers.

WATERFALL
Waterfall (ChartEx). Office 2016+. Write + round-trip supported.

TREEMAP
Treemap (ChartEx). Office 2016+. Round-trip preservation only.

SUNBURST
Sunburst (ChartEx). Office 2016+. Round-trip preservation only.

FUNNEL
Funnel (ChartEx). Office 2016+. Round-trip preservation only.

BOX_WHISKER
Box & Whisker (ChartEx). Office 2016+. Round-trip preservation only.

HISTOGRAM
Histogram (ChartEx). Office 2016+. Round-trip preservation only.

PARETO
Pareto (ChartEx). Office 2016+. Round-trip preservation only.
48 changes: 48 additions & 0 deletions docs/user/charts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,54 @@ presentation with |pp|. There are more details in the API documentation for
charts here: :ref:`chart-api`


ChartEx — modern Office 2016 charts (waterfall, treemap, sunburst, ...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Office 2016 introduced a new chart family — Waterfall, Treemap, Sunburst,
Funnel, Box & Whisker, Histogram, and Pareto — that lives in a separate XML
namespace (``cx:``, the *chart extensions* or "chartEx" part) rather than the
classic ``c:`` chart tree. |pp| supports this family with two distinct
capability levels:

================== ============================ =========================
Capability Chart types What you can do
================== ============================ =========================
**Write** ``WATERFALL`` Author a brand-new chart
**Round-trip** ``WATERFALL``, ``TREEMAP``, Open a deck that already
only ``SUNBURST``, ``FUNNEL``, contains the chart, edit
``BOX_WHISKER``, unrelated slides, and
``HISTOGRAM``, ``PARETO`` save without corrupting
the chartEx part
================== ============================ =========================

Authoring a waterfall chart uses the dedicated
:class:`~pptx.chart.data.WaterfallChartData` container::

from pptx.chart.data import WaterfallChartData
from pptx.enum.chart import XL_CHART_TYPE

chart_data = WaterfallChartData()
chart_data.categories = ['Q1', 'Q2', 'Q3', 'Q4', 'Total']
chart_data.add_series('Revenue', (100, 50, -30, 80, 200), subtotals=[4])

graphic_frame = slide.shapes.add_chart(
XL_CHART_TYPE.WATERFALL, x, y, cx, cy, chart_data
)

The returned |GraphicFrame| reports ``graphic_frame.has_chartex == True`` and
its :attr:`~pptx.shapes.graphfrm.GraphicFrame.chartex` property returns a
ChartEx proxy. (Classic charts continue to use ``.has_chart`` / ``.chart``.)

The remaining ``cx:`` types currently have **round-trip preservation only** —
``add_chart`` raises ``NotImplementedError`` for them, but a deck authored in
PowerPoint that already contains a treemap, sunburst, etc. will read, modify,
and save without damaging the existing chart. Writer support for those types
is tracked as a follow-up to issue #14.

The full set of ``cx:`` enum members is documented under
:ref:`XlChartType`.


About colors
~~~~~~~~~~~~

Expand Down
47 changes: 47 additions & 0 deletions features/cht-chartex-roundtrip.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Feature: ChartEx round-trip behavior
In order to preserve modern chart parts in saved presentations
As a developer using python-pptx
I need ChartEx content and classic-chart content to round-trip correctly


Scenario Outline: A waterfall ChartEx part survives save and reopen
Given a blank slide
And ChartEx waterfall data case q4-total
When I add the ChartEx waterfall via <add-path>
And I round-trip the presentation for ChartEx inspection
Then the active ChartEx frame exposes ChartEx but not a classic chart
And the active ChartEx part content type is the ChartEx content type
And the active ChartEx partname contains chartEx
And the active ChartEx series values are 100.0, 50.0, -30.0, 80.0, 200.0

Examples: round-trip entry points
| add-path |
| add_chart |
| add_chartex |


Scenario: Classic and ChartEx chart frames coexist on one slide across round-trip
Given a blank slide
And ChartEx waterfall data case regional-rollup
When I add a classic chart beside a ChartEx waterfall
Then the slide has one classic chart frame and one ChartEx frame
And the classic chart frame still exposes only a classic chart
And the ChartEx frame still exposes only a ChartEx chart
When I round-trip the presentation for ChartEx inspection
Then the slide has one classic chart frame and one ChartEx frame
And the classic chart frame still exposes only a classic chart
And the ChartEx frame still exposes only a ChartEx chart
And the active ChartEx series values are 30.0, -10.0, 25.0, 15.0, 60.0


Scenario: A blank presentation exposes no ChartEx frames
Given a blank slide
Then the slide has no ChartEx graphic frames


Scenario: A blank presentation saves without any ChartEx package parts
Given a blank slide
When I round-trip the presentation for ChartEx inspection
Then the slide has no ChartEx graphic frames
And the saved package contains no ChartEx partnames
And the saved package contains no ChartEx content type declaration
34 changes: 34 additions & 0 deletions features/cht-chartex-types.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Feature: ChartEx chart type members
In order to use the ChartEx chart type enumeration safely
As a developer using python-pptx
I need deferred members to fail explicitly and modern members to exist in a private range


Scenario Outline: Writer-deferred ChartEx types fail through add_chart
Given a blank slide
And ChartEx waterfall data case q4-total
When I attempt to add deferred ChartEx type <member-name>
Then adding deferred ChartEx type <member-name> raises NotImplementedError

Examples: writer-deferred ChartEx members
| member-name |
| TREEMAP |
| SUNBURST |
| FUNNEL |
| BOX_WHISKER |
| HISTOGRAM |
| PARETO |


Scenario Outline: ChartEx enum members exist in the private high range
Then XL_CHART_TYPE.<member-name> exists with value <value>

Examples: ChartEx enum members
| member-name | value |
| WATERFALL | 1001 |
| TREEMAP | 1002 |
| SUNBURST | 1003 |
| FUNNEL | 1004 |
| BOX_WHISKER | 1005 |
| HISTOGRAM | 1006 |
| PARETO | 1007 |
54 changes: 54 additions & 0 deletions features/cht-chartex-waterfall.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Feature: ChartEx waterfall charts
In order to add Office 2016 waterfall charts to a slide
As a developer using python-pptx
I need the ChartEx writer path to create modern chart graphic frames


Scenario Outline: Add a waterfall chart through either public entry point
Given a blank slide
And ChartEx waterfall data case q4-total
When I add the ChartEx waterfall via <add-path>
Then the active ChartEx frame exposes ChartEx but not a classic chart
And the active ChartEx chart type is waterfall
And the active ChartEx series is named Revenue
And the active ChartEx series values are 100.0, 50.0, -30.0, 80.0, 200.0

Examples: public waterfall entry points
| add-path |
| add_chart |
| add_chartex |


Scenario Outline: Waterfall category labels are preserved on creation
Given a blank slide
And ChartEx waterfall data case <data-case>
When I add the ChartEx waterfall via <add-path>
Then the active ChartEx category labels are <category-labels>

Examples: category label sets
| data-case | add-path | category-labels |
| q4-total | add_chart | Q1, Q2, Q3, Q4, Total |
| q4-total | add_chartex | Q1, Q2, Q3, Q4, Total |
| cash-bridge | add_chart | Start, Sales, Returns, Ops, Tax, End |
| cash-bridge | add_chartex | Start, Sales, Returns, Ops, Tax, End |
| regional-rollup | add_chart | East, West, Midwest, Online, Total |
| regional-rollup | add_chartex | East, West, Midwest, Online, Total |


Scenario Outline: Waterfall subtotal markers survive round-trip
Given a blank slide
And ChartEx waterfall data case <data-case>
When I add the ChartEx waterfall via <add-path>
And I round-trip the presentation for ChartEx inspection
Then the active ChartEx frame exposes ChartEx but not a classic chart
And the active ChartEx subtotal indices are <subtotal-indices>
And the active ChartEx category labels are <category-labels>

Examples: subtotal preservation cases
| data-case | add-path | subtotal-indices | category-labels |
| q4-total | add_chart | 4 | Q1, Q2, Q3, Q4, Total |
| q4-total | add_chartex | 4 | Q1, Q2, Q3, Q4, Total |
| cash-bridge | add_chart | 0, 5 | Start, Sales, Returns, Ops, Tax, End |
| cash-bridge | add_chartex | 0, 5 | Start, Sales, Returns, Ops, Tax, End |
| regional-rollup | add_chart | 4 | East, West, Midwest, Online, Total |
| regional-rollup | add_chartex | 4 | East, West, Midwest, Online, Total |
Loading
Loading