1 39 40 package org.jfree.data; 41 42 import org.jfree.data.time.RegularTimePeriod; 43 import org.jfree.data.time.TimeSeries; 44 import org.jfree.data.time.TimeSeriesCollection; 45 import org.jfree.data.time.TimeSeriesDataItem; 46 47 52 public class MovingAverage { 53 54 66 public static TimeSeriesCollection createMovingAverage(TimeSeriesCollection source, 67 String suffix, 68 int periodCount, 69 int skip) { 70 71 if (source == null) { 73 throw new IllegalArgumentException ( 74 "MovingAverage.createMovingAverage(...) : null source." 75 ); 76 } 77 78 if (periodCount < 1) { 79 throw new IllegalArgumentException ("MovingAverage.createMovingAverage(...) : " 80 + "periodCount must be greater than or equal to 1."); 81 } 82 83 TimeSeriesCollection result = new TimeSeriesCollection(); 84 85 for (int i = 0; i < source.getSeriesCount(); i++) { 86 TimeSeries sourceSeries = source.getSeries(i); 87 TimeSeries maSeries = createMovingAverage(sourceSeries, sourceSeries.getName() + suffix, 88 periodCount, skip); 89 result.addSeries(maSeries); 90 } 91 92 return result; 93 94 } 95 96 108 public static TimeSeries createMovingAverage(TimeSeries source, 109 String name, 110 int periodCount, 111 int skip) { 112 113 if (source == null) { 115 throw new IllegalArgumentException ( 116 "MovingAverage.createMovingAverage(...) : null source." 117 ); 118 } 119 120 if (periodCount < 1) { 121 throw new IllegalArgumentException ("MovingAverage.createMovingAverage(...) : " 122 + "periodCount must be greater than or equal to 1."); 123 124 } 125 126 TimeSeries result = new TimeSeries(name, source.getTimePeriodClass()); 127 128 if (source.getItemCount() > 0) { 129 130 long firstSerial = source.getDataItem(0).getPeriod().getSerialIndex() + skip; 133 134 for (int i = source.getItemCount() - 1; i >= 0; i--) { 135 136 TimeSeriesDataItem current = source.getDataItem(i); 138 RegularTimePeriod period = current.getPeriod(); 139 long serial = period.getSerialIndex(); 140 141 if (serial >= firstSerial) { 142 int n = 0; 144 double sum = 0.0; 145 long serialLimit = period.getSerialIndex() - periodCount; 146 int offset = 0; 147 boolean finished = false; 148 149 while ((offset < periodCount) && (!finished)) { 150 if ((i - offset) >= 0) { 151 TimeSeriesDataItem item = source.getDataItem(i - offset); 152 RegularTimePeriod p = item.getPeriod(); 153 Number v = item.getValue(); 154 long currentIndex = p.getSerialIndex(); 155 if (currentIndex > serialLimit) { 156 if (v != null) { 157 sum = sum + v.doubleValue(); 158 n = n + 1; 159 } 160 } 161 else { 162 finished = true; 163 } 164 } 165 offset = offset + 1; 166 } 167 if (n > 0) { 168 result.add(period, sum / n); 169 } 170 else { 171 result.add(period, null); 172 } 173 } 174 175 } 176 } 177 178 return result; 179 180 } 181 182 196 public static TimeSeries createPointMovingAverage(TimeSeries source, 197 String name, int pointCount) { 198 199 if (source == null) { 201 throw new IllegalArgumentException ("MovingAverage.createMovingAverage(...) : " 202 + "null source."); 203 } 204 205 if (pointCount < 2) { 206 throw new IllegalArgumentException ("MovingAverage.createMovingAverage(...) : " 207 + "periodCount must be greater than or equal to 2."); 208 209 } 210 211 TimeSeries result = new TimeSeries(name, source.getTimePeriodClass()); 212 double rollingSumForPeriod = 0.0; 213 for (int i = 0; i < source.getItemCount(); i++) { 214 TimeSeriesDataItem current = source.getDataItem(i); 216 RegularTimePeriod period = current.getPeriod(); 217 rollingSumForPeriod += current.getValue().doubleValue(); 218 219 if (i > pointCount - 1) { 220 TimeSeriesDataItem startOfMovingAvg = source.getDataItem(i - pointCount); 222 rollingSumForPeriod -= startOfMovingAvg.getValue().doubleValue(); 223 result.add(period, rollingSumForPeriod / pointCount); 224 } 225 else if (i == pointCount - 1) { 226 result.add(period, rollingSumForPeriod / pointCount); 227 } 228 } 229 return result; 230 } 231 232 243 public static XYDataset createMovingAverage(XYDataset source, String suffix, 244 long period, long skip) { 245 246 return createMovingAverage(source, suffix, (double) period, (double) skip); 247 248 } 249 250 251 262 public static XYDataset createMovingAverage(XYDataset source, String suffix, 263 double period, double skip) { 264 265 if (source == null) { 267 throw new IllegalArgumentException ( 268 "MovingAverage.createMovingAverage(...) : null source (XYDataset)." 269 ); 270 } 271 272 XYSeriesCollection result = new XYSeriesCollection(); 273 274 for (int i = 0; i < source.getSeriesCount(); i++) { 275 XYSeries s = createMovingAverage(source, i, source.getSeriesName(i) + suffix, 276 period, skip); 277 result.addSeries(s); 278 } 279 280 return result; 281 282 } 283 284 298 public static XYSeries createMovingAverage(XYDataset source, int series, String name, 299 long period, long skip) { 300 return createMovingAverage(source, series, name, (double) period, (double) skip); 301 } 302 303 315 public static XYSeries createMovingAverage(XYDataset source, int series, String name, 316 double period, double skip) { 317 318 319 if (source == null) { 321 throw new IllegalArgumentException ("MovingAverage.createMovingAverage(...) : " 322 + "null source (XYDataset)."); 323 } 324 325 if (period < Double.MIN_VALUE) { 326 throw new IllegalArgumentException ("MovingAverage.createMovingAverage(...) : " 327 + "period must be positive."); 328 329 } 330 331 if (skip < 0.0) { 332 throw new IllegalArgumentException ("MovingAverage.createMovingAverage(...) : " 333 + "skip must be >= 0.0."); 334 335 } 336 337 XYSeries result = new XYSeries(name); 338 339 if (source.getItemCount(series) > 0) { 340 341 double first = source.getXValue(series, 0).doubleValue() + skip; 344 345 for (int i = source.getItemCount(series) - 1; i >= 0; i--) { 346 347 double x = source.getXValue(series, i).doubleValue(); 349 350 if (x >= first) { 351 int n = 0; 353 double sum = 0.0; 354 double limit = x - period; 355 int offset = 0; 356 boolean finished = false; 357 358 while (!finished) { 359 if ((i - offset) >= 0) { 360 double xx = source.getXValue(series, i - offset).doubleValue(); 361 Number yy = source.getYValue(series, i - offset); 362 if (xx > limit) { 363 if (yy != null) { 364 sum = sum + yy.doubleValue(); 365 n = n + 1; 366 } 367 } 368 else { 369 finished = true; 370 } 371 } 372 else { 373 finished = true; 374 } 375 offset = offset + 1; 376 } 377 if (n > 0) { 378 result.add(x, sum / n); 379 } 380 else { 381 result.add(x, null); 382 } 383 } 384 385 } 386 } 387 388 return result; 389 390 } 391 392 } 393 | Popular Tags |