mirror of
https://github.com/bisq-network/bisq.git
synced 2025-01-19 05:44:05 +01:00
Show changes in BSQ Supply over time
This commit is contained in:
parent
72b56a2dcf
commit
5fb1167a28
@ -39,6 +39,8 @@ import bisq.core.dao.state.model.governance.ParamChange;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
import bisq.core.util.coin.BsqFormatter;
|
||||
|
||||
import bisq.common.util.Tuple2;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -1044,6 +1046,44 @@ public class DaoStateService implements DaoSetupService {
|
||||
return getTxOutputsByTxOutputType(TxOutputType.PROOF_OF_BURN_OP_RETURN_OUTPUT);
|
||||
}
|
||||
|
||||
public Set<Tuple2<Long, Long>> getTotalBsqSupply() {
|
||||
return new HashSet<>() {{
|
||||
add(new Tuple2<>(1555340856L, 372540100L)); // Cycle 01 - 15 APR 2019
|
||||
add(new Tuple2<>(1558083590L, 374541600L)); // Cycle 02 - 17 MAY 2019
|
||||
add(new Tuple2<>(1560771266L, 375464400L)); // Cycle 03 - 17 JUN 2019
|
||||
add(new Tuple2<>(1563347672L, 374153300L)); // Cycle 04 - 17 JUL 2019
|
||||
add(new Tuple2<>(1566009595L, 378733200L)); // Cycle 05 - 16 AUG 2019
|
||||
add(new Tuple2<>(1568643566L, 385347900L)); // Cycle 06 - 16 SEP 2019
|
||||
add(new Tuple2<>(1571349571L, 391167400L)); // Cycle 07 - 17 OCT 2019
|
||||
add(new Tuple2<>(1574180991L, 398324900L)); // Cycle 08 - 19 NOV 2019
|
||||
add(new Tuple2<>(1576966522L, 394719900L)); // Cycle 09 - 21 DEC 2019
|
||||
add(new Tuple2<>(1579613568L, 397643900L)); // Cycle 10 - 21 JAN 2020
|
||||
add(new Tuple2<>(1582399054L, 401189100L)); // Cycle 11 - 22 FEB 2020
|
||||
add(new Tuple2<>(1585342220L, 403141900L)); // Cycle 12 - 27 MAR 2020
|
||||
add(new Tuple2<>(1588025030L, 399991400L)); // Cycle 13
|
||||
add(new Tuple2<>(1591004931L, 411136400L)); // Cycle 14
|
||||
add(new Tuple2<>(1593654027L, 420908500L)); // Cycle 15
|
||||
add(new Tuple2<>(1596407074L, 421255800L)); // Cycle 16
|
||||
add(new Tuple2<>(1599175867L, 430737100L)); // Cycle 17
|
||||
add(new Tuple2<>(1601861442L, 429305600L)); // Cycle 18
|
||||
add(new Tuple2<>(1604845863L, 431446100L)); // Cycle 19 - 8 NOV 2020
|
||||
add(new Tuple2<>(1610233200L, 422663200L)); // Cycle 20
|
||||
add(new Tuple2<>(1612911600L, 449935500L)); // Cycle 21
|
||||
add(new Tuple2<>(1615762800L, 446547000L)); // Cycle 22
|
||||
add(new Tuple2<>(1618437600L, 441126800L)); // Cycle 23
|
||||
add(new Tuple2<>(1621288800L, 442629900L)); // Cycle 24
|
||||
add(new Tuple2<>(1624572000L, 434999300L)); // Cycle 25
|
||||
add(new Tuple2<>(1627596000L, 437237400L)); // Cycle 26
|
||||
add(new Tuple2<>(1630188000L, 431897700L)); // Cycle 27
|
||||
add(new Tuple2<>(1632952800L, 433282600L)); // Cycle 28
|
||||
add(new Tuple2<>(1635544800L, 431026400L)); // Cycle 29 - 29 SEP 2021
|
||||
add(new Tuple2<>(1638399600L, 424954400L)); // Cycle 30
|
||||
add(new Tuple2<>(1641078000L, 438560500L)); // Cycle 31
|
||||
add(new Tuple2<>(1643756400L, 433806200L)); // Cycle 32
|
||||
add(new Tuple2<>(1646555748L, 431667800L)); // Cycle 33
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Listeners
|
||||
|
@ -2600,6 +2600,7 @@ dao.factsAndFigures.supply.compRequestIssueAmount=BSQ issued for compensation re
|
||||
dao.factsAndFigures.supply.reimbursementAmount=BSQ issued for reimbursement requests
|
||||
dao.factsAndFigures.supply.totalIssued=Total issued BSQ
|
||||
dao.factsAndFigures.supply.totalBurned=Total burned BSQ
|
||||
dao.factsAndFigures.supply.totalBsqSupply=Total BSQ supply
|
||||
dao.factsAndFigures.supply.chart.tradeFee.toolTip={0}\n{1}
|
||||
dao.factsAndFigures.supply.burnt=BSQ burnt
|
||||
|
||||
|
@ -22,6 +22,7 @@ import bisq.desktop.common.model.ActivatableDataModel;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.TemporalAdjuster;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Predicate;
|
||||
|
@ -87,7 +87,7 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
private SplitPane timelineNavigation;
|
||||
protected NumberAxis xAxis, yAxis;
|
||||
protected LineChart<Number, Number> chart;
|
||||
private HBox timelineLabels, legendBox2;
|
||||
private HBox timelineLabels, legendBox2, legendBox3;
|
||||
private final ToggleGroup timeIntervalToggleGroup = new ToggleGroup();
|
||||
|
||||
protected final Set<XYChart.Series<Number, Number>> activeSeries = new HashSet<>();
|
||||
@ -157,6 +157,11 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
legendBox2 = initLegendsAndGetLegendBox(seriesForLegend2);
|
||||
}
|
||||
|
||||
Collection<XYChart.Series<Number, Number>> seriesForLegend3 = getSeriesForLegend3();
|
||||
if (seriesForLegend3 != null && !seriesForLegend3.isEmpty()) {
|
||||
legendBox3 = initLegendsAndGetLegendBox(seriesForLegend3);
|
||||
}
|
||||
|
||||
// Set active series/legends
|
||||
defineAndAddActiveSeries();
|
||||
|
||||
@ -176,6 +181,9 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
if (legendBox2 != null) {
|
||||
VBox.setMargin(legendBox2, new Insets(-20, rightPadding, 0, paddingLeft));
|
||||
}
|
||||
if (legendBox3 != null) {
|
||||
VBox.setMargin(legendBox3, new Insets(-20, rightPadding, 0, paddingLeft));
|
||||
}
|
||||
|
||||
if (model.getDividerPositions()[0] == 0 && model.getDividerPositions()[1] == 1) {
|
||||
resetTimeNavigation();
|
||||
@ -192,6 +200,10 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
VBox.setMargin(legendBox2, new Insets(-20, paddingRight, 0, paddingLeft));
|
||||
timelineNavigationBox.getChildren().add(legendBox2);
|
||||
}
|
||||
if (legendBox3 != null) {
|
||||
VBox.setMargin(legendBox3, new Insets(-20, paddingRight, 0, paddingLeft));
|
||||
timelineNavigationBox.getChildren().add(legendBox3);
|
||||
}
|
||||
root.getChildren().addAll(timeIntervalBox, chart, timelineNavigationBox);
|
||||
|
||||
// Listeners
|
||||
@ -241,6 +253,7 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
|
||||
addLegendToggleActionHandlers(getSeriesForLegend1());
|
||||
addLegendToggleActionHandlers(getSeriesForLegend2());
|
||||
addLegendToggleActionHandlers(getSeriesForLegend3());
|
||||
addActionHandlersToDividers();
|
||||
}
|
||||
|
||||
@ -258,6 +271,7 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
|
||||
removeLegendToggleActionHandlers(getSeriesForLegend1());
|
||||
removeLegendToggleActionHandlers(getSeriesForLegend2());
|
||||
removeLegendToggleActionHandlers(getSeriesForLegend3());
|
||||
removeActionHandlersToDividers();
|
||||
|
||||
// clear data, reset states. We keep timeInterval state though
|
||||
@ -541,6 +555,10 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Collection<XYChart.Series<Number, Number>> getSeriesForLegend3() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract void defineAndAddActiveSeries();
|
||||
|
||||
protected void activateSeries(XYChart.Series<Number, Number> series) {
|
||||
|
@ -24,6 +24,8 @@ import bisq.core.dao.state.model.blockchain.Tx;
|
||||
import bisq.core.dao.state.model.governance.Issuance;
|
||||
import bisq.core.dao.state.model.governance.IssuanceType;
|
||||
|
||||
import bisq.common.util.Tuple2;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
@ -45,7 +47,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
public class DaoChartDataModel extends ChartDataModel {
|
||||
private final DaoStateService daoStateService;
|
||||
private final Function<Issuance, Long> blockTimeOfIssuanceFunction;
|
||||
private Map<Long, Long> totalIssuedByInterval, compensationByInterval, reimbursementByInterval,
|
||||
private Map<Long, Long> totalSupplyByInterval, totalIssuedByInterval, compensationByInterval, reimbursementByInterval,
|
||||
totalBurnedByInterval, bsqTradeFeeByInterval, proofOfBurnByInterval;
|
||||
|
||||
|
||||
@ -68,6 +70,7 @@ public class DaoChartDataModel extends ChartDataModel {
|
||||
|
||||
@Override
|
||||
protected void invalidateCache() {
|
||||
totalSupplyByInterval = null;
|
||||
totalIssuedByInterval = null;
|
||||
compensationByInterval = null;
|
||||
reimbursementByInterval = null;
|
||||
@ -111,6 +114,19 @@ public class DaoChartDataModel extends ChartDataModel {
|
||||
// Data for chart
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Map<Long, Long> getTotalSupplyByInterval() {
|
||||
if (totalSupplyByInterval != null) {
|
||||
return totalSupplyByInterval;
|
||||
}
|
||||
|
||||
totalSupplyByInterval = getTotalBsqSupplyByInterval(
|
||||
daoStateService.getTotalBsqSupply(),
|
||||
getDateFilter()
|
||||
);
|
||||
|
||||
return totalSupplyByInterval;
|
||||
}
|
||||
|
||||
Map<Long, Long> getTotalIssuedByInterval() {
|
||||
if (totalIssuedByInterval != null) {
|
||||
return totalIssuedByInterval;
|
||||
@ -179,6 +195,12 @@ public class DaoChartDataModel extends ChartDataModel {
|
||||
// Aggregated collection data by interval
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private Map<Long, Long> getTotalBsqSupplyByInterval(Set<Tuple2<Long, Long>> bsqSupply, Predicate<Long> dateFilter) {
|
||||
return bsqSupply.stream()
|
||||
.filter(i -> dateFilter.test(i.first))
|
||||
.collect(Collectors.toMap(i -> i.first, i -> i.second));
|
||||
}
|
||||
|
||||
private Map<Long, Long> getIssuedBsqByInterval(Set<Issuance> issuanceSet, Predicate<Long> dateFilter) {
|
||||
return issuanceSet.stream()
|
||||
.collect(Collectors.groupingBy(issuance ->
|
||||
|
@ -46,7 +46,7 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
private final LongProperty proofOfBurnAmountProperty = new SimpleLongProperty();
|
||||
|
||||
private XYChart.Series<Number, Number> seriesBsqTradeFee, seriesProofOfBurn, seriesCompensation,
|
||||
seriesReimbursement, seriesTotalIssued, seriesTotalBurned;
|
||||
seriesReimbursement, seriesTotalSupply, seriesTotalIssued, seriesTotalBurned;
|
||||
|
||||
|
||||
@Inject
|
||||
@ -90,6 +90,11 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
return List.of(seriesTotalBurned, seriesBsqTradeFee, seriesProofOfBurn);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<XYChart.Series<Number, Number>> getSeriesForLegend3() {
|
||||
return List.of(seriesTotalSupply);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Timeline navigation
|
||||
@ -130,6 +135,10 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
seriesProofOfBurn = new XYChart.Series<>();
|
||||
seriesProofOfBurn.setName(Res.get("dao.factsAndFigures.supply.proofOfBurn"));
|
||||
seriesIndexMap.put(getSeriesId(seriesProofOfBurn), 5);
|
||||
|
||||
seriesTotalSupply = new XYChart.Series<>();
|
||||
seriesTotalSupply.setName(Res.get("dao.factsAndFigures.supply.totalBsqSupply"));
|
||||
seriesIndexMap.put(getSeriesId(seriesTotalSupply), 6);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -176,6 +185,11 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
allFutures.add(task6Done);
|
||||
applyProofOfBurn(task6Done);
|
||||
}
|
||||
if (activeSeries.contains(seriesTotalSupply)) {
|
||||
CompletableFuture<Boolean> task6ADone = new CompletableFuture<>();
|
||||
allFutures.add(task6ADone);
|
||||
applyTotalSupply(task6ADone);
|
||||
}
|
||||
|
||||
CompletableFuture<Boolean> task7Done = new CompletableFuture<>();
|
||||
allFutures.add(task7Done);
|
||||
@ -216,6 +230,15 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
return CompletableFutureUtils.allOf(allFutures).thenApply(e -> true);
|
||||
}
|
||||
|
||||
private void applyTotalSupply(CompletableFuture<Boolean> completeFuture) {
|
||||
model.getTotalSupplyChartData()
|
||||
.whenComplete((data, t) ->
|
||||
mapToUserThread(() -> {
|
||||
seriesTotalSupply.getData().setAll(data);
|
||||
completeFuture.complete(true);
|
||||
}));
|
||||
}
|
||||
|
||||
private void applyTotalIssued(CompletableFuture<Boolean> completeFuture) {
|
||||
model.getTotalIssuedChartData()
|
||||
.whenComplete((data, t) ->
|
||||
|
@ -54,6 +54,10 @@ public class DaoChartViewModel extends ChartViewModel<DaoChartDataModel> {
|
||||
// Chart data
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CompletableFuture<List<XYChart.Data<Number, Number>>> getTotalSupplyChartData() {
|
||||
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getTotalSupplyByInterval()));
|
||||
}
|
||||
|
||||
CompletableFuture<List<XYChart.Data<Number, Number>>> getTotalIssuedChartData() {
|
||||
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getTotalIssuedByInterval()));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user