package com.aerodynelabs.habtk.charts; import java.util.Iterator; import java.util.List; import org.jfree.data.Range; import org.jfree.data.xy.AbstractXYDataset; import org.jfree.data.xy.XYRangeInfo; import com.aerodynelabs.habtk.atmosphere.AtmosphereProfile; import com.aerodynelabs.habtk.atmosphere.AtmosphereState; @SuppressWarnings("serial") public class AtmosphereSeriesCollection extends AbstractXYDataset implements XYRangeInfo { public static final int DOMAIN_ALTITUDE = 0; public static final int DOMAIN_PRESSURE = 1; public static final int RANGE_TEMP = 0; public static final int RANGE_DEWPT = 1; public static final int RANGE_TEMPDEWPT = 2; public static final int RANGE_WINDSPD = 3; public static final int RANGE_WINDDIR = 4; public static final int RANGE_WIND = 5; public static final int RANGE_PRESSURE = 6; private int domain, range; private AtmosphereProfile atmo; public AtmosphereSeriesCollection(int domain, int range) { this.domain = domain; this.range = range; atmo = null; } public void setProfile(AtmosphereProfile profile) { atmo = profile; super.fireDatasetChanged(); } public AtmosphereProfile getProfile() { return atmo; } @Override public int getItemCount(int series) { if(atmo == null) { return 0; } else { return atmo.size(); } } @Override public Number getX(int series, int item) { if(atmo == null) return null; AtmosphereState x = atmo.get(item); if(domain == DOMAIN_ALTITUDE) return x.getAltitude(); if(domain == DOMAIN_PRESSURE) return x.getPressure() / 100; return null; } @Override public Number getY(int series, int item) { if(atmo == null) return null; AtmosphereState x = atmo.get(item); switch(range) { case RANGE_TEMP: if(series == 0) return x.getTemperature(); case RANGE_DEWPT: if(series == 0) return x.getDewPoint(); case RANGE_WINDSPD: if(series == 0) return x.getWindSpeed(); case RANGE_WINDDIR: if(series == 0) return x.getWindDirection(); case RANGE_PRESSURE: if(series == 0) return x.getPressure() / 100; case RANGE_TEMPDEWPT: if(series == 0) return x.getTemperature(); if(series == 1) return x.getDewPoint(); case RANGE_WIND: if(series == 0) return x.getWindSpeed(); if(series == 1) return x.getWindDirection(); } return null; } @Override public int getSeriesCount() { if(atmo == null) return 0; switch(range) { case RANGE_TEMP: case RANGE_DEWPT: case RANGE_WINDSPD: case RANGE_WINDDIR: case RANGE_PRESSURE: return 1; case RANGE_TEMPDEWPT: case RANGE_WIND: return 2; } return 0; } @SuppressWarnings("rawtypes") @Override public Comparable getSeriesKey(int series) { switch(range) { case RANGE_TEMP: if(series == 0) return "Temperature"; case RANGE_DEWPT: if(series == 0) return "Dew Point"; case RANGE_WINDSPD: if(series == 0) return "Wind Speed"; case RANGE_WINDDIR: if(series == 0) return "Wind Direction"; case RANGE_PRESSURE: if(series == 0) return "Pressure"; case RANGE_TEMPDEWPT: if(series == 0) return "Temperature"; if(series == 1) return "Dew Point"; case RANGE_WIND: if(series == 0) return "Wind Speed"; if(series == 1) return "Wind Direction"; } return null; } @SuppressWarnings("rawtypes") @Override public Range getRangeBounds(List keys, Range xRange, boolean include) { if(atmo == null) return null; double min = Double.NaN; double max = Double.NaN; Iterator<AtmosphereState> itr = atmo.iterator(); if(itr.hasNext()) { AtmosphereState x = itr.next(); min = getField(x, range, false); max = getField(x, range, true); } while(itr.hasNext()) { AtmosphereState x = itr.next(); // XXX Account for xRange // double value; // if(domain == DOMAIN_ALTITUDE) { // value = x.getAltitude(); // } else if(domain == DOMAIN_PRESSURE) { // value = x.getPressure(); // } else { // return null; // } // if(value < xRange.getLowerBound() || value > xRange.getUpperBound()) continue; min = Math.min(min, getField(x, range, false)); max = Math.max(max, getField(x, range, true)); } if(min == Double.NaN || max == Double.NaN) return null; return new Range(min, max); } private double getField(AtmosphereState x, int range, boolean max) { switch(range) { case RANGE_TEMP: return x.getTemperature(); case RANGE_DEWPT: return x.getDewPoint(); case RANGE_WIND: case RANGE_WINDSPD: return x.getWindSpeed(); case RANGE_WINDDIR: return x.getWindDirection(); case RANGE_PRESSURE: return x.getPressure(); case RANGE_TEMPDEWPT: if(max) { return x.getTemperature(); } else { return x.getDewPoint(); } } return Double.NaN; } }