package me.legrange.panstamp.gui.model;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import me.legrange.panstamp.Endpoint;
import me.legrange.panstamp.EndpointListener;
import me.legrange.panstamp.NetworkException;
import org.jfree.data.DomainOrder;
import org.jfree.data.general.DatasetChangeEvent;
import org.jfree.data.general.DatasetChangeListener;
import org.jfree.data.general.DatasetGroup;
import org.jfree.data.xy.XYDataset;
/**
*
* @author gideon
*/
public class EndpointDataSet implements XYDataset, EndpointListener {
public Endpoint getEndpoint() {
return ep;
}
@Override
public void valueReceived(Endpoint ep, Object value) {
addSample(asDouble(ep));
}
@Override
public DomainOrder getDomainOrder() {
return DomainOrder.ASCENDING;
}
@Override
public int getItemCount(int i) {
return data.size();
}
@Override
public Number getX(int series, int index) {
return getXValue(series, index);
}
@Override
public double getXValue(int series, int index) {
switch (series) {
case SAMPLE:
return data.get(index).sample;
default:
throw new IndexOutOfBoundsException(String.format("No series %d", series));
}
}
@Override
public Number getY(int series, int index) {
return getYValue(series, index);
}
@Override
public double getYValue(int series, int index) {
return data.get(index).time;
}
@Override
public int getSeriesCount() {
return 1;
}
@Override
public Comparable getSeriesKey(int series) {
switch (series) {
case SAMPLE:
return ep.getName();
default:
throw new IndexOutOfBoundsException(String.format("No series %d", series));
}
}
@Override
public int indexOf(Comparable key) {
if (key.equals(ep.getName())) {
return SAMPLE;
}
throw new IndexOutOfBoundsException("No series for key '" + key + "'");
}
@Override
public void addChangeListener(DatasetChangeListener dl) {
listeners.add(dl);
}
@Override
public void removeChangeListener(DatasetChangeListener dl) {
listeners.remove(dl);
}
@Override
public DatasetGroup getGroup() {
return group;
}
@Override
public void setGroup(DatasetGroup dg) {
this.group = dg;
}
public EndpointDataSet(Endpoint ep) {
this(ep, null);
}
public EndpointDataSet(Endpoint ep, String unit) {
this.ep = ep;
if (unit == null) {
List<String> units = ep.getUnits();
if (!units.isEmpty()) {
unit = units.get(0);
}
}
this.unit = unit;
ep.addListener(this);
}
private double asDouble(Endpoint ep) {
try {
switch (ep.getType()) {
case BINARY:
Boolean b = (Boolean) ep.getValue();
return b ? 1.0 : 0.0;
case INTEGER:
Integer i;
if (unit == null) {
i = (Integer) ep.getValue();
} else {
i = (Integer) ep.getValue(unit);
}
return i.doubleValue();
case NUMBER:
Double d;
if (unit == null) {
d = (Double) ep.getValue();
} else {
d = (Double) ep.getValue(unit);
}
return d;
case STRING:
case BYTE_ARRAY :
return 0.0;
}
} catch (NetworkException e) {
}
return 0.0;
}
private void addSample(double sample) {
data.add(new Entry(sample));
for (DatasetChangeListener l : listeners) {
l.datasetChanged(new DatasetChangeEvent(this, this));
}
}
private final List<Entry> data = new CopyOnWriteArrayList<>();
private final List<DatasetChangeListener> listeners = new CopyOnWriteArrayList<>();
private final Endpoint ep;
private final String unit;
private DatasetGroup group;
private class Entry {
public Entry(double sample) {
this.sample = sample;
this.time = System.currentTimeMillis();
}
final double sample;
final long time;
}
private static final int SAMPLE = 0;
}