使用colorpicker动态更改图表颜色

时间:2016-06-04 20:36:10

标签: java javafx

我想使用colorpicker动态更改不同类型图表的颜色。然后我为饼图制作了这样的示例代码。

颜色选择器动作监听器:

        colorPicker.setOnAction(event -> {           

        Node node = chart.lookup(".default-color0.chart-pie");
        String str = "-fx-pie-color:" + toRGBCode(colorPicker.getValue()) + ";";

        node.setStyle(str);
    });

CSS文件:

.default-color0.chart-pie { -fx-pie-color: #ffd700; }
.default-color1.chart-pie { -fx-pie-color: #ffa500; }
.default-color2.chart-pie { -fx-pie-color: #860061; }
.default-color3.chart-pie { -fx-pie-color: #adff2f; }
.default-color4.chart-pie { -fx-pie-color: #ff5700; }

它工作正常,但只是部分。问题是,当我改变颜色时,图表的图例并没有跟随它。如何动态更新图例?

Screenshot

2 个答案:

答案 0 :(得分:0)

您可以通过节点查找绘制图例,然后根据您在问题中所做的类似修改其样式来更新图例

这个答案建立在您提供的内容之上,因此假设您知道要更新哪个项目,因为您知道此行中的样式类:

Node node = chart.lookup(".default-color0.chart-pie");

因此,考虑到这一点,您可以执行以下类似的操作:

public static void updateChartLegendColorFromItemName(Chart chart, String itemToUpdate, Color legendColor){
        Set<Node> legendItems = chart.lookupAll("Label.chart-legend-item");
        if(legendItems.isEmpty()){ return; }
        String styleString = "-fx-background-color:" + toRGBCode(legendColor) + ";";
        for(Node legendItem : legendItems){
            Label legendLabel = (Label) legendItem;
            Node legend = legendLabel.getGraphic(); //The legend icon (circle by default)

            if(legend != null && legendLabel.getText().equals(itemToUpdate)){
                legend.setStyle(styleString);
            }
        }
    }

您提供的示例用法是:

colorPicker.setOnAction(event -> {
            Node node = chart.lookup(".default-color0.chart-pie");
            String styleString = "-fx-background-color:" + toRGBCode(colorPicker.getValue()) + ";";
            node.setStyle(styleString);
            updateChartLegendColorFromItemName(chart, "Sunday", colorPicker.getValue());
        });

希望这会有所帮助

答案 1 :(得分:0)

updateLegend()类中有一个私有方法PieChart,在修改图表数据或其名称时调用。此方法为每个PieChart.Data对象创建新的图例项,并从数据对象的styleClass加载其样式:

for (Data item : getData()) {
    LegendItem legenditem = new LegendItem(item.getName());
    legenditem.getSymbol().getStyleClass().addAll(item.getNode().getStyleClass());
    legenditem.getSymbol().getStyleClass().add("pie-legend-symbol");
    legend.getItems().add(legenditem);
}

这意味着在图表的数据对象上调用setStyle()对图例颜色没有影响。 您可以尝试直接修改图例对象,但下次调用updateLegend()时,您的更改可能会被取消,除非您修改已更改的饼图节点的样式类。下面是如何将第一个饼图及其图例项目的颜色更改为样式表中已定义的颜色(例如第二个饼图的颜色)的示例:

// reference to the first pie's node
Node node = chart.lookup(".default-color0.chart-pie");
// the default-color property is in the third line. It is defined by
// updateDataItemStyleClass(final Data item, int index) method in PieChart class
node.getStyleClass().set(2, "default-color1");
// we have to trigger some change so updateLegend() is called:
String name0 = pieChartData.get(0).getName();
pieChartData.get(0).setName("");
pieChartData.get(0).setName(name0);

要使此方法适用于您的目的,您需要在ColorPicker处理程序中更新CSS文件(或创建另一个文件)。我不知道是否可以在运行时创建/修改CSS文件时创建新的样式定义。该解决方案看起来并不优雅,但看起来JavaFX并非旨在轻松实现您的需求。