95: EMC: Display Perps positions in a tree table using dummy data
This commit is contained in:
@@ -161,7 +161,7 @@ public final class EvelynMissionControlImpl implements EvelynMissionControl, Nen
|
||||
TabPane tabs = new TabPane(
|
||||
createOverviewTab(color, statusIndexChart),
|
||||
createMissionControlTab("Portfolio", color),
|
||||
createMissionControlTab("Perps", color),
|
||||
PerpsTab.create(color),
|
||||
createMissionControlTab("Spot", color),
|
||||
createMissionControlTab("Liquidity Pools", color),
|
||||
createMissionControlTab("Alarms", color),
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
package com.r35157.evelyn.emc.impl.ref;
|
||||
|
||||
import javafx.beans.property.ReadOnlyStringWrapper;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import javafx.scene.control.TreeTableColumn;
|
||||
import javafx.scene.control.TreeTableRow;
|
||||
import javafx.scene.control.TreeTableView;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
final class PerpsTab {
|
||||
static Tab create(String environmentColor) {
|
||||
NumberFormat usdFormat = NumberFormat.getCurrencyInstance(Locale.US);
|
||||
|
||||
TreeTableColumn<PositionRow, String> position = new TreeTableColumn<>("Position");
|
||||
position.setCellValueFactory(cell -> new ReadOnlyStringWrapper(cell.getValue().getValue().label()));
|
||||
position.setPrefWidth(260);
|
||||
position.setMinWidth(180);
|
||||
position.setSortable(false);
|
||||
|
||||
TreeTableColumn<PositionRow, String> direction = new TreeTableColumn<>("Direction");
|
||||
direction.setCellValueFactory(cell -> {
|
||||
Direction value = cell.getValue().getValue().direction();
|
||||
return new ReadOnlyStringWrapper(value == null ? "" : value.label);
|
||||
});
|
||||
direction.setPrefWidth(90);
|
||||
direction.setMinWidth(80);
|
||||
direction.setSortable(false);
|
||||
|
||||
TreeTableColumn<PositionRow, String> size = new TreeTableColumn<>("Position size, USD");
|
||||
size.setCellValueFactory(cell -> {
|
||||
ΩAmountΩ value = cell.getValue().getValue().sizeUsd();
|
||||
return new ReadOnlyStringWrapper(value == null ? "" : usdFormat.format(value));
|
||||
});
|
||||
size.setPrefWidth(170);
|
||||
size.setMinWidth(155);
|
||||
size.setStyle("-fx-alignment: CENTER-RIGHT;");
|
||||
size.setSortable(false);
|
||||
|
||||
TreeTableView<PositionRow> table = new TreeTableView<>(createSampleRoot());
|
||||
table.setShowRoot(false);
|
||||
table.setTreeColumn(position);
|
||||
table.getColumns().add(position);
|
||||
table.getColumns().add(direction);
|
||||
table.getColumns().add(size);
|
||||
table.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY_FLEX_LAST_COLUMN);
|
||||
table.setRowFactory(view -> new TreeTableRow<>() {
|
||||
@Override
|
||||
protected void updateItem(PositionRow item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setStyle(empty || item == null || item.direction() == null
|
||||
? ""
|
||||
: item.direction().rowStyle);
|
||||
}
|
||||
});
|
||||
|
||||
Label sampleNotice = new Label(
|
||||
"Sample data only — not live positions. Phoenix rows are illustrative; no Phoenix integration exists."
|
||||
);
|
||||
sampleNotice.setWrapText(true);
|
||||
sampleNotice.setMinHeight(VBox.USE_PREF_SIZE);
|
||||
|
||||
VBox content = new VBox(8, sampleNotice, table);
|
||||
content.setPadding(new Insets(10));
|
||||
content.setStyle("-fx-background-color: " + environmentColor + ";");
|
||||
VBox.setVgrow(table, Priority.ALWAYS);
|
||||
|
||||
Tab tab = new Tab("Perps", content);
|
||||
tab.setStyle("-fx-background-color: " + environmentColor + ";");
|
||||
return tab;
|
||||
}
|
||||
|
||||
private static TreeItem<PositionRow> createSampleRoot() {
|
||||
return group("Sample positions",
|
||||
group("Sample wallet A",
|
||||
group("Jupiter",
|
||||
position("SOL-PERP", Direction.LONG, "12500.00"),
|
||||
position("BTC-PERP", Direction.SHORT, "8250.50")),
|
||||
group("Phoenix",
|
||||
position("SOL-PERP", Direction.SHORT, "3200.75"),
|
||||
position("ETH-PERP", Direction.LONG, "5400.00"))),
|
||||
group("Sample wallet B",
|
||||
group("Jupiter",
|
||||
position("ETH-PERP", Direction.LONG, "1875.25"),
|
||||
position("SOL-PERP", Direction.SHORT, "950.00")),
|
||||
group("Phoenix",
|
||||
position("BTC-PERP", Direction.LONG, "21000.00"),
|
||||
position("SOL-PERP", Direction.SHORT, "640.50"))));
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static TreeItem<PositionRow> group(String label, TreeItem<PositionRow>... children) {
|
||||
TreeItem<PositionRow> item = new TreeItem<>(new PositionRow(label, null, null));
|
||||
item.getChildren().addAll(children);
|
||||
item.setExpanded(true);
|
||||
return item;
|
||||
}
|
||||
|
||||
private static TreeItem<PositionRow> position(String label, Direction direction, String sizeUsd) {
|
||||
return new TreeItem<>(new PositionRow(label, direction, new BigDecimal(sizeUsd)));
|
||||
}
|
||||
|
||||
private record PositionRow(String label, Direction direction, ΩAmountΩ sizeUsd) {
|
||||
}
|
||||
|
||||
private enum Direction {
|
||||
LONG("Long", "#e6f4ea"),
|
||||
SHORT("Short", "#fce8e6");
|
||||
|
||||
Direction(String label, String background) {
|
||||
this.label = label;
|
||||
this.rowStyle = "-fx-control-inner-background: " + background + ";"
|
||||
+ "-fx-control-inner-background-alt: " + background + ";";
|
||||
}
|
||||
|
||||
private final String label;
|
||||
private final String rowStyle;
|
||||
}
|
||||
|
||||
private PerpsTab() {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user