scanny / python-pptx

Create Open XML PowerPoint documents in Python
MIT License
2.4k stars 520 forks source link

feature: series lines #846

Open iodbh opened 2 years ago

iodbh commented 2 years ago

Screenshot 2022-09-09 at 09 03 39

Powerpoint supports "series lines" in bar chart as depicted above, while the current python-pptx API does not.

I have been able to add these lines using the following:

from pptx.oxml import parse_xml
from pptx.oxml.ns import nsdecls
from pptx.oxml import register_element_cls
from .series_lines import CT_serLines

from pptx.oxml.xmlchemy import (
    BaseOxmlElement,
    ZeroOrOne,
)

class CT_serLines(BaseOxmlElement):
    """`c:serLines` element specifying series lines"""

    spPr = ZeroOrOne("c:spPr")

    @classmethod
    def new_serLines(cls):
        """Return a newly created "loose" `c:serLines` element."""
        return parse_xml("<c:serLines %s><c:spPr /></c:serLines>" % nsdecls("c"))

register_element_cls("c:serLines", CT_serLines)

and using the following to inject the new element into bar plot:

from pptx.chart.plot import _BasePlot, BarPlot
from pptx.dml.chtfmt import ChartFormat

def add_series_lines(plot: "BarPlot", color: Optional[str] = None):
    chart_xml_element = plot._element

    series_line_element = CT_serLines.new_serLines()

    # used to avoid patching CT_BarChart
    successors = ("c:axId", "c:extLst")

    inserted_element = chart_xml_element.insert_element_before(
        series_line_element,
        *successors,
    )

    fmt = ChartFormat(inserted_element)    
    # omitting code for _set_fill_color, not relevant to this issue
    _set_fill_color(fmt.line.fill, color)

(note: I am currently involved with a project that makes heavy use of python-pptx, happy to contribute that features needed during that work if provided with some guidance on how to contribute)