我成功测试了此代码,以便更改条形图列颜色:
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文件的情况下执行此操作?如果可能,我想使用上述方法。
答案 0 :(得分:2)
假设您有一个系列,图例将包含一个项目。
如果您根据某些值更改图表中项目的颜色,则根据您的条件会有三种不同的颜色。
这意味着你需要在图例上有三个不同的项目。
一种可能的方法是使用不同类型的图表,例如LineChart,为每个条形图绘制彩色线条。这就存在一个问题,即每个条形图都会创建一个新系列,因此图例将包含与系列一样多的项目。
其他方法将使用单个系列,但添加图例所需的项目。
请注意,在这两种情况下,您必须处理私有API,因为Legend
不公开,并且如您所知,这是不可取的,因为它可能随时更改。
对于第一种方法,请查看此question。
对于第二个,这是一个非常简单的工作片段:
@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);
}
这将是结果: