package gov.nasa.arc.mct.fastplot.scatter;
import gov.nasa.arc.mct.fastplot.bridge.AbstractPlotDataManager;
import gov.nasa.arc.mct.fastplot.bridge.AbstractPlotDataSeries;
import gov.nasa.arc.mct.fastplot.bridge.LegendEntry;
import gov.nasa.arc.mct.fastplot.bridge.PlotConstants;
import java.awt.Color;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
public class ScatterPlotDataManager implements AbstractPlotDataManager {
private ScatterPlot scatterPlot;
private Map<String, SortedMap<Long, Double>> dataPoints = new HashMap<String, SortedMap<Long, Double>>();
private Map<String, Map<String, ScatterPlotDataSeries>> dataSeriesMap = new HashMap<String, Map<String, ScatterPlotDataSeries>>();
private Map<String, List<ScatterPlotDataSeries>> dataSeriesList = new HashMap<String, List<ScatterPlotDataSeries>>();
private Set<String> dependentFeeds = new HashSet<String>();
private Set<String> independentFeeds = new HashSet<String>();
public ScatterPlotDataManager(ScatterPlot scatterPlot) {
super();
this.scatterPlot = scatterPlot;
}
private SortedMap<Long, Double> getDataMap(String key) {
if (!dataPoints.containsKey(key)) {
dataPoints.put(key, new TreeMap<Long,Double>());
}
return dataPoints.get(key);
}
@Override
public void addDataSet(String dataSetName, Color plottingColor) {
if (!dataSetName.contains(PlotConstants.NON_TIME_FEED_SEPARATOR)) {
if (!dataSeriesMap.containsKey(dataSetName)) {
dataSeriesMap.put(dataSetName, new HashMap<String, ScatterPlotDataSeries>());
}
} else {
String dataSetNames[] = dataSetName.split(PlotConstants.NON_TIME_FEED_SEPARATOR);
independentFeeds.add(dataSetNames[0]);
dependentFeeds.add(dataSetNames[1]);
dataSeriesMap.put(dataSetName, new HashMap<String, ScatterPlotDataSeries>());
LegendEntry legendEntry =
new LegendEntry(PlotConstants.LEGEND_BACKGROUND_COLOR, plottingColor,
PlotConstants.DEFAULT_TIME_AXIS_FONT, scatterPlot.getPlotLabelingAlgorithm());
ScatterPlotDataSeries dataSeries =
new ScatterPlotDataSeries(scatterPlot, getDataMap(dataSetNames[0]), getDataMap(dataSetNames[1]), legendEntry);
dataSeriesMap.get(dataSetNames[0]).put(dataSetNames[1], dataSeries);
addToDataSeriesList(dataSetNames[0], dataSeries);
addToDataSeriesList(dataSetNames[1], dataSeries);
}
}
private void addToDataSeriesList(String feed, ScatterPlotDataSeries series) {
if (!dataSeriesList.containsKey(feed)) {
dataSeriesList.put(feed, new ArrayList<ScatterPlotDataSeries>());
}
dataSeriesList.get(feed).add(series);
}
@Override
public void addData(String feed, SortedMap<Long, Double> points) {
SortedMap<Long, Double> target = getDataMap(feed);
for (Entry<Long, Double> point : points.entrySet()) {
target.put(point.getKey(), point.getValue());
}
if (dataSeriesList.containsKey(feed)) {
for (ScatterPlotDataSeries series : dataSeriesList.get(feed)) {
series.updatePlotLine();
}
}
enforceTimeAxisBounds(scatterPlot.getCurrentTimeAxisMin().getTimeInMillis(),
scatterPlot.getCurrentTimeAxisMax().getTimeInMillis());
}
@Override
public void informUpdateCacheDataStreamStarted() {
// TODO Auto-generated method stub
}
@Override
public void informResizeEvent() {
// TODO Auto-generated method stub
}
@Override
public void resizeAndReloadPlotBuffer() {
// Resize is not meaningful to scatterplot
}
@Override
public AbstractPlotDataSeries getNamedDataSeries(String name) {
if (name.contains(PlotConstants.NON_TIME_FEED_SEPARATOR)) {
String[] keys = name.split(PlotConstants.NON_TIME_FEED_SEPARATOR);
return dataSeriesMap.get(keys[0]).get(keys[1]);
}
return null;
}
public void enforceTimeAxisBounds (long start, long end) {
for (Map<String, ScatterPlotDataSeries> subMap : dataSeriesMap.values()) {
for (ScatterPlotDataSeries series : subMap.values()) {
series.clearBefore(start);
series.clearAfter(end);
}
}
for (SortedMap<Long, Double> points : dataPoints.values()) {
for (Object key : points.headMap(start).keySet().toArray()) {
points.remove(key);
}
for (Object key : points.tailMap(end+1).keySet().toArray()) {
points.remove(key);
}
}
}
public double getExtremum(long minTime, long maxTime, boolean maximal, boolean dependent) {
Set<String> feeds = dependent ? dependentFeeds : independentFeeds;
double extremum = maximal ? Double.MIN_VALUE : Double.MAX_VALUE;
for (String f : feeds) {
for (Double v : dataPoints.get(f).subMap(minTime, maxTime).values()) {
if (maximal && v > extremum) extremum = v;
else if (!maximal && v < extremum) extremum = v;
}
}
return extremum;
}
public int size() {
int sz = 0;
for (Map<String, ScatterPlotDataSeries> group : dataSeriesMap.values()) {
sz += group.values().size();
}
return sz;
}
}