Merge pull request #6204 from chimp1984/add-revenue-chart

Add chart series for total trade fees
This commit is contained in:
Bisq GitHub Admin 2022-05-16 16:58:27 +02:00 committed by GitHub
commit 6fa87aea11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 355 additions and 45 deletions

View File

@ -2617,10 +2617,12 @@ dao.factsAndFigures.supply.totalLockedUpAmount=Locked up in bonds
dao.factsAndFigures.supply.totalUnlockingAmount=Unlocking BSQ from bonds
dao.factsAndFigures.supply.totalUnlockedAmount=Unlocked BSQ from bonds
dao.factsAndFigures.supply.totalConfiscatedAmount=Confiscated BSQ from bonds
dao.factsAndFigures.supply.proofOfBurn=Proof of Burn
dao.factsAndFigures.supply.totalTradeFees=Total trade fees
dao.factsAndFigures.supply.bsqTradeFee=BSQ Trade fees
dao.factsAndFigures.supply.btcTradeFee=BTC Trade fees
dao.factsAndFigures.supply.btcFees=BTC trade fees (proof of Burn)
dao.factsAndFigures.supply.arbitration=From arbitration (proof of Burn))
dao.factsAndFigures.supply.proofOfBurn=Proof of Burn
dao.factsAndFigures.supply.proofOfBurnReimbursementDiff=Diff total burned-reimbursement
dao.factsAndFigures.transactions.genesis=Genesis transaction
dao.factsAndFigures.transactions.genesisBlockHeight=Genesis block height
dao.factsAndFigures.transactions.genesisTxId=Genesis transaction ID
@ -3335,6 +3337,8 @@ BTC_DAO_REGTEST=Bitcoin DAO Regtest
time.year=Year
time.month=Month
time.halfYear=Half-year
time.quarter=Quarter
time.week=Week
time.day=Day
time.hour=Hour

View File

@ -1765,36 +1765,119 @@ textfield */
#charts-dao .default-color1.chart-line-symbol { -fx-background-color: -bs-chart-dao-line2, -bs-chart-dao-line2; }
#charts-dao .default-color2.chart-series-line { -fx-stroke: -bs-chart-dao-line3; }
#charts-dao .default-color2.chart-line-symbol { -fx-background-color: -bs-chart-dao-line3, -bs-chart-dao-line3; }
#charts-dao .default-color2.chart-line-symbol {
-fx-background-color: -bs-chart-dao-line3, -bs-chart-dao-line3;
}
#charts-dao .default-color3.chart-series-line { -fx-stroke: -bs-chart-dao-line4; }
#charts-dao .default-color3.chart-line-symbol { -fx-background-color: -bs-chart-dao-line4, -bs-chart-dao-line4; }
#charts-dao .default-color3.chart-series-line {
-fx-stroke: -bs-chart-dao-line4;
}
#charts-dao .default-color4.chart-series-line { -fx-stroke: -bs-chart-dao-line5; }
#charts-dao .default-color4.chart-line-symbol { -fx-background-color: -bs-chart-dao-line5, -bs-chart-dao-line5; }
#charts-dao .default-color3.chart-line-symbol {
-fx-background-color: -bs-chart-dao-line4, -bs-chart-dao-line4;
}
#charts-dao .default-color5.chart-series-line { -fx-stroke: -bs-chart-dao-line6; }
#charts-dao .default-color5.chart-line-symbol { -fx-background-color: -bs-chart-dao-line6, -bs-chart-dao-line6; }
#charts-dao .default-color4.chart-series-line {
-fx-stroke: -bs-chart-dao-line5;
}
#charts-dao .default-color4.chart-line-symbol {
-fx-background-color: -bs-chart-dao-line5, -bs-chart-dao-line5;
}
#charts-dao .default-color5.chart-series-line {
-fx-stroke: -bs-chart-dao-line6;
}
#charts-dao .default-color5.chart-line-symbol {
-fx-background-color: -bs-chart-dao-line6, -bs-chart-dao-line6;
}
#charts-dao .default-color6.chart-series-line {
-fx-stroke: -bs-chart-dao-line7;
}
#charts-dao .default-color6.chart-line-symbol {
-fx-background-color: -bs-chart-dao-line7, -bs-chart-dao-line7;
}
#charts-dao .default-color7.chart-series-line {
-fx-stroke: -bs-chart-dao-line8;
}
#charts-dao .default-color7.chart-line-symbol {
-fx-background-color: -bs-chart-dao-line8, -bs-chart-dao-line8;
}
#charts-dao .default-color8.chart-series-line {
-fx-stroke: -bs-chart-dao-line9;
}
#charts-dao .default-color8.chart-line-symbol {
-fx-background-color: -bs-chart-dao-line9, -bs-chart-dao-line9;
}
#charts-dao .default-color9.chart-series-line {
-fx-stroke: -bs-chart-dao-line10;
}
#charts-dao .default-color9.chart-line-symbol {
-fx-background-color: -bs-chart-dao-line10, -bs-chart-dao-line10;
}
#charts-dao .default-color10.chart-series-line {
-fx-stroke: -bs-chart-dao-line11;
}
#charts-dao .default-color10.chart-line-symbol {
-fx-background-color: -bs-chart-dao-line11, -bs-chart-dao-line11;
}
#charts-legend-toggle0 {
-jfx-toggle-color: -bs-chart-dao-line1
}
#charts-legend-toggle1 {
-jfx-toggle-color: -bs-chart-dao-line2;
}
#charts-legend-toggle2 {
-jfx-toggle-color: -bs-chart-dao-line3;
}
#charts-legend-toggle3 {
-jfx-toggle-color: -bs-chart-dao-line4;
}
#charts-legend-toggle4 {
-jfx-toggle-color: -bs-chart-dao-line5;
}
#charts-legend-toggle5 {
-jfx-toggle-color: -bs-chart-dao-line6;
}
#charts-legend-toggle6 {
-jfx-toggle-color: -bs-chart-dao-line7;
}
#charts-legend-toggle7 {
-jfx-toggle-color: -bs-chart-dao-line8;
}
#charts-legend-toggle8 {
-jfx-toggle-color: -bs-chart-dao-line9;
}
#charts-legend-toggle9 {
-jfx-toggle-color: -bs-chart-dao-line10;
}
#charts-legend-toggle10 {
-jfx-toggle-color: -bs-chart-dao-line11;
}
#charts-dao .chart-series-line {
-fx-stroke-width: 2px;
}

