Кто-нибудь делал перекрестие, которое следует за мышью в JFreeChart? - PullRequest
6 голосов
/ 14 декабря 2009

Мы используем JFreeChart для создания графиков XY, и у нас есть запрос объекта для создания перекрестия, которое перемещается вместе с мышью и выделяет точку данных, которая наиболее близко соответствует значению x мыши. Вы можете увидеть похожий пример в Google Finance - http://www.google.com/finance?q=INDEXDJX:.DJI,INDEXSP:.INX,INDEXNASDAQ:.IXIC.

Эти диаграммы Google только выделяют текущее значение (мы хотим это сделать, а также показываем перекрестие), но они показывают интерактивное взаимодействие с мышью, которое мы ищем.

У кого-нибудь есть изящные предложения?

Спасибо.

Ответы [ 4 ]

4 голосов
/ 20 декабря 2009

Я получил это с помощью слушателя мыши и класса CrosshairOverlay. После того, как я вернусь из отпуска, я опубликую свой код. Это оказалось не слишком сложно.


Извините, я забыл об этом!

Сначала вы хотите вычислить значения x, y для того места, где вы хотите получить перекрестие. Для меня я хотел, чтобы он двигался вдоль точек нашей линии, поэтому я вычислил ближайшее значение x и использовал эту пару данных для x, y.

Тогда я вызываю этот метод:

protected void setCrosshairLocation(double x, Double y) {
    Crosshair domainCrosshair;
    List domainCrosshairs = crosshairOverlay.getDomainCrosshairs();
    if (domainCrosshairs.isEmpty()) {
        domainCrosshair = new Crosshair();
        domainCrosshair.setPaint(BlueStripeColors.LIGHT_GRAY_C0);
        crosshairOverlay.addDomainCrosshair(domainCrosshair);
    }
    else {
        // We only have one at a time
        domainCrosshair = (Crosshair) domainCrosshairs.get(0);
    }
    domainCrosshair.setValue(x);

    if (y != null) {
        Crosshair rangeCrosshair;
        List rangeCrosshairs = crosshairOverlay.getRangeCrosshairs();
        if (rangeCrosshairs.isEmpty()) {
            rangeCrosshair = new Crosshair();
            rangeCrosshair.setPaint(BlueStripeColors.LIGHT_GRAY_C0);
            crosshairOverlay.addRangeCrosshair(rangeCrosshair);
        }
        else {
            // We only have one at a time
            rangeCrosshair = (Crosshair) rangeCrosshairs.get(0);
        }

        rangeCrosshair.setValue(y);
    }
}

Обратите внимание, что crosshairOverlay является экземпляром CrosshairOverlay.

1 голос
/ 14 декабря 2009

JFreeChart не может отобразить подсекцию диаграммы, поэтому вы захотите сделать что-то, что не требует перерисовки диаграммы. Вы можете записать свою диаграмму в BufferedImage и сохранить ее в памяти, а затем иметь собственный компонент, который использует буферизованную диаграмму в качестве фонового изображения и рисует над ней перекрестие и другие всплывающие окна.

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

0 голосов
/ 02 февраля 2012

Это сработало для меня. Я установил

chartPanel.addChartMouseListener(new ChartMouseListener() {
public void chartMouseMoved(ChartMouseEvent event)
    {
    try
    {
        double[] values = getCrossHairValue(event);

        plot.clearRangeMarkers();
        plot.clearDomainMarkers();

        Marker yMarker = new ValueMarker(values[1]);
        yMarker.setPaint(Color.darkGray);
        plot.addRangeMarker(yMarker);

        Marker xMarker = new ValueMarker(values[0]);
        xMarker.setPaint(Color.darkGray);
        plot.addDomainMarker(xMarker);

        chartPanel.repaint();
    } catch (Exception e)
    {

    }
    }

}

0 голосов
/ 14 декабря 2009

Первое, что приходит мне в голову, это написать пользовательский Курсор и установить его на свой график. Он может иметь ссылку на диаграмму и выделять значение x, соответствующее положению курсора x / y.

...