codeNinja
codeNinja

Reputation: 1462

Setting series visiblity to False also hides it from the legend

I am using JFreeChart.

When i click on a Legend item i have put a listener. In the listener i make the series that was clicked invisble. But as a side effect the series also vanishes from the Legend.

I do not want the series to vanish from the legend. What can i do so that i can show/hide series on the plot but not affect the legend.

Setting the Legend to be fixed using plot.setFixedLegendItems(list) cause other mouse effects to stop working (on mouse over of data point the series line currently becomes thicker and the same in the legend).

chartPanel.addChartMouseListener(new ChartMouseListener() {
    @Override
    public void chartMouseClicked(ChartMouseEvent event) {
        ChartEntity entity = event.getEntity();
        if (entity instanceof LegendItemEntity) {
            //*
            LegendItemEntity itemEntity = (LegendItemEntity) entity;
            XYDataset dataset = (XYDataset) itemEntity.getDataset();
            int index = dataset.indexOf(itemEntity.getSeriesKey());
            XYPlot plot = (XYPlot) event.getChart().getPlot();

            //set the renderer to hide the series
            XYItemRenderer renderer = plot.getRenderer();
            renderer.setSeriesVisible(index, !renderer.isSeriesVisible(index), false);
            renderer.setSeriesVisibleInLegend(index, true, false);
            //*/        
        }
    }
});

Upvotes: 1

Views: 3369

Answers (3)

Georg
Georg

Reputation: 261

I suggest that you change the XYPlot.getLegendItems() default code so it does allow a series to appear in the legend even if not visible in the plot:

for (int i = 0; i < seriesCount; i++) {
    boolean v1 = renderer.isSeriesVisible(i);
    boolean v2 = renderer.isSeriesVisibleInLegend(i);
    if (v2) {// original code: v1 && v2
        boolean workaround = !v1 && v2;
        if (workaround)  renderer.setSeriesVisible(i, true, false);// temporarily enable before getLegendItem()
        LegendItem item = renderer.getLegendItem(datasetIndex, i);
        if (workaround)  renderer.setSeriesVisible(i, false, false);

Upvotes: 1

Heather Chen
Heather Chen

Reputation: 21

You can also call getLegendItems(), save it as a LegendItemCollection and set plot.setFixedLegendItems(legendItems) before any action listener occurs. This way it'll set all the legend items from the initial state, even when legend items are clicked on and off.

XYPlot plot = chart.getXYPlot();
LegendItemCollection legendItems = plot.getLegendItems();
plot.setFixedLegendItems(legendItems);
chartPanel.addChartMouseListener(new ChartMouseListener() {
  @Override
  public void chartMouseClicked(ChartMouseEvent chartMouseEvent) {
    ChartEntity entity = chartMouseEvent.getEntity();
    if (chartMouseEvent.getEntity() instanceof LegendItemEntity) {
      LegendItemEntity itemEntity = (LegendItemEntity) entity;
      XYDataset dataset = (XYDataset) itemEntity.getDataset();
      int index = dataset.indexOf(itemEntity.getSeriesKey());
      XYPlot plot = (XYPlot) chartMouseEvent.getChart().getPlot();

      //set the renderer to hide the series
      XYItemRenderer renderer = plot.getRenderer();
      renderer.setSeriesVisible(index, !renderer.isSeriesVisible(index), true);
    }
  }

Upvotes: 2

David Gilbert
David Gilbert

Reputation: 4477

It is the getLegendItems() method in the XYPlot class that does the visibility checking, so you could subclass XYPlot and override this method (or modify it directly if you want to build your own custom version of JFreeChart).

Upvotes: 2

Related Questions