【问题标题】:How do I display a "single bar chart" in a TableColumn of a TableView (javaFX 8)?如何在 TableView (javaFX 8) 的 TableColumn 中显示“单个条形图”?
【发布时间】:2015-01-25 17:52:00
【问题描述】:

这是截图:

感兴趣:右上部分和下部分。

在下半部分,选择了一条规则;这条规则总共有:1080次调用,其中成功调用274次,空调用成功84次。现在我正在显示成功与总的比率,以及空与成功的比率。

我想要做的是废弃比率,而是使用一个图形栏显示非空成功/空成功/失败的比率,使用 相同的配色方案上面的饼图……

我遇到的一个问题是我“没有为该配色方案做任何事情”。这是填充饼图的代码:

@Override
public void loadPieChart(final int failedMatches, final int emptyMatches,
    final int nonEmptyMatches)
{
    final int totalInvocations = failedMatches + emptyMatches
        + nonEmptyMatches;
    final List<Data> list = new ArrayList<>(3);

    int nr;
    double percent;
    String fmt;

    /*
     * Failures
     */
    nr = failedMatches;
    percent = 100.0 * nr / totalInvocations;
    fmt = String.format("Failures (%d - %.02f%%)", nr, percent);
    list.add(new Data(fmt, percent));

    /*
     * Empty
     */
    nr = emptyMatches;
    percent = 100.0 * nr / totalInvocations;
    fmt = String.format("Empty matches (%d - %.02f%%)", nr, percent);
    list.add(new Data(fmt, percent));

    /*
     * Non empty
     */
    nr = nonEmptyMatches;
    percent = 100.0 * nr / totalInvocations;
    fmt = String.format("Non empty matches (%d; %.02f%%)", nr, percent);
    list.add(new Data(fmt, percent));

    display.matchChart.getData().setAll(list);

    fmt = String.format("Rule rundown (%d total)", totalInvocations);
    display.matchChart.setTitle(fmt);
}

获取数据不是问题,问题是我在 JavaFX javadoc 中找不到如何显示像上面这样的“单个图形栏”...

我从哪里开始?

(哦,我的图形很烂,所以甚至不要让我“画”我想要的东西;如果需要更高的精度,我会很乐意给他们)


编辑好的,这是我的意思的一个例子:

http://www.highcharts.com/demo/bar-stacked

除了我只需要一个栏,我不关心弹出菜单,我不想要轴,我不想要图例,我只想要裸露的,没有多余的栏。

从那以后我也稍微修改了输出:

我们的目标是用我不知道如何生成的该死的图形替换最后一列:(

【问题讨论】:

  • 对于默认的饼图颜色,请查看modena.css,有类似.default-color0.chart-pie 或更全局颜色变量CHART_COLOR_1 之类的规则。考虑到您的其他问题:我建议不要在 TableView 中显示图表(虚拟化容器中的重量级组件......)
  • 哦还有一件事:所选规则总共有 1080 次调用? ;-)
  • @eckig 是的,1080;不要让这吓到你,在我拥有的其他一些转储中,对单个规则的调用超出了 10k 限制......
  • 我没有问,因为这个数字大得吓人,但你的问题中有一个错字,你写的是1090而不是1080 ;-)
  • @eckig 哎呀...很好的发现...已修复...

标签: java charts javafx-8


【解决方案1】:
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.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.HBox;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class TableBar 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(100);
        col3.setCellValueFactory((p)->{return new ReadOnlyObjectWrapper<>(p.getValue());});
        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 {
                        double tot = item.num1.get() + item.num2.get();
                        double ratio1 = item.num1.get() / tot;
                        double ratio2 = item.num2.get() / tot;

                        Rectangle r1 = new Rectangle();
                        //the param is the column, bind so rects resize with column
                        r1.widthProperty().bind(param.widthProperty().multiply(ratio1));
                        r1.heightProperty().bind(this.getTableRow().heightProperty().multiply(0.5));
                        r1.setStyle("-fx-fill:#f3622d;");
                        Rectangle r2 = new Rectangle(0, 20);
                        r2.widthProperty().bind(param.widthProperty().multiply(ratio2));
                        r2.setStyle("-fx-fill:#fba71b;");

                        HBox hbox = new HBox(r1,r2);
                        hbox.setAlignment(Pos.CENTER_LEFT);
                        setGraphic(hbox);
                        setText(null);
                    }
                }

            };
        });

        tv.getColumns().addAll(col1,col2,col3);
        Scene scene = new Scene(tv);

        stage.setScene(scene);
        stage.show();
    }

    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;}
    }
}

我刚刚意识到应该有 3 个数字,但我相信你明白了。

【讨论】:

  • 我确实明白了!谢谢!我唯一感到不安的是构造函数中的硬编码 0.0 和 20.0:/ 我尝试使用空构造函数,但没有出现任何内容。德拉斯。
  • 0 是宽度,我稍后将其绑定到列宽的比率以防调整大小。 20 是高度,它应该是行高的一部分,具体取决于您想要的栏的厚度。行高将基于字体大小。
  • 嗯,但是文本设置为null...不能绑定到行高吗?
  • 高度基于行高,适合整行中最大的文本。我将使用绑定进行更新。如果您希望它更小,我还将对齐 HBox,使条居中。
  • 我已尝试按照您的示例绑定高度,但我得到一个 NPE...getTableRow() 似乎返回 null :( 嗯,它工作得很好,我会看到在我真正需要时进行改进!谢谢!
猜你喜欢
  • 2014-04-07
  • 2020-05-07
  • 2017-11-25
  • 2013-11-09
  • 2019-05-27
  • 2013-02-20
  • 2015-01-05
  • 1970-01-01
相关资源
最近更新 更多