графики - scatter chart javafx




JavaFX Использовать диаграмму Легенда для переключения show/hide Возможна серия? (2)

Можно ли использовать легенду диаграммы для переключения шоу / скрыть серию?

У меня есть LineChart с легендой, и слишком много Series поэтому вы не можете хорошо прочитать информацию. Мне было интересно, есть ли возможность использовать легенду, чтобы переключать серию, чтобы показать / скрыть?

Большинство имен моей Series довольно длинны, и это выглядит очень странно, если они дважды написаны в легенде, поэтому вы знаете, какой цвет принадлежит к этой Series и второй раз, кроме CheckBox чтобы переключать их.

Edit1: Возможно, я был неясен, даже если для этого нет встроенной функции, я мог бы использовать некоторый вклад для того, как выглядел бы workaroud, потому что я ничего не могу придумать.


Вот как я решил это - я не знаю ни одного более простого встроенного решения

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;
                }
            }
        }
    }
}

Вам нужно запустить этот код один раз на вашей диаграмме ( LineChart в этом примере, но вы, вероятно, можете адаптировать его к любой другой диаграмме). Я нахожу Legend , а потом перебираю все его элементы. Я сопоставляю элемент легенды с правильной серией, основанной на имени, - по моему опыту они всегда совпадают, и я не мог найти лучшего способа их сопоставления. Тогда это просто вопрос добавления правильного обработчика событий к этому конкретному элементу легенды.


Для справки аналогичный подход работает с JFreeChart в JavaFX, как показано здесь . Адаптированный в этом примере вариант ниже добавляет ChartMouseListenerFX в ChartViewer . Нажмите на серию или ее элемент легенды, чтобы сделать серию невидимой; щелкните в другом месте, чтобы восстановить его.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.entity.ChartEntity;
import org.jfree.chart.entity.LegendItemEntity;
import org.jfree.chart.entity.XYItemEntity;
import org.jfree.chart.fx.ChartViewer;
import org.jfree.chart.fx.interaction.ChartMouseEventFX;
import org.jfree.chart.fx.interaction.ChartMouseListenerFX;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 * @see https://.com/a/44967809/230513
 * @see https://.com/a/43286042/230513
 */
public class VisibleTest extends Application {

    @Override
    public void start(Stage stage) {
        XYSeriesCollection dataset = new XYSeriesCollection();
        for (int i = 0; i < 3; i++) {
            XYSeries series = new XYSeries("value" + i);
            for (double t = 0; t < 2 * Math.PI; t += 0.5) {
                series.add(t, Math.sin(t) + i);
            }
            dataset.addSeries(series);
        }
        NumberAxis xAxis = new NumberAxis("domain");
        NumberAxis yAxis = new NumberAxis("range");
        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, true);
        renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);
        JFreeChart chart = new JFreeChart("Test", plot);
        ChartViewer viewer = new ChartViewer(chart);
        viewer.addChartMouseListener(new ChartMouseListenerFX() {
            @Override
            public void chartMouseClicked(ChartMouseEventFX e) {
                ChartEntity ce = e.getEntity();
                if (ce instanceof XYItemEntity) {
                    XYItemEntity item = (XYItemEntity) ce;
                    renderer.setSeriesVisible(item.getSeriesIndex(), false);
                } else if (ce instanceof LegendItemEntity) {
                    LegendItemEntity item = (LegendItemEntity) ce;
                    Comparable key = item.getSeriesKey();
                    renderer.setSeriesVisible(dataset.getSeriesIndex(key), false);
                } else {
                    for (int i = 0; i < dataset.getSeriesCount(); i++) {
                        renderer.setSeriesVisible(i, true);
                    }
                }
            }

            @Override
            public void chartMouseMoved(ChartMouseEventFX e) {}
        });
        stage.setScene(new Scene(viewer));
        stage.setTitle("JFreeChartFX");
        stage.setWidth(640);
        stage.setHeight(480);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}




legend