001: /*
002: * Copyright 2006 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: *
013: * Created Jul 06, 2007
014: * @author gmoran
015: */
016: package org.pentaho.plugin.jfreereport.reportcharts;
017:
018: import java.util.ArrayList;
019: import java.util.Arrays;
020: import java.util.List;
021:
022: import org.apache.commons.logging.Log;
023: import org.apache.commons.logging.LogFactory;
024: import org.jfree.data.general.AbstractDataset;
025: import org.jfree.report.function.Expression;
026: import org.jfree.util.ObjectUtilities;
027:
028: public class XYZSeriesCollectorFunction extends
029: XYSeriesCollectorFunction {
030: private static final long serialVersionUID = -3612902208762624893L;
031:
032: private ArrayList zValueColumns;
033: private double maxZValue = 1.0;
034:
035: private static final Log myLogger = LogFactory
036: .getLog(XYZSeriesCollectorFunction.class);
037:
038: public XYZSeriesCollectorFunction() {
039: super ();
040: zValueColumns = new ArrayList();
041: }
042:
043: public void setzValueColumn(final int index, final String field) {
044: if (zValueColumns.size() == index) {
045: zValueColumns.add(field);
046: } else {
047: zValueColumns.set(index, field);
048: }
049: }
050:
051: public String getzValueColumn(final int index) {
052: return (String) zValueColumns.get(index);
053: }
054:
055: public int getzValueColumnCount() {
056: return zValueColumns.size();
057: }
058:
059: public String[] getzValueColumn() {
060: return (String[]) zValueColumns
061: .toArray(new String[zValueColumns.size()]);
062: }
063:
064: public void setzValueColumn(final String[] fields) {
065: this .zValueColumns.clear();
066: this .zValueColumns.addAll(Arrays.asList(fields));
067: }
068:
069: public double getMaxZValue() {
070: return maxZValue;
071: }
072:
073: protected void buildDataset() {
074:
075: ExtendedXYZDataset xyzDataset = null;
076: if (getDatasourceValue() instanceof ExtendedXYZDataset) {
077: xyzDataset = (ExtendedXYZDataset) getDatasourceValue();
078: }
079:
080: final int maxIndex = Math.min(this .getSeriesNameCount(), this
081: .getxValueColumnCount());
082: for (int i = 0; i < maxIndex; i++) {
083: String seriesName = this .getSeriesName(i);
084: final String xColumn = this .getxValueColumn(i);
085: final String yColumn = this .getyValueColumn(i);
086: final String zColumn = this .getzValueColumn(i);
087: final Object xValueObject = getDataRow().get(xColumn);
088: final Object yValueObject = getDataRow().get(yColumn);
089: final Object zValueObject = getDataRow().get(zColumn);
090:
091: if (isSeriesColumn()) {
092: Object tmp = getDataRow().get(seriesName);
093: if (tmp != null) {
094: seriesName = tmp.toString();
095: }
096: }
097:
098: Number xValue = (xValueObject instanceof Number) ? (Number) xValueObject
099: : null;
100: Number yValue = (yValueObject instanceof Number) ? (Number) yValueObject
101: : null;
102: Number zValue = (zValueObject instanceof Number) ? (Number) zValueObject
103: : null;
104:
105: if ((zValue != null) && (zValue.doubleValue() > maxZValue)) {
106: maxZValue = zValue.doubleValue();
107: }
108:
109: double[][] seriesValues = new double[3][1];
110: seriesValues[0][0] = xValue.doubleValue();
111: seriesValues[1][0] = yValue.doubleValue();
112: seriesValues[2][0] = zValue.doubleValue();
113:
114: // The way this is coded, it prevents there from
115: // ever being more than one point in a data series...
116: // This sounds vaguely correct for a bubble chart,
117: // and it is the way the bubble charts work in other engines..
118: // TODO review this with someone who knows the requirement
119:
120: xyzDataset.addSeries(seriesName, seriesValues);
121: xyzDataset.setMaxZValue(maxZValue);
122: }
123: }
124:
125: public AbstractDataset getNewDataset() {
126: return new ExtendedXYZDataset();
127: }
128:
129: /**
130: * Return a completly separated copy of this function. The copy no longer
131: * shares any changeable objects with the original function.
132: * Also from Thomas:
133: * Should retain data from the report definition, but clear calculated data.
134: *
135: * @return a copy of this function.
136: */
137: public Expression getInstance() {
138: final XYZSeriesCollectorFunction fn = (XYZSeriesCollectorFunction) super
139: .getInstance();
140: try {
141: fn.zValueColumns = (ArrayList) zValueColumns.clone();
142: fn.maxZValue = 1.0; // Reset this to the default value as it's a calculated value.
143: } catch (Exception ex) {
144: myLogger.error(ex);
145: throw new IllegalStateException(ex);
146: }
147: return fn;
148: }
149:
150: }
|