更改条形图图例中的颜色
Change color in barchart legend
我成功测试了此代码以更改条形图列的颜色:
XYChart.Data<String, Number> dataS1 = new XYChart.Data<>();
dataS1.nodeProperty().addListener(new ChangeListener<Node>()
{
@Override
public void changed(ObservableValue<? extends Node> ov, Node oldNode, Node newNode)
{
if (newNode != null)
{
if (dataS1.getYValue().intValue() > 8)
{
newNode.setStyle("-fx-bar-fill: navy;");
}
else if (dataS1.getYValue().intValue() > 5)
{
newNode.setStyle("-fx-bar-fill: firebrick;");
}
}
}
});
但事实证明,图例的颜色并没有改变。
有没有办法不使用传统的 CSS 文件来做到这一点?如果可能的话,我想使用上面的方法。
假设您只有一个系列,图例将包含一个项目。
如果你根据某个值改变图表中项目的颜色,根据你的条件会有三种不同的颜色。
这意味着您需要在图例上显示三个不同的项目。
一种可能的方法是使用不同类型的图表,例如折线图,为每个条形图绘制一条彩色线条。这有一个问题,即您为每个条创建一个新系列,因此图例将包含与系列一样多的项目。
其他方法将使用单个系列,但根据需要向图例添加尽可能多的项目。
请注意,在这两种情况下,您都必须处理 private API,因为 Legend
不是 public,而且如您所知,这是不可取的,因为它可能随时更改时间.
对于第一种方法,请查看此 。
对于第二个,这是一个非常简单的工作片段:
@Override
public void start(Stage stage) {
NumberAxis yAxis = new NumberAxis();
CategoryAxis xAxis = new CategoryAxis();
BarChart<String,Number> barChart = new BarChart<>(xAxis,yAxis);
barChart.setTitle("Tricolored BarChart");
yAxis.setLabel("Value");
XYChart.Series<String,Number> series1 = new XYChart.Series();
series1.getData().add(new XYChart.Data("Item 1", 7.5));
series1.getData().add(new XYChart.Data("Item 2", 2.3));
series1.getData().add(new XYChart.Data("Item 3", 8.5));
series1.getData().add(new XYChart.Data("Item 4", 4.8));
series1.getData().add(new XYChart.Data("Item 5", 13.5));
series1.getData().add(new XYChart.Data("Item 6", 6.5));
Scene scene = new Scene(barChart,600,400);
barChart.getData().addAll(series1);
stage.setScene(scene);
stage.show();
series1.getData().forEach(d->
d.getNode().setStyle("-fx-bar-fill: "
.concat(d.getYValue().floatValue()>8?"navy;":
d.getYValue().floatValue()>5?"firebrick;":"orange")));
Legend legend = (Legend)barChart.lookup(".chart-legend");
Legend.LegendItem li1=new Legend.LegendItem("Over 8", new Rectangle(10,4,Color.NAVY));
Legend.LegendItem li2=new Legend.LegendItem("Over 5 up to 8", new Rectangle(10,4,Color.FIREBRICK));
Legend.LegendItem li3=new Legend.LegendItem("Below 5", new Rectangle(10,4,Color.ORANGE));
legend.getItems().setAll(li1,li2,li3);
}
这将是结果:
我成功测试了此代码以更改条形图列的颜色:
XYChart.Data<String, Number> dataS1 = new XYChart.Data<>();
dataS1.nodeProperty().addListener(new ChangeListener<Node>()
{
@Override
public void changed(ObservableValue<? extends Node> ov, Node oldNode, Node newNode)
{
if (newNode != null)
{
if (dataS1.getYValue().intValue() > 8)
{
newNode.setStyle("-fx-bar-fill: navy;");
}
else if (dataS1.getYValue().intValue() > 5)
{
newNode.setStyle("-fx-bar-fill: firebrick;");
}
}
}
});
但事实证明,图例的颜色并没有改变。 有没有办法不使用传统的 CSS 文件来做到这一点?如果可能的话,我想使用上面的方法。
假设您只有一个系列,图例将包含一个项目。
如果你根据某个值改变图表中项目的颜色,根据你的条件会有三种不同的颜色。
这意味着您需要在图例上显示三个不同的项目。
一种可能的方法是使用不同类型的图表,例如折线图,为每个条形图绘制一条彩色线条。这有一个问题,即您为每个条创建一个新系列,因此图例将包含与系列一样多的项目。
其他方法将使用单个系列,但根据需要向图例添加尽可能多的项目。
请注意,在这两种情况下,您都必须处理 private API,因为 Legend
不是 public,而且如您所知,这是不可取的,因为它可能随时更改时间.
对于第一种方法,请查看此
对于第二个,这是一个非常简单的工作片段:
@Override
public void start(Stage stage) {
NumberAxis yAxis = new NumberAxis();
CategoryAxis xAxis = new CategoryAxis();
BarChart<String,Number> barChart = new BarChart<>(xAxis,yAxis);
barChart.setTitle("Tricolored BarChart");
yAxis.setLabel("Value");
XYChart.Series<String,Number> series1 = new XYChart.Series();
series1.getData().add(new XYChart.Data("Item 1", 7.5));
series1.getData().add(new XYChart.Data("Item 2", 2.3));
series1.getData().add(new XYChart.Data("Item 3", 8.5));
series1.getData().add(new XYChart.Data("Item 4", 4.8));
series1.getData().add(new XYChart.Data("Item 5", 13.5));
series1.getData().add(new XYChart.Data("Item 6", 6.5));
Scene scene = new Scene(barChart,600,400);
barChart.getData().addAll(series1);
stage.setScene(scene);
stage.show();
series1.getData().forEach(d->
d.getNode().setStyle("-fx-bar-fill: "
.concat(d.getYValue().floatValue()>8?"navy;":
d.getYValue().floatValue()>5?"firebrick;":"orange")));
Legend legend = (Legend)barChart.lookup(".chart-legend");
Legend.LegendItem li1=new Legend.LegendItem("Over 8", new Rectangle(10,4,Color.NAVY));
Legend.LegendItem li2=new Legend.LegendItem("Over 5 up to 8", new Rectangle(10,4,Color.FIREBRICK));
Legend.LegendItem li3=new Legend.LegendItem("Below 5", new Rectangle(10,4,Color.ORANGE));
legend.getItems().setAll(li1,li2,li3);
}
这将是结果: