blob: ad43e765faf36d359c0d04cb94503f929df24177 [file] [log] [blame]
package com.pivotal.javafx.scene.chart;
import java.util.stream.Collectors;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.property.StringPropertyBase;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.chart.Axis;
import javafx.scene.chart.ValueAxis;
import com.pivotal.com.sun.javafx.charts.LegendItem;
/**
* A named series of data items
*/
public abstract class AbstractSeries<X extends Number,Y extends Number> implements Series<X, Y> {
// -------------- PRIVATE PROPERTIES ----------------------------------------
/** the style class for default color for this series */
protected String defaultColorStyleClass;
// TODO make property
@Override
public String getDefaultColorStyleClass() {
return defaultColorStyleClass;
}
@Override
public void setDefaultColorStyleClass(String defaultColorStyleClass) {
this.defaultColorStyleClass = defaultColorStyleClass;
}
// // TODO remove
// protected Data<X,Y> begin = null; // start pointer of a data linked list.
//
// // TODO remove
// @Override
// public Data<X, Y> getBegin() {
// return begin;
// }
//
// // TODO remove
// @Override
// public void setBegin(Data<X, Y> begin) {
// this.begin = begin;
// }
/*
* Next pointer for the next series. We maintain a linkedlist of the
* serieses so even after the series is deleted from the list,
* we have a reference to it - needed by BarChart e.g.
*/
// TODO remove
protected Series<X,Y> next = null;
// TODO remove
@Override
public Series<X, Y> getNext() {
return next;
}
// TODO remove
@Override
public void setNext(Series<X, Y> next) {
this.next = next;
}
// -------------- PUBLIC PROPERTIES ----------------------------------------
/** Reference to the chart this series belongs to */
private final ReadOnlyObjectWrapper<MultiAxisChart<X, Y>> chart = new ReadOnlyObjectWrapper<MultiAxisChart<X, Y>>(this, "chart");
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#getChart()
*/
@Override
public final MultiAxisChart<X,Y> getChart() { return chart.get(); }
@Override
public void setChart(MultiAxisChart<X,Y> value) { chart.set(value); }
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#chartProperty()
*/
@Override
public final ReadOnlyObjectProperty<MultiAxisChart<X,Y>> chartProperty() { return chart.getReadOnlyProperty(); }
/** Reference to the Y Axis this chart belongs to */
private final ReadOnlyObjectWrapper<Axis<Y>> yAxis = new ReadOnlyObjectWrapper<Axis<Y>>(null, "yAxis") {
protected void invalidated() {
final Axis<Y> axis = get();
axis.autoRangingProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue) {
// TODO keep lists in series changed listener?
axis.invalidateRange(getData().stream().map((Data<X,Y> d) -> d.getYValue()).collect(Collectors.toList()));
}
}
});
};
};
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#getYAxis()
*/
@Override
public final Axis<Y> getYAxis() { return yAxis.get(); }
// TODO change axis event
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#setYAxis(javafx.scene.chart.Axis)
*/
@Override
public void setYAxis(Axis<Y> value) { yAxis.set(value); }
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#yAxisProperty()
*/
@Override
public final ReadOnlyObjectProperty<Axis<Y>> yAxisProperty() { return yAxis.getReadOnlyProperty(); }
/** Reference to the legend for this series */
private final ReadOnlyObjectWrapper<LegendItem> legendItem = new ReadOnlyObjectWrapper<>(null, "legendItem");
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#getLegendItem()
*/
@Override
public final LegendItem getLegendItem() { return legendItem.get(); }
@Override
public void setLegendItem(LegendItem value) { legendItem.set(value); }
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#legendItemProperty()
*/
@Override
public final ReadOnlyObjectProperty<LegendItem> legendItemProperty() { return legendItem.getReadOnlyProperty(); }
/** The user displayable name for this series */
private final StringProperty name = new StringPropertyBase() {
@Override protected void invalidated() {
get(); // make non-lazy
if(getChart() != null) getChart().seriesNameChanged();
}
@Override
public Object getBean() {
return AbstractSeries.this;
}
@Override
public String getName() {
return "name";
}
};
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#getName()
*/
@Override
public final String getName() { return name.get(); }
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#setName(java.lang.String)
*/
@Override
public final void setName(String value) { name.set(value); }
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#nameProperty()
*/
@Override
public final StringProperty nameProperty() { return name; }
/**
* The node to display for this series. This is created by the chart if it uses nodes to represent the whole
* series. For example line chart uses this for the line but scatter chart does not use it. This node will be
* set as soon as the series is added to the chart. You can then get it to add mouse listeners etc.
*/
private ObjectProperty<Node> node = new SimpleObjectProperty<Node>(this, "node");
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#getNode()
*/
@Override
public final Node getNode() { return node.get(); }
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#setNode(javafx.scene.Node)
*/
@Override
public final void setNode(Node value) { node.set(value); }
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#nodeProperty()
*/
@Override
public final ObjectProperty<Node> nodeProperty() { return node; }
// -------------- CONSTRUCTORS ----------------------------------------------
/**
* Construct a empty series
*/
public AbstractSeries() {
}
/**
* Constructs a named Series and populates it with the given {@link ObservableList} data.
*
* @param name a name for the series
* @param data ObservableList of MultiAxisChart.Data
*/
public AbstractSeries(String name, ObservableList<Data<X,Y>> data) {
setName(name);
}
// -------------- PUBLIC METHODS ----------------------------------------------
/* (non-Javadoc)
* @see com.pivotal.javafx.scene.chart.Series#toString()
*/
@Override public String toString() {
return "Series["+getName()+"]";
}
// -------------- PRIVATE/PROTECTED METHODS -----------------------------------
/*
* The following methods are for manipulating the pointers in the linked list
* when data is deleted.
*/
// @Override
// public void removeDataItemRef(Data<X,Y> item) {
// if (begin == item) {
// begin = item.next;
// } else {
// Data<X,Y> ptr = begin;
// while(ptr != null && ptr.next != item) {
// ptr = ptr.next;
// }
// if(ptr != null) ptr.next = item.next;
// }
// }
@Override
public int getItemIndex(Data<X,Y> item) {
// int itemIndex = 0;
// for (Data<X,Y> d = begin; d != null; d = d.next) {
// if (d == item) break;
// itemIndex++;
// }
// return itemIndex;
return getData().indexOf(item);
}
@Override
public int getDataSize() {
// int count = 0;
// for (Data<X,Y> d = begin; d != null; d = d.next) {
// count++;
// }
// return count;
return getData().size();
}
}