Chapter 29. Column Charts
All the chart examples in the next four chapters come from the same program, Chart2 Views, which loads a spreadsheet from chartsData.ods
.
Depending on the function, a different table in the sheet is used to create a chart from a template.
The main() function of chart_2_views.py is:
# Chart2View.main() ofchart_2_views.py
def main(self) -> None:
_ = Lo.load_office(connector=Lo.ConnectPipe(), opt=Lo.Options(verbose=True))
try:
doc = Calc.open_doc(fnm=self._data_fnm)
GUI.set_visible(is_visible=True, odoc=doc)
sheet = Calc.get_sheet(doc=doc)
chart_doc = None
if self._chart_kind == ChartKind.AREA:
chart_doc = self._area_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.BAR:
chart_doc = self._bar_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.BUBBLE_LABELED:
chart_doc = self._labeled_bubble_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.COLUMN:
chart_doc = self._col_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.COLUMN_LINE:
chart_doc = self._col_line_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.COLUMN_MULTI:
chart_doc = self._mult_col_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.DONUT:
chart_doc = self._donut_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.HAPPY_STOCK:
chart_doc = self._happy_stock_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.LINE:
chart_doc = self._line_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.LINES:
chart_doc = self._lines_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.NET:
chart_doc = self._net_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.PIE:
chart_doc = self._pie_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.PIE_3D:
chart_doc = self._pie_3d_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.SCATTER:
chart_doc = self._scatter_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.SCATTER_LINE_ERROR:
chart_doc = self._scatter_line_error_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.SCATTER_LINE_LOG:
chart_doc = self._scatter_line_log_chart(doc=doc, sheet=sheet)
elif self._chart_kind == ChartKind.STOCK_PRICES:
chart_doc = self._stock_prices_chart(doc=doc, sheet=sheet)
if chart_doc:
Chart2.print_chart_types(chart_doc)
template_names = Chart2.get_chart_templates(chart_doc)
Lo.print_names(template_names, 1)
Lo.delay(2000)
msg_result = MsgBox.msgbox(
"Do you wish to close document?",
"All done",
boxtype=MessageBoxType.QUERYBOX,
buttons=MessageBoxButtonsEnum.BUTTONS_YES_NO,
)
if msg_result == MessageBoxResultsEnum.YES:
Lo.close_doc(doc=doc, deliver_ownership=True)
Lo.close_office()
else:
print("Keeping document open")
except Exception:
Lo.close_office()
raise
Lets assume that self._chart_kind == ChartKind.COLUMN
for now.
_col_chart()
utilizes the “Sneakers Sold this Month” table in chartsData.ods
(see Fig. 240) to generate the column chart in Fig. 241.
_col_chart()
is:
# Chart2View._col_chart() of chart_2_views.py
def _col_chart(self, doc: XSpreadsheetDocument, sheet: XSpreadsheet) -> XChartDocument:
# draw a column chart;
# uses "Sneakers Sold this Month" table
range_addr = Calc.get_address(sheet=sheet, range_name="A2:B8")
chart_doc = Chart2.insert_chart(
sheet=sheet,
cells_range=range_addr,
cell_name="C3",
width=15,
height=11,
diagram_name=ChartTypes.Column.TEMPLATE_STACKED.COLUMN,
)
Calc.goto_cell(cell_name="A1", doc=doc)
Chart2.set_title(chart_doc=chart_doc, title=Calc.get_string(sheet=sheet, cell_name="A1"))
Chart2.set_x_axis_title(
chart_doc=chart_doc, title=Calc.get_string(sheet=sheet, cell_name="A2")
)
Chart2.set_y_axis_title(
chart_doc=chart_doc, title=Calc.get_string(sheet=sheet, cell_name="B2")
)
Chart2.rotate_y_axis_title(chart_doc=chart_doc, angle=Angle(90))
return chart_doc
The column chart created by Chart2.insert_chart()
utilizes the cell range A2:B8
, which spans the two columns of the table, but not the title in cell A1
.
The C3
argument specifies where the top-left corner of the chart will be positioned in the sheet, and 15x11
are the dimensions of the image in millimeters.
Calc.goto_cell()
causes the application window’s view of the spreadsheet to move so that cell A1
is visible, which lets the user see the sneakers table and the chart together.
If the three set methods and rotateYAxisTitle()
are left out of _col_chart()
, then the generated chart will have no titles as in Fig. 242.
29.1 Creating a Chart Title
Chart2.set_title()
is passed a string which becomes the chart’s title. For example:
# part of _col_chart() in Chart2View class
Chart2.set_title(chart_doc=chart_doc, title=Calc.get_string(sheet=sheet, cell_name="A1"))
utilizes the string from cell A1
of the spreadsheet (see Fig. 240).
Setting a title requires three interfaces: XTitled, XTitle, and XFormattedString. XTitled is utilized by several chart services, as shown in Fig. 243.
The XChartDocument interface is converted into XTitled by Chart2.set_title()
, so an XTitle object can be assigned to the chart:
# in Chart2 class
@staticmethod
def get_title(chart_doc: XChartDocument) -> XTitle:
try:
xtilted = Lo.qi(XTitled, chart_doc, True)
return xtilted.getTitleObject()
except Exception as e:
raise ChartError("Error getting title from chart") from e
The XTitle object is an instance of the Title service which inherits a wide assortment of properties related to the text’s paragraph, fill, and line styling, as shown in Fig. 244.
Text is added to the XTitle object by Chart2.create_title()
, as an XFormattedString array:
# in Chart2 class
@staticmethod
def create_title(title: str) -> XTitle:
try:
xtitle = Lo.create_instance_mcf(XTitle, "com.sun.star.chart2.Title", raise_err=True)
xtitle_str = Lo.create_instance_mcf(
XFormattedString, "com.sun.star.chart2.FormattedString", raise_err=True
)
xtitle_str.setString(title)
title_arr = (xtitle_str,)
xtitle.setText(title_arr)
return xtitle
except Exception as e:
raise ChartError(f'Error creating title for: "{title}"') from e
The use of an XFormattedString tuple (title_arr = (xtitle_str,)
) may seem to be overkill when the title is a single string,
but it also allows character properties to be associated with the string through XFormattedString2, as shown in Fig. 245.
Character properties allow the font and point size of the title to be changed to Arial 14pt
by Chart2.set_x_title_font()
:
# in Chart2 class
@staticmethod
def set_x_title_font(xtitle: XTitle, font_name: str, pt_size: int) -> None:
try:
fo_strs = xtitle.getText()
if fo_strs:
Props.set_property(fo_strs[0], "CharFontName", font_name)
Props.set_property(fo_strs[0], "CharHeight", pt_size)
except Exception as e:
raise ChartError("Error setting x title font") from e
The CharFontName
and CharHeight
properties come from the CharacterProperties class.
29.2 Creating Axis Titles
Setting the axes titles needs a reference to the XAxis interface.
Incidentally, this interface name is a little misleading since X
is the naming convention for interfaces, not a reference to the x-axis
.
Fig. 235 shows that the XAxis interface is available via the XCoordinateSystem interface,
which can be obtained by calling Chart2.get_coord_system()
.
XCoordinateSystem.getAxisByDimension()
can then be employed to get an axis reference.
This is implemented by Chart2.get_axis()
:
# in chart2 class
@classmethod
def get_axis(cls, chart_doc: XChartDocument, axis_val: AxisKind, idx: int) -> XAxis:
try:
coord_sys = cls.get_coord_system(chart_doc)
result = coord_sys.getAxisByDimension(int(axis_val), idx)
if result is None:
raise UnKnownError("None Value: getAxisByDimension() returned None")
return result
except ChartError:
raise
except Exception as e:
raise ChartError("Error getting Axis for chart") from e
See also
XCoordinateSystem.getAxisByDimension()
takes two integer arguments: the first represents the axis (x
, y
, or z
), while the second is a primary or secondary index (0
or 1
) for the chosen axis.
Chart2
includes wrapper functions for Chart2.get_axis()
for the most common cases:
# in Chart2 class
@classmethod
def get_x_axis(cls, chart_doc: XChartDocument) -> XAxis:
return cls.get_axis(chart_doc=chart_doc, axis_val=AxisKind.X, idx=0)
@classmethod
def get_y_axis(cls, chart_doc: XChartDocument) -> XAxis:
return cls.get_axis(chart_doc=chart_doc, axis_val=AxisKind.Y, idx=0)
@classmethod
def get_x_axis2(cls, chart_doc: XChartDocument) -> XAxis:
return cls.get_axis(chart_doc=chart_doc, axis_val=AxisKind.X, idx=1)
@classmethod
def get_y_axis2(cls, chart_doc: XChartDocument) -> XAxis:
return cls.get_axis(chart_doc=chart_doc, axis_val=AxisKind.Y, idx=1)
Chart2.set_axis_title()
calls Chart2.get_axis()
to get a reference to the correct axis, and then reuses many of the methods described earlier for setting the chart title:
# in Chart2 class
@classmethod
def set_axis_title(
cls, chart_doc: XChartDocument, title: str, axis_val: AxisKind, idx: int
) -> XTitle:
try:
axis = cls.get_axis(chart_doc=chart_doc, axis_val=axis_val, idx=idx)
titled_axis = Lo.qi(XTitled, axis, True)
xtitle = cls.create_title(title)
titled_axis.setTitleObject(xtitle)
fname = Info.get_font_general_name()
cls.set_x_title_font(xtitle, fname, 12)
return xtitle
except ChartError:
raise
except Exception as e:
raise ChartError(f'Error setting axis tile: "{title}" for chart') from e
As with Chart2.get_axis()
, Chart2
includes wrapper methods for Chart2.set_axis_title()
to simplify common axis cases:
# in Chart2 class
@classmethod
def set_x_axis_title(cls, chart_doc: XChartDocument, title: str) -> XTitle:
return cls.set_axis_title(chart_doc=chart_doc, title=title, axis_val=AxisKind.X, idx=0)
@classmethod
def set_y_axis_title(cls, chart_doc: XChartDocument, title: str) -> XTitle:
return cls.set_axis_title(chart_doc=chart_doc, title=title, axis_val=AxisKind.Y, idx=0)
@classmethod
def set_x_axis2_title(cls, chart_doc: XChartDocument, title: str) -> XTitle:
return cls.set_axis_title(chart_doc=chart_doc, title=title, axis_val=AxisKind.X, idx=1)
@classmethod
def set_y_axis2_title(cls, chart_doc: XChartDocument, title: str) -> XTitle:
return cls.set_axis_title(chart_doc=chart_doc, title=title, axis_val=AxisKind.Y, idx=1)
29.3 Rotating Axis Titles
The default orientation for titles is horizontal, which is fine for the chart and x-axis
titles, but can cause the y-axis
title to occupy too much horizontal space.
The solution is to call Chart2.rotate_y_axis_title()
with an angle (usually 90 degrees) to turn the text counter-clockwise so it’s vertically orientated (see Fig. 241).
The implementation accesses the XTitle interface for the axis title, and then modifies its TextRotation
property from the Title service (see Fig. 244).
# in Chart2 class
@classmethod
def rotate_y_axis_title(cls, chart_doc: XChartDocument, angle: Angle) -> None:
cls.rotate_axis_title(chart_doc=chart_doc, axis_val=AxisKind.Y, idx=0, angle=angle)
@classmethod
def rotate_axis_title(
cls, chart_doc: XChartDocument, axis_val: AxisKind, idx: int, angle: Angle
) -> None:
try:
xtitle = cls.get_axis_title(chart_doc=chart_doc, axis_val=axis_val, idx=idx)
Props.set(xtitle, TextRotation=angle.Value)
except ChartError:
raise
except Exception as e:
raise ChartError("Error while trying to rotate axis title") from e
@classmethod
def get_axis_title(cls, chart_doc: XChartDocument, axis_val: AxisKind, idx: int) -> XTitle:
try:
axis = cls.get_axis(chart_doc=chart_doc, axis_val=axis_val, idx=idx)
titled_axis = Lo.qi(XTitled, axis, True)
result = titled_axis.getTitleObject()
if result is None:
raise UnKnownError("None Value: getTitleObject() return a value of None")
return result
except ChartError:
raise
except Exception as e:
raise ChartError("Error getting axis title") from e
29.4 What Chart Templates are Available?
_col_chart()
in chart_2_views.py returns its XChartDocument reference.
This isn’t necessary for rendering the chart, but allows the reference to be passed to Chart2.get_chart_templates()
:
# in main() of chart_2_views.py
# ...
chart_doc = self._col_chart(doc=doc, sheet=sheet)
# ...
template_names = Chart2.get_chart_templates(chart_doc)
Lo.print_names(template_names, 1)
The only way to list the chart templates supported by the chart2
module (i.e. those shown in Table 8) is by querying an existing chart document.
That’s the purpose of Chart2.get_chart_templates()
:
# in Chart2 class
@staticmethod
def get_chart_templates(chart_doc: XChartDocument) -> List[str]:
try:
ct_man = chart_doc.getChartTypeManager()
return Info.get_available_services(ct_man)
except Exception as e:
raise ChartError("Error getting chart templates") from e
Normally XChartTypeManager is used to create a template instance, but Info.get_available_services()
accesses its XMultiServiceFactory.getAvailableServiceNames()
method to list the names of all its supported services, which are templates:
# in Info class
@staticmethod
def get_available_services(obj: object) -> List[str]:
services: List[str] = []
try:
sf = Lo.qi(XMultiServiceFactory, obj, True)
service_names = sf.getAvailableServiceNames()
services.extend(service_names)
services.sort()
except Exception as e:
Lo.print(e)
raise Exception() from e
return services
The output lists has 64 names, same as Table 8, starting and ending like so:
com.sun.star.chart2.template.Area
com.sun.star.chart2.template.Bar
com.sun.star.chart2.template.Bubble
com.sun.star.chart2.template.Column
:
com.sun.star.chart2.template.ThreeDLineDeep
com.sun.star.chart2.template.ThreeDPie
com.sun.star.chart2.template.ThreeDPieAllExploded
com.sun.star.chart2.template.ThreeDScatter
29.5 Multiple Columns
The _mult_col_chart()
method in chart_2_views.py uses a table containing three columns of data (see Fig. 246)
to generate two column graphs in the same chart, as in Fig. 247.
_mult_col_chart()
is:
#
def _mult_col_chart(self, doc: XSpreadsheetDocument, sheet: XSpreadsheet) -> XChartDocument:
range_addr = Calc.get_address(sheet=sheet, range_name="E15:G21")
d_name = ChartTypes.Column.TEMPLATE_STACKED.COLUMN
# d_name = ChartTypes.Column.TEMPLATE_PERCENT.COLUMN_DEEP_3D
# d_name = ChartTypes.Column.TEMPLATE_PERCENT.COLUMN_FLAT_3D
chart_doc = Chart2.insert_chart(
sheet=sheet,
cells_range=range_addr,
cell_name="A22",
width=20,
height=11,
diagram_name=d_name,
)
ChartTypes.Column.TEMPLATE_STACKED.COLUMN
Calc.goto_cell(cell_name="A13", doc=doc)
Chart2.set_title(chart_doc=chart_doc, title=Calc.get_string(sheet=sheet, cell_name="E13"))
Chart2.set_x_axis_title(
chart_doc=chart_doc, title=Calc.get_string(sheet=sheet, cell_name="E15")
)
Chart2.set_y_axis_title(
chart_doc=chart_doc, title=Calc.get_string(sheet=sheet, cell_name="F14")
)
Chart2.rotate_y_axis_title(chart_doc=chart_doc, angle=Angle(90))
Chart2.view_legend(chart_doc=chart_doc, is_visible=True)
# for the 3D versions
# Chart2.show_axis_label(chart_doc=chart_doc, axis_val=AxisKind.Z, idx=0, is_visible=False)
# Chart2.set_chart_shape_3d(chart_doc=chart_doc, shape=DataPointGeometry3DEnum.CYLINDER)
return chart_doc
The same Column
chart template is used as in _col_chart()
, and the additional column of data is treated as an extra column graph.
The chart title and axis titles are added in the same way as before, and a legend is included by calling Chart2.view_legend()
:
# in Chart2 class
@staticmethod
def view_legend(chart_doc: XChartDocument, is_visible: bool) -> None:
try:
diagram = chart_doc.getFirstDiagram()
legend = diagram.getLegend()
if is_visible and legend is None:
leg = Lo.create_instance_mcf(XLegend, "com.sun.star.chart2.Legend", raise_err=True)
Props.set(
leg,
LineStyle=LineStyle.NONE,
FillStyle=FillStyle.SOLID,
FillTransparence=100
)
diagram.setLegend(leg)
Props.set(leg, Show=is_visible)
except Exception as e:
raise ChartError("Error while setting legend visibility") from e
The legend is accessible via the chart Diagram service.
view_legend()
creates an instance, and sets a few properties to make it look nicer.
Fig. 248 shows the Legend service, which defines several properties, and inherits many others from FillProperties and LineProperties.
The LineStyle
, FillStyle
, and FillTransparence
properties utilized in view_legend()
come from the inherited property classes, but Show
is from the Legend service.
The XLegend interface contains no methods, and is used only to access the properties in its defining service.
29.6 3D Pizazz
You may not be a fan of 3D charts which are often harder to understand than their 2D equivalents, even if they do look more “hi-tech”.
But if you really want a 3D version of a chart, it’s mostly just a matter of changing the template name in the call to Chart2.insert_chart()
.
If d_name
were were set to enum value of ChartTypes.Column.TEMPLATE_PERCENT.COLUMN_DEEP_3D
or string value of ThreeDColumnDeep
or enum value of ChartTypes.Column.TEMPLATE_PERCENT.COLUMN_FLAT_3D
or string value of ThreeDColumnFlat
in _mult_col_chart()
, then the charts in Fig. 249 appear.
deep
orders the two 3D graphs along the z-axis
, and labels the axis.
The x-axis
labels are rotated automatically in the top-most chart of Fig. 249 because the width of the chart wasn’t sufficient to draw them horizontally,
and that’s caused the graphs to be squashed into less vertical space.
_mult_col_chart()
contains two commented out lines which illustrate how a 3D graph can be changed:
# in _mult_col_chart()...
# hide labels
Chart2.show_axis_label(chart_doc=chart_doc, axis_val=AxisKind.Z, idx=0, is_visible=False)
Chart2.set_chart_shape_3d(chart_doc=chart_doc, shape=DataPointGeometry3DEnum.CYLINDER)
See also
Chart2.show_axis_label()
is passed the boolean False
to switch off the display of the z-axis
labels.
Chart2.set_chart_shape_3d()
changes the shape of the columns; in this case to cylinders, as in Fig. 250.
Chart2.show_axis_label()
uses Chart2.get_axis()
to access the XAxis interface, and then modifies its Show
property:
# in Chart2 class
@classmethod
def get_axis(cls, chart_doc: XChartDocument, axis_val: AxisKind, idx: int) -> XAxis:
try:
coord_sys = cls.get_coord_system(chart_doc)
result = coord_sys.getAxisByDimension(int(axis_val), idx)
if result is None:
raise UnKnownError("None Value: getAxisByDimension() returned None")
return result
except ChartError:
raise
except Exception as e:
raise ChartError("Error getting Axis for chart") from e
The Axis service contains a large assortment of properties, and inherits character and line properties depicted in Fig. 251.
Chart2.set_chart_shape_3d()
affects the data points
(which in a 3D column chart are boxes by default).
This requires access to the XDataSeries array of data points by calling Chart2.get_data_series()
,
and then the Geometry3D
property in the DataSeries service is modified.
Fig. 237 shows the service and its interfaces, and most of its properties are inherited from the DataPointProperties class, including Geometry3D
.
The code for Chart2.set_chart_shape_3d()
:
# in Chart2 class
@classmethod
def set_chart_shape_3d(cls, chart_doc: XChartDocument, shape: DataPointGeometry3DEnum) -> None:
try:
data_series_arr = cls.get_data_series(chart_doc=chart_doc)
for data_series in data_series_arr:
Props.set_property(data_series, "Geometry3D", int(shape))
except ChartError:
raise
except Exception as e:
raise ChartError("Error setting chart shape 3d") from e
29.7 The Column and Line Chart
Another way to display the multiple columns of data in the “States with the Most Colleges” table (Fig. 246) is to draw a column and line chart. The column is generated from the first data column, and the line graph uses the second column. The result is shown in Fig. 252.
_col_line_chart()
in chart_2_views.py generates Fig. 252:
# Chart2View._col_line_chart() in chart_2_views.py
def _col_line_chart(self, doc: XSpreadsheetDocument, sheet: XSpreadsheet) -> XChartDocument:
range_addr = Calc.get_address(sheet=sheet, range_name="E15:G21")
chart_doc = Chart2.insert_chart(
sheet=sheet,
cells_range=range_addr,
cell_name="B3",
width=20,
height=11,
diagram_name=ChartTypes.ColumnAndLine.TEMPLATE_STACKED.COLUMN_WITH_LINE,
)
Calc.goto_cell(cell_name="A13", doc=doc)
Chart2.set_title(
chart_doc=chart_doc, title=Calc.get_string(sheet=sheet, cell_name="E13")
)
Chart2.set_x_axis_title(
chart_doc=chart_doc, title=Calc.get_string(sheet=sheet, cell_name="E15")
)
Chart2.set_y_axis_title(
chart_doc=chart_doc, title=Calc.get_string(sheet=sheet, cell_name="F14")
)
Chart2.rotate_y_axis_title(chart_doc=chart_doc, angle=Angle(90))
Chart2.view_legend(chart_doc=chart_doc, is_visible=True)
return chart_doc
It’s nearly identical to _mul_col_chart()
except for ChartTypes.ColumnAndLine.TEMPLATE_STACKED.COLUMN_WITH_LINE
passed to Chart2.insert_chart()
.
A chart’s coordinate system may utilize multiple chart types.
Up to now a chart template (i.e. Column
) has been converted to a single chart type (i.e. ColumnChartType
) by the chart API (specifically by the chart type manager),
but the ColumnWithLine
template is different. The manager implements that template using two chart types, ColumnChartType
and LineChartType
.
This is reported by Chart2.insert_chart()
calling Chart2.print_chart_types()
:
No. of chart types: 2
com.sun.star.chart2.ColumnChartType
com.sun.star.chart2.LineChartType
Chart2.print_chart_types()
uses Chart2.get_chart_types()
, which was defined earlier:
# in Chart2 class
@classmethod
def print_chart_types(cls, chart_doc: XChartDocument) -> None:
chart_types = cls.get_chart_types(chart_doc)
if len(chart_types) > 1:
print(f"No. of chart types: {len(chart_types)}")
for ct in chart_types:
print(f" {ct.getChartType()}")
else:
print(f"Chart Type: {chart_types[0].getChartType()}")
print()
Why is this separation of a single template into two chart types important?
The short answer is that it complicates the search for a chart template’s data.
For example Chart2.get_chart_type()
returns the first chart type in the XChartType array since most templates only use a single chart type:
# in Chart2 class
@classmethod
def get_chart_type(cls, chart_doc: XChartDocument) -> XChartType:
try:
chart_types = cls.get_chart_types(chart_doc)
return chart_types[0]
except ChartError:
raise
except Exception as e:
raise ChartError("Error getting chart type") from e
This method is insufficient for examining a chart created with the ColumnWithLine
template since the XChartType array holds two chart types.
A programmer will have to use Chart2.find_chart_type()
, which searches the array for the specified chart type:
# in Chart2 class
@classmethod
def find_chart_type(
cls, chart_doc: XChartDocument, chart_type: ChartTypeNameBase | str
) -> XChartType:
# Ensure chart_type is ChartTypeNameBase | str
Info.is_type_enum_multi(
alt_type="str", enum_type=ChartTypeNameBase, enum_val=chart_type, arg_name="chart_type"
)
try:
srch_name = f"com.sun.star.chart2.{str(chart_type).lower()}"
chart_types = cls.get_chart_types(chart_doc)
for ct in chart_types:
ct_name = ct.getChartType().lower()
if ct_name == srch_name:
return ct
except Exception as e:
raise ChartError(f'Error Finding chart for "{chart_type}"') from e
raise NotFoundError(f'Chart for type "{chart_type}" was not found')
For example, the following call returns a reference to the line chart type:
line_ct = Chart2.find_chart_type(chart_doc=chart_doc, chart_type="LineChartType") # XChartType
The simple get_chart_type()
is used in Chart2.get_data_series()
:
# in Chart2 class
@classmethod
def get_data_series(
cls, chart_doc: XChartDocument, chart_type: ChartTypeNameBase | str = ""
) -> Tuple[XDataSeries, ...]:
try:
if chart_type:
xchart_type = cls.find_chart_type(chart_doc, chart_type)
else:
xchart_type = cls.get_chart_type(chart_doc)
ds_con = Lo.qi(XDataSeriesContainer, xchart_type, True)
return ds_con.getDataSeries()
except Exception as e:
raise ChartError("Error getting chart data series") from e
When chart_type
is omitted it means that Chart2.get_data_series()
can only access the data associated with the column (the first chart type) in a ColumnWithLine
chart document.
When chart_type
is included it requires a chart_type
argument to get the correct chart type. For example, the call:
ds = Chart2.get_data_series(chart_doc=chart_doc, chart_type=ChartTypes.Line.NAMED.LINE_CHART)
# chart_type could also be "LineChartType"
returns the data series associated with the line chart type.