java – TableCell:如何使用StackedBarChart(或者它是不可能的)?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – TableCell:如何使用StackedBarChart(或者它是不可能的)?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6778字,纯文字阅读大概需要10分钟。
内容图文
![java – TableCell:如何使用StackedBarChart(或者它是不可能的)?](/upload/InfoBanner/zyjiaocheng/704/c19a006fba734ad1be5f7f18cd597f68.jpg)
我的实验的触发器是recent question – 连续的一个单元格应该可视化同一行中几个单元格值中的值的相对比例.在fx中,StackedBarChart支持这种可视化(退化为单个类别,yAxis为类别轴).
不幸的是,使用这样的图表作为单元格图形在更新项目时会产生奇怪的效果,具体取决于我们如何进行更新:
>场景A:使用系列初始化图表并更新系列中的数据.条形图仅在第一次显示时显得很好,来回滚动留下随机的“间隙”
>场景B:在每轮中创建并设置新系列.条形似乎具有正确的宽度,但它们的颜色在滚动时随机变化
此外,还有一些小的视觉怪癖f.i.找不到根据需要限制单元格高度的方法.
问题:
>如何使其正常工作,或
>出了什么问题,渲染机制的哪一部分干扰了?
这个例子:
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.StackedBarChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
/**
* from SO, how to show relative bars with colors of
* a related chart
*
* https://stackoverflow.com/a/28141421/203657
*
* That's a solution with manually calculating and
* filling a rectangle with base chart colors
*
* Here trying to use StackedBarChart .. problems as noted in cell doc.
* Extracted TableStackedBarChart for SO question.
*/
public class TableStackedBar extends Application {
public static void main(String[] args) { launch(args); }
@Override
public void start(Stage stage) {
ObservableList<Data> data = FXCollections.observableArrayList();
for (int i = 0; i<10; i++) data.add(new Data());
TableView<Data> tv = new TableView<>(data);
TableColumn<Data, Number> col1 = new TableColumn<>("num1");
TableColumn<Data, Number> col2 = new TableColumn<>("num2");
col1.setCellValueFactory((p)->{return p.getValue().num1;});
col2.setCellValueFactory((p)->{return p.getValue().num2;});
//make this column hold the entire Data object so we can access all fields
TableColumn<Data, Data> col3 = new TableColumn<>("bar");
col3.setPrefWidth(500);
col3.setCellValueFactory((p)->{return new ReadOnlyObjectWrapper<>(p.getValue());});
col3.setCellFactory(p -> new StackedBarChartCell(2000.));
tv.getColumns().addAll(col1,col2,col3);
tv.setFixedCellSize(50.);
Scene scene = new Scene(tv);
stage.setScene(scene);
stage.show();
}
/**
* TableCell that uses a StackedBarChart to visualize relation of
* data.
*
* Problems with updating items:
* - scenario A: updating the series leaves empty patches horizontally
* - scenario B: re-setting the series changes colors randomly
*
* Other problems
* - runs amok without fixedCellSize on tableView
* - can't max the height of the chart (so it's cut-off in the middle
*/
public static class StackedBarChartCell extends TableCell<Data, Data> {
NumberAxis xAxisHoriz = new NumberAxis();
CategoryAxis yAxisHoriz = new CategoryAxis();
StackedBarChart<Number, String> sbcHoriz = new StackedBarChart<>(xAxisHoriz, yAxisHoriz);
XYChart.Series<Number, String> series1Horiz = new XYChart.Series<>();
XYChart.Series<Number, String> series2Horiz = new XYChart.Series<>();
public StackedBarChartCell(double upperBound) {
yAxisHoriz.setTickLabelsVisible(false);
yAxisHoriz.setTickMarkVisible(false);
yAxisHoriz.setStyle("-fx-border-color: transparent transparent transparent transparent;");
xAxisHoriz.setTickLabelsVisible(false);
xAxisHoriz.setTickMarkVisible(false);
xAxisHoriz.setMinorTickVisible(false);
xAxisHoriz.setStyle("-fx-border-color: transparent transparent transparent transparent;");
xAxisHoriz.setAutoRanging(false);
xAxisHoriz.setUpperBound(upperBound);
xAxisHoriz.setLowerBound(0.);
sbcHoriz.setHorizontalGridLinesVisible(false);
sbcHoriz.setVerticalGridLinesVisible(false);
sbcHoriz.setLegendVisible(false);
sbcHoriz.setAnimated(false);
// scenario A: set series initially
sbcHoriz.getData().setAll(series1Horiz, series2Horiz);
sbcHoriz.setCategoryGap(0);
// no effect
sbcHoriz.setMaxHeight(20);
}
@Override
protected void updateItem(Data item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
setGraphic(sbcHoriz);
// scenario B: set new series
// uncomment for scenario A
// XYChart.Series<Number, String> series1Horiz = new XYChart.Series<>();
// XYChart.Series<Number, String> series2Horiz = new XYChart.Series<>();
// sbcHoriz.getData().setAll(series1Horiz, series2Horiz);
//---- end of scenario B
series1Horiz.getData().setAll(new XYChart.Data(item.num1.get(), "none"));
series2Horiz.getData().setAll(new XYChart.Data(item.num2.get(), "none"));
}
}
}
private static class Data{
private SimpleIntegerProperty num1 = new SimpleIntegerProperty((int)(Math.random()*1000));
private SimpleIntegerProperty num2 = new SimpleIntegerProperty((int)(Math.random()*1000));
public SimpleIntegerProperty num1Property(){return num1;}
public SimpleIntegerProperty num2Property(){return num2;}
}
}
更新:似乎是8u40的回归 – 适用于8u20 / 25,而不适用于8u40b20. Reported as RT-39884
解决方法:
这是我将东西复制到我的CellFactory的地方
col3.setCellFactory((TableColumn<Data, Data> param) -> {
return new TableCell<Data, Data>() {
@Override
protected void updateItem(Data item, boolean empty) {
super.updateItem(item, empty);
if (empty) setGraphic(null);
else {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
} else {
NumberAxis xAxisHoriz = new NumberAxis(0, 2000, 1000);
CategoryAxis yAxisHoriz = new CategoryAxis(FXCollections.observableArrayList(""));
XYChart.Series<Number, String> series1Horiz = new XYChart.Series<>();
XYChart.Series<Number, String> series2Horiz = new XYChart.Series<>();
StackedBarChart<Number, String> sbcHoriz = new StackedBarChart<>(xAxisHoriz, yAxisHoriz);
sbcHoriz.getData().setAll(series1Horiz, series2Horiz);
yAxisHoriz.setStyle("-fx-border-color: transparent transparent transparent transparent;"
+ "-fx-tick-labels-visible: false;"
+ "-fx-tick-mark-visible: false;"
+ "-fx-minor-tick-visible: false;"
+ "-fx-padding: 0 0 0 0;");
xAxisHoriz.setStyle("-fx-border-color: transparent transparent transparent transparent;"
+ "-fx-tick-labels-visible: false;"
+ "-fx-tick-mark-visible: false;"
+ "-fx-minor-tick-visible: false;"
+ "-fx-padding: 0 0 0 0;");
sbcHoriz.setHorizontalGridLinesVisible(false);
sbcHoriz.setVerticalGridLinesVisible(false);
sbcHoriz.setLegendVisible(false);
sbcHoriz.setAnimated(false);
xAxisHoriz.setMaxWidth(100);
sbcHoriz.setMaxWidth(100);
sbcHoriz.setPadding(Insets.EMPTY);
sbcHoriz.setCategoryGap(0);
setGraphic(sbcHoriz);
series1Horiz.getData().setAll(new XYChart.Data(item.num1.get(), ""));
series2Horiz.getData().setAll(new XYChart.Data(item.num2.get(), ""));
}
}
}
};
});
并且在我设置了这个tv.setFixedCellSize(30)之后;
我还必须将列宽更改为200,我不能使图表更小.
内容总结
以上是互联网集市为您收集整理的java – TableCell:如何使用StackedBarChart(或者它是不可能的)?全部内容,希望文章能够帮你解决java – TableCell:如何使用StackedBarChart(或者它是不可能的)?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。