[英]Barchart as TableRow in JavaFX
我想使用JavaFX將這種條形圖添加到我的應用程序中:
本質上:一個(可能很大,即最多 50 個條目)表。 對於每一行,有幾列包含信息。 一條信息是關於贏/平/輸比的百分比,即三個數字 10%、50%、40%。 我想以圖形方式將這三個百分比顯示為一個垂直條,其中包含三個不同的 colors。 這樣用戶就可以獲得這些百分比中的每一個的視覺印象。
我還沒有找到使用 JavaFX 的簡單或直接的方法。 至少現在似乎無法控制。 我也無法從 ControlsFX 中找到合適的控件。 我目前正在做的是擁有信息本身,以及像這樣的百分比的三列:
Option Win Draw Loss
============================
option1 10% 50% 40%
option2 20% 70% 10%
option3 ...
但這不是很好。 如何實現上述圖形顯示?
(添加了一張圖片以便更好地理解;它來自 lichess.org,他們在 html 中正是這樣做的)
這結合了垃圾神和 James_D 的想法:
具有自定義單元工廠和圖形的 TableView,
圖形可能只是在設置了列約束的單行網格窗格中的三個適當樣式的標簽。
除此之外,它是一個標准的表格視圖實現。
由於四舍五入,我的示例中的數字並不總是等於 100%,因此您可能希望對此做一些事情,如果是這樣,我將其留給您。
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.collections.*;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.text.NumberFormat;
import java.util.Arrays;
public class ChartTableApp extends Application {
private final ObservableList<Outcomes> outcomes = FXCollections.observableList(
Arrays.asList(
new Outcomes("Qxd5", 5722, 5722, 3646),
new Outcomes("Kf6", 2727, 2262, 1597),
new Outcomes("c6", 11, 1, 5),
new Outcomes("e6", 0, 1, 1)
)
);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
stage.setScene(new Scene(createOutcomesTableView()));
stage.show();
}
private TableView<Outcomes> createOutcomesTableView() {
final TableView<Outcomes> outcomesTable = new TableView<>(outcomes);
TableColumn<Outcomes, String> moveCol = new TableColumn<>("Move");
moveCol.setCellValueFactory(o ->
new SimpleStringProperty(o.getValue().move())
);
TableColumn<Outcomes, Integer> totalCol = new TableColumn<>("Total");
totalCol.setCellValueFactory(o ->
new SimpleIntegerProperty(o.getValue().total()).asObject()
);
totalCol.setCellFactory(p ->
new IntegerCell()
);
totalCol.setStyle("-fx-alignment: BASELINE_RIGHT;");
TableColumn<Outcomes, Outcomes> outcomesCol = new TableColumn<>("Outcomes");
outcomesCol.setCellValueFactory(o ->
new SimpleObjectProperty<>(o.getValue())
);
outcomesCol.setCellFactory(p ->
new OutcomesCell()
);
//noinspection unchecked
outcomesTable.getColumns().addAll(
moveCol,
totalCol,
outcomesCol
);
outcomesTable.setPrefSize(450, 150);
return outcomesTable;
}
public record Outcomes(String move, int wins, int draws, int losses) {
public int total() { return wins + draws + losses; }
public double winPercent() { return percent(wins); }
public double drawPercent() { return percent(draws); }
public double lossPercent() { return percent(losses); }
private double percent(int value) { return value * 100.0 / total(); }
}
private static class OutcomesCell extends TableCell<Outcomes, Outcomes> {
OutcomesBar bar = new OutcomesBar();
@Override
protected void updateItem(Outcomes item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
} else {
bar.setOutcomes(item);
setGraphic(bar);
}
}
}
private static class OutcomesBar extends GridPane {
private final Label winsLabel = new Label();
private final Label drawsLabel = new Label();
private final Label lossesLabel = new Label();
private final ColumnConstraints winsColConstraints = new ColumnConstraints();
private final ColumnConstraints drawsColConstraints = new ColumnConstraints();
private final ColumnConstraints lossesColConstraints = new ColumnConstraints();
public OutcomesBar() {
winsLabel.setStyle("-fx-background-color : lightgray");
drawsLabel.setStyle("-fx-background-color : darkgray");
lossesLabel.setStyle("-fx-background-color : gray");
winsLabel.setAlignment(Pos.CENTER);
drawsLabel.setAlignment(Pos.CENTER);
lossesLabel.setAlignment(Pos.CENTER);
winsLabel.setMaxWidth(Double.MAX_VALUE);
drawsLabel.setMaxWidth(Double.MAX_VALUE);
lossesLabel.setMaxWidth(Double.MAX_VALUE);
addRow(0, winsLabel, drawsLabel, lossesLabel);
getColumnConstraints().addAll(
winsColConstraints,
drawsColConstraints,
lossesColConstraints
);
}
public void setOutcomes(Outcomes outcomes) {
winsLabel.setText((int) outcomes.winPercent() + "%");
drawsLabel.setText((int) outcomes.drawPercent() + "%");
lossesLabel.setText((int) outcomes.lossPercent() + "%");
winsColConstraints.setPercentWidth(outcomes.winPercent());
drawsColConstraints.setPercentWidth(outcomes.drawPercent());
lossesColConstraints.setPercentWidth(outcomes.lossPercent());
}
}
private static class IntegerCell extends TableCell<Outcomes, Integer> {
@Override
protected void updateItem(Integer item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
} else {
setText(
NumberFormat.getNumberInstance().format(
item
)
);
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.