View File

@ -291,6 +291,10 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
protected HBox getTimeIntervalBox() {
ToggleButton year = getTimeIntervalToggleButton(Res.get("time.year"), TemporalAdjusterModel.Interval.YEAR,
timeIntervalToggleGroup, "toggle-left");
ToggleButton halfYear = getTimeIntervalToggleButton(Res.get("time.halfYear"), TemporalAdjusterModel.Interval.HALF_YEAR,
timeIntervalToggleGroup, "toggle-center");
ToggleButton quarter = getTimeIntervalToggleButton(Res.get("time.quarter"), TemporalAdjusterModel.Interval.QUARTER,
timeIntervalToggleGroup, "toggle-center");
ToggleButton month = getTimeIntervalToggleButton(Res.get("time.month"), TemporalAdjusterModel.Interval.MONTH,
timeIntervalToggleGroup, "toggle-center");
ToggleButton week = getTimeIntervalToggleButton(Res.get("time.week"), TemporalAdjusterModel.Interval.WEEK,
@ -302,7 +306,7 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
toggleBox.setAlignment(Pos.CENTER_LEFT);
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
toggleBox.getChildren().addAll(spacer, year, month, week, day);
toggleBox.getChildren().addAll(spacer, year, halfYear, quarter, month, week, day);
return toggleBox;
}

View File

@ -79,6 +79,8 @@ public abstract class ChartViewModel<T extends ChartDataModel> extends Activatab
case YEAR:
dateFormatPatters = "yyyy";
break;
case HALF_YEAR:
case QUARTER:
case MONTH:
dateFormatPatters = "MMM\nyyyy";
break;

View File

@ -17,21 +17,58 @@
package bisq.desktop.components.chart;
import bisq.common.util.MathUtils;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
import java.math.RoundingMode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import static java.time.temporal.ChronoField.DAY_OF_YEAR;
@Slf4j
public class TemporalAdjusterModel {
private static final ZoneId ZONE_ID = ZoneId.systemDefault();
public enum Interval {
YEAR(TemporalAdjusters.firstDayOfYear()),
HALF_YEAR(temporal -> {
long halfYear = temporal.range(DAY_OF_YEAR).getMaximum() / 2;
int dayOfYear = 0;
if (temporal instanceof LocalDate) {
dayOfYear = ((LocalDate) temporal).getDayOfYear(); // getDayOfYear delivers 1-365 (366 in leap years)
}
if (dayOfYear <= halfYear) {
return temporal.with(DAY_OF_YEAR, 1);
} else {
return temporal.with(DAY_OF_YEAR, halfYear + 1);
}
}),
QUARTER(temporal -> {
long quarter1 = temporal.range(DAY_OF_YEAR).getMaximum() / 4;
long halfYear = temporal.range(DAY_OF_YEAR).getMaximum() / 2;
long quarter3 = MathUtils.roundDoubleToLong(temporal.range(DAY_OF_YEAR).getMaximum() * 0.75, RoundingMode.FLOOR);
int dayOfYear = 0;
if (temporal instanceof LocalDate) {
dayOfYear = ((LocalDate) temporal).getDayOfYear();
}
if (dayOfYear <= quarter1) {
return temporal.with(DAY_OF_YEAR, 1);
} else if (dayOfYear <= halfYear) {
return temporal.with(DAY_OF_YEAR, quarter1 + 1);
} else if (dayOfYear <= quarter3) {
return temporal.with(DAY_OF_YEAR, halfYear + 1);
} else {
return temporal.with(DAY_OF_YEAR, quarter3 + 1);
}
}),
MONTH(TemporalAdjusters.firstDayOfMonth()),
WEEK(TemporalAdjusters.next(DayOfWeek.MONDAY)),
DAY(TemporalAdjusters.ofDateAdjuster(d -> d));

View File

@ -25,6 +25,8 @@ import bisq.core.dao.state.model.governance.BsqSupplyChange;
import bisq.core.dao.state.model.governance.Issuance;
import bisq.core.dao.state.model.governance.IssuanceType;
import bisq.common.util.Hex;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -32,9 +34,11 @@ import java.time.Instant;
import java.util.Collection;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
@ -47,11 +51,19 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Singleton
public class DaoChartDataModel extends ChartDataModel {
// Date when we started to use tags for separating proof of burn txs
private static final GregorianCalendar TAG_DATE = new GregorianCalendar(2021, GregorianCalendar.NOVEMBER, 3, 13, 0);
private final DaoStateService daoStateService;
private final Function<Issuance, Long> blockTimeOfIssuanceFunction;
private Map<Long, Long> totalSupplyByInterval, totalIssuedByInterval, compensationByInterval, reimbursementByInterval,
totalBurnedByInterval, bsqTradeFeeByInterval, proofOfBurnByInterval;
totalBurnedByInterval, bsqTradeFeeByInterval, proofOfBurnByInterval,
proofOfBurnFromBtcFeesByInterval, proofOfBurnFromArbitrationByInterval,
proofOfBurnReimbursementDiffByInterval, totalTradeFeesByInterval;
static {
TAG_DATE.setTimeZone(TimeZone.getTimeZone("UTC"));
}
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
@ -79,7 +91,10 @@ public class DaoChartDataModel extends ChartDataModel {
totalBurnedByInterval = null;
bsqTradeFeeByInterval = null;
proofOfBurnByInterval = null;
proofOfBurnFromBtcFeesByInterval = null;
proofOfBurnFromArbitrationByInterval = null;
proofOfBurnReimbursementDiffByInterval = null;
totalTradeFeesByInterval = null;
}
@ -125,10 +140,43 @@ public class DaoChartDataModel extends ChartDataModel {
daoStateService.getBsqSupplyChanges(),
getDateFilter()
);
return totalSupplyByInterval;
}
Map<Long, Long> getProofOfBurnReimbursementDiffByInterval() {
if (proofOfBurnReimbursementDiffByInterval != null) {
return proofOfBurnReimbursementDiffByInterval;
}
// By subtracting the reimbursement amounts from the total burned amount we derive the total trade fees.
// Reimbursements have not been used in early days, so those periods do not reflect the value correctly.
// Due to time delays between reimbursements and burning there is not a very good temporal match.
// For shorter time periods we even get negative values if reimbursement was larger than accumulated
// burned BSQ in that time frame.
// It is an alternative view on the revenue to the total fee data which we only support since Nov 2021
Map<Long, Long> burnedMap = getTotalBurnedByInterval();
Map<Long, Long> reimbursementMap = getReimbursementByInterval();
proofOfBurnReimbursementDiffByInterval = getMergedMap(burnedMap, reimbursementMap, (a, b) -> a - b);
return proofOfBurnReimbursementDiffByInterval;
}
Map<Long, Long> getTotalTradeFeesByInterval() {
if (totalTradeFeesByInterval != null) {
return totalTradeFeesByInterval;
}
// From Nov 2021 we use tags for the burned BSQ from BTC fees and for those from delayed payout txs.
// By that we can filter out the burned BSQ from BTC fees.
Map<Long, Long> tradeFee = getBsqTradeFeeByInterval();
Map<Long, Long> proofOfBurn = getProofOfBurnFromBtcFeesByInterval();
Map<Long, Long> merged = getMergedMap(tradeFee, proofOfBurn, Long::sum);
totalTradeFeesByInterval = merged.entrySet().stream()
.filter(entry -> entry.getKey() * 1000 >= TAG_DATE.getTimeInMillis())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return totalTradeFeesByInterval;
}
Map<Long, Long> getTotalIssuedByInterval() {
if (totalIssuedByInterval != null) {
return totalIssuedByInterval;
@ -192,12 +240,44 @@ public class DaoChartDataModel extends ChartDataModel {
return proofOfBurnByInterval;
}
Map<Long, Long> getProofOfBurnFromBtcFeesByInterval() {
if (proofOfBurnFromBtcFeesByInterval != null) {
return proofOfBurnFromBtcFeesByInterval;
}
// Tagging started Nov 2021
// opReturn data from BTC fees: 1701721206fe6b40777763de1c741f4fd2706d94775d
Set<Tx> proofOfBurnTxs = daoStateService.getProofOfBurnTxs();
Set<Tx> feeTxs = proofOfBurnTxs.stream()
.filter(tx -> "1701721206fe6b40777763de1c741f4fd2706d94775d".equals(Hex.encode(tx.getLastTxOutput().getOpReturnData())))
.collect(Collectors.toSet());
proofOfBurnFromBtcFeesByInterval = getBurntBsqByInterval(feeTxs, getDateFilter());
return proofOfBurnFromBtcFeesByInterval;
}
Map<Long, Long> getProofOfBurnFromArbitrationByInterval() {
if (proofOfBurnFromArbitrationByInterval != null) {
return proofOfBurnFromArbitrationByInterval;
}
// Tagging started Nov 2021
// opReturn data from delayed payout txs: 1701e47e5d8030f444c182b5e243871ebbaeadb5e82f
// opReturn data from BM trades with a trade who got reimbursed by the DAO : 1701293c488822f98e70e047012f46f5f1647f37deb7
Set<Tx> feeTxs = daoStateService.getProofOfBurnTxs().stream()
.filter(e -> "1701e47e5d8030f444c182b5e243871ebbaeadb5e82f".equals(Hex.encode(e.getLastTxOutput().getOpReturnData())) ||
"1701293c488822f98e70e047012f46f5f1647f37deb7".equals(Hex.encode(e.getLastTxOutput().getOpReturnData())))
.collect(Collectors.toSet());
proofOfBurnFromArbitrationByInterval = getBurntBsqByInterval(feeTxs, getDateFilter());
return proofOfBurnFromArbitrationByInterval;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Aggregated collection data by interval
///////////////////////////////////////////////////////////////////////////////////////////
private Map<Long, Long> getTotalBsqSupplyByInterval(Stream<BsqSupplyChange> bsqSupplyChanges, Predicate<Long> dateFilter) {
private Map<Long, Long> getTotalBsqSupplyByInterval(Stream<BsqSupplyChange> bsqSupplyChanges,
Predicate<Long> dateFilter) {
AtomicLong supply = new AtomicLong(
DaoEconomyHistoricalData.TOTAL_SUPPLY_BY_CYCLE_DATE.get(1555340856L)
);

View File

@ -46,7 +46,9 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
private final LongProperty proofOfBurnAmountProperty = new SimpleLongProperty();
private XYChart.Series<Number, Number> seriesBsqTradeFee, seriesProofOfBurn, seriesCompensation,
seriesReimbursement, seriesTotalSupply, seriesTotalIssued, seriesTotalBurned;
seriesReimbursement, seriesTotalSupply, seriesTotalIssued, seriesTotalBurned,
seriesTotalTradeFees, seriesProofOfBurnFromBtcFees,
seriesProofOfBurnFromArbitration, seriesProofOfBurnReimbursementDiff;
@Inject
@ -87,12 +89,12 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
@Override
protected Collection<XYChart.Series<Number, Number>> getSeriesForLegend2() {
return List.of(seriesTotalBurned, seriesBsqTradeFee, seriesProofOfBurn);
return List.of(seriesTotalBurned, seriesBsqTradeFee, seriesProofOfBurnFromBtcFees, seriesProofOfBurnFromArbitration, seriesProofOfBurn);
}
@Override
protected Collection<XYChart.Series<Number, Number>> getSeriesForLegend3() {
return List.of(seriesTotalSupply);
return List.of(seriesTotalTradeFees, seriesTotalSupply, seriesProofOfBurnReimbursementDiff);
}
@ -139,6 +141,22 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
seriesTotalSupply = new XYChart.Series<>();
seriesTotalSupply.setName(Res.get("dao.factsAndFigures.supply.totalBsqSupply"));
seriesIndexMap.put(getSeriesId(seriesTotalSupply), 6);
seriesTotalTradeFees = new XYChart.Series<>();
seriesTotalTradeFees.setName(Res.get("dao.factsAndFigures.supply.totalTradeFees"));
seriesIndexMap.put(getSeriesId(seriesTotalTradeFees), 7);
seriesProofOfBurnFromBtcFees = new XYChart.Series<>();
seriesProofOfBurnFromBtcFees.setName(Res.get("dao.factsAndFigures.supply.btcFees"));
seriesIndexMap.put(getSeriesId(seriesProofOfBurnFromBtcFees), 8);
seriesProofOfBurnFromArbitration = new XYChart.Series<>();
seriesProofOfBurnFromArbitration.setName(Res.get("dao.factsAndFigures.supply.arbitration"));
seriesIndexMap.put(getSeriesId(seriesProofOfBurnFromArbitration), 9);
seriesProofOfBurnReimbursementDiff = new XYChart.Series<>();
seriesProofOfBurnReimbursementDiff.setName(Res.get("dao.factsAndFigures.supply.proofOfBurnReimbursementDiff"));
seriesIndexMap.put(getSeriesId(seriesProofOfBurnReimbursementDiff), 10);
}
@Override
@ -156,39 +174,59 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
protected CompletableFuture<Boolean> applyData() {
List<CompletableFuture<Boolean>> allFutures = new ArrayList<>();
if (activeSeries.contains(seriesTotalIssued)) {
CompletableFuture<Boolean> task1Done = new CompletableFuture<>();
allFutures.add(task1Done);
applyTotalIssued(task1Done);
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyTotalIssued(future);
}
if (activeSeries.contains(seriesCompensation)) {
CompletableFuture<Boolean> task2Done = new CompletableFuture<>();
allFutures.add(task2Done);
applyCompensation(task2Done);
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyCompensation(future);
}
if (activeSeries.contains(seriesReimbursement)) {
CompletableFuture<Boolean> task3Done = new CompletableFuture<>();
allFutures.add(task3Done);
applyReimbursement(task3Done);
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyReimbursement(future);
}
if (activeSeries.contains(seriesTotalBurned)) {
CompletableFuture<Boolean> task4Done = new CompletableFuture<>();
allFutures.add(task4Done);
applyTotalBurned(task4Done);
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyTotalBurned(future);
}
if (activeSeries.contains(seriesBsqTradeFee)) {
CompletableFuture<Boolean> task5Done = new CompletableFuture<>();
allFutures.add(task5Done);
applyBsqTradeFee(task5Done);
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyBsqTradeFee(future);
}
if (activeSeries.contains(seriesProofOfBurn)) {
CompletableFuture<Boolean> task6Done = new CompletableFuture<>();
allFutures.add(task6Done);
applyProofOfBurn(task6Done);
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyProofOfBurn(future);
}
if (activeSeries.contains(seriesTotalSupply)) {
CompletableFuture<Boolean> task6ADone = new CompletableFuture<>();
allFutures.add(task6ADone);
applyTotalSupply(task6ADone);
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyTotalSupply(future);
}
if (activeSeries.contains(seriesTotalTradeFees)) {
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyTotalTradeFees(future);
}
if (activeSeries.contains(seriesProofOfBurnFromBtcFees)) {
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyProofOfBurnFromBtcFees(future);
}
if (activeSeries.contains(seriesProofOfBurnFromArbitration)) {
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyProofOfBurnFromArbitration(future);
}
if (activeSeries.contains(seriesProofOfBurnReimbursementDiff)) {
CompletableFuture<Boolean> future = new CompletableFuture<>();
allFutures.add(future);
applyProofOfBurnReimbursementDiff(future);
}
CompletableFuture<Boolean> task7Done = new CompletableFuture<>();
@ -239,6 +277,42 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
}));
}
private void applyTotalTradeFees(CompletableFuture<Boolean> completeFuture) {
model.getTotalTradeFeesChartData()
.whenComplete((data, t) ->
mapToUserThread(() -> {
seriesTotalTradeFees.getData().setAll(data);
completeFuture.complete(true);
}));
}
private void applyProofOfBurnFromBtcFees(CompletableFuture<Boolean> completeFuture) {
model.getProofOfBurnFromBtcFeesChartData()
.whenComplete((data, t) ->
mapToUserThread(() -> {
seriesProofOfBurnFromBtcFees.getData().setAll(data);
completeFuture.complete(true);
}));
}
private void applyProofOfBurnFromArbitration(CompletableFuture<Boolean> completeFuture) {
model.getProofOfBurnFromArbitrationChartData()
.whenComplete((data, t) ->
mapToUserThread(() -> {
seriesProofOfBurnFromArbitration.getData().setAll(data);
completeFuture.complete(true);
}));
}
private void applyProofOfBurnReimbursementDiff(CompletableFuture<Boolean> completeFuture) {
model.getProofOfBurnReimbursementDiffChartData()
.whenComplete((data, t) ->
mapToUserThread(() -> {
seriesProofOfBurnReimbursementDiff.getData().setAll(data);
completeFuture.complete(true);
}));
}
private void applyTotalIssued(CompletableFuture<Boolean> completeFuture) {
model.getTotalIssuedChartData()
.whenComplete((data, t) ->

View File

@ -58,6 +58,22 @@ public class DaoChartViewModel extends ChartViewModel<DaoChartDataModel> {
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getTotalSupplyByInterval()));
}
CompletableFuture<List<XYChart.Data<Number, Number>>> getTotalTradeFeesChartData() {
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getTotalTradeFeesByInterval()));
}
CompletableFuture<List<XYChart.Data<Number, Number>>> getProofOfBurnFromBtcFeesChartData() {
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getProofOfBurnFromBtcFeesByInterval()));
}
CompletableFuture<List<XYChart.Data<Number, Number>>> getProofOfBurnFromArbitrationChartData() {
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getProofOfBurnFromArbitrationByInterval()));
}
CompletableFuture<List<XYChart.Data<Number, Number>>> getProofOfBurnReimbursementDiffChartData() {
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getProofOfBurnReimbursementDiffByInterval()));
}
CompletableFuture<List<XYChart.Data<Number, Number>>> getTotalIssuedChartData() {
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getTotalIssuedByInterval()));
}

