JavaFX LineChart 动态改变图例颜色

Jer*_*mas 0 java charts javafx linechart

我正在尝试动态更改图例的颜色,因此我的 css 类中没有任何线条和符号的样式。我可以动态更改图表中的所有线条和符号,但遗憾的是无法更改图例。他们保持默认状态。有没有办法动态地做到这一点?

所以,我尝试过:

1)

for (int index = 0; index < series.getData().size(); index++) {
    XYChart.Data dataPoint = series.getData().get(index);
    Node lineSymbol = dataPoint.getNode().lookup(".chart-legend");
    lineSymbol.setStyle("-fx-background-color: #00ff00, #000000; -fx-background-insets: 0, 2;\n" +
            "    -fx-background-radius: 3px;\n" +
            "    -fx-padding: 3px;");
}
Run Code Online (Sandbox Code Playgroud)

根据 caspian.css 和下面的链接问题,这应该可以工作,但它给了我NullPointerException因为无法找到 .chart-legend 即使它在那里。

2)

for (Node n : lineChart.getChildrenUnmodifiable())
{
    if (n instanceof Legend)
    {
        final Legend legend = (Legend) n;

        // remove the legend
        legend.getChildrenUnmodifiable().addListener(new ListChangeListener<Object>()
        {
            @Override
            public void onChanged(Change<?> arg0)
            {
                for (Node node : legend.getChildrenUnmodifiable())
                {
                    if (node instanceof Label)
                    {
                        final Label label = (Label) node;
                        label.getChildrenUnmodifiable().addListener(new ListChangeListener<Object>()
                        {
                            @Override
                            public void onChanged(Change<?> arg0)
                            {
                                //make style changes here
                            }

                        });
                    }
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

这也没有起到任何作用,而且使程序速度减慢了很多。

3)

   int index = 2;
Platform.runLater(new Runnable() {
    @Override
    public void run() {
        myChart.lookupAll(".chart-legend-item-symbol").toArray()[index].setStyle("-fx-border-color: rgba(200,0,0,1)");
}});
Run Code Online (Sandbox Code Playgroud)

这要么没有做任何事情。

任何帮助将不胜感激。

我查看了所有这些,但它们没有帮助:

JavaFX StackedBarChart图例颜色不遵循图表颜色CSS样式

JavaFX 2.0 - 如何动态更改折线图的图例颜色?

JavaFX LineChart 图例样式

编辑:这是我找到的解决方案

这些都不适合我,所以我找到了另一个解决方案。答案和 Platform.runLater 方法都不是。

XYChart.Series<Number,Number> value  //is our serie value.

for(int index = 0; index<value.getData().size(); index++){
    // we're looping for each data point, changing the color of line symbol
    XYChart.Data dataPoint = value.getData().get(index);
    Node lineSymbol = dataPoint.getNode().lookup(".chart-line-symbol");
    lineSymbol.setStyle("-fx-background-color: #0000FF, white;");
}
// and this is for the color of the line
value.getNode().setStyle("-fx-border-style: solid; -fx-stroke: #0000FF; -fx-background-color: #0000FF;");
Run Code Online (Sandbox Code Playgroud)

对于图例颜色更改:

for(Node n : chart.getChildrenUnmodifiable()){
   if(n instanceof Legend){
      for(Legend.LegendItem legendItem : ((Legend)n).getItems()){
        legendItem.getSymbol().setStyle("-fx-background-color: #0000ff, white;");
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

希望这也适用于任何搜索此内容的人。

向版主编辑:这被标记为重复,但这个问题主要是关于 LineChart 的图例,因为尽管系列颜色正在变化,但它们没有按应有的方式更新。重复的问题只是关于更改系列的颜色。这个问题是关于这些物品的传说。

Jam*_*s_D 5

它对我来说只是为了更改查找的颜色名称,CHART_COLOR_x其中x是该系列的(基于 1 的)索引。

即只是做

chart.setStyle("CHART_COLOR_1: #ff0000 ; CHART_COLOR_2: #0000FF ;");
Run Code Online (Sandbox Code Playgroud)

将第一个系列(线、点和图例)的颜色设置为红色,将第二个系列的颜色设置为蓝色。

这是一个 SSCCE:

import java.util.Random;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.ColorPicker;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class DynamicLinechart extends Application {

    @Override
    public void start(Stage primaryStage) {
        LineChart<Number, Number> chart = new LineChart<>(new NumberAxis(), new NumberAxis());

        Series<Number, Number> series1 = new Series<>();
        series1.setName("Data set 1");

        Series<Number, Number> series2 = new Series<>();
        series2.setName("Data set 2");

        chart.getData().add(series1);
        chart.getData().add(series2);

        Random rng = new Random();
        for (int i = 0 ; i <= 20 ; i++) {
            series1.getData().add(new Data<>(i, rng.nextInt(100)));
            series2.getData().add(new Data<>(i, rng.nextInt(100)));
        }

        ColorPicker picker1 = new ColorPicker();
        ColorPicker picker2 = new ColorPicker();

        ChangeListener<Color> listener = (obs, oldColor, newColor) -> 
            updateStyles(chart, picker1.getValue(), picker2.getValue());

        picker1.valueProperty().addListener(listener);
        picker2.valueProperty().addListener(listener);

        picker1.setValue(Color.RED);
        picker2.setValue(Color.BLUE);

        BorderPane root = new BorderPane(chart);
        HBox controls = new HBox(5, picker1, picker2);
        controls.setPadding(new Insets(5));

        root.setTop(controls);

        Scene scene = new Scene(root);

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

    private void updateStyles(Node node, Color color1, Color color2) {
        node.setStyle(String.format("CHART_COLOR_1: %s ; CHART_COLOR_2: %s ;", format(color1), format(color2))); 
    }

    private String format(Color c) {
        int r = (int) (255 * c.getRed()) ;
        int g = (int) (255 * c.getGreen()) ;
        int b = (int) (255 * c.getBlue()) ;

        return String.format("#%02x%02x%02x", r, g, b);
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述

在此输入图像描述

如果您想要更多的控制(也许还需要更多的稳健性),请定义您自己的查找颜色并修改它们。即在外部 CSS 文件中,执行类似的操作

chart.setStyle("CHART_COLOR_1: #ff0000 ; CHART_COLOR_2: #0000FF ;");
Run Code Online (Sandbox Code Playgroud)

现在只需更新您定义的查找颜色的值:

private void updateStyles(Node node, Color color1, Color color2) {
    node.setStyle(String.format("-data-color-1: %s ; -data-color-2: %s ;", format(color1), format(color2))); 
}
Run Code Online (Sandbox Code Playgroud)