algorithms-for-computing-li.../LinearRegressionTool/src/main/java/de/wwwu/awolf/view/panels/DualityPanel.java

287 lines
9.2 KiB
Java

package de.wwwu.awolf.view.panels;
import de.wwwu.awolf.model.Line;
import de.wwwu.awolf.model.Point;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.DateRange;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.LinkedList;
import java.util.List;
/**
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
*
* @Author: Armin Wolf
* @Email: a_wolf28@uni-muenster.de
* @Date: 28.05.2017.
*/
public class DualityPanel extends JPanel {
private List<Line> lines;
private List<Point> points;
private JFreeChart chart;
private ChartPanel panel;
private XYSeriesCollection dataset;
private JScrollPane scrollPane;
private double domainMin, domainMax;
private double rangeMin, rangeMax;
private ValueAxis domain;
private ValueAxis range;
private Double delta = 1d;
private Boolean ctrlPressed = false;
private Boolean shiftPressed = false;
/**
* Konstruktor
*/
public DualityPanel() {
super();
this.setPreferredSize(new Dimension(800, 800));
this.setMinimumSize(new Dimension(800, 800));
this.setLayout(new BorderLayout());
}
/**
* Hilfsmethode um die Parameter im einem Schritt zu setzen
*
* @param lines Liste der Geraden
* @param points Liste der Schnittpunkte
* @param xmin minimale x-Koordinate
* @param xmax maximale x-Koordinate
* @param ymin minimale y-Koordinate
* @param ymax maximale y-Koordinate
*/
public void setPrameters(List<Line> lines, List<Point> points, Double xmin, Double xmax, Double ymin, Double ymax) {
this.lines = new LinkedList<>(lines);
this.points = new LinkedList<>(points);
this.domainMin = xmin;
this.domainMax = xmax;
this.rangeMin = ymin;
this.rangeMax = ymax;
}
/**
* Die Methode erzeugt ein Arrangement von Geraden.
*/
public void createArrangement() {
dataset = new XYSeriesCollection();
for (Line p : lines) {
XYSeries series = new XYSeries(p.getId() + "#" + p.getX1() + "---" + p.getY1());
series.add(p.getX1(), p.getY1());
series.add(p.getX2(), p.getY2());
dataset.addSeries(series);
}
XYSeries intersections = new XYSeries("intersections");
for (Point p : points) {
intersections.add(p.getX(), p.getY());
}
dataset.addSeries(intersections);
chart = ChartFactory.createXYLineChart(null, null, null, dataset,
PlotOrientation.HORIZONTAL, false, false, false);
chart.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON));
chart.setAntiAlias(true);
final XYPlot plot = chart.getXYPlot();
domain = plot.getDomainAxis();
range = plot.getRangeAxis();
domain.setRange(domainMin - 1, domainMax + 1);
range.setRange(rangeMin - 1, rangeMax + 1);
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
renderer.setSeriesLinesVisible(dataset.indexOf(intersections), false);
plot.setRenderer(renderer);
for (int i = 0; i < lines.size(); i++) {
// Setze die Shapes für die Schnittpunkte
renderer.setSeriesPaint(i, Color.BLUE);
renderer.setBaseSeriesVisible(true);
}
Shape shape = ShapeUtilities.createDiagonalCross(4, 1);
renderer.setSeriesPaint(lines.size(), Color.BLACK);
renderer.setSeriesShape(lines.size(), shape);
panel = new ChartPanel(chart);
panel.setPreferredSize(new Dimension(800, 800));
addKeyListener(this);
addZooming(panel);
this.setFocusable(true);
JTextArea info = new JTextArea();
info.setWrapStyleWord(true);
info.setLineWrap(true);
info.setAlignmentX(JTextArea.CENTER_ALIGNMENT);
info.setText("Um in dem Plot hineinzuzoomen kann das Mausrad verwendett werden. Um sich anschließen vertikal bzw. horizontal zu bewegen kann die Kombination (Umschalt/Steuerung) und Mausrad verwendett werden.");
Font font = new Font("Serif", Font.ITALIC, 14);
info.setFont(font);
//info.setForeground(Color.DARK_GRAY);
info.setEditable(false);
info.setWrapStyleWord(true);
this.add(info, BorderLayout.SOUTH);
this.add(panel, BorderLayout.CENTER);
}
/**
* Hilfmethode für die Zoom-Funktion im Panel
*
* @param component Komponente
*/
public void addKeyListener(JComponent component) {
component.addKeyListener(new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
ctrlPressed = false;
shiftPressed = false;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.isControlDown()) {
ctrlPressed = true;
}
if (e.isShiftDown()) {
shiftPressed = true;
}
}
});
}
/**
* Zoom-Funktionalität für das Panel
*
* @param chartPanel
*/
protected void addZooming(ChartPanel chartPanel) {
chartPanel.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
double min;
double max;
Double val;
val = e.getPreciseWheelRotation() * -1;
if (ctrlPressed) {
//Logging.logInfo("CTRL + ZOOM");
min = range.getLowerBound();
max = range.getUpperBound();
DateRange dateRangeX = move(val, min, max);
range.setRange(dateRangeX);
} else if (shiftPressed) {
//Logging.logInfo("SHIFT + ZOOM");
min = domain.getLowerBound();
max = domain.getUpperBound();
DateRange dateRangeY = move(val, min, max);
domain.setRange(dateRangeY);
} else {
Double x = (double) e.getY();
Double y = (double) e.getY();
if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL)
return;
if (e.getWheelRotation() < 0)
increaseZoom((ChartPanel) e.getComponent());
else
decreaseZoom((ChartPanel) e.getComponent());
}
}
/**
* Bewegung im Panel
* @param val Bewegung
* @param min minimale Wert
* @param max maximale Wert
* @return aktuell Sichtbare Teil des Panels
*/
private DateRange move(Double val, Double min, Double max) {
Double minimum = min;
Double maximum = max;
delta = Math.abs(maximum - minimum) * 0.01 * val;
minimum = minimum + delta;
maximum = maximum + delta;
return new DateRange(minimum, maximum);
}
/**
* Reinzoomen
* @param chart chart
*/
public synchronized void increaseZoom(JComponent chart) {
ChartPanel ch = (ChartPanel) chart;
zoomChartAxis(ch, true);
}
/**
* Rauszoomen
* @param chart chart
*/
public synchronized void decreaseZoom(JComponent chart) {
ChartPanel ch = (ChartPanel) chart;
zoomChartAxis(ch, false);
}
/**
* Zoom
* @param chartP
* @param increase
*/
private void zoomChartAxis(ChartPanel chartP, boolean increase) {
int width = chartP.getMaximumDrawWidth() - chartP.getMinimumDrawWidth();
int height = chartP.getMaximumDrawHeight() - chartP.getMinimumDrawWidth();
if (increase) {
chartP.zoomInBoth(width * 0.5, height * 0.5);
} else {
chartP.zoomOutBoth(width * 0.5, height * 0.5);
}
}
});
}
/**
* Datensatz leeren
*/
public void clear() {
if (dataset != null)
dataset.removeAllSeries();
}
}