mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-26 00:15:18 -04:00
show sum volume and amount in market view
This commit is contained in:
parent
11de7f540b
commit
11b0fab728
4 changed files with 74 additions and 8 deletions
|
@ -51,6 +51,7 @@ import org.bitcoinj.utils.MonetaryFormat;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class VolumeUtil {
|
public class VolumeUtil {
|
||||||
|
@ -187,4 +188,35 @@ public class VolumeUtil {
|
||||||
private static MonetaryFormat getMonetaryFormat(String currencyCode) {
|
private static MonetaryFormat getMonetaryFormat(String currencyCode) {
|
||||||
return CurrencyUtil.isVolumeRoundedToNearestUnit(currencyCode) ? VOLUME_FORMAT_UNIT : VOLUME_FORMAT_PRECISE;
|
return CurrencyUtil.isVolumeRoundedToNearestUnit(currencyCode) ? VOLUME_FORMAT_UNIT : VOLUME_FORMAT_PRECISE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Volume sum(Collection<Volume> volumes) {
|
||||||
|
if (volumes == null || volumes.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Volume sum = null;
|
||||||
|
for (Volume volume : volumes) {
|
||||||
|
if (sum == null) {
|
||||||
|
sum = volume;
|
||||||
|
} else {
|
||||||
|
if (!sum.getCurrencyCode().equals(volume.getCurrencyCode())) {
|
||||||
|
throw new IllegalArgumentException("Cannot sum volumes with different currencies");
|
||||||
|
}
|
||||||
|
sum = add(sum, volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Volume add(Volume volume1, Volume volume2) {
|
||||||
|
if (volume1 == null) return volume2;
|
||||||
|
if (volume2 == null) return volume1;
|
||||||
|
if (!volume1.getCurrencyCode().equals(volume2.getCurrencyCode())) {
|
||||||
|
throw new IllegalArgumentException("Cannot add volumes with different currencies");
|
||||||
|
}
|
||||||
|
if (volume1.getMonetary() instanceof CryptoMoney) {
|
||||||
|
return new Volume(((CryptoMoney) volume1.getMonetary()).add((CryptoMoney) volume2.getMonetary()));
|
||||||
|
} else {
|
||||||
|
return new Volume(((TraditionalMoney) volume1.getMonetary()).add((TraditionalMoney) volume2.getMonetary()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,8 +407,10 @@ shared.notSigned.noNeedAlts=Cryptocurrency accounts do not feature signing or ag
|
||||||
|
|
||||||
offerbook.nrOffers=No. of offers: {0}
|
offerbook.nrOffers=No. of offers: {0}
|
||||||
offerbook.volume={0} (min - max)
|
offerbook.volume={0} (min - max)
|
||||||
|
offerbook.volumeTotal={0} ({1})
|
||||||
offerbook.deposit=Deposit XMR (%)
|
offerbook.deposit=Deposit XMR (%)
|
||||||
offerbook.deposit.help=Deposit paid by each trader to guarantee the trade. Will be returned when the trade is completed.
|
offerbook.deposit.help=Deposit paid by each trader to guarantee the trade. Will be returned when the trade is completed.
|
||||||
|
offerbook.XMRTotal=XMR ({0})
|
||||||
|
|
||||||
offerbook.createNewOffer=Create offer to {0} {1}
|
offerbook.createNewOffer=Create offer to {0} {1}
|
||||||
offerbook.createOfferDisabled.tooltip=You can only create one offer at a time
|
offerbook.createOfferDisabled.tooltip=You can only create one offer at a time
|
||||||
|
|
|
@ -95,7 +95,10 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
private AnchorPane chartPane;
|
private AnchorPane chartPane;
|
||||||
private AutocompleteComboBox<CurrencyListItem> currencyComboBox;
|
private AutocompleteComboBox<CurrencyListItem> currencyComboBox;
|
||||||
private Subscription tradeCurrencySubscriber;
|
private Subscription tradeCurrencySubscriber;
|
||||||
private final StringProperty volumeColumnLabel = new SimpleStringProperty();
|
private final StringProperty volumeSellColumnLabel = new SimpleStringProperty();
|
||||||
|
private final StringProperty volumeBuyColumnLabel = new SimpleStringProperty();
|
||||||
|
private final StringProperty amountSellColumnLabel = new SimpleStringProperty();
|
||||||
|
private final StringProperty amountBuyColumnLabel = new SimpleStringProperty();
|
||||||
private final StringProperty priceColumnLabel = new SimpleStringProperty();
|
private final StringProperty priceColumnLabel = new SimpleStringProperty();
|
||||||
private AutoTooltipButton sellButton;
|
private AutoTooltipButton sellButton;
|
||||||
private AutoTooltipButton buyButton;
|
private AutoTooltipButton buyButton;
|
||||||
|
@ -201,7 +204,6 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
tradeCurrencySubscriber = EasyBind.subscribe(model.selectedTradeCurrencyProperty,
|
tradeCurrencySubscriber = EasyBind.subscribe(model.selectedTradeCurrencyProperty,
|
||||||
tradeCurrency -> {
|
tradeCurrency -> {
|
||||||
String code = tradeCurrency.getCode();
|
String code = tradeCurrency.getCode();
|
||||||
volumeColumnLabel.set(Res.get("offerbook.volume", code));
|
|
||||||
xAxis.setTickLabelFormatter(new StringConverter<>() {
|
xAxis.setTickLabelFormatter(new StringConverter<>() {
|
||||||
final int cryptoPrecision = 3;
|
final int cryptoPrecision = 3;
|
||||||
final DecimalFormat df = new DecimalFormat(",###");
|
final DecimalFormat df = new DecimalFormat(",###");
|
||||||
|
@ -351,6 +353,11 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void updateChartData() {
|
private synchronized void updateChartData() {
|
||||||
|
volumeSellColumnLabel.set(Res.get("offerbook.volumeTotal", model.getCurrencyCode(), VolumeUtil.formatVolume(model.getTotalVolume(OfferDirection.SELL))));
|
||||||
|
volumeBuyColumnLabel.set(Res.get("offerbook.volumeTotal", model.getCurrencyCode(), VolumeUtil.formatVolume(model.getTotalVolume(OfferDirection.BUY))));
|
||||||
|
amountSellColumnLabel.set(Res.get("offerbook.XMRTotal", "" + model.getTotalAmount(OfferDirection.SELL)));
|
||||||
|
amountBuyColumnLabel.set(Res.get("offerbook.XMRTotal", "" + model.getTotalAmount(OfferDirection.BUY)));
|
||||||
|
|
||||||
seriesBuy.getData().clear();
|
seriesBuy.getData().clear();
|
||||||
seriesSell.getData().clear();
|
seriesSell.getData().clear();
|
||||||
areaChart.getData().clear();
|
areaChart.getData().clear();
|
||||||
|
@ -491,11 +498,13 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
boolean isSellTable = model.isSellOffer(direction);
|
||||||
|
|
||||||
// volume
|
// volume
|
||||||
TableColumn<OfferListItem, OfferListItem> volumeColumn = new TableColumn<>();
|
TableColumn<OfferListItem, OfferListItem> volumeColumn = new TableColumn<>();
|
||||||
volumeColumn.setMinWidth(115);
|
volumeColumn.setMinWidth(115);
|
||||||
volumeColumn.setSortable(false);
|
volumeColumn.setSortable(false);
|
||||||
volumeColumn.textProperty().bind(volumeColumnLabel);
|
volumeColumn.textProperty().bind(isSellTable ? volumeSellColumnLabel : volumeBuyColumnLabel);
|
||||||
volumeColumn.getStyleClass().addAll("number-column");
|
volumeColumn.getStyleClass().addAll("number-column");
|
||||||
volumeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
volumeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper<>(offer.getValue()));
|
||||||
volumeColumn.setCellFactory(
|
volumeColumn.setCellFactory(
|
||||||
|
@ -553,7 +562,8 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
});
|
});
|
||||||
|
|
||||||
// amount
|
// amount
|
||||||
TableColumn<OfferListItem, OfferListItem> amountColumn = new AutoTooltipTableColumn<>(Res.get("shared.XMRMinMax"));
|
TableColumn<OfferListItem, OfferListItem> amountColumn = new TableColumn<>();
|
||||||
|
amountColumn.textProperty().bind(isSellTable ? amountSellColumnLabel : amountBuyColumnLabel);
|
||||||
amountColumn.setMinWidth(115);
|
amountColumn.setMinWidth(115);
|
||||||
amountColumn.setSortable(false);
|
amountColumn.setSortable(false);
|
||||||
amountColumn.getStyleClass().add("number-column");
|
amountColumn.getStyleClass().add("number-column");
|
||||||
|
@ -577,10 +587,8 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
boolean isSellOffer = model.isSellOffer(direction);
|
|
||||||
|
|
||||||
// trader avatar
|
// trader avatar
|
||||||
TableColumn<OfferListItem, OfferListItem> avatarColumn = new AutoTooltipTableColumn<>(isSellOffer ?
|
TableColumn<OfferListItem, OfferListItem> avatarColumn = new AutoTooltipTableColumn<>(isSellTable ?
|
||||||
Res.get("shared.sellerUpperCase") : Res.get("shared.buyerUpperCase")) {
|
Res.get("shared.sellerUpperCase") : Res.get("shared.buyerUpperCase")) {
|
||||||
{
|
{
|
||||||
setMinWidth(80);
|
setMinWidth(80);
|
||||||
|
@ -645,7 +653,7 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||||
AutoTooltipButton button = new AutoTooltipButton();
|
AutoTooltipButton button = new AutoTooltipButton();
|
||||||
button.setContentDisplay(ContentDisplay.RIGHT);
|
button.setContentDisplay(ContentDisplay.RIGHT);
|
||||||
button.setGraphicTextGap(10);
|
button.setGraphicTextGap(10);
|
||||||
button.updateText(isSellOffer ? Res.get("market.offerBook.buy") : Res.get("market.offerBook.sell"));
|
button.updateText(isSellTable ? Res.get("market.offerBook.buy") : Res.get("market.offerBook.sell"));
|
||||||
button.setMinHeight(32);
|
button.setMinHeight(32);
|
||||||
button.setOnAction(e -> model.goToOfferView(direction));
|
button.setOnAction(e -> model.goToOfferView(direction));
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import haveno.core.locale.CurrencyUtil;
|
||||||
import haveno.core.locale.GlobalSettings;
|
import haveno.core.locale.GlobalSettings;
|
||||||
import haveno.core.locale.TradeCurrency;
|
import haveno.core.locale.TradeCurrency;
|
||||||
import haveno.core.monetary.Price;
|
import haveno.core.monetary.Price;
|
||||||
|
import haveno.core.monetary.Volume;
|
||||||
import haveno.core.offer.Offer;
|
import haveno.core.offer.Offer;
|
||||||
import haveno.core.offer.OfferDirection;
|
import haveno.core.offer.OfferDirection;
|
||||||
import haveno.core.offer.OpenOfferManager;
|
import haveno.core.offer.OpenOfferManager;
|
||||||
|
@ -215,6 +216,29 @@ class OfferBookChartViewModel extends ActivatableViewModel {
|
||||||
return direction == OfferDirection.SELL;
|
return direction == OfferDirection.SELL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getTotalAmount(OfferDirection direction) {
|
||||||
|
synchronized (offerBookListItems) {
|
||||||
|
return offerBookListItems.stream()
|
||||||
|
.map(OfferBookListItem::getOffer)
|
||||||
|
.filter(e -> e.getCurrencyCode().equals(selectedTradeCurrencyProperty.get().getCode())
|
||||||
|
&& e.getDirection().equals(direction))
|
||||||
|
.mapToDouble(item -> HavenoUtils.atomicUnitsToXmr(item.getAmount()))
|
||||||
|
.sum();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Volume getTotalVolume(OfferDirection direction) {
|
||||||
|
synchronized (offerBookListItems) {
|
||||||
|
List<Volume> volumes = offerBookListItems.stream()
|
||||||
|
.map(OfferBookListItem::getOffer)
|
||||||
|
.filter(e -> e.getCurrencyCode().equals(selectedTradeCurrencyProperty.get().getCode())
|
||||||
|
&& e.getDirection().equals(direction))
|
||||||
|
.map(Offer::getVolume)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return VolumeUtil.sum(volumes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isMyOffer(Offer offer) {
|
public boolean isMyOffer(Offer offer) {
|
||||||
return openOfferManager.isMyOffer(offer);
|
return openOfferManager.isMyOffer(offer);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue