JavaFX XYChart替换所有系列时的怪异行为

时间:2018-08-17 10:48:16

标签: javafx javafx-8

再一次,当我使用JavaFX-Charts ...时,我挠头了...:-(

我有一个用例,需要替换图表中的所有系列,我从头开始创建所有内容。在清除之前的数据后添加时,图表将 default-color 的错误样式类分配给添加的系列的 some 。 更确切地说,分配的类别编号发生了变化……为什么他们在地球上采用模运算来实现,默认情况下,该模数仅限制为8(!)个不同的颜色符号组合...?!

前8个(提示:mod 8 ...)默认颜色是正确的:

default-color0
...
default-color7

,并且在第一次运行时,它再次继续,也正确,再次为0:

default-color0
...
default-color6 (for 15 series in my example)

第二次运行,我得到:

default-color0
...
default-color7
default-color7 <-- shift from here
default-color0
...
default-color5
如您所见,

它被移动了两次,为7,然后一直运行到5。 再进行一次换班,继续:

default-color0
...
default-color7
default-color6 <-- shift from here
default-color7
default-color0
...
default-color4

移位量取决于序列数-对于16,一切正常,对于14,它每次移位2,依此类推。

在图表中,如果您看到图例在变化,这很明显...

我尝试了不同的数据替换方法,但没有一个成功,请参见下面的代码中的注释。 实际的解决方案是手动覆盖样式类,但在我看来这不是一个很漂亮的解决方案,由于任务类的进取习惯... wtf ?! >

无论如何-如果有人对此有任何帮助的想法?也许我想念什么?

注意:要查看奇怪的结果,请删除标记为 DIRTY-WORKAROUND-SOLUTION 的行。否则它将起作用...;-)

奖金问题:也许我很傻,正在使用JavaFX图表...有些事情很酷,但是很多时候,我对此感到很奇怪...还有更好的替代方法,您会建议我抽出来吗?

谢谢!

import javafx.application.Application;
import javafx.beans.InvalidationListener;
import javafx.scene.Scene;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.ScatterChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;

public class ChartSeriesReplacing extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {

        VBox root = new VBox();

        ScatterChart<Number, Number> chart = new ScatterChart<>(new NumberAxis(), new NumberAxis());

        Button refresh = new Button("Refresh");

        refresh.setOnAction(clicked -> {
            List<XYChart.Series<Number, Number>> seriesList = new ArrayList<>();
            for (int i = 0; i < 15; i++) {
                XYChart.Series<Number, Number> series = new XYChart.Series<>();
                series.setName(i + "");

                XYChart.Data<Number, Number> data = new XYChart.Data<>(Math.random(), Math.random());
                int finalI = i;
                data.nodeProperty().addListener(__ -> {
                    if (data.getNode() != null) {
                        data.getNode().getStyleClass().addListener((InvalidationListener) ___ -> {

                            System.out.println("[pre] Data #" + finalI + ": Style = " + data.getNode().getStyleClass());

                            // DIRTY-WORKAROUND-SOLUTION:
                            // (has to live in listener, otherwise the chart erases any custom styling on adding... :-/ )
                            String colorString = "default-color" + finalI % 8;
                            data.getNode().getStyleClass().removeIf(s -> s.startsWith("default-color") && !s.equals(colorString));
                            if (!data.getNode().getStyleClass().contains(colorString)) {
                                data.getNode().getStyleClass().add(colorString);
                            }
                            // --------------------------

                            System.out.println("[post] Data #" + finalI + ": Style = " + data.getNode().getStyleClass());
                        });
                    }
                });
                series.getData().add(data);

                seriesList.add(series);
            }
            System.out.println("-----------------");

            // What I tried:
            // 1)
            chart.getData().setAll(seriesList);

            // 2)
            // chart.dataProperty().setValue(FXCollections.observableArrayList(seriesList));

            // 3)
            // chart.getData().clear();
            // 3a)
            // chart.getData().addAll(seriesList);
            // 3b)
            // seriesList.forEach(series->chart.getData().add(series));
        });


        root.getChildren().add(chart);
        root.getChildren().add(refresh);

        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}

Java版本jdk1.8.0_171(x64)

0 个答案:

没有答案