Package com.CompPad.OOO

Source Code of com.CompPad.OOO.OOOPlot

/* Copyright 2011 Toby D. Rule

  This file is part of CompPad, an OpenOffice extension to provide live
  mathematical and engineering calculations within a Writer document.

    CompPad is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    CompPad is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with CompPad.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.CompPad.OOO;

import com.CompPad.model.ComplexAmount;
import com.CompPad.model.Matrix;
import com.CompPad.model.Plot;
import com.sun.star.beans.XPropertySet;
import com.sun.star.chart.ChartAxisPosition;
import com.sun.star.chart.ChartSymbolType;
import com.sun.star.chart.XAxisXSupplier;
import com.sun.star.chart.XAxisYSupplier;
import com.sun.star.chart.XChartDataArray;
import com.sun.star.chart.XChartDocument;
import com.sun.star.chart.XDiagram;
import com.sun.star.container.XNamed;
import com.sun.star.document.XEmbeddedObjectSupplier;
import com.sun.star.drawing.XShape;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.text.TextContentAnchorType;
import com.sun.star.text.XTextContent;
import com.sun.star.text.XTextCursor;
import com.sun.star.text.XTextRange;
import com.sun.star.uno.Any;
import com.sun.star.uno.Type;
import com.sun.star.uno.UnoRuntime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.measure.unit.Unit;
import org.jscience.mathematics.number.Float64;
import sun.nio.cs.ext.ISCII91;

/**
* Wrapper for openoffice chart for plotting comppad results
* @author Toby D. Rule
*/

/* Refer to the following page on how to insert a chart */
/* http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Text/Embedded_Objects */

public class OOOPlot extends OOOElement{
    private  Class[] valueTypes={Plot.class};
    private OOODocument oooDocument;
    private OOOExpression oooExpression;
    private XEmbeddedObjectSupplier xEOS;
    private String name;
    private Plot plot;
    private XChartDocument xChartDoc;
    public OOOPlot(){
       
    }
    public OOOPlot(OOODocument docArg, OOOExpression expArg){
        oooExpression = expArg;
        oooDocument = docArg;
        Logger.getLogger("com.CompPad").log(Level.FINE,"Initializing OOOPlot, oooExpression = "
                +oooExpression+" oooDocument = "+oooDocument);
        xTextDocument=docArg.getTextDocument();
    }
    public OOOPlot(OOODocument docArg,XEmbeddedObjectSupplier xEOS){
        this.xEOS=xEOS;
        oooDocument = docArg;
        XNamed xNxEOS = (XNamed) UnoRuntime.queryInterface(XNamed.class, xEOS);
        // Get name of object and use as name for expression
        name = xNxEOS.getName();
        xTextDocument=docArg.getTextDocument();
    }
   
    public boolean canHandle(Object e) throws Exception{
        for (Class v : valueTypes){
            if (v.isInstance(e)){
                Logger.getLogger("com.CompPad").log(Level.FINE,"Can Handle Plot!");
                return true;
            }
        }
        return false;
    }
    @Override
    public XTextRange getTextRange(){
        XTextContent xTCxEOS = (XTextContent)
                UnoRuntime.queryInterface(XTextContent.class, xEOS);
        XTextRange xTextRange = xTCxEOS.getAnchor();
        return xTextRange;
    }
    @Override
    public void setDependsOn(OOOExpression arg){
        oooExpression=arg;
    }
    public String getName() {
        return name;
    }

