使用JFreeChart上下拖动点后获取值

时间:2016-08-06 14:20:15

标签: java jfreechart

下面的代码绘制了可以向下拖动的点。但是现在我想在拖动后获得每个点的Y轴(速度)的更新值,并再次使用这些更新的值绘制。最初在Y轴上的速度设置为4,但在拖动之后我想获得更新的速度值。

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import org.jfree.chart.*;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.entity.ChartEntity;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.entity.XYItemEntity;
import org.jfree.chart.labels.StandardXYSeriesLabelGenerator;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

   /**
* @see http://stackoverflow.com/a/38711095/230513
* @see http://www.jfree.org/forum/viewtopic.php?f=3&t=30569
   */
public class SeriesAndPointDragAndMove extends ApplicationFrame
implements ChartMouseListener, MouseListener, MouseMotionListener {

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            SeriesAndPointDragAndMove app = new         SeriesAndPointDragAndMove("Plot");
            app.pack();
            RefineryUtilities.centerFrameOnScreen(app);
            app.setVisible(true);
        }
    });
}

private boolean canMove = false;
private double finalMovePointY = 0;
private ChartRenderingInfo info = null;
private double initialMovePointY = 0;
private JFreeChart jFreeChart = null;
private ChartPanel chartPanel = null;
private XYSeries series = new XYSeries("Series");
private XYSeriesCollection collection = new XYSeriesCollection();
private XYItemEntity xyItemEntity = null;

public SeriesAndPointDragAndMove(String paramString) {
    super(paramString);
    jFreeChart = ChartFactory.createXYLineChart(
        "Drag Point", "Points (Index)", "Velocity (m/s)",
        createDataset(), PlotOrientation.VERTICAL, true, true, false);
    chartPanel = new ChartPanel(jFreeChart) {
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(640, 480);
        }
    };
    chartPanel.addChartMouseListener(this);
    chartPanel.addMouseMotionListener(this);
    chartPanel.addMouseListener(this);
    chartPanel.setAutoscrolls(false);
    chartPanel.setMouseZoomable(false);
    this.info = chartPanel.getChartRenderingInfo();
    XYPlot localXYPlot = (XYPlot) jFreeChart.getPlot();
    XYItemRenderer localXYItemRenderer = localXYPlot.getRenderer();
    localXYItemRenderer.setSeriesStroke(0, new BasicStroke(2.0F));
    XYLineAndShapeRenderer localXYLineAndShapeRenderer
        = (XYLineAndShapeRenderer) localXYPlot.getRenderer();
    localXYLineAndShapeRenderer.setBaseShapesVisible(true);
    localXYLineAndShapeRenderer.setSeriesFillPaint(0, Color.white);
    localXYLineAndShapeRenderer.setUseFillPaint(true);
    localXYLineAndShapeRenderer.setLegendItemToolTipGenerator(
        new StandardXYSeriesLabelGenerator("Tooltip {0}"));
    ValueAxis range = localXYPlot.getRangeAxis();
    range.setLowerBound(0);
    range.setUpperBound(20);
    setContentPane(chartPanel);
}

@Override
public void chartMouseClicked(ChartMouseEvent paramChartMouseEvent) {
}

@Override
public void chartMouseMoved(ChartMouseEvent paramChartMouseEvent) {
}

public XYDataset createDataset() {
    for (int i = 0; i < 8; i++) {
        series.add(i, 4);
    }
    collection.addSeries(series);
    return collection;
}

@Override
public void mouseClicked(MouseEvent e) {
}

@Override
public void mouseDragged(MouseEvent e) {
    movePoint(e);
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
    canMove = false; // stop movement if cursor is out from the chart area
    initialMovePointY = 0;
    chartPanel.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}

public void mouseMoved(MouseEvent e) {
}

public void mousePressed(MouseEvent e) {
    int x = e.getX(); // initialized point whenenver mouse is pressed
    int y = e.getY();
    EntityCollection entities = this.info.getEntityCollection();
    ChartMouseEvent cme = new ChartMouseEvent(jFreeChart, e, entities
        .getEntity(x, y));
    ChartEntity entity = cme.getEntity();
    if ((entity != null) && (entity instanceof XYItemEntity)) {
        xyItemEntity = (XYItemEntity) entity;
    } else if (!(entity instanceof XYItemEntity)) {
        xyItemEntity = null;
        return;
    }
    if (xyItemEntity == null) {
        return; // return if not pressed on any series point
    }
    Point pt = e.getPoint();
    XYPlot xy = jFreeChart.getXYPlot();
    Rectangle2D dataArea = chartPanel.getChartRenderingInfo()
        .getPlotInfo().getDataArea();
    Point2D p = chartPanel.translateScreenToJava2D(pt);
    initialMovePointY = xy.getRangeAxis().java2DToValue(p.getY(), dataArea,
        xy.getRangeAxisEdge());
    canMove = true;
    chartPanel.setCursor(new Cursor(Cursor.HAND_CURSOR));
}

