基于此example,此代码用于拖动图表中的点。我想用TimeSeries
替换XYSeries
对象,因为我不想在X轴上使用月份;我想要一系列像Point1
,Point2
,Point3
等的数字,并希望具有相同的逻辑。用XYSeries
替换时,我没有获得如何更改XYSeries
逻辑的方法。
package com.example.java;
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.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
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;
@SuppressWarnings("serial")
public class SeriesAndPointDragAndMove extends ApplicationFrame implements ChartMouseListener, MouseListener, MouseMotionListener {
public static void main(String paramArrayOfString) {
SeriesAndPointDragAndMove seriesAndPointDragAndMove = new SeriesAndPointDragAndMove(
"Plot");
seriesAndPointDragAndMove.pack();
RefineryUtilities.centerFrameOnScreen(seriesAndPointDragAndMove);
seriesAndPointDragAndMove.setVisible(true);
}
boolean canMove = false;
double finalMovePointY = 0;
ChartRenderingInfo info = null;;
double initialMovePointY = 0;
JFreeChart jfreechart = null;
ChartPanel localChartPanel = null;
TimeSeries localTimeSeries = new TimeSeries("Series");
// XYSeries localTimeSeries1 = new XYSeries("series"); //test
TimeSeriesCollection timeseriescollection = new TimeSeriesCollection();
// XYSeriesCollection timeseriescollection1 = new XYSeriesCollection();//test
XYItemEntity xyItemEntity = null;
public SeriesAndPointDragAndMove(String paramString) {
super(paramString);
jfreechart = ChartFactory.createTimeSeriesChart(
"Velocity Point Plot", "Points (Index)", "Velocity (m/s)",
createDataset(), true, true, false);
localChartPanel = new ChartPanel(jfreechart);
localChartPanel.addChartMouseListener(this);
localChartPanel.addMouseMotionListener(this);
localChartPanel.addMouseListener(this);
localChartPanel.setPreferredSize(new Dimension(750, 500));
localChartPanel.setAutoscrolls(false);
localChartPanel.setMouseZoomable(false);
this.info = localChartPanel.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); // set lower limit so that can't move in -ve
// range
range.setUpperBound(20); // set upper limit as per app. needs
setContentPane(localChartPanel);
}
public void chartMouseClicked(ChartMouseEvent paramChartMouseEvent) {
}
public void chartMouseMoved(ChartMouseEvent paramChartMouseEvent) {
}
public XYDataset createDataset() {
//
// for (int i = 0; i <6 ; i++) {
// localTimeSeries.add(i,4);
//
// }
localTimeSeries.add(new Month(1, 2002), 4);
localTimeSeries.add(new Month(2, 2002), 4);
localTimeSeries.add(new Month(3, 2002), 4);
localTimeSeries.add(new Month(4, 2002), 4);
localTimeSeries.add(new Month(5, 2002), 4);
localTimeSeries.add(new Month(6, 2002), 4);
localTimeSeries.add(new Month(7, 2002), 4);
localTimeSeries.add(new Month(8, 2002), 4);
localTimeSeries.add(new Month(9, 2002), 4);
localTimeSeries.add(new Month(10, 2002), 4);
localTimeSeries.add(new Month(11, 2002), 4);
localTimeSeries.add(new Month(12, 2002), 4);
timeseriescollection.addSeries(localTimeSeries);
// timeseriescollection1.addSeries(localTimeSeries1);
return timeseriescollection;
}
public void mouseClicked(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
// at a time use one of them.
//moveTimeSeries(e); // comment or uncomment to enable or disable series
// movement
movePoint(e); // comment or uncomment to enable or disable selected
// point movement
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
canMove = false; // stop movement if cursor is moved out from the chart
// area
initialMovePointY = 0;
localChartPanel.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 = localChartPanel.getChartRenderingInfo()
.getPlotInfo().getDataArea();
Point2D p = localChartPanel.translateScreenToJava2D(pt);
initialMovePointY = xy.getRangeAxis().java2DToValue(p.getY(), dataArea,
xy.getRangeAxisEdge());
canMove = true;
localChartPanel.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
public void mouseReleased(MouseEvent e) {
// stop dragging on mouse released
canMove = false;
initialMovePointY = 0;
localChartPanel.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
public void movePoint(MouseEvent me) {
try {
if (canMove) {
int itemIndex = xyItemEntity.getItem();
Point pt = me.getPoint();
XYPlot xy = jfreechart.getXYPlot();
Rectangle2D dataArea = localChartPanel.getChartRenderingInfo()
.getPlotInfo().getDataArea();
Point2D p = localChartPanel.translateScreenToJava2D(pt);
finalMovePointY = xy.getRangeAxis().java2DToValue(p.getY(),
dataArea, xy.getRangeAxisEdge());
double difference = finalMovePointY - initialMovePointY;
if (localTimeSeries.getValue(itemIndex).doubleValue()
+ difference > xy.getRangeAxis().getRange().getLength()
|| localTimeSeries.getValue(itemIndex).doubleValue()
+ difference < 0.0D) {
initialMovePointY = finalMovePointY;
}
// retrict movement for upper and lower limit (upper limit
// should be as per application needs)
double targetPoint = localTimeSeries.getValue(itemIndex)
.doubleValue()
+ difference;
if (targetPoint > 15 || targetPoint < 0) {
return;
} else
localTimeSeries.update(itemIndex, targetPoint);
jfreechart.fireChartChanged();
localChartPanel.updateUI();
initialMovePointY = finalMovePointY;
}
} catch (Exception e) {
System.out.println(e);
}
}
public void moveTimeSeries(MouseEvent me) {
try {
if (canMove) {
Point pt = me.getPoint();
XYPlot xy = jfreechart.getXYPlot();
Rectangle2D dataArea = localChartPanel.getChartRenderingInfo()
.getPlotInfo().getDataArea();
Point2D p = localChartPanel.translateScreenToJava2D(pt);
finalMovePointY = xy.getRangeAxis().java2DToValue(p.getY(),
dataArea, xy.getRangeAxisEdge());
double difference = finalMovePointY - initialMovePointY;
for (int i = 0; i < localTimeSeries.getItemCount(); i++) {
System.out.println(localTimeSeries.getItemCount());
if (localTimeSeries.getValue(i).doubleValue() + difference > xy.getRangeAxis().getRange().getLength()
|| localTimeSeries.getValue(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 < localTimeSeries.getItemCount(); i++) {
double targetPoint = localTimeSeries.getValue(i)
.doubleValue()
+ difference;
if (targetPoint > 50 || targetPoint < 0) {
return;
}
}
for (int i = 0; i < localTimeSeries.getItemCount(); i++) {
double targetPoint = localTimeSeries.getValue(i)
.doubleValue()
+ difference;
localTimeSeries.update(i, targetPoint);
}
jfreechart.fireChartChanged();
localChartPanel.updateUI();
initialMovePointY = finalMovePointY;
}
} catch (Exception e) {
System.out.println(e);
}
}
}
最佳答案
由于两者都接受XYDataset
并且都在内部使用XYLineAndShapeRenderer
,因此基本步骤是替换ChartFactory
:
// ChartFactory.createTimeSeriesChart(…);
ChartFactory.createXYLineChart(…);
其余更改将替换
XYSeries
访问器/更改器,并在event dispatch thread上构造GUI。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;
}
}
}