Basics
Code for the chart engine is actually located outside the sc module since it is shared across applications. The chart2 module contains the implementation for the chart drawing layer. From here on I’ll refer to the chart2 implementation code simply as ‘chart2′.
Chart2 also relies on callbacks from sc for certain operations (TODO: find out what exactly). Classes ScChart2DataProvider, ScChart2DataSource, ScChart2LabeledDataSequence, ScChart2DataSequence, and ScChart2EmptyDataSequence implement such callbacks to chart2. (TODO: ScChart2EmptyDataSequence does not appear to be used any more.)
Chart listener registration on file load (ODF)
When a Calc document with embedded chart objects is loaded, the chart objects do not immediately get loaded from the file. Instead, Calc registers them with their associated range addresses, and load them only when a value in one of those ranges changes.
In ScMyShapeResizer::CreateChartListener, Calc registers a chart object by creating an instance of ScChartListener, with the listened ranges passed to that instance.
Drawing charts
Each drawing object inside the chart object area is represented by an instance of com.sun.star.drawing.XShape interface type, while an instance of com.sun.star.drawing.XShape represents a collection of such drawing objects.
The current chart2 implementation supports two coordinate systems:
- Cartesian coordinate system
- polar coordinate system
Class VCoordinateSystem abstracts the coordinate system layer. This class also stores a variable number of instances of class VAxisBase which abstracts an axis object in either coordinate system. Two classes are derived from VCoordinateSystem: VCartesianCoordinateSystem and VPolarCoordinateSystem, which support their respective coordinate system. Likewise, classes VCartesianAxis and VPolarAxis inherits from VAxisBase to support Cartesian axis and polar axis, respectively.
Each instance of struct TickInfo stores the displayed text label as the com.sun.star.drawing.XShape interface type. For chart of the Cartesian coordinate system, labels are created in method VCartesianAxis::createTextShapes. Class VAxisBase holds multiple instances of struct TickInfo in a 2-dimensional array vector.
Method ChartView::createShapes draws the entire graphics within the drawing frame including the titles and the legend. It calls impl_createDiagramAndContent to draw chart diagram part. In that method, class VDiagram is used locally to represent the diagram object. Method VDiagram::adjustInnerSize adjusts the position and size of the inner rectangle (the inner gray box) based on the spaces required to draw the axis labels.
Here is how the size of the inner gray rectangle gets calculated. First, the size is set to exactly 1/3 of the entire available area size via VDiagram::reduceToMinimumSize. Method VCoordinateSystem::createMaximumAxesLabels then gets called to add axis labels around this minimum diagram box in order to obtain the smallest bounding box that would encompass the diagram as well as the axis label texts. Comparing that bounding box with the original box size gives the margins needed for the axis label texts. From there, the final diagram box size gets calculated based on the size of the area allocated for drawing the diagram and axis labels. Once the size and position of the diagram box is determined, the axis label’s positions get re-calculated from the final geometry of the diagram box.
