/*
* VTSeries.java - Copyright(c) 2013 Joe Pasqua
* Provided under the MIT License. See the LICENSE file for details.
* Created: Aug 25, 2013
*/
package org.noroomattheinn.fxextensions;
import javafx.collections.ObservableList;
import javafx.scene.chart.XYChart;
import org.noroomattheinn.utils.Utils;
/**
* VTSeries: Adds some small additional functionality to an XYChart.Series. It
* should be a subclass, but unfortunately it's declared final
*
* @author Joe Pasqua <joe at NoRoomAtTheInn dot org>
*/
public class VTSeries {
/*------------------------------------------------------------------------------
*
* Internal State
*
*----------------------------------------------------------------------------*/
private final XYChart.Series<Number,Number> series; // The real underlying series
private final Transform<Number> xXform; // Transform for X values
private final Transform<Number> yXform; // Transform for Y Values
private final Object seriesLock; // Concurrency control
private boolean visibile;
/*==============================================================================
* ------- -------
* ------- Public Interface To This Class -------
* ------- -------
*============================================================================*/
public VTSeries(String name, Transform<Number> xXform, Transform<Number> yXform) {
this.xXform = xXform;
this.yXform = yXform;
series = new XYChart.Series<>();
series.setAppendOnly(true);
series.setName(name);
seriesLock = new Object();
visibile = true;
}
public void setData(ObservableList<XYChart.Data<Number,Number>> data) {
series.setData(data);
}
/*------------------------------------------------------------------------------
*
* "Getters" for various fields
*
*----------------------------------------------------------------------------*/
public XYChart.Series<Number,Number> getSeries() { return series; }
public String getName() { return series.getName(); }
public void setVisible(boolean visible) { this.visibile = visible; }
public boolean isVisible() { return this.visibile; }
/*------------------------------------------------------------------------------
*
* Adding data to the underlying series
*
*----------------------------------------------------------------------------*/
/**
* Append a new XYChart.Data element to the series with the supplied values.
* Add an appropriate marker to the newly added XYChart.Data
*
* @param time The time value (X Axis)
* @param value The value for that time (Y Axis)
*/
public void addToSeries(Number time, Number value) {
synchronized (seriesLock) {
XYChart.Data<Number,Number> data = addToData(series.getData(), time, value);
}
}
/**
* Append a new XYChart.Data element to the supplied list.
* This list may be the list associated with this series, or it may be a
* list that will later be added to this series.
*
* @param time The time value (X Axis)
* @param value The value for that time (Y Axis)
*/
public XYChart.Data<Number,Number> addToData(
ObservableList<XYChart.Data<Number,Number>> list,
Number time, Number value)
{
XYChart.Data<Number,Number> data = xform(time, value);
list.add(data);
return data;
}
/*------------------------------------------------------------------------------
*
* PRIVATE - Utility Methods
*
*----------------------------------------------------------------------------*/
private XYChart.Data<Number,Number> xform(Number time, Number value) {
return new XYChart.Data<>(xXform.transform(time), yXform.transform(value));
}
/*------------------------------------------------------------------------------
*
* The Transform Interface and several interesting instances
*
*----------------------------------------------------------------------------*/
public interface Transform<T> {
T transform(T value);
}
public static final Transform<Number> idTransform = new Transform<Number>() {
@Override public Number transform(Number value) { return value; }
};
public static final Transform<Number> cToFTransform = new Transform<Number>() {
@Override public Number transform(Number value) { return Utils.cToF(value.doubleValue()); }
};
public static final Transform<Number> fToCTransform = new Transform<Number>() {
@Override public Number transform(Number value) { return Utils.fToC(value.doubleValue()); }
};
public static final Transform<Number> mToKTransform = new Transform<Number>() {
@Override public Double transform(Number value) { return Utils.milesToKm(value.doubleValue()); }
};
public static final Transform<Number> kToMTransform = new Transform<Number>() {
@Override public Double transform(Number value) { return Utils.kmToMiles(value.doubleValue()); }
};
public static final Transform<Number> millisToSeconds = new Transform<Number>() {
@Override public Long transform(Number value) { return value.longValue()/1000; }
};
}