diff --git a/gui/src/main/java/io/bitsquare/gui/CandleStickChart.css b/gui/src/main/java/io/bitsquare/gui/CandleStickChart.css index f94c27e0c9..5c2a26228e 100644 --- a/gui/src/main/java/io/bitsquare/gui/CandleStickChart.css +++ b/gui/src/main/java/io/bitsquare/gui/CandleStickChart.css @@ -73,18 +73,29 @@ -demo-bar-fill: #cccccc; } - -.chart-plot-background { - -fx-background-color: transparent; +.volume-bar { + -fx-padding: 5; + -demo-bar-fill: #91b1cc; + -fx-background-color: #91b1cc; + -fx-background-insets: 0, 1, 2; } -.default-color0.chart-series-line { +.volume-bar.bg { + -demo-bar-fill: #91b1cc; +} + +.volume-bar { + -fx-effect: dropshadow(two-pass-box, rgba(0, 0, 0, 0.4), 10, 0.0, 2, 4); +} + +/*.default-color0.chart-series-line { -fx-stroke: blue; } .default-color0.chart-line-symbol { -fx-background-color: red, green; -} +}*/ + .chart-alternative-row-fill { @@ -97,6 +108,7 @@ -fx-background-color: transparent; } +/* .chart-legend { -fx-background-color: transparent; -fx-padding: 20px; @@ -105,4 +117,4 @@ .chart-legend-item-symbol { -fx-background-radius: 0; } - \ No newline at end of file + */ diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/trades/TradesChartsView.java b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/TradesChartsView.java index 1fb5d06d75..01de6824c9 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/markets/trades/TradesChartsView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/TradesChartsView.java @@ -21,7 +21,7 @@ import io.bitsquare.common.UserThread; import io.bitsquare.gui.common.view.ActivatableViewAndModel; import io.bitsquare.gui.common.view.FxmlView; import io.bitsquare.gui.main.markets.trades.candlestick.CandleStickChart; -import io.bitsquare.gui.main.markets.trades.candlestick.MyBarChart; +import io.bitsquare.gui.main.markets.trades.candlestick.VolumeChart; import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.locale.CryptoCurrency; import io.bitsquare.locale.FiatCurrency; @@ -36,7 +36,6 @@ import javafx.collections.ListChangeListener; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.geometry.Side; -import javafx.scene.chart.CategoryAxis; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; import javafx.scene.control.*; @@ -45,6 +44,7 @@ import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.util.Callback; import javafx.util.StringConverter; +import org.bitcoinj.core.Coin; import org.bitcoinj.utils.Fiat; import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.Subscription; @@ -54,6 +54,7 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import java.util.Date; +import java.util.concurrent.TimeUnit; @FxmlView public class TradesChartsView extends ActivatableViewAndModel { @@ -70,10 +71,9 @@ public class TradesChartsView extends ActivatableViewAndModel priceSeries; - private XYChart.Series volumeSeries; - private MyBarChart volumeChart; + private XYChart.Series volumeSeries; + private VolumeChart volumeChart; private CandleStickChart priceChart; private final ListChangeListener> itemsChangeListener; @@ -88,7 +88,7 @@ public class TradesChartsView extends ActivatableViewAndModel updateChartData(); + itemsChangeListener = c -> UserThread.runAfter(() -> updateChartData(), 20, TimeUnit.MILLISECONDS); } @Override @@ -99,7 +99,7 @@ public class TradesChartsView extends ActivatableViewAndModel(); + timeAxisX = new NumberAxis(0, model.upperBound + 1, 1); + timeAxisX.setTickUnit(1); + timeAxisX.setMinorTickCount(0); + timeAxisX.setForceZeroInRange(false); + timeAxisX.setLabel("Date/Time"); + timeAxisX.setTickLabelFormatter(getTimeAxisStringConverter()); - volumeAxisX = new CategoryAxis(); + volumeSeries = new XYChart.Series<>(); volumeAxisY = new NumberAxis(); volumeAxisY.setForceZeroInRange(false); @@ -168,23 +173,20 @@ public class TradesChartsView extends ActivatableViewAndModel(volumeAxisX, volumeAxisY); + NumberAxis volumeAxisX = new NumberAxis(0, model.upperBound + 1, 1); + volumeAxisX.setTickLabelsVisible(false); + volumeAxisX.setTickMarkVisible(false); + volumeAxisX.lookup(".axis-minor-tick-mark").setOpacity(0); + + volumeChart = new VolumeChart(volumeAxisX, volumeAxisY); volumeChart.setData(FXCollections.observableArrayList(volumeSeries)); - volumeChart.setAnimated(true); + volumeChart.setAnimated(false); volumeChart.setMinHeight(300); - volumeChart.setPadding(new Insets(0, 0, -10, 75)); + volumeChart.setPadding(new Insets(0, 0, 40, 69)); volumeChart.setLegendVisible(false); - 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(getTimeAxisStringConverter()); - priceAxisY = new NumberAxis(); priceAxisY.setForceZeroInRange(false); priceAxisY.setAutoRanging(true); @@ -197,7 +199,7 @@ public class TradesChartsView extends ActivatableViewAndModel(); volumeSeries.getData().setAll(model.volumeItems); + volumeChart.getData().clear(); + volumeChart.setData(FXCollections.observableArrayList(volumeSeries)); } @NotNull @@ -261,7 +267,7 @@ public class TradesChartsView extends ActivatableViewAndModel tradeCurrency = new SimpleObjectProperty<>(); private final HashMapChangedListener mapChangedListener; ObservableList> priceItems = FXCollections.observableArrayList(); - ObservableList> volumeItems = FXCollections.observableArrayList(); + ObservableList> volumeItems = FXCollections.observableArrayList(); private P2PService p2PService; final ObservableList tradeStatistics = FXCollections.observableArrayList(); @@ -162,7 +162,7 @@ class TradesChartsViewModel extends ActivatableViewModel { .collect(Collectors.toList())); volumeItems.setAll(candleDataList.stream() - .map(e -> new XYChart.Data(String.valueOf(e.tick), e.open, new CandleStickExtraValues(e.close, e.high, e.low, e.average))) + .map(e -> new XYChart.Data(e.tick, e.accumulatedAmount)) .collect(Collectors.toList())); } @@ -171,17 +171,17 @@ class TradesChartsViewModel extends ActivatableViewModel { long close = 0; long high = 0; long low = 0; - long volume = 0; - long amount = 0; + long accumulatedVolume = 0; + long accumulatedAmount = 0; for (TradeStatistics item : set) { final long tradePriceAsLong = item.tradePriceAsLong; low = (low != 0) ? Math.min(low, tradePriceAsLong) : tradePriceAsLong; high = (high != 0) ? Math.max(high, tradePriceAsLong) : tradePriceAsLong; - volume += item.getTradeVolume().value; - amount += item.tradeAmountAsLong; + accumulatedVolume += item.getTradeVolume().value; + accumulatedAmount += item.tradeAmountAsLong; } - long averagePrice = Math.round(volume * Coin.COIN.value / amount); + long averagePrice = Math.round(accumulatedVolume * Coin.COIN.value / accumulatedAmount); List list = new ArrayList<>(set); list.sort((o1, o2) -> (o1.tradeDateAsTime < o2.tradeDateAsTime ? -1 : (o1.tradeDateAsTime == o2.tradeDateAsTime ? 0 : 1))); @@ -190,7 +190,7 @@ class TradesChartsViewModel extends ActivatableViewModel { close = list.get(list.size() - 1).tradePriceAsLong; } boolean isBullish = close > open; - return new CandleData(tick, open, close, high, low, averagePrice, amount, volume, isBullish); + return new CandleData(tick, open, close, high, low, averagePrice, accumulatedAmount, accumulatedVolume, isBullish); } diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/CandleData.java b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/CandleData.java index bfa1544ddd..a93328b432 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/CandleData.java +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/CandleData.java @@ -7,19 +7,19 @@ public class CandleData { public final long high; public final long low; public final long average; - public final long amount; - public final long volume; + public final long accumulatedAmount; + public final long accumulatedVolume; public final boolean isBullish; - public CandleData(long tick, long open, long close, long high, long low, long average, long amount, long volume, boolean isBullish) { + public CandleData(long tick, long open, long close, long high, long low, long average, long accumulatedAmount, long accumulatedVolume, boolean isBullish) { this.tick = tick; this.open = open; this.close = close; this.high = high; this.low = low; this.average = average; - this.amount = amount; - this.volume = volume; + this.accumulatedAmount = accumulatedAmount; + this.accumulatedVolume = accumulatedVolume; this.isBullish = isBullish; } } diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/MyBarChart.java b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/MyBarChart.java deleted file mode 100644 index 8c7be3a7ba..0000000000 --- a/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/MyBarChart.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.bitsquare.gui.main.markets.trades.candlestick; - -import javafx.collections.ObservableList; -import javafx.scene.chart.Axis; -import javafx.scene.chart.BarChart; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MyBarChart extends BarChart { - private static final Logger log = LoggerFactory.getLogger(MyBarChart.class); - - public MyBarChart(Axis xAxis, Axis yAxis) { - super(xAxis, yAxis); - } - - public MyBarChart(Axis xAxis, Axis yAxis, ObservableList> data) { - super(xAxis, yAxis, data); - } - - public MyBarChart(Axis xAxis, Axis yAxis, ObservableList> data, double categoryGap) { - super(xAxis, yAxis, data, categoryGap); - } - - @Override - protected void dataItemAdded(Series series, int itemIndex, Data item) { - if (getPlotChildren().contains(item.getNode())) - getPlotChildren().remove(item.getNode()); - - super.dataItemAdded(series, itemIndex, item); - } -} diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/TooltipContent.java b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/TooltipContent.java index ad4dbb8b2c..d46c5a3dba 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/TooltipContent.java +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/TooltipContent.java @@ -69,9 +69,11 @@ public class TooltipContent extends GridPane { } public void update(double open, double close, double high, double low) { - openValue.setText(toolTipStringConverter.toString(open)); - closeValue.setText(toolTipStringConverter.toString(close)); - highValue.setText(toolTipStringConverter.toString(high)); - lowValue.setText(toolTipStringConverter.toString(low)); + if (toolTipStringConverter != null) { + openValue.setText(toolTipStringConverter.toString(open)); + closeValue.setText(toolTipStringConverter.toString(close)); + highValue.setText(toolTipStringConverter.toString(high)); + lowValue.setText(toolTipStringConverter.toString(low)); + } } } \ No newline at end of file diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/VolumeBar.java b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/VolumeBar.java new file mode 100644 index 0000000000..037140f475 --- /dev/null +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/VolumeBar.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008, 2014, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package io.bitsquare.gui.main.markets.trades.candlestick; + +import javafx.scene.Group; +import javafx.scene.layout.Region; +import javafx.util.StringConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Candle node used for drawing a candle + */ +public class VolumeBar extends Group { + private static final Logger log = LoggerFactory.getLogger(VolumeBar.class); + + private Region bar = new Region(); + private String seriesStyleClass; + private String dataStyleClass; + + VolumeBar(String seriesStyleClass, String dataStyleClass, StringConverter toolTipStringConverter) { + setAutoSizeChildren(false); + bar.setOpacity(0.7); + getChildren().add(bar); + this.seriesStyleClass = seriesStyleClass; + this.dataStyleClass = dataStyleClass; + updateStyleClasses(); + } + + public void setSeriesAndDataStyleClasses(String seriesStyleClass, String dataStyleClass) { + this.seriesStyleClass = seriesStyleClass; + this.dataStyleClass = dataStyleClass; + updateStyleClasses(); + } + + public void update(double volume, double candleWidth) { + updateStyleClasses(); + if (candleWidth == -1) + candleWidth = bar.prefWidth(-1); + + log.error("closeOffset " + volume); + bar.resizeRelocate(-candleWidth / 2, 0, candleWidth, Math.max(5, volume)); + } + + private void updateStyleClasses() { + bar.getStyleClass().setAll("volume-bar", seriesStyleClass, dataStyleClass, "bg"); + } +} \ No newline at end of file diff --git a/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/VolumeChart.java b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/VolumeChart.java new file mode 100644 index 0000000000..0df85ea50b --- /dev/null +++ b/gui/src/main/java/io/bitsquare/gui/main/markets/trades/candlestick/VolumeChart.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2008, 2014, Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package io.bitsquare.gui.main.markets.trades.candlestick; + +import javafx.animation.FadeTransition; +import javafx.event.ActionEvent; +import javafx.scene.Node; +import javafx.scene.chart.Axis; +import javafx.scene.chart.NumberAxis; +import javafx.scene.chart.XYChart; +import javafx.util.Duration; +import javafx.util.StringConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * A candlestick chart is a style of bar-chart used primarily to describe price movements of a security, derivative, + * or currency over time. + *