View File

@ -141,10 +141,15 @@
/* dao chart colors */
-bs-chart-dao-line1: -bs-color-blue-5;
-bs-chart-dao-line2: -bs-color-green-3;
-bs-chart-dao-line3: -bs-turquoise;
-bs-chart-dao-line4: -bs-turquoise-light;
-bs-chart-dao-line3: #0195fe;
-bs-chart-dao-line4: -bs-soft-red;
-bs-chart-dao-line5: -bs-yellow;
-bs-chart-dao-line6: -bs-soft-red;
-bs-chart-dao-line6: -bs-turquoise-light;
-bs-chart-dao-line7: #ff6c00;
-bs-chart-dao-line8: -bs-turquoise;
-bs-chart-dao-line9: #7fad01;
-bs-chart-dao-line10: #420080;
-bs-chart-dao-line11: #ff3939;
/* Monero orange color code */
-xmr-orange: #f26822;

View File

@ -108,10 +108,15 @@
/* dao chart colors */
-bs-chart-dao-line1: -bs-color-blue-5;
-bs-chart-dao-line2: -bs-color-green-3;
-bs-chart-dao-line3: -bs-turquoise;
-bs-chart-dao-line4: -bs-turquoise-light;
-bs-chart-dao-line3: #0195fe;
-bs-chart-dao-line4: -bs-soft-red;
-bs-chart-dao-line5: -bs-yellow;
-bs-chart-dao-line6: -bs-soft-red;
-bs-chart-dao-line6: -bs-turquoise-light;
-bs-chart-dao-line7: #ff6c00;
-bs-chart-dao-line8: -bs-turquoise;
-bs-chart-dao-line9: #7fad01;
-bs-chart-dao-line10: #420080;
-bs-chart-dao-line11: #ff3939;
/* Monero orange color code */
-xmr-orange: #f26822;