Update chart

This commit is contained in:
Manfred Karrer 2016-07-24 02:04:36 +02:00
parent bd4f0742fd
commit 5ca8ae8f34
6 changed files with 327 additions and 155 deletions

View file

@ -38,7 +38,7 @@
}
.candlestick-average-line {
-fx-stroke: #106ece;
-fx-stroke: #00b2ff;
-fx-stroke-width: 2px;
}
@ -53,7 +53,7 @@
.candlestick-bar {
-fx-padding: 5;
-demo-bar-fill: red;
-demo-bar-fill: #e81a00;
-fx-background-color: linear-gradient(derive(-demo-bar-fill, -30%), derive(-demo-bar-fill, -40%)),
linear-gradient(derive(-demo-bar-fill, 100%), derive(-demo-bar-fill, 10%)),
linear-gradient(derive(-demo-bar-fill, 30%), derive(-demo-bar-fill, -10%));
@ -61,9 +61,35 @@
}
.candlestick-bar.close-above-open {
-demo-bar-fill: #95ce1b;
-demo-bar-fill: #1bff06;
}
.candlestick-bar.open-above-close {
-demo-bar-fill: #ce2700;
-demo-bar-fill: #e81a00;
}
.candlestick-bar.empty {
-demo-bar-fill: #cccccc;
}
.chart-plot-background {
-fx-background-color: transparent;
}
.default-color0.chart-series-line {
-fx-stroke: blue;
}
.default-color0.chart-line-symbol {
-fx-background-color: blue, white;
}
.chart-plot-background {
-fx-background-color: transparent;
}
.chart-alternative-row-fill {
-fx-fill: transparent;
-fx-stroke: transparent;
-fx-stroke-width: 0;
}

View file

@ -1069,4 +1069,35 @@ textfield */
-fx-alignment: center;
-fx-font-size: 10;
-fx-text-fill: white;
}
}
#toggle-left {
-fx-border-radius: 4 0 0 4;
-fx-padding: 4 4 4 4;
-fx-border-color: #aaa;
-fx-border-style: solid solid solid solid;
-fx-border-insets: 0 -2 0 0;
-fx-background-insets: 0 -2 0 0;
-fx-background-radius: 4 0 0 4;
}
#toggle-center {
-fx-border-radius: 0 0 0 0;
-fx-padding: 4 4 4 4;
-fx-border-color: #aaa;
-fx-border-style: solid solid solid solid;
-fx-border-insets: 0 0 0 0;
-fx-background-insets: 0 0 0 0;
-fx-background-radius: 0 0 0 0;
}
#toggle-right {
-fx-border-radius: 0 4 4 0;
-fx-padding: 4 4 4 4;
-fx-border-color: #aaa;
-fx-border-style: solid solid solid solid;
-fx-border-insets: 0 0 0 -2;
-fx-background-insets: 0 0 0 -2;
-fx-background-radius: 0 4 4 0;
}

View file

