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.LogisticsInventoryFormatter;
042:
043: import org.cougaar.logistics.ui.inventory.data.InventoryData;
044: import org.cougaar.logistics.ui.inventory.data.InventoryLevel;
045: import org.cougaar.logistics.ui.inventory.data.InventoryScheduleHeader;
046: import org.cougaar.logistics.ui.inventory.data.InventoryScheduleElement;
047:
048: /**
049: * <pre>
050: *
051: * The OrgActivityChartDataModel is the 2nd ChartDataModel for the
052: * InventoryLevelChart. It shows the defensive and offensive,
053: * org activities as background to the inventory levels.
054: *
055: *
056: * @see InventoryBaseChartDataModel
057: *
058: **/
059:
060: public class OrgActivityChartDataModel extends
061: InventoryBaseChartDataModel {
062:
063: protected double offensiveQty = 0.0;
064: protected double defensiveQty = 0.0;
065:
066: protected ArrayList orgActs;
067:
068: public static final int OFFENSIVE_SERIES_INDEX = 0;
069: public static final int DEFENSIVE_SERIES_INDEX = 1;
070:
071: public static final String ORG_ACTIVITY_SERIES_LABEL = "Activity Level";
072:
073: public static final String OFFENSIVE_SERIES_LABEL = "Offensive";
074: public static final String DEFENSIVE_SERIES_LABEL = "Defensive";
075:
076: public static final String ORG_ACTIVITY_LEGEND = "";
077:
078: public OrgActivityChartDataModel() {
079: this (null, ORG_ACTIVITY_LEGEND);
080: }
081:
082: public OrgActivityChartDataModel(String legendTitle) {
083: this (null, legendTitle);
084: }
085:
086: //Subclass needed a no arg construtor that did nothing but that
087: //was taken above.
088: //The below constructor was made to prevent the subclass from calling
089: //the no arg constructor automatically.
090: //This allowed me to call this one explicitly from the subclass.
091: public OrgActivityChartDataModel(String x, String y, String z) {
092: }
093:
094: public OrgActivityChartDataModel(InventoryData data,
095: String theLegendTitle) {
096: inventory = data;
097: legendTitle = theLegendTitle;
098: nSeries = 2;
099: seriesLabels = new String[nSeries];
100: seriesLabels[OFFENSIVE_SERIES_INDEX] = OFFENSIVE_SERIES_LABEL;
101: seriesLabels[DEFENSIVE_SERIES_INDEX] = DEFENSIVE_SERIES_LABEL;
102: logger = Logging.getLogger(this );
103: orgActs = new ArrayList();
104: initValues();
105: }
106:
107: public String getActivityFromLevel(double value) {
108: if (value == defensiveQty) {
109: return "Defensive";
110: } else {
111: return "Offensive";
112: }
113: }
114:
115: public double getLevelFromActivity(String value) {
116: if (value.trim().toLowerCase().equals("defensive")) {
117: return defensiveQty;
118: } else {
119: return offensiveQty;
120: }
121: }
122:
123: public void setValues() {
124: if (valuesSet)
125: return;
126: setInventoryValues();
127: valuesSet = true;
128: }
129:
130: public boolean hasOrgActivities() {
131: return !orgActs.isEmpty();
132: }
133:
134: public void setInventoryValues() {
135:
136: if (inventory == null) {
137: xvalues = new double[nSeries][0];
138: yvalues = new double[nSeries][0];
139: return;
140: }
141:
142: InventoryScheduleHeader schedHeader = (InventoryScheduleHeader) inventory
143: .getSchedules()
144: .get(LogisticsInventoryFormatter.INVENTORY_LEVELS_TAG);
145: ArrayList levels = schedHeader.getSchedule();
146:
147: computeCriticalNValues();
148:
149: xvalues = new double[nSeries][];
150: yvalues = new double[nSeries][];
151: //initZeroYVal(nValues);
152: for (int i = 0; i < (nSeries); i++) {
153: xvalues[i] = new double[nValues];
154: yvalues[i] = new double[nValues];
155: for (int j = 0; j < nValues; j++) {
156: xvalues[i][j] = minBucket + (j * bucketDays);
157: yvalues[i][j] = 0;
158: }
159: }
160:
161: orgActs.clear();
162:
163: double maxQty = 0;
164:
165: //Need to add target level which is a little more complicated
166: //than you think. We don't know how many values there are
167: //in this third series. We have to add them if they are non null
168: //to a vector, allocated the third series same length as the
169: //vector and put them into there. mildly tricky business.
170: for (int i = 0; i < levels.size(); i++) {
171: InventoryLevel level = (InventoryLevel) levels.get(i);
172: Double invQty = level.getInventoryLevel();
173: if (invQty != null) {
174: maxQty = Math.max(maxQty,
175: (invQty.doubleValue() * unitFactor));
176: }
177: double reorderQty = level.getReorderLevel();
178: maxQty = Math.max(maxQty, reorderQty);
179: if (level.getTargetLevel() != null) {
180: maxQty = Math.max(maxQty, level.getTargetLevel()
181: .doubleValue());
182: }
183: if (level.getActivityType() != null) {
184: orgActs.add(level);
185: }
186: }
187:
188: offensiveQty = maxQty * 1.15;
189: //offensiveQty = maxQty + 5;
190: //defensiveQty = offensiveQty * .25;
191: //offensiveQty = defensiveQty;
192: defensiveQty = offensiveQty;
193:
194: for (int i = 0; i < orgActs.size(); i++) {
195: InventoryLevel level = (InventoryLevel) orgActs.get(i);
196: long startTime = level.getStartTime();
197: long endTime = level.getEndTime();
198: int startDay = (int) computeBucketFromTime(startTime);
199: int endDay = (int) computeBucketFromTime(endTime);
200: String actType = level.getActivityType();
201: //xvalues[OFFENSIVE_SERIES_INDEX][i] = startDay;
202: for (int j = startDay; j < endDay; j += bucketDays) {
203: if (actType.trim().toLowerCase().equals("defensive")) {
204: yvalues[DEFENSIVE_SERIES_INDEX][(j - minBucket)
205: / bucketDays] = defensiveQty;
206: } else {
207: yvalues[OFFENSIVE_SERIES_INDEX][(j - minBucket)
208: / bucketDays] = offensiveQty;
209: }
210: }
211: }
212: }
213: }
|