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.
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
}
});
}
}
}
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With