+ * The Data Y value is used for the opening price and then the close, high and low values are stored in the Data's + * extra value property using a CandleStickExtraValues object. + */ +public class VolumeChart extends XYChart { + private static final Logger log = LoggerFactory.getLogger(CandleStickChart.class); + + private StringConverter toolTipStringConverter; + + // -------------- CONSTRUCTORS ---------------------------------------------- + + /** + * Construct a new CandleStickChart with the given axis. + * + * @param xAxis The x axis to use + * @param yAxis The y axis to use + */ + public VolumeChart(Axis xAxis, Axis yAxis) { + super(xAxis, yAxis); + } + + // -------------- METHODS ------------------------------------------------------------------------------------------ + + public final void setToolTipStringConverter(StringConverter toolTipStringConverter) { + this.toolTipStringConverter = toolTipStringConverter; + } + + /** + * Called to update and layout the content for the plot + */ + @Override + protected void layoutPlotChildren() { + // we have nothing to layout if no data is present + if (getData() == null) { + return; + } + // update volumeBar positions + for (int seriesIndex = 0; seriesIndex < getData().size(); seriesIndex++) { + XYChart.Series series = getData().get(seriesIndex); + Iterator> iter = getDisplayedDataIterator(series); + while (iter.hasNext()) { + XYChart.Data item = iter.next(); + double x = getXAxis().getDisplayPosition(getCurrentDisplayedXValue(item)); + double y = getYAxis().getDisplayPosition(getCurrentDisplayedYValue(item)); + Node itemNode = item.getNode(); + if (itemNode instanceof VolumeBar) { + VolumeBar volumeBar = (VolumeBar) itemNode; + double candleWidth = -1; + if (getXAxis() instanceof NumberAxis) { + NumberAxis xa = (NumberAxis) getXAxis(); + candleWidth = xa.getDisplayPosition(xa.getTickUnit()) * 0.90; // use 90% width between ticks + } + volumeBar.update(y, candleWidth); + + // position the volumeBar + volumeBar.setLayoutX(x); + volumeBar.setLayoutY(y); + } + } + } + } + + @Override + protected void dataItemChanged(XYChart.Data item) { + } + + @Override + protected void dataItemAdded(XYChart.Series series, int itemIndex, XYChart.Data item) { + Node volumeBar = createCandle(getData().indexOf(series), item, itemIndex); + if (getPlotChildren().contains(volumeBar)) + getPlotChildren().remove(volumeBar); + + if (shouldAnimate()) { + volumeBar.setOpacity(0); + getPlotChildren().add(volumeBar); + // fade in new volumeBar + FadeTransition ft = new FadeTransition(Duration.millis(500), volumeBar); + ft.setToValue(1); + ft.play(); + } else { + getPlotChildren().add(volumeBar); + } + } + + @Override + protected void dataItemRemoved(XYChart.Data item, XYChart.Series series) { + final Node node = item.getNode(); + if (shouldAnimate()) { + // fade out old volumeBar + FadeTransition ft = new FadeTransition(Duration.millis(500), node); + ft.setToValue(0); + ft.setOnFinished((ActionEvent actionEvent) -> { + getPlotChildren().remove(node); + }); + ft.play(); + } else { + getPlotChildren().remove(node); + } + } + + @Override + protected void seriesAdded(XYChart.Series series, int seriesIndex) { + // handle any data already in series + for (int j = 0; j < series.getData().size(); j++) { + XYChart.Data item = series.getData().get(j); + Node volumeBar = createCandle(seriesIndex, item, j); + if (shouldAnimate()) { + volumeBar.setOpacity(0); + getPlotChildren().add(volumeBar); + // fade in new volumeBar + FadeTransition ft = new FadeTransition(Duration.millis(500), volumeBar); + ft.setToValue(1); + ft.play(); + } else { + getPlotChildren().add(volumeBar); + } + } + } + + @Override + protected void seriesRemoved(XYChart.Series series) { + // remove all volumeBar nodes + for (XYChart.Data d : series.getData()) { + final Node volumeBar = d.getNode(); + if (shouldAnimate()) { + // fade out old volumeBar + FadeTransition ft = new FadeTransition(Duration.millis(500), volumeBar); + ft.setToValue(0); + ft.setOnFinished((ActionEvent actionEvent) -> { + getPlotChildren().remove(volumeBar); + }); + ft.play(); + } else { + getPlotChildren().remove(volumeBar); + } + } + } + + /** + * Create a new VolumeBar node to represent a single data item + * + * @param seriesIndex The index of the series the data item is in + * @param item The data item to create node for + * @param itemIndex The index of the data item in the series + * @return New volumeBar node to represent the give data item + */ + private Node createCandle(int seriesIndex, final XYChart.Data item, int itemIndex) { + Node volumeBar = item.getNode(); + // check if volumeBar has already been created + if (volumeBar instanceof VolumeBar) { + ((VolumeBar) volumeBar).setSeriesAndDataStyleClasses("series" + seriesIndex, "data" + itemIndex); + } else { + volumeBar = new VolumeBar("series" + seriesIndex, "data" + itemIndex, toolTipStringConverter); + item.setNode(volumeBar); + } + return volumeBar; + } + + /** + * This is called when the range has been invalidated and we need to update it. If the axis are auto + * ranging then we compile a list of all data that the given axis has to plot and call invalidateRange() on the + * axis passing it that data. + */ + @Override + protected void updateAxisRange() { + // For volumeBar stick chart we need to override this method as we need to let the axis know that they need to be able + // to cover the whole area occupied by the high to low range not just its center data value + final Axis xa = getXAxis(); + final Axis ya = getYAxis(); + List xData = null; + List yData = null; + if (xa.isAutoRanging()) { + xData = new ArrayList(); + } + if (ya.isAutoRanging()) { + yData = new ArrayList(); + } + if (xData != null || yData != null) { + for (XYChart.Series series : getData()) { + for (XYChart.Data data : series.getData()) { + if (xData != null) { + xData.add(data.getXValue()); + } + if (yData != null) + yData.add(data.getYValue()); + } + } + if (xData != null) { + xa.invalidateRange(xData); + } + if (yData != null) { + ya.invalidateRange(yData); + } + } + } +} \ No newline at end of file diff --git a/gui/src/test/java/io/bitsquare/gui/main/markets/trades/TradesChartsViewModelTest.java b/gui/src/test/java/io/bitsquare/gui/main/markets/trades/TradesChartsViewModelTest.java index aceb3571b3..f7084b3c42 100644 --- a/gui/src/test/java/io/bitsquare/gui/main/markets/trades/TradesChartsViewModelTest.java +++ b/gui/src/test/java/io/bitsquare/gui/main/markets/trades/TradesChartsViewModelTest.java @@ -62,8 +62,8 @@ public class TradesChartsViewModelTest { assertEquals(high, candleData.high); assertEquals(low, candleData.low); assertEquals(average, candleData.average); - assertEquals(amount, candleData.amount); - assertEquals(volume, candleData.volume); + assertEquals(amount, candleData.accumulatedAmount); + assertEquals(volume, candleData.accumulatedVolume); assertEquals(isBullish, candleData.isBullish); } }