Move candlechart classes, fix redraw bug

This commit is contained in:
Manfred Karrer 2016-07-23 22:42:20 +02:00
parent 3d11f8295d
commit bd4f0742fd
11 changed files with 112 additions and 99 deletions

View file

@ -175,7 +175,7 @@ public class BitsquareApp extends Application {
scene.getStylesheets().setAll(
"/io/bitsquare/gui/bitsquare.css",
"/io/bitsquare/gui/images.css",
"/io/bitsquare/gui/components/candlestick/CandleStickChart.css");
"/io/bitsquare/gui/CandleStickChart.css");
// configure the system tray
SystemTray.create(primaryStage, shutDownHandler);

View file

@ -18,10 +18,9 @@
package io.bitsquare.gui.main.markets.trades;
import io.bitsquare.common.UserThread;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
import io.bitsquare.gui.common.view.FxmlView;
import io.bitsquare.gui.components.candlestick.CandleStickChart;
import io.bitsquare.gui.main.markets.trades.candlestick.CandleStickChart;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.locale.CryptoCurrency;
import io.bitsquare.locale.FiatCurrency;
@ -58,7 +57,6 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
private NumberAxis xAxis, yAxis;
XYChart.Series<Number, Number> series;
private final ListChangeListener<XYChart.Data<Number, Number>> itemsChangeListener;
private final Navigation navigation;
private final BSFormatter formatter;
private TableView<TradeStatistics> tableView;
private ComboBox<TradeCurrency> currencyComboBox;
@ -73,9 +71,8 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public TradesChartsView(TradesChartsViewModel model, Navigation navigation, BSFormatter formatter) {
public TradesChartsView(TradesChartsViewModel model, BSFormatter formatter) {
super(model);
this.navigation = navigation;
this.formatter = formatter;
itemsChangeListener = c -> updateChartData();
@ -154,6 +151,89 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
}
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));
}
@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;
}
};
}
private VBox getTableBox() {
tableView = new TableView<>();
@ -296,83 +376,4 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
return vBox;
}
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(new StringConverter<Number>() {
@Override
public String toString(Number object) {
// comes as double
long index = new Double((double) object).longValue();
// int pos = model.upperBound - index;
// model.getTickFromTime(new Date().getTime(), model.tickUnit);
//final long time1 = model.getTickFromTime(e.tradeDateAsTime, model.tickUnit);
final long now = model.getTickFromTime(new Date().getTime(), model.tickUnit);
// long index11 = model.upperBound - (now - time);
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;
}
});
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(false);
candleStickChart.setId("charts");
candleStickChart.setMinHeight(300);
candleStickChart.setPadding(new Insets(0, 30, 10, 0));
candleStickChart.setToolTipStringConverter(getStringConverter());
}
@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;
}
};
}
private void updateChartData() {
series.getData().clear();
series.getData().addAll(model.getItems());
// xAxis.setLowerBound((double) model.getTimeInterval(0, model.tickUnit));
//xAxis.setUpperBound((double) model.getTimeInterval((long) root.getWidth() / 20, model.tickUnit));
}
}

View file

