使用鼠标平移图表-Jfreechart [英] Pan chart using mouse - Jfreechart

查看:53
本文介绍了使用鼠标平移图表-Jfreechart的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们可以在JfreeChart中将平移功能实现为鼠标拖动事件吗?现在,我按下 CTRL 并拖动鼠标以平移图表.我只想通过拖动鼠标来实现平移功能.有可能吗?

Can we implement the pan functionality as a mouse drag event in JfreeChart? Right now I press CTRL and drag my mouse to pan a chart. I want to implement the pan functionality just by dragging the mouse. Is that possible ?

推荐答案

用当前的JFreeChart API更改修改键显然是不可能的,如

It is apparently impossible to change the modifier key with the current JFreeChart API, as discussed here (but it is in the pipeline).

但是,所有内容都可以通过编程方式平移图表,因此您可以尝试以下操作:

However, everything is there to pan a chart programmatically, so you could try the following:

  • Add a MouseMotionListener to your ChartPanel to track mouseDragged() events.
  • From these events, compute the requested movement of the chart.
  • Call directly XYPlot.panDomainAxes() and XYPlot.panRangeAxis() (API here).

ChartPanel中获取灵感源代码:

/** 
 * Temporary storage for the width and height of the chart 
 * drawing area during panning.
 */
private double panW, panH;

/** The last mouse position during panning. */
private Point panLast;

/**
 * The mask for mouse events to trigger panning.
 *
 * @since 1.0.13
 */
private int panMask = InputEvent.CTRL_MASK;

...

/**
 * Handles a 'mouse pressed' event.
 * <P>
 * This event is the popup trigger on Unix/Linux.  For Windows, the popup
 * trigger is the 'mouse released' event.
 *
 * @param e  The mouse event.
 */
@Override
public void mousePressed(MouseEvent e) {
    if (this.chart == null) {
        return;
    }
    Plot plot = this.chart.getPlot();
    int mods = e.getModifiers();
    if ((mods & this.panMask) == this.panMask) {
        // can we pan this plot?
        if (plot instanceof Pannable) {
            Pannable pannable = (Pannable) plot;
            if (pannable.isDomainPannable() || pannable.isRangePannable()) {
                Rectangle2D screenDataArea = getScreenDataArea(e.getX(),
                        e.getY());
                if (screenDataArea != null && screenDataArea.contains(
                        e.getPoint())) {
                    this.panW = screenDataArea.getWidth();
                    this.panH = screenDataArea.getHeight();
                    this.panLast = e.getPoint();
                    setCursor(Cursor.getPredefinedCursor(
                            Cursor.MOVE_CURSOR));
                }
            }
            // the actual panning occurs later in the mouseDragged() 
            // method
        }
    }
    else if (this.zoomRectangle == null) {
        ...
    }
}

...

/**
 * Handles a 'mouse dragged' event.
 *
 * @param e  the mouse event.
 */
@Override
public void mouseDragged(MouseEvent e) {

    // if the popup menu has already been triggered, then ignore dragging...
    if (this.popup != null && this.popup.isShowing()) {
        return;
    }

    // handle panning if we have a start point
    if (this.panLast != null) {
        double dx = e.getX() - this.panLast.getX();
        double dy = e.getY() - this.panLast.getY();
        if (dx == 0.0 && dy == 0.0) {
            return;
        }
        double wPercent = -dx / this.panW;
        double hPercent = dy / this.panH;
        boolean old = this.chart.getPlot().isNotify();
        this.chart.getPlot().setNotify(false);
        Pannable p = (Pannable) this.chart.getPlot();
        if (p.getOrientation() == PlotOrientation.VERTICAL) {
            p.panDomainAxes(wPercent, this.info.getPlotInfo(),
                    this.panLast);
            p.panRangeAxes(hPercent, this.info.getPlotInfo(),
                    this.panLast);
        }
        else {
            p.panDomainAxes(hPercent, this.info.getPlotInfo(),
                    this.panLast);
            p.panRangeAxes(wPercent, this.info.getPlotInfo(),
                    this.panLast);
        }
        this.panLast = e.getPoint();
        this.chart.getPlot().setNotify(old);
        return;
    }

    ...

}

...

/**
 * Handles a 'mouse released' event.  On Windows, we need to check if this
 * is a popup trigger, but only if we haven't already been tracking a zoom
 * rectangle.
 *
 * @param e  information about the event.
 */
@Override
public void mouseReleased(MouseEvent e) {

    // if we've been panning, we need to reset now that the mouse is 
    // released...
    if (this.panLast != null) {
        this.panLast = null;
        setCursor(Cursor.getDefaultCursor());
    }

    ...

}

编辑:注意到当前API的唯一问题是panMask是私有的,为什么不尝试通过反射来破解该字段:

Noticing that the only problem with the current API is that panMask is private, why don't you try to hack the field with reflection:

Field mask = ChartPanel.class.getDeclaredField("panMask");
mask.setAccessible(true);
mask.set(yourChartPanel, Integer.valueOf(0)); // The "0" mask is equivalent to no mask. You could also set a different modifier.

这篇关于使用鼠标平移图表-Jfreechart的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