How Add-Ins Work
The method initialize()
from the com.sun.star.lang.XInitialization interface is the first method that is called for an add-in. It is called directly after it is created by the com.sun.star.lang.XMultiServiceFactory provided by the chart document. This method gets the XChartDocument
object.
When initialize()
is called, the argument returned is the chart document. Store this as a member to that it can be called later in the refresh()
call to access all elements of the chart. The following is an example for the initialize()
method of an add-in written in Java:
// XInitialization public void initialize(Object[] aArguments) throws Exception, RuntimeException { if (aArguments.length > 0) { // maChartDocument is a member // which is set to the parent chart document // that is given as first argument maChartDocument = (XChartDocument) UnoRuntime.queryInterface( XChartDocument.class, aArguments[0]); XPropertySet aDocProp = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, maChartDocument); if (aDocProp != null) { // set base diagram which will be extended in refresh() aDocProp.setPropertyValue("BaseDiagram", "com.sun.star.chart.XYDiagram"); } // remember the draw page, as it is frequently used by refresh() // (this is not necessary but convenient) XDrawPageSupplier aPageSupp = (XDrawPageSupplier) UnoRuntime.queryInterface( XDrawPageSupplier.class, maChartDocument); if( aPageSupp != null ) maDrawPage = (XDrawPage) UnoRuntime.queryInterface( XDrawPage.class, aPageSupp.getDrawPage()); } }
An important method of an add-in component is refresh()
from the com.sun.star.util.XRefreshable. This method is called every time the chart is rebuilt. A change of data results in a refresh, but also a resizing or changing of a property that affects the layout calls the refresh()
method. For example, the property HasLegend
that switches the legend on and off.
To add shapes to the chart, create them once and modify them later during the refresh calls. In the following example, a line is created in initialize()
and modified during refresh()
:
// XInitialization public void initialize(Object[] aArguments) throws Exception, RuntimeException { // get document and page -- see above // ... // get a shape factory maShapeFactory = ...; // create top line maTopLine = (XShape) UnoRuntime.queryInterface( XShape.class, maShapeFactory.createInstance("com.sun.star.drawing.LineShape")); maDrawPage.add(maTopLine); // make line red and thicker XPropertySet aShapeProp = (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class, maTopLine); aShapeProp.setPropertyValue("LineColor", new Integer(0xe01010)); aShapeProp.setPropertyValue("LineWidth", new Integer(50)); // create bottom line maBottomLine = (XShape) UnoRuntime.queryInterface( XShape.class, maShapeFactory.createInstance("com.sun.star.drawing.LineShape")); maDrawPage.add(maBottomLine); // make line green and thicker aShapeProp = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, maBottomLine); aShapeProp.setPropertyValue("LineColor", new Integer(0x10e010)); aShapeProp.setPropertyValue("LineWidth", new Integer(50)); } } // XRefreshable public void refresh() throws RuntimeException { // position lines // -------------- // get data XChartDataArray aDataArray = (XChartDataArray) UnoRuntime.queryInterface( XChartDataArray.class, maChartDocument.getData()); double aData[][] = aDataArray.getData(); // get axes XDiagram aDiagram = maChartDocument.getDiagram(); XShape aXAxis = (XShape) UnoRuntime.queryInterface( XShape.class, ((XAxisXSupplier) UnoRuntime.queryInterface( XAxisXSupplier.class, aDiagram)).getXAxis()); XShape aYAxis = (XShape) UnoRuntime.queryInterface( XShape.class, ((XAxisYSupplier) UnoRuntime.queryInterface( XAxisYSupplier.class, aDiagram)).getYAxis()); // calculate points for hull final int nLength = aData.length; int i, j; double fMax, fMin; Point aMaxPtSeq[][] = new Point[1][]; aMaxPtSeq[0] = new Point[nLength]; Point aMinPtSeq[][] = new Point[1][]; aMinPtSeq[0] = new Point[nLength]; for (i = 0; i < nLength; i++) { fMin = fMax = aData[i][1]; for (j = 1; j < aData[i].length; j++) { if (aData[i][j] > fMax) fMax = aData[i][j]; else if (aData[i][j] < fMin) fMin = aData[i][j]; } aMaxPtSeq[0][i] = new Point(getAxisPosition(aXAxis, aData[i][0], false), getAxisPosition(aYAxis, fMax, true)); aMinPtSeq[0][i] = new Point(getAxisPosition(aXAxis, aData[i][0], false), getAxisPosition(aYAxis, fMin, true)); } // apply point sequences to lines try { XPropertySet aShapeProp = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, maTopLine); aShapeProp.setPropertyValue("PolyPolygon", aMaxPtSeq); aShapeProp = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, maBottomLine); aShapeProp.setPropertyValue("PolyPolygon", aMinPtSeq); } catch (Exception ex) { } } // determine the position of a value along an axis // bVertical is true for the y-axis and false for the x-axis private int getAxisPosition(XShape aAxis, double fValue, boolean bVertical) { int nResult = 0; if (aAxis != null) { XPropertySet aAxisProp = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, aAxis); try { double fMin, fMax; fMin = ((Double) aAxisProp.getPropertyValue("Min")).doubleValue(); fMax = ((Double) aAxisProp.getPropertyValue("Max")).doubleValue(); double fRange = fMax - fMin; if (fMin <= fValue && fValue <= fMax && fRange != 0) { if (bVertical) { // y==0 is at the top, thus take 1.0 - ... nResult = aAxis.getPosition().Y + (int)((double)(aAxis.getSize().Height) * (1.0 - ((fValue - fMin) / fRange))); } else { nResult = aAxis.getPosition().X + (int)((double)(aAxis.getSize().Width) * ((fValue - fMin) / fRange)); } } } catch (Exception ex) { } } return nResult; }
The subroutine getAxisPosition()
is a helper to determine the position of a point inside the diagram coordinates. This add-in calculates the maximum and minimum values for each slice of data points, and creates two polygons based on these points.
Content on this page is licensed under the Public Documentation License (PDL). |