Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX 2.0 - How to change legend color of a LineChart dynamically?

Tags:

javafx-2

I am trying to style my JavaFX linechart but I have some trouble with the legend.

I know how to change the legend color of a line chart in the css file:

.default-color0.chart-series-line { -fx-stroke:  #FF0000, white; } 
.default-color1.chart-series-line { -fx-stroke:  #00FF00, white; }
.default-color2.chart-series-line { -fx-stroke:  #0000FF, white; }
.default-color0.chart-line-symbol { -fx-background-color: #FF0000, white; }
.default-color1.chart-line-symbol { -fx-background-color: #00FF00, white; } 
.default-color2.chart-line-symbol { -fx-background-color: #0000FF, white; }

But this is not enough for my purposes. I have three or more colored toggle buttons and a series of data for every button. The data should be displayed in the same color the button has after I have selected the button. This should be possible with a multiselection of the buttons, so that more than one series of data can be displayed simultaneously.

For the chart lines I have managed it by changing the style after I clicked the button:

..
dataList.add(series); 
..
series.getNode().setStyle("-fx-stroke: rgba(" + rgba + ")");

If I deselect the button I remove the data from the list.

dataList.remove(series);

That is working fine for the strokes, but how can I do the same for the legend?

You can see an example below. First I clicked the red button, thus the stroke and the legend is red (default-color0). After that I clicked the blue button. Here you can see the problem. The stroke is blue but the legend is green, because default color1 is used and I do not know how to change the legend color.

enter image description here

like image 449
marie Avatar asked Sep 27 '12 13:09

marie


1 Answers

I ran into this issue as well. The issue seems to be that when data series are added to the chart, the legend isn't updated at the same time, so when you lookup components with that seriesN style class they don't exist yet. Came up with a work-around that detects when the legend items are created so that dynamic styling can be added to them.

I added a ListChangeListener to the chart legend's "getChildrenUnmodifiable()" ObservableList, which in turn adds a ListChangeListener to each of the legend's children as they get added. From within this listener, we can tell when new items are being added to the legend (or removed). This allow us to then make the dynamic style changes.

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
                                }

                            });
                        }
                    }
                }
            });
        }
    }
like image 183
Jack Straw Avatar answered Jan 04 '23 00:01

Jack Straw