@ -20,7 +20,8 @@ package io.bitsquare.gui.main.markets.trades;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import io.bitsquare.gui.common.model.ActivatableViewModel;
import io.bitsquare.gui.components.candlestick.CandleStickExtraValues;
import io.bitsquare.gui.main.markets.trades.candlestick.CandleData;
import io.bitsquare.gui.main.markets.trades.candlestick.CandleStickExtraValues;
import io.bitsquare.locale.CurrencyUtil;
import io.bitsquare.locale.TradeCurrency;
import io.bitsquare.p2p.P2PService;
@ -61,7 +62,7 @@ class TradesChartsViewModel extends ActivatableViewModel {
ObservableList<XYChart.Data<Number, Number>> items = FXCollections.observableArrayList();
private P2PService p2PService;
final ObservableList<TradeStatistics> tradeStatistics = FXCollections.observableArrayList();
TickUnit tickUnit = TickUnit.HOUR;
TickUnit tickUnit = TickUnit.MINUTE;
int upperBound = 30;
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -29,7 +29,7 @@
* (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.components.candlestick;
package io.bitsquare.gui.main.markets.trades.candlestick;
import javafx.scene.Group;
import javafx.scene.control.Tooltip;

View file

@ -1,4 +1,4 @@
package io.bitsquare.gui.main.markets.trades;
package io.bitsquare.gui.main.markets.trades.candlestick;
public class CandleData {
public final long tick; // Is the time tick in the chosen time interval

View file

@ -29,7 +29,7 @@
* (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.components.candlestick;
package io.bitsquare.gui.main.markets.trades.candlestick;
import javafx.animation.FadeTransition;
import javafx.event.ActionEvent;
@ -42,6 +42,8 @@ import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.util.Duration;
import javafx.util.StringConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Iterator;
@ -55,7 +57,9 @@ import java.util.List;
* extra value property using a CandleStickExtraValues object.
*/
public class CandleStickChart extends XYChart<Number, Number> {
private static final Logger log = LoggerFactory.getLogger(CandleStickChart.class);
private StringConverter<Number> toolTipStringConverter;
private Path seriesPath;
// -------------- CONSTRUCTORS ----------------------------------------------
@ -160,17 +164,18 @@ public class CandleStickChart extends XYChart<Number, Number> {
@Override
protected void dataItemRemoved(XYChart.Data<Number, Number> item, XYChart.Series<Number, Number> series) {
final Node candle = item.getNode();
seriesPath.getElements().clear();
final Node node = item.getNode();
if (shouldAnimate()) {
// fade out old candle
FadeTransition ft = new FadeTransition(Duration.millis(500), candle);
FadeTransition ft = new FadeTransition(Duration.millis(500), node);
ft.setToValue(0);
ft.setOnFinished((ActionEvent actionEvent) -> {
getPlotChildren().remove(candle);
getPlotChildren().remove(node);
});
ft.play();
} else {
getPlotChildren().remove(candle);
getPlotChildren().remove(node);
}
}
@ -192,7 +197,7 @@ public class CandleStickChart extends XYChart<Number, Number> {
}
}
// create series path
Path seriesPath = new Path();
seriesPath = new Path();
seriesPath.getStyleClass().setAll("candlestick-average-line", "series" + seriesIndex);
series.setNode(seriesPath);
getPlotChildren().add(seriesPath);
@ -215,6 +220,11 @@ public class CandleStickChart extends XYChart<Number, Number> {
getPlotChildren().remove(candle);
}
}
if (series.getNode() instanceof Path) {
Path seriesPath = (Path) series.getNode();
seriesPath.getElements().clear();
}
}
/**

View file

@ -29,7 +29,7 @@
* (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.components.candlestick;
package io.bitsquare.gui.main.markets.trades.candlestick;
import javafx.application.Application;
import javafx.collections.FXCollections;
@ -108,7 +108,7 @@ public class CandleStickChartApp extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
final Scene scene = new Scene(createContent());
scene.getStylesheets().add("/io/bitsquare/gui/components/candlestick/CandleStickChart.css");
scene.getStylesheets().add("/io/bitsquare/gui/CandleStickChart.css");
primaryStage.setScene(scene);
primaryStage.show();

View file

@ -29,7 +29,7 @@
* (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.components.candlestick;
package io.bitsquare.gui.main.markets.trades.candlestick;
/**
* Data extra values for storing close, high and low.

View file

@ -29,7 +29,7 @@
* (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.components.candlestick;
package io.bitsquare.gui.main.markets.trades.candlestick;
import io.bitsquare.gui.util.BSFormatter;
import javafx.scene.control.Label;

View file

@ -1,5 +1,6 @@
package io.bitsquare.gui.main.markets.trades;
import io.bitsquare.gui.main.markets.trades.candlestick.CandleData;
import io.bitsquare.trade.TradeStatistics;
import io.bitsquare.trade.offer.Offer;
import org.bitcoinj.core.Coin;