From d60030e2f2eedc16e77ea8b154678ca05a318286 Mon Sep 17 00:00:00 2001 From: Deus Max Date: Thu, 3 Dec 2020 21:06:34 +0200 Subject: [PATCH] Offer Book chart outlier filter improved. Outlier data filter used for the Market Offer Book chart, now accounts for the switching display position of Buy, Sell data depending on currency type (Crypto or Fiat). --- .../market/offerbook/OfferBookChartView.java | 96 ++++++++++++------- 1 file changed, 63 insertions(+), 33 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartView.java b/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartView.java index e79b701f324..3cfb832cfc4 100644 --- a/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartView.java +++ b/desktop/src/main/java/bisq/desktop/main/market/offerbook/OfferBookChartView.java @@ -127,7 +127,7 @@ public class OfferBookChartView extends ActivatableViewAndModel changeListener; private ListChangeListener currencyListItemsListener; - private final double chartDataFactor = 3; + private final double dataLimitFactor = 3; private final double initialOfferTableViewHeight = 121; private final double pixelsPerOfferTableRow = (initialOfferTableViewHeight - 30) / 5.0; // initial visible row count=5, header height=30 private final Function offerTableViewHeight = (screenSize) -> { @@ -387,48 +387,78 @@ private void updateChartData() { seriesSell.getData().clear(); areaChart.getData().clear(); - double buyMinValue = model.getBuyData().stream() - .mapToDouble(o -> o.getXValue().doubleValue()) - .min() - .orElse(Double.MAX_VALUE); - - // Hide buy offers that are more than a factor of chartDataFactor higher than the lowest buy offer - double buyMaxValue = model.getBuyData().stream() - .mapToDouble(o -> o.getXValue().doubleValue()) - .filter(o -> o < buyMinValue * chartDataFactor) - .max() - .orElse(Double.MIN_VALUE); - - double sellMaxValue = model.getSellData().stream() - .mapToDouble(o -> o.getXValue().doubleValue()) - .max() - .orElse(Double.MIN_VALUE); - - // Hide sell offers that are less than a factor of chartDataFactor lower than the highest sell offer - double sellMinValue = model.getSellData().stream() - .mapToDouble(o -> o.getXValue().doubleValue()) - .filter(o -> o > sellMaxValue / chartDataFactor) - .min() - .orElse(Double.MAX_VALUE); - - double minValue = Double.min(buyMinValue, sellMinValue); - double maxValue = Double.max(buyMaxValue, sellMaxValue); + List leftMnMx, rightMnMx; + boolean isCrypto = CurrencyUtil.isCryptoCurrency(model.getCurrencyCode()); + if (isCrypto) { // crypto: left-sell, right-buy, + leftMnMx = minMaxFilterLeft(model.getSellData()); + rightMnMx = minMaxFilterRight(model.getBuyData()); + } else { // fiat: left-buy, right-sell + leftMnMx = minMaxFilterLeft(model.getBuyData()); + rightMnMx = minMaxFilterRight(model.getSellData()); + } + + double minValue = Double.min(leftMnMx.get(0).doubleValue(), rightMnMx.get(0).doubleValue()); + double maxValue = Double.max(leftMnMx.get(1).doubleValue(), rightMnMx.get(1).doubleValue()); if (minValue == Double.MAX_VALUE || maxValue == Double.MIN_VALUE) { // no filtering seriesBuy.getData().addAll(model.getBuyData()); seriesSell.getData().addAll(model.getSellData()); } else { // apply filtering - seriesBuy.getData().addAll(model.getBuyData().stream() - .filter(o -> o.getXValue().doubleValue() < buyMinValue * 3) - .collect(Collectors.toList())); - seriesSell.getData().addAll(model.getSellData().stream() - .filter(o -> o.getXValue().doubleValue() > sellMaxValue / 3) - .collect(Collectors.toList())); + if (isCrypto) { // crypto: left-sell, right-buy + seriesBuy.getData().addAll(filterRight(model.getBuyData(), rightMnMx.get(0))); + seriesSell.getData().addAll(filterLeft(model.getSellData(), leftMnMx.get(1))); + } else { // fiat: left-buy, right-sell + seriesBuy.getData().addAll(filterLeft(model.getBuyData(), leftMnMx.get(1))); + seriesSell.getData().addAll(filterRight(model.getSellData(), rightMnMx.get(0))); + } } areaChart.getData().addAll(List.of(seriesBuy, seriesSell)); } + private List minMaxFilterLeft(List> data) { + double maxValue = data.stream() + .mapToDouble(o -> o.getXValue().doubleValue()) + .max() + .orElse(Double.MIN_VALUE); + // Hide sell offers that are less than a div-factor of dataLimitFactor + // lower than the highest sell offer. + double minValue = data.stream() + .mapToDouble(o -> o.getXValue().doubleValue()) + .filter(o -> o > maxValue / dataLimitFactor) + .min() + .orElse(Double.MAX_VALUE); + return List.of(minValue, maxValue); + } + + private List minMaxFilterRight(List> data) { + double minValue = data.stream() + .mapToDouble(o -> o.getXValue().doubleValue()) + .min() + .orElse(Double.MAX_VALUE); + + // Hide sell offers that are more than dataLimitFactor factor higher + // than the lowest sell offer + double maxValue = data.stream() + .mapToDouble(o -> o.getXValue().doubleValue()) + .filter(o -> o < minValue * dataLimitFactor) + .max() + .orElse(Double.MIN_VALUE); + return List.of(minValue, maxValue); + } + + private List> filterLeft(List> data, double maxValue) { + return data.stream() + .filter(o -> o.getXValue().doubleValue() > maxValue / dataLimitFactor) + .collect(Collectors.toList()); + } + + private List> filterRight(List> data, double minValue) { + return data.stream() + .filter(o -> o.getXValue().doubleValue() < minValue * dataLimitFactor) + .collect(Collectors.toList()); + } + private Tuple4, VBox, Button, Label> getOfferTable(OfferPayload.Direction direction) { TableView tableView = new TableView<>(); tableView.setMinHeight(initialOfferTableViewHeight);