Is it possible to use a chart’s legend to toggle show/hide a series?
I got a LineChart
with a legend and there are too many Series
so you can’t read out the information well. I was wondering if there is a possibility to use the legend to toggle the series to show/hide?
Most of the names of my Series
are pretty long and it looks very weird if they are written twice once in the legend so you know which color belongs to which Series
and a second time besides a CheckBox
to toggle them.
Edit1: Maybe I was unclear, even if there is no built in function for this, I could use some input for how a workaround could look like, because I can’t come up with anything.
Advertisement
Answer
Here is how I solved this – I am not aware of any simpler built-in solution
LineChart<Number, Number> chart; for (Node n : chart.getChildrenUnmodifiable()) { if (n instanceof Legend) { Legend l = (Legend) n; for (Legend.LegendItem li : l.getItems()) { for (XYChart.Series<Number, Number> s : chart.getData()) { if (s.getName().equals(li.getText())) { li.getSymbol().setCursor(Cursor.HAND); // Hint user that legend symbol is clickable li.getSymbol().setOnMouseClicked(me -> { if (me.getButton() == MouseButton.PRIMARY) { s.getNode().setVisible(!s.getNode().isVisible()); // Toggle visibility of line for (XYChart.Data<Number, Number> d : s.getData()) { if (d.getNode() != null) { d.getNode().setVisible(s.getNode().isVisible()); // Toggle visibility of every node in the series } } } }); break; } } } } }
You need to run this code once on your chart (LineChart
in this example, but you can probably adapt it to any other chart). I find the Legend
child, and then iterate over all of its’ items. I match the legend item to the correct series based on the name – from my experience they always match, and I couldn’t find a better way to match them. Then it’s just a matter of adding the correct event handler to that specific legend item.