001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.logistics.ui.inventory;
028:
029: import java.util.ArrayList;
030:
031: import com.klg.jclass.chart.ChartDataModel;
032: import com.klg.jclass.chart.LabelledChartDataModel;
033: import com.klg.jclass.chart.ChartDataSupport;
034: import com.klg.jclass.chart.ChartDataEvent;
035: import com.klg.jclass.chart.ChartDataManageable;
036: import com.klg.jclass.chart.ChartDataManager;
037:
038: import org.cougaar.util.log.Logging;
039: import org.cougaar.util.log.Logger;
040:
041: import org.cougaar.logistics.plugin.inventory.TimeUtils;
042:
043: import org.cougaar.logistics.plugin.inventory.LogisticsInventoryFormatter;
044:
045: import org.cougaar.logistics.ui.inventory.data.InventoryData;
046: import org.cougaar.logistics.ui.inventory.data.InventoryScheduleHeader;
047: import org.cougaar.logistics.ui.inventory.data.InventoryScheduleElement;
048: import org.cougaar.logistics.ui.inventory.data.InventoryPreferenceData;
049:
050: /**
051: * <pre>
052: *
053: * The InventoryBaseChartDataModel is the base abstract superclass of all
054: * the data models that underly the charts in the gui.
055: * Its the bridge between the data and the interface necessary
056: * to use the jchart software.
057: *
058: *
059: * @see InventoryLevelChartDataModel
060: *
061: **/
062:
063: public abstract class InventoryBaseChartDataModel extends
064: ChartDataSupport implements ChartDataManageable,
065: ChartDataModel, LabelledChartDataModel {
066:
067: private final static long MILLIS_IN_DAY = TimeUtils.MSEC_PER_DAY;
068: private final static long MILLIS_IN_HOUR = TimeUtils.MSEC_PER_HOUR;
069:
070: protected int nSeries;
071: protected double xvalues[][];
072: protected double yvalues[][];
073: protected String[] seriesLabels;
074: protected String[] scheduleNames;
075:
076: protected int minBucket = -1;
077: protected int maxBucket = 0;
078: protected int bucketDays = 1;
079: protected long bucketSize = MILLIS_IN_DAY;
080:
081: protected int nValues = 0;
082:
083: protected String legendTitle;
084:
085: protected InventoryData inventory;
086: protected InventoryPreferenceData prefData;
087:
088: protected double unitFactor;
089:
090: protected boolean valuesSet;
091:
092: protected Logger logger;
093:
094: protected boolean useCDay = false;
095: protected long baseCDayTime = 0L;
096: protected long baseTime = 0L;
097:
098: public ChartDataManager getChartDataManager() {
099: return (ChartDataManager) this ;
100: }
101:
102: public String getDataSourceName() {
103: return legendTitle;
104: }
105:
106: public void resetInventory(InventoryData newInventory) {
107: inventory = newInventory;
108: baseCDayTime = inventory.getStartCDay();
109: baseTime = (useCDay) ? baseCDayTime
110: : InventoryChartBaseCalendar.getBaseTime();
111: unitFactor = (InventoryChart.getConversionTable()
112: .getConversionForData(newInventory, prefData))
113: .getFactor();
114: valuesSet = false;
115: initValues();
116: fireChartDataEvent(ChartDataEvent.RELOAD, 0, 0);
117: }
118:
119: public void setDisplayCDay(boolean doUseCDay) {
120: if (doUseCDay != useCDay) {
121: useCDay = doUseCDay;
122: if (inventory != null) {
123: resetInventory(inventory);
124: }
125: }
126: }
127:
128: public void setInitialDisplayCDay(boolean doUseCDay) {
129: useCDay = doUseCDay;
130: }
131:
132: /**
133: * Retrieves the specified x-value series
134: * This returns the nominal getXSeries of the super class
135: * @param index data series index
136: * @return array of double values representing x-value data
137: */
138: public double[] getRealXSeries(int index) {
139: return getXSeries(index);
140: }
141:
142: /**
143: * Retrieves the specified y-value series
144: * The nth asset.
145: * This returns the nominal getYSeries of the super class
146: * This aids the ProjectionChartDataModel which
147: * has a real projected dimension which is added
148: * to actual demand to give an artificial
149: * bar type chart.
150: * @param index data series index
151: * @return array of double values representing y-value data
152: */
153: public synchronized double[] getRealYSeries(int index) {
154: return getYSeries(index);
155: }
156:
157: /**
158: * Retrieves the specified x-value series
159: * Start and end times of the schedule for each asset
160: * @param index data series index
161: * @return array of double values representing x-value data
162: */
163: public double[] getXSeries(int index) {
164: initValues();
165: if (xvalues == null) {
166: logger
167: .error("InventoryChartDataModel ERROR getXSeries no xvalues?");
168: }
169: return xvalues[index];
170: }
171:
172: /**
173: * Retrieves the specified y-value series
174: * The nth asset
175: * @param index data series index
176: * @return array of double values representing y-value data
177: */
178: public synchronized double[] getYSeries(int index) {
179: initValues();
180: if (yvalues == null) {
181: logger
182: .error("InventoryChartDataModel ERROR getYSeries no yvalues?");
183: }
184: return yvalues[index];
185: }
186:
187: /**
188: * Retrieves the number of data series.
189: */
190: public int getNumSeries() {
191: initValues();
192: return nSeries;
193: }
194:
195: public String[] getPointLabels() {
196: return null;
197: }
198:
199: public String[] getSeriesLabels() {
200: return seriesLabels;
201: }
202:
203: public void initValues() {
204: if (!valuesSet) {
205: setValues();
206: }
207: }
208:
209: public abstract void setValues();
210:
211: public int computeBucketFromTime(long time) {
212: long graphTime = (time - baseTime);
213: int bucket = (int) (graphTime / bucketSize);
214: if (graphTime < 0) {
215: bucket--;
216: }
217: return bucket;
218: }
219:
220: public void computeCriticalNValues() {
221:
222: minBucket = 0;
223: maxBucket = 0;
224: bucketDays = 1;
225: nValues = 0;
226:
227: if (inventory == null)
228: return;
229:
230: InventoryScheduleHeader schedHeader = (InventoryScheduleHeader) inventory
231: .getSchedules()
232: .get(LogisticsInventoryFormatter.INVENTORY_LEVELS_TAG);
233: ArrayList levels = schedHeader.getSchedule();
234:
235: if (levels.size() == 0) {
236: return;
237: }
238:
239: bucketDays = -1;
240: maxBucket = Integer.MIN_VALUE;
241: minBucket = Integer.MIN_VALUE;
242:
243: for (int i = 0; i < levels.size(); i++) {
244: InventoryScheduleElement level = (InventoryScheduleElement) levels
245: .get(i);
246: long startTime = level.getStartTime();
247: long endTime = level.getEndTime();
248: bucketSize = endTime - startTime;
249: int startBucket = computeBucketFromTime(startTime);
250: int endBucket = computeBucketFromTime(endTime);
251:
252: if (bucketDays == -1) {
253: if (bucketSize >= MILLIS_IN_DAY) {
254: bucketDays = (int) (bucketSize / MILLIS_IN_DAY);
255: } else {
256: bucketDays = (int) (bucketSize / MILLIS_IN_HOUR);
257: }
258: }
259: if (minBucket == Integer.MIN_VALUE) {
260: minBucket = startBucket;
261: } else if (startBucket < minBucket) {
262: minBucket = startBucket;
263: }
264: maxBucket = Math.max(endBucket, maxBucket);
265: }
266: if (bucketDays >= 1) {
267: nValues = (maxBucket - minBucket + 1) / bucketDays;
268:
269: if (logger.isDebugEnabled()) {
270: logger.debug("computeNValues:minBucket=" + minBucket
271: + " maxBucket=" + maxBucket + " bucketDays="
272: + bucketDays + " nValues=" + nValues);
273: }
274: }
275: }
276:
277: public void prefDataChanged(InventoryPreferenceData origData,
278: InventoryPreferenceData newData) {
279: prefData = newData;
280: }
281: }
|