@ -29,10 +29,13 @@ import io.bitsquare.trade.TradeStatistics;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.*;
@ -54,17 +57,23 @@ import java.util.Date;
public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesChartsViewModel> {
private static final Logger log = LoggerFactory.getLogger(TradesChartsView.class);
private NumberAxis xAxis, yAxis;
XYChart.Series<Number, Number> series;
private final ListChangeListener<XYChart.Data<Number, Number>> itemsChangeListener;
private final BSFormatter formatter;
private TableView<TradeStatistics> tableView;
private ComboBox<TradeCurrency> currencyComboBox;
private Subscription tradeCurrencySubscriber;
private final StringProperty priceColumnLabel = new SimpleStringProperty();
private final StringProperty volumeColumnLabel = new SimpleStringProperty();
private CandleStickChart candleStickChart;
private ChangeListener<Toggle> toggleChangeListener;
private ToggleGroup toggleGroup;
private NumberAxis timeAxisX, priceAxisY, volumeAxisY;
private XYChart.Series<Number, Number> priceSeries;
private XYChart.Series<Number, Number> volumeSeries;
private LineChart<Number, Number> volumeChart;
private CandleStickChart priceChart;
private final ListChangeListener<XYChart.Data<Number, Number>> itemsChangeListener;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, lifecycle
@ -80,6 +89,179 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
@Override
public void initialize() {
HBox currencyHBox = createCurrencyComboBox();
HBox toggleBarHBox = createToggleBar();
createChart();
final VBox tableVBox = getTableBox();
/* StackPane stackPane = new StackPane();
stackPane.getChildren().addAll(priceChart, volumeChart);*/
root.getChildren().addAll(currencyHBox, toggleBarHBox, priceChart, tableVBox);
toggleChangeListener = (observable, oldValue, newValue) -> {
if (newValue != null)
model.setTickUnit((TradesChartsViewModel.TickUnit) newValue.getUserData());
};
}
@Override
protected void activate() {
currencyComboBox.setItems(model.getTradeCurrencies());
currencyComboBox.getSelectionModel().select(model.getTradeCurrency());
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 25));
currencyComboBox.setOnAction(e -> model.onSetTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem()));
model.items.addListener(itemsChangeListener);
tradeCurrencySubscriber = EasyBind.subscribe(model.tradeCurrency,
tradeCurrency -> {
String code = tradeCurrency.getCode();
String tradeCurrencyName = tradeCurrency.getName();
priceSeries.setName(tradeCurrencyName);
priceColumnLabel.set("Price (" + formatter.getCurrencyPair(code) + ")");
volumeColumnLabel.set("Volume (" + code + ")");
priceAxisY.setLabel(priceColumnLabel.get());
});
tableView.setItems(model.tradeStatistics);
toggleGroup.selectedToggleProperty().addListener(toggleChangeListener);
updateChartData();
}
@Override
protected void deactivate() {
model.items.removeListener(itemsChangeListener);
tradeCurrencySubscriber.unsubscribe();
currencyComboBox.setOnAction(null);
toggleGroup.selectedToggleProperty().removeListener(toggleChangeListener);
priceSeries.getData().clear();
priceChart.getData().clear();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Chart
///////////////////////////////////////////////////////////////////////////////////////////
private void createChart() {
priceSeries = new XYChart.Series<>();
timeAxisX = new NumberAxis(0, model.upperBound + 1, 1);
timeAxisX.setTickUnit(1);
timeAxisX.setMinorTickCount(0);
timeAxisX.setForceZeroInRange(false);
timeAxisX.setLabel("Date/Time");
timeAxisX.setTickLabelFormatter(getXAxisStringConverter());
priceAxisY = new NumberAxis();
priceAxisY.setForceZeroInRange(false);
priceAxisY.setAutoRanging(true);
priceAxisY.setLabel(priceColumnLabel.get());
priceAxisY.setTickLabelFormatter(getPriceStringConverter());
priceChart = new CandleStickChart(timeAxisX, priceAxisY);
priceChart.setData(FXCollections.observableArrayList(priceSeries));
priceChart.setAnimated(true);
priceChart.setId("charts");
priceChart.setMinHeight(300);
priceChart.setPadding(new Insets(0, 30, 10, 0));
priceChart.setToolTipStringConverter(getPriceStringConverter());
volumeSeries = new XYChart.Series<>();
volumeAxisY = new NumberAxis();
volumeAxisY.setForceZeroInRange(false);
volumeAxisY.setAutoRanging(true);
volumeAxisY.setLabel(volumeColumnLabel.get());
volumeAxisY.setTickLabelFormatter(getVolumeStringConverter());
volumeAxisY.setSide(Side.RIGHT);
volumeChart = new LineChart<>(timeAxisX, volumeAxisY);
volumeChart.setData(FXCollections.observableArrayList(volumeSeries));
volumeChart.setAnimated(true);
volumeChart.setId("charts");
volumeChart.setMinHeight(300);
volumeChart.setPadding(new Insets(0, 30, 10, 0));
}
private void updateChartData() {
priceSeries.getData().clear();
priceChart.getData().clear();
priceSeries = new XYChart.Series<>();
priceSeries.getData().addAll(model.items);
priceChart.setData(FXCollections.observableArrayList(priceSeries));
volumeSeries.getData().clear();
volumeChart.getData().clear();
volumeSeries = new XYChart.Series<>();
volumeSeries.getData().addAll(model.volumeItems);
volumeChart.setData(FXCollections.observableArrayList(volumeSeries));
timeAxisX.setTickLabelFormatter(getXAxisStringConverter());
}
@NotNull
private StringConverter<Number> getXAxisStringConverter() {
return new StringConverter<Number>() {
@Override
public String toString(Number object) {
// comes as double
long index = new Double((double) object).longValue();
final long now = model.getTickFromTime(new Date().getTime(), model.tickUnit);
final long tick = now - (model.upperBound - index);
final long time = model.getTimeFromTick(tick, model.tickUnit);
if (model.tickUnit.ordinal() <= TradesChartsViewModel.TickUnit.DAY.ordinal())
return index % 4 == 0 ? formatter.formatDate(new Date(time)) : "";
else
return index % 3 == 0 ? formatter.formatTime(new Date(time)) : "";
}
@Override
public Number fromString(String string) {
return null;
}
};
}
@NotNull
private StringConverter<Number> getPriceStringConverter() {
return new StringConverter<Number>() {
@Override
public String toString(Number object) {
// comes as double
return formatter.formatFiat(Fiat.valueOf(model.getCurrencyCode(), new Double((double) object).longValue()));
}
@Override
public Number fromString(String string) {
return null;
}
};
}
@NotNull
private StringConverter<Number> getVolumeStringConverter() {
return new StringConverter<Number>() {
@Override
public String toString(Number object) {
// comes as double
return formatter.formatFiat(Fiat.valueOf(model.getCurrencyCode(), new Double((double) object).longValue()));
}
@Override
public Number fromString(String string) {
return null;
}
};
}
///////////////////////////////////////////////////////////////////////////////////////////
// CurrencyComboBox
///////////////////////////////////////////////////////////////////////////////////////////
private HBox createCurrencyComboBox() {
currencyComboBox = new ComboBox<>();
currencyComboBox.setPromptText("Select currency");
currencyComboBox.setConverter(new StringConverter<TradeCurrency>() {
@ -107,133 +289,49 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
currencyHBox.setPadding(new Insets(10, -20, 0, 20));
currencyHBox.setAlignment(Pos.CENTER_LEFT);
currencyHBox.getChildren().addAll(currencyLabel, currencyComboBox);
createChart();
final VBox vBox = getTableBox();
root.getChildren().addAll(currencyHBox, candleStickChart, vBox);
}
@Override
protected void activate() {
currencyComboBox.setItems(model.getTradeCurrencies());
currencyComboBox.getSelectionModel().select(model.getTradeCurrency());
currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 25));
currencyComboBox.setOnAction(e -> {
TradeCurrency tradeCurrency = currencyComboBox.getSelectionModel().getSelectedItem();
model.onSetTradeCurrency(tradeCurrency);
updateChartData();
});
model.items.addListener(itemsChangeListener);
tradeCurrencySubscriber = EasyBind.subscribe(model.tradeCurrency,
tradeCurrency -> {
String code = tradeCurrency.getCode();
String tradeCurrencyName = tradeCurrency.getName();
//lineChart.setTitle("Trade history for " + tradeCurrencyName);
series.setName(tradeCurrencyName);
priceColumnLabel.set("Price (" + formatter.getCurrencyPair(code) + ")");
volumeColumnLabel.set("Volume (" + code + ")");
yAxis.setLabel(priceColumnLabel.get());
// xAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(xAxis, "", ""));
});
tableView.setItems(model.tradeStatistics);
updateChartData();
}
@Override
protected void deactivate() {
model.items.removeListener(itemsChangeListener);
tradeCurrencySubscriber.unsubscribe();
currencyComboBox.setOnAction(null);
}
private void createChart() {
xAxis = new NumberAxis(0, model.upperBound + 1, 1);
xAxis.setTickUnit(1);
// final double lowerBound = (double) model.getTimeInterval(0, model.tickUnit);
//xAxis.setLowerBound(lowerBound);
//final long minWith = (long) root.getWidth() / 20;
//final double upperBound = (double) minWith;
// xAxis.setUpperBound(upperBound);
xAxis.setMinorTickCount(0);
xAxis.setForceZeroInRange(false);
//xAxis.setAutoRanging(true);
xAxis.setLabel("Date/Time");
xAxis.setTickLabelFormatter(getXAxisStringConverter());
yAxis = new NumberAxis();
yAxis.setForceZeroInRange(false);
yAxis.setAutoRanging(true);
yAxis.setLabel(priceColumnLabel.get());
yAxis.setTickLabelFormatter(getStringConverter());
series = new XYChart.Series<>();
candleStickChart = new CandleStickChart(xAxis, yAxis);
candleStickChart.setData(FXCollections.observableArrayList(series));
candleStickChart.setAnimated(true);
candleStickChart.setId("charts");
candleStickChart.setMinHeight(300);
candleStickChart.setPadding(new Insets(0, 30, 10, 0));
candleStickChart.setToolTipStringConverter(getStringConverter());
}
@NotNull
private StringConverter<Number> getXAxisStringConverter() {
return new StringConverter<Number>() {
@Override
public String toString(Number object) {
// comes as double
long index = new Double((double) object).longValue();
final long now = model.getTickFromTime(new Date().getTime(), model.tickUnit);
final long tick = now - (model.upperBound - index);
final long time = model.getTimeFromTick(tick, model.tickUnit);
if (model.tickUnit.ordinal() <= TradesChartsViewModel.TickUnit.DAY.ordinal())
return index % 7 == 0 ? formatter.formatDate(new Date(time)) : "";
else
return index % 4 == 0 ? formatter.formatTime(new Date(time)) : "";
}
@Override
public Number fromString(String string) {
return null;
}
};
}
private void updateChartData() {
series.getData().clear();
candleStickChart.getData().clear();
series = new XYChart.Series<>();
candleStickChart.setData(FXCollections.observableArrayList(series));
series.getData().addAll(model.getItems());
xAxis.setTickLabelFormatter(getXAxisStringConverter());
// xAxis.setLowerBound((double) model.getTimeInterval(0, model.tickUnit));
//xAxis.setUpperBound((double) model.getTimeInterval((long) root.getWidth() / 20, model.tickUnit));
return currencyHBox;
}
@NotNull
private StringConverter<Number> getStringConverter() {
return new StringConverter<Number>() {
@Override
public String toString(Number object) {
// comes as double
return formatter.formatFiat(Fiat.valueOf(model.getCurrencyCode(), new Double((double) object).longValue()));
}
@Override
public Number fromString(String string) {
return null;
}
};
///////////////////////////////////////////////////////////////////////////////////////////
// ToggleBar
///////////////////////////////////////////////////////////////////////////////////////////
private HBox createToggleBar() {
HBox hBox = new HBox();
hBox.setSpacing(0);
hBox.setPadding(new Insets(0, 0, -26, 85));
Label label = new Label("Interval:");
label.setPadding(new Insets(5, 5, 0, 0));
toggleGroup = new ToggleGroup();
ToggleButton month = getToggleButton("Month", TradesChartsViewModel.TickUnit.MONTH, toggleGroup, "toggle-left");
ToggleButton week = getToggleButton("Week", TradesChartsViewModel.TickUnit.WEEK, toggleGroup, "toggle-center");
ToggleButton day = getToggleButton("Day", TradesChartsViewModel.TickUnit.DAY, toggleGroup, "toggle-center");
ToggleButton hour = getToggleButton("Hour", TradesChartsViewModel.TickUnit.HOUR, toggleGroup, "toggle-center");
ToggleButton minute10 = getToggleButton("10 Minute", TradesChartsViewModel.TickUnit.MINUTE_10, toggleGroup, "toggle-center");
ToggleButton minute = getToggleButton("Minute", TradesChartsViewModel.TickUnit.MINUTE, toggleGroup, "toggle-right");
minute10.setSelected(true);
hBox.getChildren().addAll(label, month, week, day, hour, minute10, minute);
return hBox;
}
private ToggleButton getToggleButton(String label, TradesChartsViewModel.TickUnit tickUnit, ToggleGroup toggleGroup, String style) {
ToggleButton toggleButton = new ToggleButton(label);
toggleButton.setPadding(new Insets(0, 3, 0, 3));
toggleButton.setUserData(tickUnit);
toggleButton.setToggleGroup(toggleGroup);
toggleButton.setId(style);
return toggleButton;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Table
///////////////////////////////////////////////////////////////////////////////////////////
private VBox getTableBox() {
tableView = new TableView<>();

View file

@ -52,17 +52,19 @@ class TradesChartsViewModel extends ActivatableViewModel {
WEEK,
DAY,
HOUR,
MINUTE,
SECOND
MINUTE_10,
MINUTE
}
private final Preferences preferences;
final ObjectProperty<TradeCurrency> tradeCurrency = new SimpleObjectProperty<>();
private final HashMapChangedListener mapChangedListener;
ObservableList<XYChart.Data<Number, Number>> items = FXCollections.observableArrayList();
ObservableList<XYChart.Data<Number, Number>> volumeItems = FXCollections.observableArrayList();
private P2PService p2PService;
final ObservableList<TradeStatistics> tradeStatistics = FXCollections.observableArrayList();
TickUnit tickUnit = TickUnit.MINUTE;
TickUnit tickUnit = TickUnit.MINUTE_10;
int upperBound = 30;
///////////////////////////////////////////////////////////////////////////////////////////
@ -124,6 +126,10 @@ class TradesChartsViewModel extends ActivatableViewModel {
p2PService.removeHashMapChangedListener(mapChangedListener);
}
public void setTickUnit(TickUnit tickUnit) {
this.tickUnit = tickUnit;
updateChartData();
}
private void updateChartData() {
items.clear();
@ -155,6 +161,10 @@ class TradesChartsViewModel extends ActivatableViewModel {
items.addAll(candleDataList.stream()
.map(e -> new XYChart.Data<Number, Number>(e.tick, e.open, new CandleStickExtraValues(e.close, e.high, e.low, e.average)))
.collect(Collectors.toList()));
volumeItems.addAll(candleDataList.stream()
.map(e -> new XYChart.Data<Number, Number>(e.tick, e.volume, new CandleStickExtraValues(e.close, e.high, e.low, e.average)))
.collect(Collectors.toList()));
}
CandleData getCandleData(long tick, Set<TradeStatistics> set) {
@ -187,16 +197,18 @@ class TradesChartsViewModel extends ActivatableViewModel {
long getTickFromTime(long tradeDateAsTime, TickUnit tickUnit) {
switch (tickUnit) {
case MONTH:
return TimeUnit.MILLISECONDS.toDays(tradeDateAsTime) / 31;
case WEEK:
return TimeUnit.MILLISECONDS.toDays(tradeDateAsTime) * 7;
return TimeUnit.MILLISECONDS.toDays(tradeDateAsTime) / 7;
case DAY:
return TimeUnit.MILLISECONDS.toDays(tradeDateAsTime);
case HOUR:
return TimeUnit.MILLISECONDS.toHours(tradeDateAsTime);
case MINUTE_10:
return TimeUnit.MILLISECONDS.toMinutes(tradeDateAsTime) / 10;
case MINUTE:
return TimeUnit.MILLISECONDS.toMinutes(tradeDateAsTime);
case SECOND:
return TimeUnit.MILLISECONDS.toSeconds(tradeDateAsTime);
default:
return tradeDateAsTime;
}
@ -204,16 +216,18 @@ class TradesChartsViewModel extends ActivatableViewModel {
long getTimeFromTick(long tick, TickUnit tickUnit) {
switch (tickUnit) {
case MONTH:
return TimeUnit.DAYS.toMillis(tick) * 31;
case WEEK:
return TimeUnit.DAYS.toMillis(tick) * 7;
case DAY:
return TimeUnit.DAYS.toMillis(tick);
case HOUR:
return TimeUnit.HOURS.toMillis(tick);
case MINUTE_10:
return TimeUnit.MINUTES.toMillis(tick) * 10;
case MINUTE:
return TimeUnit.MINUTES.toMillis(tick);
case SECOND:
return TimeUnit.SECONDS.toMillis(tick);
default:
return tick;
}
@ -235,10 +249,6 @@ class TradesChartsViewModel extends ActivatableViewModel {
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public List<XYChart.Data<Number, Number>> getItems() {
return items;
}
public String getCurrencyCode() {
return tradeCurrency.get().getCode();
}

View file

@ -36,11 +36,15 @@ import javafx.scene.control.Tooltip;
import javafx.scene.layout.Region;
import javafx.scene.shape.Line;
import javafx.util.StringConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Candle node used for drawing a candle
*/
public class Candle extends Group {
private static final Logger log = LoggerFactory.getLogger(Candle.class);
private final TooltipContent tooltipContent;
private Line highLowLine = new Line();
private Region bar = new Region();
@ -48,6 +52,7 @@ public class Candle extends Group {
private String dataStyleClass;
private boolean openAboveClose = true;
private Tooltip tooltip = new Tooltip();
private double closeOffset;
Candle(String seriesStyleClass, String dataStyleClass, StringConverter<Number> toolTipStringConverter) {
setAutoSizeChildren(false);
@ -67,6 +72,7 @@ public class Candle extends Group {
}
public void update(double closeOffset, double highOffset, double lowOffset, double candleWidth) {
this.closeOffset = closeOffset;
openAboveClose = closeOffset > 0;
updateStyleClasses();
highLowLine.setStartY(highOffset);
@ -75,22 +81,27 @@ public class Candle extends Group {
candleWidth = bar.prefWidth(-1);
}
if (openAboveClose) {
bar.resizeRelocate(-candleWidth / 2, 0, candleWidth, closeOffset);
bar.resizeRelocate(-candleWidth / 2, 0, candleWidth, Math.max(5, closeOffset));
} else {
bar.resizeRelocate(-candleWidth / 2, closeOffset, candleWidth, closeOffset * -1);
bar.resizeRelocate(-candleWidth / 2, closeOffset, candleWidth, Math.max(5, closeOffset * -1));
}
}
public void updateTooltip(double open, double close, double high, double low) {
tooltipContent.update(open, close, high, low);
//tooltip.setText("Open: " + open + "\nClose: " + close + "\nHigh: " + high + "\nLow: " + low);
}
private void updateStyleClasses() {
getStyleClass().setAll("candlestick-candle", seriesStyleClass, dataStyleClass);
String style = openAboveClose ? "open-above-close" : "close-above-open";
if (closeOffset == 0)
style = "empty";
highLowLine.getStyleClass().setAll("candlestick-line", seriesStyleClass, dataStyleClass,
openAboveClose ? "open-above-close" : "close-above-open");
style);
bar.getStyleClass().setAll("candlestick-bar", seriesStyleClass, dataStyleClass,
openAboveClose ? "open-above-close" : "close-above-open");
style);
}
}

View file

@ -58,6 +58,7 @@ import java.util.List;
*/
public class CandleStickChart extends XYChart<Number, Number> {
private static final Logger log = LoggerFactory.getLogger(CandleStickChart.class);
private StringConverter<Number> toolTipStringConverter;
private Path seriesPath;
@ -71,11 +72,6 @@ public class CandleStickChart extends XYChart<Number, Number> {
*/
public CandleStickChart(Axis<Number> xAxis, Axis<Number> yAxis) {
super(xAxis, yAxis);
getStylesheets().add(
CandleStickChart.class.getResource("CandleStickChart.css").toExternalForm());
setAnimated(false);
xAxis.setAnimated(false);
yAxis.setAnimated(false);
}
// -------------- METHODS ------------------------------------------------------------------------------------------
@ -146,6 +142,7 @@ public class CandleStickChart extends XYChart<Number, Number> {
@Override
protected void dataItemAdded(XYChart.Series<Number, Number> series, int itemIndex, XYChart.Data<Number, Number> item) {
Node candle = createCandle(getData().indexOf(series), item, itemIndex);
if (shouldAnimate()) {
candle.setOpacity(0);
getPlotChildren().add(candle);
@ -157,9 +154,8 @@ public class CandleStickChart extends XYChart<Number, Number> {
getPlotChildren().add(candle);
}
// always draw average line on top
if (series.getNode() != null) {
series.getNode().toFront();
}
if (seriesPath != null)
seriesPath.toFront();
}
@Override