@Override
public void mouseReleased(MouseEvent e) {
    // stop dragging on mouse released
    canMove = false;
    initialMovePointY = 0;
    chartPanel.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}

public void movePoint(MouseEvent me) {
    if (canMove) {
        int itemIndex = xyItemEntity.getItem();
        Point pt = me.getPoint();
        XYPlot xy = jFreeChart.getXYPlot();
        Rectangle2D dataArea = chartPanel.getChartRenderingInfo()
            .getPlotInfo().getDataArea();
        Point2D p = chartPanel.translateScreenToJava2D(pt);
        finalMovePointY = xy.getRangeAxis().java2DToValue(p.getY(),
            dataArea, xy.getRangeAxisEdge());
        double difference = finalMovePointY - initialMovePointY;
        if (series.getY(itemIndex).doubleValue()
            + difference > xy.getRangeAxis().getRange().getLength()
            || series.getY(itemIndex).doubleValue()
            + difference < 0.0D) {
            initialMovePointY = finalMovePointY;
        }
        // retrict movement for upper and lower limit (upper limit
        // should be as per application needs)
        double targetPoint = series.getY(itemIndex).doubleValue() + difference;
        if (targetPoint > 15 || targetPoint < 0) {
            return;
        } else {
            series.update(Integer.valueOf(itemIndex), Double.valueOf(targetPoint));
        }
        jFreeChart.fireChartChanged();
        chartPanel.updateUI();
        initialMovePointY = finalMovePointY;
    }
}

public void moveSeries(MouseEvent me) {
    if (canMove) {
        Point pt = me.getPoint();
        XYPlot xy = jFreeChart.getXYPlot();
        Rectangle2D dataArea = chartPanel.getChartRenderingInfo()
            .getPlotInfo().getDataArea();
        Point2D p = chartPanel.translateScreenToJava2D(pt);
        finalMovePointY = xy.getRangeAxis().java2DToValue(p.getY(),
            dataArea, xy.getRangeAxisEdge());
        double difference = finalMovePointY - initialMovePointY;

        for (int i = 0; i < series.getItemCount(); i++) {
            System.out.println(series.getItemCount());
            if (series.getY(i).doubleValue() + difference > xy.getRangeAxis().getRange().getLength()
                || series.getY(i).doubleValue()
                + difference < 0.0D) {
                initialMovePointY = finalMovePointY;
            }
        }

        // retrict movement for upper and lower limit (upper limit
        // should be as per application needs)
        for (int i = 0; i < series.getItemCount(); i++) {
            double targetPoint = series.getY(i)
                .doubleValue()
                + difference;
            if (targetPoint > 50 || targetPoint < 0) {
                return;
            }
        }
        for (int i = 0; i < series.getItemCount(); i++) {
            double targetPoint = series.getY(i)
                .doubleValue()
                + difference;
            series.update(Integer.valueOf(i), Double.valueOf(targetPoint));
        }
        jFreeChart.fireChartChanged();
        chartPanel.updateUI();
        initialMovePointY = finalMovePointY;
    }
}

}

1 个答案:

答案 0 :(得分:1)

要接收XYSeries更改通知,请添加SeriesChangeListener,如下所示:

public SeriesAndPointDragAndMove(String paramString) {
    …
    series.addChangeListener(new SeriesChangeListener() {
        @Override
        public void seriesChanged(SeriesChangeEvent e) {
            XYSeries series = (XYSeries) e.getSource();
            System.out.println(series.getItems());
        }
    });
}

image

输出为横坐标为3.0的点从速度4.0移动到5.0

[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.053908355795149], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.107816711590297], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.161725067385444], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.215633423180593], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.323450134770890], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.431266846361186], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.485175202156334], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.539083557951483], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.592991913746631], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.646900269541780], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.700808625336927], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.754716981132076], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.862533692722372], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.916442048517521], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.9703504043126685], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 4.9703504043126685], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]
[[0.0, 4.0], [1.0, 4.0], [2.0, 4.0], [3.0, 5.0242587601078160], [4.0, 4.0], [5.0, 4.0], [6.0, 4.0], [7.0, 4.0]]