    @Override
    public void handle(Object e) throws Exception{
        /* Note that this is using the old API, not chart2.
         * I should probably update this to use the newer API */

        /* Information on the following web page: */
        /* http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Charts/Charts */

        XMultiServiceFactory chartMSF;
        XDiagram aDiagram;

        /* Either update existing plot, or create a new one */
        /* Should check this! */
        plot = (Plot)e;
        Object obj = plot.getObject();

        if (Matrix.class.isInstance(obj)){

        /* Plot real components, assume that they are dimensionless */

            /* Inner sequence represents rows */

            /* New method: */
        /* 2 n columns consisting of n x-y pairs */
        /* m rows, but some rows may be null */
        /* plotting expeccts an x column and n y-columns, so we'll
         * create a list of rows with n+1 elements, then convert to array */

        /* Inner sequence represents rows */
            // x and y units
            javax.measure.unit.Unit xunits=null;
            javax.measure.unit.Unit yunits=null;
            // strings that will be used to set x and y labels
            String xUnitString;
            String yUnitString;
            com.CompPad.model.EvalUnit xEvalUnit = null;
            com.CompPad.model.EvalUnit yEvalUnit = null;
            Matrix mmatrix = (Matrix) plot.getObject();
            int m = (int) Math.round(mmatrix.getNumberOfRows().getReal(Unit.ONE));
            int n = (int) Math.round(mmatrix.getNumberOfColumns().getReal(Unit.ONE)) / 2;
            String[] colDescriptions = new String[n+1];
            colDescriptions[0] = "x";
            List<Double[]> x = new ArrayList(); /* List of x/y pairs */
            Double newRow[];
            int mm = 0; /* Total number of rows after loop */
            // iterate columns
            for (int j=0; j<n; ++j){
                /* Create column label sequence */
                colDescriptions[j+1] = "series "+(j+1);
                // iterate rows
                for (int i=0; i<m;++i){
                    if (mmatrix.get(i,2*j)==null){
                        /* Set "no data" value */
                    }
                    else {
                        newRow = new Double[n+1];
//                        Arrays.fill(newRow,Double.MIN_NORMAL);
                        Arrays.fill(newRow,Math.pow(2.0, -1022.0));
                        // x value
                        ComplexAmount a1 = (ComplexAmount)mmatrix.get(i,2*j);
                        // y value
                        ComplexAmount a2 = (ComplexAmount)mmatrix.get(i,2*j+1);
                        // Check whether units have been defined
                        if (xunits==null){
                            // if not then define x and y units
                            xunits = a1.getUnit();
                            yunits = a2.getUnit();

                            // get units string for system units.  These will later
                            // be assigned to x and y axes.

                            // Must get evaluator to get a units string.
                            com.CompPad.model.Evaluator evaluator
                                    = oooDocument.getCompPadDocument().getEvaluator();
                            xEvalUnit = evaluator.getUnits(a1);
                            yEvalUnit = evaluator.getUnits(a2);
                            // these units will be based on the unit system
                            // defined in the evaluator.
                           
                        }
                        else{
                            // If units have been defined, then check that the
                            // units of the current row are compatible.
                            if (!xunits.isCompatible(a1.getUnit()) || !yunits.isCompatible(a2.getUnit())){
                                throw new Exception("Inconsistant dimension in arguments to plotxy.");
                            }
                            else{
                                // otherwise, we're good.
                                // divide out by our x and y units
                                newRow[0] = a1.divide(xEvalUnit.getValue()).getReal(Unit.ONE);
                                newRow[j+1] = a2.divide(yEvalUnit.getValue()).getReal(Unit.ONE);
                                x.add(newRow);
                                mm++;
                            }

                        }

                    }
                }
            }
            // convert list to array
            double[][] ar = new double[mm][n+1];
            for (int i = 0; i < mm; ++i){
                for (int j=0; j<n+1; ++j){
                    ar[i][j] = x.get(i)[j];
                }
            }

            boolean newChart = true;
            // check if chart exists
            if (xEOS!=null){
                xChartDoc = (XChartDocument)UnoRuntime.queryInterface(
                        XChartDocument.class,xEOS.getEmbeddedObject());
                newChart = false;
                /* For some reason, it is sometimes necessary, especially with a
                   plot located at the end of a long document, to hit this twice
                   to get a non-null xChartDoc!!! */
                if (xChartDoc==null){
                    xChartDoc = (XChartDocument)UnoRuntime.queryInterface(
                            XChartDocument.class,xEOS.getEmbeddedObject());
                            newChart = false;
                }
            }
            else{
                XMultiServiceFactory xMSF =
                        (XMultiServiceFactory) UnoRuntime.queryInterface(
                        XMultiServiceFactory.class,
                        oooDocument.getTextDocument());
                XTextContent xTC =
                        (XTextContent)(UnoRuntime.queryInterface(
                        XTextContent.class,xMSF.createInstance(
                        "com.sun.star.text.TextEmbeddedObject")));
                /* Position chart inline. */
                XPropertySet xFrameProps =
                       (XPropertySet)UnoRuntime.queryInterface(
                    XPropertySet.class, xTC );
                xFrameProps.setPropertyValue( "AnchorType",
                        TextContentAnchorType.AS_CHARACTER );
                xFrameProps.setPropertyValue("CLSID", OOODocument.CLSID_CHART);

                XTextCursor xTextCursor=oooExpression.getTextCursor();
                xTextCursor.goRight((short) 1, false);
                xTextCursor.getText().insertTextContent(
                        xTextCursor, xTC, false);
                XComponent xModel=
                        ((XEmbeddedObjectSupplier) UnoRuntime.queryInterface(
                        XEmbeddedObjectSupplier.class,xTC)).getEmbeddedObject();
                 xChartDoc= (XChartDocument)UnoRuntime.queryInterface(
                        XChartDocument.class, xModel);

                chartMSF=
                        (XMultiServiceFactory)UnoRuntime.queryInterface(
                        XMultiServiceFactory.class, xChartDoc);
                aDiagram = (XDiagram) UnoRuntime.queryInterface(
                    XDiagram.class,
                    chartMSF.createInstance("com.sun.star.chart.XYDiagram"));
                // if x or y values are not dimensionless, then set titles
                XShape yTitleShape = ((XAxisYSupplier) UnoRuntime.queryInterface(XAxisYSupplier.class, aDiagram))
                        .getYAxisTitle();
                XShape xTitleShape = ((XAxisXSupplier) UnoRuntime.queryInterface(XAxisXSupplier.class, aDiagram))
                        .getXAxisTitle();
                if (xEvalUnit.getName()!=null){
                    ((XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, aDiagram))
                            .setPropertyValue("HasXAxisTitle", true);
                    ((XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xTitleShape))
                            .setPropertyValue("String", "["+xEvalUnit.getName()+"]");
                }
                if (yEvalUnit.getName()!=null){
                    ((XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, aDiagram))
                            .setPropertyValue("HasYAxisTitle", true);
                    ((XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, yTitleShape))
                            .setPropertyValue("String", "["+yEvalUnit.getName()+"]");
                }

                /* Default to no points */
                XPropertySet chartXPS = (XPropertySet)UnoRuntime.queryInterface(
                        XPropertySet.class,aDiagram);
                /* Fix formatting so it looks good (X and Y Grid,
                 * no markers by default) */
                chartXPS.setPropertyValue("SymbolType", ChartSymbolType.NONE);
                chartXPS.setPropertyValue("HasYAxisGrid",false);
                xChartDoc.setDiagram(aDiagram);
                // set xaxis to cross y-axis at minimum value
                ((XAxisXSupplier) UnoRuntime.queryInterface(XAxisXSupplier.class, aDiagram))
                        .getXAxis()
                        .setPropertyValue("CrossoverPosition",ChartAxisPosition.START );
                // set xaxis to cross y-axis at minimum value
                ((XAxisYSupplier) UnoRuntime.queryInterface(XAxisYSupplier.class, aDiagram))
                        .getYAxis()
                        .setPropertyValue("CrossoverPosition",ChartAxisPosition.START );
                long legendWidth = xChartDoc.getLegend().getSize().Width
                        + yTitleShape.getSize().Width
                        + yTitleShape.getPosition().X + 6000;
                // Must convert Long to Any to do setProperty
                xFrameProps.setPropertyValue("Width", new Any(Type.LONG,legendWidth));
                Integer xTitleHeight;
                if (xTitleShape.getPosition().Y==0){
                    xTitleHeight = 0;
                }
                else{
                    // I think Y position will be distance to the top corner,
                    // so I do not also need the height of the XTitleShape.
                    xTitleHeight = (Integer)xFrameProps.getPropertyValue("Height")
                            - xTitleShape.getPosition().Y;
                }
                xFrameProps.setPropertyValue("Height",
                        xTitleHeight+ 6000);

            }


            /* Set chart data */
            XChartDataArray xDataArray=
                    (XChartDataArray)UnoRuntime.queryInterface(
                    XChartDataArray.class, xChartDoc.getData());


            xDataArray.setData(ar);
            if (newChart){
                /* Set row descriptions */
                xDataArray.setColumnDescriptions(colDescriptions);
            }

        }

    }


    @Override
    public void dispose() throws Exception{
        if (xChartDoc!=null){
            xChartDoc.dispose();
        }
    }
   
}
TOP

Related Classes of com.CompPad.OOO.OOOPlot

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.