blob: fb6870afb2979e10a4f9186813e77f7511c27f88 [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
package org.odftoolkit.simple.chart;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.Vector;
import org.odftoolkit.odfdom.dom.OdfDocumentNamespace;
import org.odftoolkit.odfdom.dom.attribute.chart.ChartClassAttribute;
import org.odftoolkit.odfdom.dom.attribute.chart.ChartDimensionAttribute;
import org.odftoolkit.odfdom.dom.attribute.chart.ChartLegendPositionAttribute;
import org.odftoolkit.odfdom.dom.attribute.dr3d.Dr3dProjectionAttribute;
import org.odftoolkit.odfdom.dom.attribute.dr3d.Dr3dShadeModeAttribute;
import org.odftoolkit.odfdom.dom.attribute.office.OfficeValueTypeAttribute;
import org.odftoolkit.odfdom.dom.attribute.style.StyleLegendExpansionAttribute;
import org.odftoolkit.odfdom.dom.element.chart.ChartAxisElement;
import org.odftoolkit.odfdom.dom.element.chart.ChartCategoriesElement;
import org.odftoolkit.odfdom.dom.element.chart.ChartChartElement;
import org.odftoolkit.odfdom.dom.element.chart.ChartDataPointElement;
import org.odftoolkit.odfdom.dom.element.chart.ChartFloorElement;
import org.odftoolkit.odfdom.dom.element.chart.ChartGridElement;
import org.odftoolkit.odfdom.dom.element.chart.ChartLegendElement;
import org.odftoolkit.odfdom.dom.element.chart.ChartPlotAreaElement;
import org.odftoolkit.odfdom.dom.element.chart.ChartSeriesElement;
import org.odftoolkit.odfdom.dom.element.chart.ChartTitleElement;
import org.odftoolkit.odfdom.dom.element.chart.ChartWallElement;
import org.odftoolkit.odfdom.dom.element.dr3d.Dr3dLightElement;
import org.odftoolkit.odfdom.dom.element.style.StyleChartPropertiesElement;
import org.odftoolkit.odfdom.dom.element.style.StyleGraphicPropertiesElement;
import org.odftoolkit.odfdom.dom.element.style.StyleTextPropertiesElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableCellElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableColumnElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableColumnsElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableHeaderColumnsElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableHeaderRowsElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableRowElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableRowsElement;
import org.odftoolkit.odfdom.dom.element.text.TextPElement;
import org.odftoolkit.odfdom.incubator.doc.text.OdfTextParagraph;
import org.odftoolkit.odfdom.pkg.OdfName;
import org.odftoolkit.odfdom.pkg.OdfNamespace;
import org.w3c.dom.NodeList;
/**
* <code>Chart</code> represents the chart feature of the ODF document.
* <code>Chart</code> provides methods to get/set chart title, get/set chart
* data, etc.
*
* @since 0.6
*/
public class Chart {
private final static String AXIS_SVG_X = "3.104cm";
private final static String AXIS_SVG_Y = "6.359cm";
private final static String AXIS_FONTSIZE = "10pt";
private final static String AXIS_FONTSIZEASIAN = "10pt";
private final static String AXIS_FONTSIZECOMPLEX = "10pt";
private final static String CHART_SVG_WIDTH = "7cm";
private final static String CHART_SVG_HEIGH = "8cm";
private final static String CHART_CLASS_TYPE = "chart:bar";
private final static String CHART_PROPERTIES_STROKE = "none";
private final static String PLOTAREA_SVG_HEIGHT = "7.52cm";
private final static String PLOTAREA_SVG_WIDTH = "4.73cm";
private final static String PLOTAREA_SVG_X = "0.16cm";
private final static String PLOTAREA_SVG_Y = "1.375cm";
private ChartChartElement chartElement;
private DataSet dataSet;
private ChartTitleElement chartTitle;
private ChartLegendElement legend;
private ChartPlotAreaElement plotArea;
private TableTableElement table;
private TableTableHeaderColumnsElement headerColumns;
private TableTableColumnsElement columns;
private TableTableColumnElement column;
private TableTableHeaderRowsElement headerRows;
private TableTableRowElement headerRow;
private TableTableRowsElement rows;
private String chartID;
private boolean isApply3DEffect = false;
private boolean isUseLegend = false;
Chart(ChartChartElement chartElement, String chartID) {
this.chartElement = chartElement;
this.chartID = chartID;
init();
}
private void init() {
chartElement.setSvgWidthAttribute(CHART_SVG_WIDTH);
chartElement.setSvgHeightAttribute(CHART_SVG_HEIGH);
chartElement.setChartClassAttribute(CHART_CLASS_TYPE);
chartElement.setProperty(StyleGraphicPropertiesElement.Stroke, CHART_PROPERTIES_STROKE);
}
private void setPlotArea() {
// chart:plotarea
NodeList plotAreas = chartElement.getElementsByTagName(ChartPlotAreaElement.ELEMENT_NAME.getQName());
if (plotAreas.getLength() > 0) {
chartElement.removeChild(plotAreas.item(0));
}
plotArea = (ChartPlotAreaElement) chartElement.newChartPlotAreaElement();
plotArea = (ChartPlotAreaElement) plotAreas.item(0);
plotArea.setProperty(StyleChartPropertiesElement.RightAngledAxes, "true");
plotArea.setSvgHeightAttribute(PLOTAREA_SVG_HEIGHT);
plotArea.setSvgWidthAttribute(PLOTAREA_SVG_WIDTH);
plotArea.setSvgXAttribute(PLOTAREA_SVG_X);
plotArea.setSvgYAttribute(PLOTAREA_SVG_Y);
// chart:axis
ChartAxisElement axisX = plotArea.newChartAxisElement(ChartDimensionAttribute.Value.x.toString());
if (getTableCellRange() != null) {
ChartCategoriesElement categories = (ChartCategoriesElement) axisX.newChartCategoriesElement();
categories.setTableCellRangeAddressAttribute(getTableCellRange());
}
axisX.setChartDimensionAttribute(ChartDimensionAttribute.Value.x.toString());
axisX.setChartNameAttribute("primary-x");
axisX.setProperty(StyleChartPropertiesElement.DisplayLabel, "true");
axisX.setProperty(StyleChartPropertiesElement.Logarithmic, "false");
axisX.setProperty(StyleChartPropertiesElement.ReverseDirection, "false");
axisX.setProperty(StyleChartPropertiesElement.LineBreak, "false");
axisX.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
axisX.setProperty(StyleTextPropertiesElement.FontSize, "10pt");
axisX.setProperty(StyleTextPropertiesElement.FontSizeAsian, "10pt");
axisX.setProperty(StyleTextPropertiesElement.FontCharsetComplex, "10pt");
ChartAxisElement axisY = (ChartAxisElement) plotArea.newChartAxisElement(ChartDimensionAttribute.Value.y
.toString());
axisY.setChartDimensionAttribute(ChartDimensionAttribute.Value.y.toString());
axisY.setChartNameAttribute("primary-y");
axisY.setProperty(StyleChartPropertiesElement.DisplayLabel, "true");
axisY.setProperty(StyleChartPropertiesElement.Logarithmic, "false");
axisY.setProperty(StyleChartPropertiesElement.ReverseDirection, "false");
axisY.setProperty(StyleChartPropertiesElement.LineBreak, "false");
axisY.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
axisY.setProperty(StyleTextPropertiesElement.FontSize, "10pt");
axisY.setProperty(StyleTextPropertiesElement.FontSizeAsian, "10pt");
axisY.setProperty(StyleTextPropertiesElement.FontCharsetComplex, "10pt");
// chart:grid
ChartGridElement grid = axisY.newChartGridElement();
grid.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
grid.setChartClassAttribute(ChartClassAttribute.Value.MAJOR.toString());
// chart:series
int numSeries = dataSet.getDataSeriesCount();
Object[] valueCellRange = getValueCellRange();
Object[] labelCellRange = getLabelCellRange();
for (int i = 0; i < numSeries; i++) {
ChartSeriesElement series = plotArea.newChartSeriesElement();
series.setChartClassAttribute(chartElement.getChartClassAttribute());
series.setProperty(StyleGraphicPropertiesElement.Stroke, "solid");
series.setProperty(StyleGraphicPropertiesElement.FillColor, getRandColorCode());
series.setProperty(StyleGraphicPropertiesElement.EdgeRounding, "0%");
series.setProperty(StyleTextPropertiesElement.FontSize, "6pt");
series.setProperty(StyleTextPropertiesElement.FontSizeAsian, "6pt");
series.setProperty(StyleTextPropertiesElement.FontCharsetComplex, "6pt");
if ((String) valueCellRange[i] != null) {
series.setChartValuesCellRangeAddressAttribute((String) valueCellRange[i]);
}
if ((String) labelCellRange[i] != null) {
series.setChartLabelCellAddressAttribute((String) labelCellRange[i]);
}
ChartDataPointElement point = series.newChartDataPointElement();
point.setChartRepeatedAttribute(new Integer(numSeries));
}
ChartWallElement wall = plotArea.newChartWallElement();
wall.setProperty(StyleGraphicPropertiesElement.Stroke, "none");
wall.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
wall.setProperty(StyleGraphicPropertiesElement.Fill, "none");
wall.setProperty(StyleGraphicPropertiesElement.FillColor, "#e6e6e6");
ChartFloorElement floor = plotArea.newChartFloorElement();
floor.setProperty(StyleGraphicPropertiesElement.Stroke, "none");
floor.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
floor.setProperty(StyleGraphicPropertiesElement.Fill, "none");
floor.setProperty(StyleGraphicPropertiesElement.FillColor, "#e6e6e6");
}
/**
* 3D effect manipulation, get whether the chart apples 3D effect
*
* @return return true if the chart is applied 3D effect
*/
public boolean IsApply3DEffect() {
return isApply3DEffect;
}
/**
* chart axis manipulation, temporarily only consider the axis title
*
* @param dimType
* the chart axis dimension, x, y or z
* @return return axis title according to the given dimension,null if the
* specific dimensional axis has no title
*/
public String getAxisTitle(String dimType) {
NodeList chartAxises = (NodeList) plotArea.getElementsByTagName(ChartAxisElement.ELEMENT_NAME.getQName());
for (int i = 0; i < chartAxises.getLength(); i++) {
ChartAxisElement axis = (ChartAxisElement) chartAxises.item(i);
String dimension = axis.getAttributeNS(OdfDocumentNamespace.CHART.getUri(), "dimension");
if (dimension.equals(dimType)) {
NodeList titles = axis.getElementsByTagName(ChartTitleElement.ELEMENT_NAME.getQName());
ChartTitleElement axisTitle = (ChartTitleElement) titles.item(0);
NodeList paras = (NodeList) axisTitle.getElementsByTagName(TextPElement.ELEMENT_NAME.getQName());
return paras.item(0).getTextContent();
}
}
return null;
}
/**
* chart data manipulation, get the chart data
*
* @return return the chart data
*/
public DataSet getChartData() {
String[] labels;
String[] legends;
double[][] values;
if (dataSet == null) {
this.dataSet = new DataSet();
if (table == null) {
table = (TableTableElement) chartElement
.getElementsByTagName(TableTableElement.ELEMENT_NAME.getQName()).item(0);
headerRows = (TableTableHeaderRowsElement) table.getElementsByTagName(
TableTableHeaderRowsElement.ELEMENT_NAME.getQName()).item(0);
headerRow = (TableTableRowElement) table.getElementsByTagName(
TableTableRowElement.ELEMENT_NAME.getQName()).item(0);
NodeList headerCells = headerRow.getElementsByTagName(TableTableCellElement.ELEMENT_NAME.getQName());
// column count
int legendcount = headerCells.getLength() - 1;
legends = new String[legendcount];
for (int i = 1; i < legendcount + 1; i++) {
TableTableCellElement headerCell = (TableTableCellElement) headerCells.item(i);
legends[i - 1] = ((OdfTextParagraph) headerCell.getElementsByTagName(
TextPElement.ELEMENT_NAME.getQName()).item(0)).getTextContent();
}
rows = (TableTableRowsElement) table
.getElementsByTagName(TableTableRowsElement.ELEMENT_NAME.getQName()).item(0);
NodeList row = rows.getElementsByTagName(TableTableRowElement.ELEMENT_NAME.getQName());
// row count
int labelcount = row.getLength();
values = new double[legendcount][labelcount];
labels = new String[labelcount];
for (int i = 0; i < labelcount; i++) {
NodeList cells = ((TableTableRowElement) row.item(i)).getElementsByTagNameNS(
OdfDocumentNamespace.TABLE.getUri(), "table-cell");
labels[i] = ((OdfTextParagraph) ((TableTableCellElement) cells.item(0)).getElementsByTagNameNS(
OdfDocumentNamespace.TEXT.getUri(), "p").item(0)).getTextContent();
for (int j = 0; j < legendcount; j++) {
String aValue = ((TableTableCellElement) cells.item(j + 1)).getOdfAttributeValue(OdfName
.newName(OdfNamespace.newNamespace(OdfDocumentNamespace.OFFICE), "value"));
if (aValue == null || aValue.equals("")) {
values[j][i] = Double.NaN;
} else {
values[j][i] = Double.valueOf(aValue).doubleValue();
}
}
}
dataSet.setValues(labels, legends, values);
}
}
return dataSet;
}
/**
* chart title manipulation, get the current chart title
*
* @return return the chart title
*/
public String getChartTitle() {
if (chartTitle == null) {
chartTitle = (ChartTitleElement) chartElement.getElementsByTagName(
ChartTitleElement.ELEMENT_NAME.getQName()).item(0);
}
NodeList paras = (NodeList) chartTitle.getElementsByTagName(TextPElement.ELEMENT_NAME.getQName());
if (paras.getLength() > 0) {
return paras.item(0).getTextContent();
} else {
return "";
}
}
/**
* chart type manipulation, get the current chart type
*
* @return the chart type
*/
public ChartType getChartType() {
return ChartType.enumValueOf(chartElement.getChartClassAttribute());
}
/**
* chart id manipulation, get the current chart id
*
* @return the chart id
*/
public String getChartID() {
return chartID;
}
/**
* chart legend manipulation
*
*@return returns true if it is using legend, otherwise returns false
*/
public boolean isUseLegend() {
return isUseLegend;
}
/**
* 3D effect manipulation, set to apply 3D effect
*
* @param _3deffect
* a flag specifying whether or not apply a 3D effect
*/
public void setApply3DEffect(boolean _3deffect) {
isApply3DEffect = _3deffect;
if (_3deffect) {
legend.setProperty(StyleGraphicPropertiesElement.Stroke, "none");
legend.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
legend.setProperty(StyleGraphicPropertiesElement.Fill, "none");
legend.setProperty(StyleGraphicPropertiesElement.FillColor, "#e6e6e6");
legend.setProperty(StyleTextPropertiesElement.FontSize, "10pt");
legend.setProperty(StyleTextPropertiesElement.FontSizeAsian, "10pt");
legend.setProperty(StyleTextPropertiesElement.FontSizeComplex, "10pt");
plotArea.setDr3dVpnAttribute("(0.416199821709347 0.173649045905254 0.892537795986984)");
plotArea.setDr3dVrpAttribute("(17634.6218373783 10271.4823817647 24594.8639082739)");
plotArea.setDr3dVupAttribute("(-0.0733876362771618 0.984807599917971 -0.157379306090273)");
plotArea.setDr3dProjectionAttribute(Dr3dProjectionAttribute.Value.PARALLEL.toString());
plotArea.setDr3dDistanceAttribute("4.2cm");
plotArea.setDr3dFocalLengthAttribute("8cm");
plotArea.setDr3dShadowSlantAttribute("0");
plotArea.setDr3dShadeModeAttribute(Dr3dShadeModeAttribute.Value.FLAT.toString());
plotArea.setDr3dAmbientColorAttribute("#999999");
plotArea.setDr3dLightingModeAttribute("");
plotArea.setProperty(StyleChartPropertiesElement.ThreeDimensional, "true");
plotArea.setProperty(StyleChartPropertiesElement.SortByXValues, "false");
plotArea.setProperty(StyleChartPropertiesElement.RightAngledAxes, "true");
NodeList chartAxises = (NodeList) plotArea.getElementsByTagName(ChartAxisElement.ELEMENT_NAME.getQName());
for (int i = 0; i < chartAxises.getLength(); i++) {
ChartAxisElement axis = (ChartAxisElement) chartAxises.item(i);
if (axis.getChartDimensionAttribute().equals("x")) {
// x axis
axis.setProperty(StyleChartPropertiesElement.DisplayLabel, "true");
axis.setProperty(StyleChartPropertiesElement.Logarithmic, "false");
axis.setProperty(StyleChartPropertiesElement.ReverseDirection, "false");
axis.setProperty(StyleChartPropertiesElement.LineBreak, "false");
axis.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
axis.setProperty(StyleTextPropertiesElement.FontSize, "10pt");
axis.setProperty(StyleTextPropertiesElement.FontSizeAsian, "10pt");
axis.setProperty(StyleTextPropertiesElement.FontSizeComplex, "10pt");
}
if (axis.getChartDimensionAttribute().equals("y")) {
// y axis
axis.setProperty(StyleTextPropertiesElement.FontSize, "9pt");
axis.setProperty(StyleTextPropertiesElement.FontSizeAsian, "9pt");
axis.setProperty(StyleTextPropertiesElement.FontSizeComplex, "9pt");
}
if (axis.getChartDimensionAttribute().equals("z")) {
// z axis
axis.setProperty(StyleChartPropertiesElement.DisplayLabel, "true");
axis.setProperty(StyleChartPropertiesElement.Logarithmic, "false");
axis.setProperty(StyleChartPropertiesElement.ReverseDirection, "false");
axis.setProperty(StyleChartPropertiesElement.LineBreak, "false");
axis.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
axis.setProperty(StyleTextPropertiesElement.FontSize, "10pt");
axis.setProperty(StyleTextPropertiesElement.FontSizeAsian, "10pt");
axis.setProperty(StyleTextPropertiesElement.FontSizeComplex, "10pt");
}
}
Dr3dLightElement light1 = plotArea.newDr3dLightElement("");
light1.setDr3dDiffuseColorAttribute("#b3b3b3");
light1.setDr3dDirectionAttribute("(0 0 1)");
light1.setDr3dEnabledAttribute(new Boolean(false));
light1.setDr3dSpecularAttribute(new Boolean(true));
Dr3dLightElement light2 = plotArea.newDr3dLightElement("");
light2.setDr3dDiffuseColorAttribute("#999999");
light2.setDr3dDirectionAttribute("(-0.2 0.7 0.6)");
light2.setDr3dEnabledAttribute(new Boolean(true));
light2.setDr3dSpecularAttribute(new Boolean(false));
Dr3dLightElement light3 = plotArea.newDr3dLightElement("");
light3.setDr3dDiffuseColorAttribute("#b3b3b3");
light3.setDr3dDirectionAttribute("(0 0 1)");
light3.setDr3dEnabledAttribute(new Boolean(false));
light3.setDr3dSpecularAttribute(new Boolean(false));
Dr3dLightElement light4 = plotArea.newDr3dLightElement("");
light4.setDr3dDiffuseColorAttribute("#b3b3b3");
light4.setDr3dDirectionAttribute("(0 0 1)");
light4.setDr3dEnabledAttribute(new Boolean(false));
light4.setDr3dSpecularAttribute(new Boolean(false));
Dr3dLightElement light5 = plotArea.newDr3dLightElement("");
light5.setDr3dDiffuseColorAttribute("#b3b3b3");
light5.setDr3dDirectionAttribute("(0 0 1)");
light5.setDr3dEnabledAttribute(new Boolean(false));
light5.setDr3dSpecularAttribute(new Boolean(false));
Dr3dLightElement light6 = plotArea.newDr3dLightElement("");
light6.setDr3dDiffuseColorAttribute("#b3b3b3");
light6.setDr3dDirectionAttribute("(0 0 1)");
light6.setDr3dEnabledAttribute(new Boolean(false));
light6.setDr3dSpecularAttribute(new Boolean(false));
Dr3dLightElement light7 = plotArea.newDr3dLightElement("");
light7.setDr3dDiffuseColorAttribute("#b3b3b3");
light7.setDr3dDirectionAttribute("(0 0 1)");
light7.setDr3dEnabledAttribute(new Boolean(false));
light7.setDr3dSpecularAttribute(new Boolean(false));
Dr3dLightElement light8 = plotArea.newDr3dLightElement("");
light8.setDr3dDiffuseColorAttribute("#b3b3b3");
light8.setDr3dDirectionAttribute("(0 0 1)");
light8.setDr3dEnabledAttribute(new Boolean(false));
light8.setDr3dSpecularAttribute(new Boolean(false));
} else {
NodeList lights = plotArea.getElementsByTagName(Dr3dLightElement.ELEMENT_NAME.getQName());
for (int i = 0; i < lights.getLength(); i++) {
plotArea.removeChild(lights.item(i));
}
if (lights.getLength() > 0) {
plotArea.removeAttributeNS(OdfDocumentNamespace.SVG.getUri(), "vpn");
plotArea.removeAttributeNS(OdfDocumentNamespace.SVG.getUri(), "vrn");
plotArea.removeAttributeNS(OdfDocumentNamespace.SVG.getUri(), "vun");
plotArea.removeAttributeNS(OdfDocumentNamespace.SVG.getUri(), "projection");
plotArea.removeAttributeNS(OdfDocumentNamespace.SVG.getUri(), "distance");
plotArea.removeAttributeNS(OdfDocumentNamespace.SVG.getUri(), "focal-length");
plotArea.removeAttributeNS(OdfDocumentNamespace.SVG.getUri(), "shadow-slant");
plotArea.removeAttributeNS(OdfDocumentNamespace.SVG.getUri(), "shade-mode");
plotArea.removeAttributeNS(OdfDocumentNamespace.SVG.getUri(), "ambient-color");
plotArea.removeAttributeNS(OdfDocumentNamespace.SVG.getUri(), "lighting-mode");
plotArea.removeProperty(StyleChartPropertiesElement.ThreeDimensional);
plotArea.removeProperty(StyleChartPropertiesElement.SortByXValues);
plotArea.setProperty(StyleChartPropertiesElement.RightAngledAxes, "true");
}
NodeList chartAxises = (NodeList) plotArea.getElementsByTagName(ChartAxisElement.ELEMENT_NAME.getQName());
for (int i = 0; i < chartAxises.getLength(); i++) {
ChartAxisElement axis = (ChartAxisElement) chartAxises.item(i);
if (axis.getChartDimensionAttribute().equals("x")) {
// x axis
axis.setProperty(StyleChartPropertiesElement.DisplayLabel, "true");
axis.setProperty(StyleChartPropertiesElement.Logarithmic, "false");
axis.setProperty(StyleChartPropertiesElement.ReverseDirection, "false");
axis.setProperty(StyleChartPropertiesElement.LineBreak, "false");
axis.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
axis.setProperty(StyleTextPropertiesElement.FontSize, "10pt");
axis.setProperty(StyleTextPropertiesElement.FontSizeAsian, "10pt");
axis.setProperty(StyleTextPropertiesElement.FontSizeComplex, "10pt");
}
if (axis.getChartDimensionAttribute().equals("y")) {
// y axis
axis.setProperty(StyleChartPropertiesElement.DisplayLabel, "true");
axis.setProperty(StyleChartPropertiesElement.Logarithmic, "false");
axis.setProperty(StyleChartPropertiesElement.ReverseDirection, "false");
axis.setProperty(StyleChartPropertiesElement.LineBreak, "false");
axis.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
axis.setProperty(StyleTextPropertiesElement.FontSize, "10pt");
axis.setProperty(StyleTextPropertiesElement.FontSizeAsian, "10pt");
axis.setProperty(StyleTextPropertiesElement.FontCharsetComplex, "10pt");
}
if (axis.getChartDimensionAttribute().equals("z")) {
// z axis
axis.removeProperty(StyleChartPropertiesElement.DisplayLabel);
axis.removeProperty(StyleChartPropertiesElement.Logarithmic);
axis.removeProperty(StyleChartPropertiesElement.ReverseDirection);
axis.removeProperty(StyleChartPropertiesElement.LineBreak);
axis.removeProperty(StyleGraphicPropertiesElement.StrokeColor);
axis.removeProperty(StyleTextPropertiesElement.FontSize);
axis.removeProperty(StyleTextPropertiesElement.FontSizeAsian);
axis.removeProperty(StyleTextPropertiesElement.FontSizeComplex);
}
}
}
}
/**
* chart axis manipulation, set the chart axis title according to the give
* dimension
*
* @param dimType
* the chart axis dimension, x,y, or z
* @param title
* the title of axis
*/
public void setAxisTitle(String dimType, String title) {
NodeList chartAxises = (NodeList) plotArea.getElementsByTagName(ChartAxisElement.ELEMENT_NAME.getQName());
for (int i = 0; i < chartAxises.getLength(); i++) {
ChartAxisElement axis = (ChartAxisElement) chartAxises.item(i);
String dimension = axis.getAttributeNS(OdfDocumentNamespace.CHART.getUri(), "dimension");
if (dimension.equals(dimType)) {
NodeList titles = axis.getElementsByTagName(ChartTitleElement.ELEMENT_NAME.getQName());
ChartTitleElement axisTitle;
if (titles.getLength() == 0) {
axisTitle = axis.newChartTitleElement();
if (dimension.equals(ChartDimensionAttribute.Value.x.toString())) {
axisTitle.setSvgXAttribute(AXIS_SVG_X);
axisTitle.setSvgYAttribute(AXIS_SVG_Y);
} else {
axisTitle.setSvgXAttribute("0.161cm");
axisTitle.setSvgYAttribute("4.188cm");
}
axisTitle.setProperty(StyleTextPropertiesElement.FontSize, AXIS_FONTSIZE);
axisTitle.setProperty(StyleTextPropertiesElement.FontSizeAsian, AXIS_FONTSIZEASIAN);
axisTitle.setProperty(StyleTextPropertiesElement.FontSizeComplex, AXIS_FONTSIZECOMPLEX);
} else {
axisTitle = (ChartTitleElement) titles.item(0);
}
NodeList paras = axisTitle.getElementsByTagNameNS(OdfDocumentNamespace.TEXT.getUri(), "p");
if (paras.getLength() == 0) {
axisTitle.newTextPElement().setTextContent(title);
} else {
TextPElement para0 = (TextPElement) paras.item(0);
para0.setTextContent(title);
}
}
}
}
/**
* chart data manipulation, set chart data
*
* @param dataset
* the data set for the chart, which is a 2 dimensional data
* container
*/
public void setChartData(DataSet dataset) {
this.dataSet = dataset;
boolean isFirstRowAsLabel = dataSet.isFirstRowAsLabel();
boolean isFirstColumnAsLabel = dataSet.isFirstColumnAsLabel();
boolean isRowAsSeries = dataSet.isRowAsDataSeries();
setPlotArea();
NodeList tables = chartElement.getElementsByTagNameNS(OdfDocumentNamespace.CHART.getUri(), "table");
if (tables.getLength() > 0) {
chartElement.removeChild(tables.item(0));
}
// judge the cell range or local data
/*
* if (dataset.getCellRangeAddress() != null) {
* plotArea.setTableCellRangeAddressAttribute
* (dataset.getCellRangeAddress().toString()); if
* (dataset.isFirstColumnAsLabel() && dataset.isFirstRowAsLabel())
* plotArea
* .setChartDataSourceHasLabelsAttribute(ChartDataSourceHasLabelsAttribute
* .Value.BOTH.toString()); else if (dataset.isFirstColumnAsLabel())
* plotArea
* .setChartDataSourceHasLabelsAttribute(ChartDataSourceHasLabelsAttribute
* .Value.COLUMN.toString()); else if (dataset.isFirstRowAsLabel())
* plotArea
* .setChartDataSourceHasLabelsAttribute(ChartDataSourceHasLabelsAttribute
* .Value.ROW.toString()); if (dataset.isRowAsDataSeries())
* plotArea.setProperty(StyleChartPropertiesElement.SeriesSource,
* "rows"); else
* plotArea.setProperty(StyleChartPropertiesElement.SeriesSource,
* "columns"); }
*/
table = chartElement.newTableTableElement();
headerColumns = table.newTableTableHeaderColumnsElement();
headerColumns.newTableTableColumnElement();
columns = table.newTableTableColumnsElement();
column = columns.newTableTableColumnElement();
headerRows = table.newTableTableHeaderRowsElement();
headerRow = headerRows.newTableTableRowElement();
rows = table.newTableTableRowsElement();
// create table lable cells
int numColumns = dataset.getLocalTableFirstRow().length;
int numRows = dataset.getLocalTableFirstColumn().length;
column.setTableNumberColumnsRepeatedAttribute(new Integer(numColumns));
headerRow.newTableTableCellElement(0.0, "string");
Object[] labelCellRange = getLabelCellRange();
Object[] valueCellRange = getValueCellRange();
for (int i = 0; i < numColumns; i++) {
TableTableCellElement cell = headerRow.newTableTableCellElement(0.0, "string");
cell.setOfficeValueTypeAttribute(OfficeValueTypeAttribute.Value.STRING.toString());
String[] cellContents = dataset.getLocalTableFirstRow();
OdfTextParagraph paragraph = (OdfTextParagraph) cell.newTextPElement();
if (isFirstRowAsLabel && !isRowAsSeries) {
if ((String) labelCellRange[i] != null) {
paragraph.setTextIdAttribute((String) labelCellRange[i]);
}
}
if (isFirstRowAsLabel && isRowAsSeries && i == 0) {
if ((String) getTableCellRange() != null) {
paragraph.setTextIdAttribute(getTableCellRange());
}
}
if (cellContents[i] != null) {
paragraph.setTextContent(cellContents[i]);
} else {
paragraph.setTextContent("");
}
}
// create table rows
Double[][] cellValues = dataset.getLocalTableData();
for (int i = 0; i < numRows; i++) {
TableTableRowElement row = rows.newTableTableRowElement();
TableTableCellElement nameCell = row.newTableTableCellElement(0.0, "string");
nameCell.setOfficeValueTypeAttribute(OfficeValueTypeAttribute.Value.STRING.toString());
OdfTextParagraph paragraph = (OdfTextParagraph) nameCell.newTextPElement();
String[] cellContents = dataset.getLocalTableFirstColumn();
if (cellContents[i] != null) {
if (isFirstColumnAsLabel) {
if (isRowAsSeries) {
paragraph.setTextIdAttribute((String) labelCellRange[i]);
}
if (!isRowAsSeries && i == 0) {
paragraph.setTextIdAttribute(getTableCellRange());
}
}
paragraph.setTextContent(cellContents[i]);
} else {
paragraph.setTextContent("");
}
for (int j = 0; j < numColumns; j++) {
TableTableCellElement cell = row.newTableTableCellElement(0.0, "string");
cell.setOfficeValueTypeAttribute(OfficeValueTypeAttribute.Value.FLOAT.toString());
if (cellValues[i][j] != null) {
cell.setOfficeValueAttribute(cellValues[i][j]);
OdfTextParagraph paragraph1 = (OdfTextParagraph) cell.newTextPElement();
paragraph1.setTextContent(cellValues[i][j].toString());
if (isRowAsSeries && j == 0) {
paragraph1.setTextIdAttribute((String) valueCellRange[i]);
}
if (!isRowAsSeries && i == 0) {
paragraph1.setTextIdAttribute((String) valueCellRange[j]);
}
} else {
cell.setOfficeValueAttribute(new Double(Double.NaN));
OdfTextParagraph paragraph1 = (OdfTextParagraph) cell.newTextPElement();
paragraph1.setTextContent("1.#NAN");
if (isRowAsSeries && j == 0) {
paragraph1.setTextIdAttribute((String) valueCellRange[i]);
}
if (!isRowAsSeries && i == 0) {
paragraph1.setTextIdAttribute((String) valueCellRange[j]);
}
}
}
}
}
/**
* chart title manipulation, get the current chart title
*
* @return return the chart title
*/
public boolean setChartTitle(String title) {
// chart:title
NodeList titles = chartElement.getElementsByTagNameNS(OdfDocumentNamespace.CHART.getUri(), "title");
if (titles.getLength() == 0) {
chartTitle = chartElement.newChartTitleElement();
chartTitle.setSvgXAttribute("3.669cm");
chartTitle.setSvgYAttribute("0.141cm");
chartTitle.setProperty(StyleTextPropertiesElement.FontSize, "12pt");
chartTitle.setProperty(StyleTextPropertiesElement.FontSizeAsian, "12pt");
chartTitle.setProperty(StyleTextPropertiesElement.FontSizeComplex, "12pt");
} else {
chartTitle = (ChartTitleElement) titles.item(0);
}
NodeList paras = chartTitle.getElementsByTagNameNS(OdfDocumentNamespace.TEXT.getUri(), "p");
if (paras.getLength() == 0) {
chartTitle.newTextPElement().setTextContent(title);
} else {
OdfTextParagraph para0 = (OdfTextParagraph) paras.item(0);
para0.setTextContent(title);
}
return true;
}
/**
* chart type manipulation, set a chart type when chart type is changed, all
* the corresponding chart behaviors and properties should be changed
* accordingly
*
* @param type
* the type of chart
*/
public void setChartType(ChartType type) {
// set chart:class for chart:chart element
chartElement.setChartClassAttribute(type.toString());
// set chart:class for the chart:series
NodeList plotAreas = chartElement.getElementsByTagName(ChartPlotAreaElement.ELEMENT_NAME.getQName());
if (plotAreas.getLength() > 0) {
ChartPlotAreaElement plotArea = (ChartPlotAreaElement) plotAreas.item(0);
NodeList series = plotArea.getElementsByTagName(ChartSeriesElement.ELEMENT_NAME.getQName());
for (int i = 0; i < series.getLength(); i++) {
ChartSeriesElement serie = (ChartSeriesElement) series.item(i);
serie.setChartClassAttribute(type.toString());
}
}
}
/**
* chart legend manipulation, get whether the chart use legend
*
* @param useLegend
* a flag specifying whether or not use legend
*/
public void setUseLegend(boolean useLegend) {
this.isUseLegend = useLegend;
NodeList legends = chartElement.getElementsByTagNameNS(OdfDocumentNamespace.CHART.getUri(), "legend");
if (useLegend) {
if (legends.getLength() == 0) {
legend = chartElement.newChartLegendElement(ChartLegendPositionAttribute.Value.TOP_END.toString(),
StyleLegendExpansionAttribute.Value.BALANCED.toString());
legend.setSvgXAttribute("6.715cm");
legend.setSvgYAttribute("3.192cm");
legend.setProperty(StyleGraphicPropertiesElement.Stroke, "none");
legend.setProperty(StyleGraphicPropertiesElement.StrokeColor, "#b3b3b3");
legend.setProperty(StyleGraphicPropertiesElement.Fill, "none");
legend.setProperty(StyleGraphicPropertiesElement.FillColor, "#e6e6e6");
legend.setProperty(StyleTextPropertiesElement.FontSize, "10pt");
legend.setProperty(StyleTextPropertiesElement.FontSizeAsian, "10pt");
legend.setProperty(StyleTextPropertiesElement.FontSizeComplex, "10pt");
}
} else {
if (legends.getLength() > 0) {
chartElement.removeChild(legends.item(0));
}
}
}
/**
* Refresh chart view and data setting.
*/
public void refreshChart() {
setPlotArea();
setChartData(dataSet);
}
private String getRandColorCode() {
String r, g, b;
Random random = new Random();
r = Integer.toHexString(random.nextInt(256)).toUpperCase();
g = Integer.toHexString(random.nextInt(256)).toUpperCase();
b = Integer.toHexString(random.nextInt(256)).toUpperCase();
r = r.length() == 1 ? "0" + r : r;
g = g.length() == 1 ? "0" + g : g;
b = b.length() == 1 ? "0" + b : b;
return "#" + r + g + b;
}
private Object[] getValueCellRange() {
Vector<String> seriesCellRange = new Vector<String>();
Vector<String> legendCellAddr = new Vector<String>();
if (dataSet.isLocalTable()) {
dataSet.getLocalTableCellRanges(dataSet.getDataSeriesCount(), dataSet.getLabels().length, seriesCellRange,
legendCellAddr);
} else {
dataSet.getCellRanges(dataSet.getCellRangeAddress().toString(), dataSet.isFirstRowAsLabel(), dataSet
.isFirstColumnAsLabel(), dataSet.isRowAsDataSeries(), seriesCellRange, legendCellAddr);
}
return seriesCellRange.toArray();
}
private Object[] getLabelCellRange() {
Vector<String> seriesCellRange = new Vector<String>();
Vector<String> legendCellAddr = new Vector<String>();
if (dataSet.isLocalTable()) {
getLocalTableCellRanges(dataSet.getDataSeriesCount(), dataSet.getLabels().length, seriesCellRange,
legendCellAddr);
} else {
getCellRanges(dataSet.getCellRangeAddress().toString(), dataSet.isFirstRowAsLabel(), dataSet
.isFirstColumnAsLabel(), dataSet.isRowAsDataSeries(), seriesCellRange, legendCellAddr);
}
return legendCellAddr.toArray();
}
private String getTableCellRange() {
Vector<String> seriesCellRange = new Vector<String>();
Vector<String> legendCellAddr = new Vector<String>();
String cellRange;
if (dataSet.isLocalTable()) {
cellRange = getLocalTableCellRanges(dataSet.getDataSeriesCount(), dataSet.getLabels().length,
seriesCellRange, legendCellAddr);
} else {
cellRange = getCellRanges(dataSet.getCellRangeAddress().toString(), dataSet.isFirstRowAsLabel(), dataSet
.isFirstColumnAsLabel(), dataSet.isRowAsDataSeries(), seriesCellRange, legendCellAddr);
}
return cellRange;
}
// return label cell ranges
private String getCellRanges(String tablecellrange, boolean bFirstRowAsLabel, boolean bFirstColumnAsLabel,
boolean rowAsDataSeries, Vector<String> seriesCellRange, Vector<String> legendCellAddr) {
// prepare variables
String labelCellRange = null;
if (seriesCellRange == null)
seriesCellRange = new Vector<String>();
else
seriesCellRange.removeAllElements();
if (legendCellAddr == null)
legendCellAddr = new Vector<String>();
else
legendCellAddr.removeAllElements();
// seperate column and row from cell range
StringTokenizer st = new StringTokenizer(tablecellrange, ".:$ ");
if (st.countTokens() < 3)
return null;
String sheettable = st.nextToken();
String begincell = st.nextToken();
String endcell = st.nextToken();
if (st.hasMoreTokens()) {
endcell = st.nextToken();
}
char beginColumn = begincell.charAt(0);
char endColumn = endcell.charAt(0);
int beginRow = Integer.parseInt(begincell.substring(1));
int endRow = Integer.parseInt(endcell.substring(1));
if (rowAsDataSeries) {
int starti = beginRow + 1;
if (!bFirstRowAsLabel) {
labelCellRange = null;
starti = beginRow;
} else if (bFirstColumnAsLabel)
labelCellRange = createCellRange(sheettable, beginRow, (char) (beginColumn + 1), beginRow, endColumn);
else
labelCellRange = createCellRange(sheettable, beginRow, beginColumn, beginRow, endColumn);
for (int i = starti; i < endRow + 1; i++) {
if (bFirstColumnAsLabel) {
seriesCellRange.add(createCellRange(sheettable, i, (char) (beginColumn + 1), i, endColumn));
} else {
seriesCellRange.add(createCellRange(sheettable, i, beginColumn, i, endColumn));
}
if (bFirstColumnAsLabel) {
legendCellAddr.add(sheettable + "." + beginColumn + i);
} else {
legendCellAddr.add(null);
}
}
} else {
char startch = (char) (beginColumn + 1);
if (!bFirstColumnAsLabel) {
labelCellRange = null;
startch = beginColumn;
} else if (bFirstRowAsLabel)
labelCellRange = createCellRange(sheettable, beginRow + 1, beginColumn, endRow, beginColumn);
else
labelCellRange = createCellRange(sheettable, beginRow, beginColumn, endRow, beginColumn);
for (char ch = startch; ch <= endColumn; ch++) {
if (bFirstRowAsLabel)
seriesCellRange.add(createCellRange(sheettable, beginRow + 1, ch, endRow, ch));
else
seriesCellRange.add(createCellRange(sheettable, beginRow, ch, endRow, ch));
if (bFirstRowAsLabel)
legendCellAddr.add(sheettable + "." + ch + beginRow);
else
legendCellAddr.add(null);
}
}
return labelCellRange;
}
// return legend cell ranges
private String getLocalTableCellRanges(int seriesCount, int labelLength, Vector<String> seriesCellRange,
Vector<String> legendCellAddr) {
String localtable = "local-table";
String tablecellrange = localtable + "." + "A1:" + (char) ('A' + seriesCount) + (1 + labelLength);
return dataSet.getCellRanges(tablecellrange, true, true, false, seriesCellRange, legendCellAddr);
}
private String createCellRange(String table, int beginRow, char beginColumn, int endRow, char endColumn) {
return table + "." + beginColumn + beginRow + ":" + table + "." + endColumn + endRow;
}
}