From 82686fd280e04ee9280791dac4f8cbea9c88d995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Dr=C3=A4ger?= Date: Mon, 12 Apr 2010 04:49:28 +0000 Subject: [PATCH] Improved the FunctionArea: Now a color can be set directly for a certain plot. --- src/eva2/gui/FunctionArea.java | 1380 +++++++++++---------- src/eva2/gui/GraphPointSet.java | 970 ++++++++------- src/eva2/tools/chart2d/DArea.java | 1476 +++++++++++----------- src/eva2/tools/math/Mathematics.java | 1712 +++++++++++++------------- 4 files changed, 2858 insertions(+), 2680 deletions(-) diff --git a/src/eva2/gui/FunctionArea.java b/src/eva2/gui/FunctionArea.java index 5b19b2fd..5e2dccee 100644 --- a/src/eva2/gui/FunctionArea.java +++ b/src/eva2/gui/FunctionArea.java @@ -58,19 +58,19 @@ public class FunctionArea extends DArea implements Serializable { * Generated serial version identifier. */ private static final long serialVersionUID = 1238444548498667204L; - private InterfaceRefPointListener m_RefPointListener; - private JFileChooser m_FileChooser; - private ArrayList m_PointSetContainer; + private GraphPointSetLegend legendBox = null; private ScaledBorder m_Border; - private boolean m_log = false; - private boolean notifyNegLog = true; + private DPointIcon m_CurrentPointIcon; + private JFileChooser m_FileChooser; private boolean m_legend = true; + private boolean m_log = false; + private ArrayList m_PointSetContainer; + private InterfaceRefPointListener m_RefPointListener; private int m_x; + private int m_y; - private GraphPointSetLegend legendBox = null; - - private DPointIcon m_CurrentPointIcon; + private boolean notifyNegLog = true; /** * @@ -102,371 +102,6 @@ public class FunctionArea extends DArea implements Serializable { notifyNegLog = true; } - /** - * Set a legend for the function area. If null is given, the former legend - * is deactivated. - * - * @param lBox - */ - protected void setLegend(GraphPointSetLegend lBox) { - legendBox = lBox; - if (lBox != null && m_legend) - repaint(); - } - - /** - * Plot a circle icon to the function area which is annotated with a char - * and a double value. - * - * @param c - * @param val - * @param position - */ - public void drawCircle(double val, double[] position, int graphID) { - drawCircle("" + val, position, graphID); - } - - /** - * Plot a circle icon to the function area which is annotated with a char - * and a double value. - * - * @param c - * @param val - * @param position - * @param graphID - */ - public void drawCircle(char c, double val, double[] position, int graphID) { - drawCircle(c + "" + val, position, graphID); - } - - public void drawCircle(String label, double xPos, double yPos, int graphID) { - double[] pos = new double[2]; - pos[0] = xPos; - pos[1] = yPos; - drawCircle(label, pos, graphID); - } - - /** - * Plot a circle icon to the function area which is annotated with a char - * and a double value. The color corresponds to the color of the graph with - * given ID - * - * @param label - * @param position - * @param graphID - */ - public void drawCircle(String label, double[] position, int graphID) { - drawIcon(new Chart2DDPointIconCircle(), label, position, graphID); - } - - /** - * Plot an icon to the function area which is annotated with a char and a - * double value. The color corresponds to the color of the graph with given - * ID Icon types are 0: circle, 1: cross, otherwise: point. - * - * @param label - * @param position - * @param graphID - */ - public void drawIcon(int iconType, String label, double[] position, - int graphID) { - DPointIcon theIcon; - switch (iconType) { - case 0: - theIcon = new Chart2DDPointIconCircle(); - break; - case 1: - theIcon = new Chart2DDPointIconCross(); - break; - default: - case 2: - theIcon = new Chart2DDPointIconPoint(); - break; - } - drawIcon(theIcon, label, position, graphID); - } - - /** - * Draw a line with given start and end points. - * - * @param p1 - * @param p2 - */ - public void drawLine(double[] p1, double[] p2) { - DPointSet popRep = new DPointSet(); - popRep.setConnected(true); - popRep.addDPoint(new DPoint(p1[0], p1[1])); - popRep.addDPoint(new DPoint(p2[0], p2[1])); - addDElement(popRep); - } - - /** - * Plot a circle icon to the function area which is annotated with a char - * and a double value. The color corresponds to the color of the graph with - * given ID - * - * @param label - * @param position - * @param graphID - */ - public void drawIcon(DPointIcon theIcon, String label, double[] position, - int graphID) { - DPointSet popRep; - popRep = new DPointSet(); - popRep.addDPoint(new DPoint(position[0], position[1])); - DPointIcon icon = new Chart2DDPointIconText(label); - ((Chart2DDPointIconText) icon).setIcon(theIcon); - ((Chart2DDPointIconText) icon).setColor(getGraphPointSet(graphID) - .getColor()); - popRep.setIcon(icon); - addDElement(popRep); - } - - /** - * - */ - public String getGraphInfo(int x, int y) { - String ret = ""; - if ((m_PointSetContainer == null) || (m_PointSetContainer.size() == 0)) - return ret; - int minindex = getNearestGraphIndex(x, y); - if (minindex >= 0) - return ((GraphPointSet) (m_PointSetContainer.get(minindex))) - .getInfoString(); - else - return "none"; - } - - /** - * - */ - public boolean isStatisticsGraph(int x, int y) { - boolean ret = false; - if ((m_PointSetContainer == null) || (m_PointSetContainer.size() == 0)) - return ret; - int minindex = getNearestGraphIndex(x, y); - ret = ((GraphPointSet) (m_PointSetContainer.get(minindex))) - .isStatisticsGraph(); - return ret; - } - - /** - * - */ - private int getNearestGraphIndex(int x, int y) { - // get index of nearest Graph - double distmin = 10000000; - int minindex = -1; - DPoint point1 = getDMeasures().getDPoint(x, y); - DPoint point2 = null; - double dist = 0; - for (int i = 0; i < m_PointSetContainer.size(); i++) { - GraphPointSet pointset = m_PointSetContainer.get(i); - point2 = pointset.getNearestDPoint(point1); - if (point2 == null) - continue; - if (point1 == null) - System.err.println("point1 == null"); - - dist = (point1.x - point2.x) * (point1.x - point2.x) - + (point1.y - point2.y) * (point1.y - point2.y); - // System.out.println("dist="+dist+"i="+i); - if (dist < distmin) { - distmin = dist; - minindex = i; - } - } - return minindex; - } - - /** - * - */ - private DPoint getNearestDPoint(int x, int y) { - // get index of nearest Graph - double distmin = 10000000; - DPoint ret = null; - DPoint point1 = getDMeasures().getDPoint(x, y); - DPoint point2 = null; - double dist = 0; - for (int i = 0; i < m_PointSetContainer.size(); i++) { - if (m_PointSetContainer.get(i) instanceof GraphPointSet) { - GraphPointSet pointset = (GraphPointSet) (m_PointSetContainer - .get(i)); - point2 = pointset.getNearestDPoint(point1); - if (point2 == null) - continue; - dist = (point1.x - point2.x) * (point1.x - point2.x) - + (point1.y - point2.y) * (point1.y - point2.y); - // System.out.println("dist="+dist+"i="+i); - if (dist < distmin) { - distmin = dist; - ret = point2; - } - if ((dist == distmin) - && !(ret.getIcon() instanceof Chart2DDPointIconContent) - && !(ret.getIcon() instanceof InterfaceSelectablePointIcon)) { - distmin = dist; - ret = point2; - } - } - } - return ret; - } - - /** - * Export contained data to standard output. - * - */ - public void exportToAscii() { - exportToAscii((File) null); - } - - private String cleanBlanks(String str, Character rpl) { - return str.replace(' ', rpl); - } - - /** - * Export contained data to a file or to standard out if null is given. The - * given File will be overwritten! - * - * @param file - * a File instance or null to export to standard out - * @return true if the export succeeded, else false - */ - public boolean exportToAscii(File file) { - String[] s = null; - int maxSize = 0; - DPointSet maxSet = null; - for (int i = 0; i < m_PointSetContainer.size(); i++) { - // find maximum length of all point sets - if (m_PointSetContainer.get(i).getConnectedPointSet().getSize() > maxSize) { - maxSet = m_PointSetContainer.get(i).getConnectedPointSet(); - maxSize = maxSet.getSize(); - } - } - if (maxSize > 0) { // if there is any data, init string array and set x - // value column - s = new String[maxSize + 1]; - s[0] = "calls"; - for (int j = 1; j <= maxSize; j++) - s[j] = "" + maxSet.getDPoint(j - 1).x; - } else { - System.err.println("Error: no data to export"); - return true; - } - for (int i = 0; i < m_PointSetContainer.size(); i++) { - if (m_PointSetContainer.get(i) instanceof GraphPointSet) { - GraphPointSet set = (GraphPointSet) m_PointSetContainer.get(i); - DPointSet pset = set.getConnectedPointSet(); - s[0] = s[0] + " " + cleanBlanks(set.getInfoString(), '_'); // add - // column - // name - for (int j = 1; j < s.length; j++) { // add column data of place - // holder if no value in - // this set - if ((j - 1) < pset.getSize()) - s[j] = s[j] + " " + pset.getDPoint(j - 1).y; - else - s[j] += " #"; - } - } else - System.err.println("error in FunctionArea::exportToAscii"); - } - if (file == null) { - for (int j = 0; j < s.length; j++) { - System.out.println(s[j]); - } - return true; - } else - try { - PrintWriter out = new PrintWriter(new FileOutputStream(file)); - for (int j = 0; j < s.length; j++) - out.println(s[j]); - out.flush(); - out.close(); - return true; - } catch (Exception e) { - System.err.println("Error on data export:" + e.getMessage()); - return false; - } - } - - /** - * Export contained data to a file with a given String as prefix - * - * @param prefix - * file name prefix - * @return true if the export succeeded, else false - */ - public boolean exportToAscii(String prefix) { - SimpleDateFormat formatter = new SimpleDateFormat( - "E'_'yyyy.MM.dd'_'HH.mm.ss"); - String fname = prefix + "PlotExport_" + formatter.format(new Date()) - + ".txt"; - try { - File f = new File(fname); - f.createNewFile(); - return exportToAscii(f); - } catch (Exception e) { - System.err.println("Error:" + e.getMessage()); - return false; - } - - } - - @Override - public void paint(Graphics g) { - super.paint(g); - if (legendBox != null && (m_legend)) - legendBox.paintIn(g, m_Border.getInnerRect(this)); - } - - /** - * - */ - public void setConnectedPoint(double[] p, int graphLabel) { - setConnectedPoint(p[0], p[1], graphLabel); - } - - /** - * - */ - public void setConnectedPoint(double x, double y, int graphLabel) { - if (!checkLogValidYValue(x, y, graphLabel)) { - if (m_log) - toggleLog(); - } - // if (y <= 0.0) { - // // y = Double.MIN_VALUE; - // if (notifyNegLog) { - // System.err.println("Warning: trying to plot value (" + x + "/" + y + - // ") with y <= 0 in logarithmic mode! Setting y to " + 1e-30); - // notifyNegLog = false; - // } - // y = 1e-30; - // } - getGraphPointSet(graphLabel).addDPoint(x, y); - } - - // public void setConnectedPoint(double x, double y, int GraphLabel) { - // if (m_log == true && y <= 0.0) { - // // y = Double.MIN_VALUE; - // if (notifyNegLog) { - // System.err.println("Warning: trying to plot value (" + x + "/" + y + - // ") with y <= 0 in logarithmic mode! Setting y to " + 1e-30); - // notifyNegLog = false; - // } - // y = 1e-30; - // } - // getGraphPointSet(GraphLabel).addDPoint(x, y); - // - // } - - public void addGraphPointSet(GraphPointSet d) { - this.m_PointSetContainer.add(d); - } - /** * */ @@ -476,299 +111,8 @@ public class FunctionArea extends DArea implements Serializable { notifyNegLog = true; } - /** - * - */ - public void clearGraph(int graphLabel) { - getGraphPointSet(graphLabel).removeAllPoints(); - m_PointSetContainer.remove(getGraphPointSet(graphLabel)); - repaint(); - notifyNegLog = true; - } - - /** - * - */ - public void changeColorGraph(int GraphLabel) { - getGraphPointSet(GraphLabel).incColor(); - repaint(); - } - - /** - * - */ - public void clearGraph(int x, int y) { - int index = getNearestGraphIndex(x, y); - if (index == -1) - return; - int GraphLabel = ((GraphPointSet) (this.m_PointSetContainer.get(index))) - .getGraphLabel(); - clearGraph(GraphLabel); - updateLegend(); - } - - /** - * - */ - public void changeColorGraph(int x, int y) { - int index = getNearestGraphIndex(x, y); - if (index == -1) - return; - int GraphLabel = ((GraphPointSet) (this.m_PointSetContainer.get(index))) - .getGraphLabel(); - changeColorGraph(GraphLabel); - updateLegend(); - } - - /** - * - */ - public void removePoint(int x, int y) { - DPoint point = getNearestDPoint(x, y); - int index = getNearestGraphIndex(x, y); - if (index == -1 || point == null) - return; - GraphPointSet pointset = (GraphPointSet) (this.m_PointSetContainer - .get(index)); - pointset.removePoint(point); - } - - /** - * - */ - public void setInfoString(int GraphLabel, String Info, float stroke) { - getGraphPointSet(GraphLabel).setInfoString(Info, stroke); - } - - /** - * - */ - public void clearAll() { - this.removeAllDElements(); - for (int i = 0; i < m_PointSetContainer.size(); i++) - ((GraphPointSet) (m_PointSetContainer.get(i))).removeAllPoints(); - m_PointSetContainer.clear(); - notifyNegLog = true; - } - - /** - * - */ - private GraphPointSet getGraphPointSet(int GraphLabel) { - // System.out.println("looping through " + m_PointSetContainer.size() + - // " point sets..."); - for (int i = 0; i < m_PointSetContainer.size(); i++) { - if (m_PointSetContainer.get(i) instanceof GraphPointSet) { - GraphPointSet xx = (GraphPointSet) (m_PointSetContainer.get(i)); - // System.out.println("looking at "+xx.getGraphLabel()); - if (xx.getGraphLabel() == GraphLabel) { - // System.out.println("match!"); - return xx; - } - } - } - // create new GraphPointSet - GraphPointSet NewPointSet = new GraphPointSet(GraphLabel, this); - // System.out.println("adding new point set " + GraphLabel); - // NewPointSet.setStroke(new BasicStroke( (float)1.0 )); - // addGraphPointSet(NewPointSet); already done within GraphPointSet!!! - return NewPointSet; - } - - public void setUnconnectedPoint(double[] p, int GraphLabel) { - setUnconnectedPoint(p[0], p[1], GraphLabel); - } - - /** - * - */ - public void setUnconnectedPoint(double x, double y, int GraphLabel) { - if (!checkLogValidYValue(x, y, GraphLabel)) { - if (m_log) - toggleLog(); - } - this.getGraphPointSet(GraphLabel).addDPoint(x, y); - this.getGraphPointSet(GraphLabel).setConnectedMode(false); - repaint(); - } - - protected boolean checkLoggable() { - double minY = Double.MAX_VALUE; - for (int i = 0; i < m_PointSetContainer.size(); i++) { - DPointSet pSet = (m_PointSetContainer.get(i).getConnectedPointSet()); - if (pSet.getSize() > 0) - minY = Math.min(minY, pSet.getMinYVal()); - } - // if (TRACE) System.out.println("min is " + minY); - return (minY > 0); - } - - protected boolean checkLogValidYValue(double x, double y, int graphLabel) { - if (y <= 0.0) { - if (m_log && notifyNegLog) { - System.err.println("Warning: trying to plot value (" + x + "/" - + y + ") with y <= 0 in logarithmic mode!"); - notifyNegLog = false; - } - return false; - } - return true; - } - - public void setGraphColor(int GraphLabel, int colorindex) { - this.getGraphPointSet(GraphLabel).setColorByIndex(colorindex); - } - - /** - * Returns the number of points within the graph of the given label. - * - * @param index - * @return - */ - public int getPointCount(int label) { - return getGraphPointSet(label).getPointCount(); - } - - /** - * - */ - public int getContainerSize() { - return m_PointSetContainer.size(); - } - - /** - * - */ - public DPointSet[] printPoints() { - DPointSet[] ret = new DPointSet[m_PointSetContainer.size()]; - for (int i = 0; i < m_PointSetContainer.size(); i++) { - System.out.println(""); - System.out.println("GraphPointSet No " + i); - - ret[i] = ((GraphPointSet) m_PointSetContainer.get(i)).printPoints(); - } - return ret; - - } - - public DPointSet printPoints(int i) { - // for (int i = 0; i < m_PointSetContainer.size();i++) { - System.out.println(""); - System.out.println("GraphPointSet No " + i); - - return ((GraphPointSet) m_PointSetContainer.get(i)).printPoints(); - // } - } - - /** - * - */ - public void toggleLog() { - // System.out.println("ToggleLog log was: "+m_log); - if (!m_log && !checkLoggable()) { - System.err.println("Cant toggle log with values <= 0!"); - return; - } - if (m_log == false) { - setMinRectangle(0.001, 0.001, 1, 1); - // setVisibleRectangle( 0.001, 0.001, 100000, 1000 ); - setYScale(new Exp()); - m_Border.setSrcdY(Math.log(10)); - m_Border.applyPattern(false, "0.###E0"); - m_log = true; - } else { - m_log = false; - setYScale(null); - ScaledBorder buffer = m_Border; - m_Border = new ScaledBorder(); - m_Border.x_label = buffer.x_label; // "App. " + Name + - // " func. calls"; - m_Border.y_label = buffer.y_label; // "fitness"; - setBorder(m_Border); - } - repaint(); - } - - /** - * Causes all PointSets to interupt the connected painting at the current - * position. - */ - public void jump() { - for (int i = 0; i < m_PointSetContainer.size(); i++) - ((GraphPointSet) (m_PointSetContainer.get(i))).jump(); - } - - // /** - // */ - // public Object openObject() { - // if (m_FileChooser == null) - // createFileChooser(); - // int returnVal = m_FileChooser.showOpenDialog(this); - // if (returnVal == JFileChooser.APPROVE_OPTION) { - // File selected = m_FileChooser.getSelectedFile(); - // try { - // ObjectInputStream oi = new ObjectInputStream(new BufferedInputStream(new - // FileInputStream(selected))); - // Object obj = oi.readObject(); - // oi.close(); - // - // Object[] objects = (Object[]) obj; - // for (int i = 0; i < objects.length; i++) { - // GraphPointSet xx = ((GraphPointSet.SerPointSet) - // objects[i]).getGraphPointSet(); - // xx.initGraph(this); - // addGraphPointSet(xx); - // } - // repaint(); - // return obj; - // } catch (Exception ex) { - // JOptionPane.showMessageDialog(this, - // "Couldn't read object: " - // + selected.getName() - // + "\n" + ex.getMessage(), - // "Open object file", - // JOptionPane.ERROR_MESSAGE); - // } - // } - // return null; - // } - - // /** - // * - // */ - // public void saveObject() { - // Object[] object = new Object[m_PointSetContainer.size()]; - // for (int i = 0; i < m_PointSetContainer.size(); i++) { - // object[i] = ((GraphPointSet) - // m_PointSetContainer.get(i)).getSerPointSet(); - // } - // if (m_FileChooser == null) - // createFileChooser(); - // int returnVal = m_FileChooser.showSaveDialog(this); - // if (returnVal == JFileChooser.APPROVE_OPTION) { - // File sFile = m_FileChooser.getSelectedFile(); - // try { - // ObjectOutputStream oo = new ObjectOutputStream(new - // BufferedOutputStream(new FileOutputStream(sFile))); - // oo.writeObject(object); - // oo.close(); - // } catch (IOException ex) { - // JOptionPane.showMessageDialog(this, - // "Couldn't write to file: " - // + sFile.getName() - // + "\n" + ex.getMessage(), - // "Save object", - // JOptionPane.ERROR_MESSAGE); - // } - // } - // } - - /** - * - */ - protected void createFileChooser() { - m_FileChooser = new JFileChooser(new File("/resources")); - m_FileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + public void addGraphPointSet(GraphPointSet d) { + this.m_PointSetContainer.add(d); } /** @@ -794,14 +138,14 @@ public class FunctionArea extends DArea implements Serializable { .getDPoint(FunctionArea.this.m_x, FunctionArea.this.m_y); DPointIcon icon1 = new DPointIcon() { + public DBorder getDBorder() { + return new DBorder(4, 4, 4, 4); + } + public void paint(Graphics g) { g.drawLine(-2, 0, 2, 0); g.drawLine(0, 0, 0, 4); } - - public DBorder getDBorder() { - return new DBorder(4, 4, 4, 4); - } }; temp.setIcon(icon1); FunctionArea.this.addDElement(temp); @@ -931,6 +275,442 @@ public class FunctionArea extends DArea implements Serializable { this.m_RefPointListener = a; } + /** + * + */ + public void changeColorGraph(int GraphLabel) { + getGraphPointSet(GraphLabel).incColor(); + repaint(); + } + + /** + * + */ + public void changeColorGraph(int x, int y) { + int index = getNearestGraphIndex(x, y); + if (index == -1) + return; + int GraphLabel = ((GraphPointSet) (this.m_PointSetContainer.get(index))) + .getGraphLabel(); + changeColorGraph(GraphLabel); + updateLegend(); + } + + protected boolean checkLoggable() { + double minY = Double.MAX_VALUE; + for (int i = 0; i < m_PointSetContainer.size(); i++) { + DPointSet pSet = (m_PointSetContainer.get(i).getConnectedPointSet()); + if (pSet.getSize() > 0) + minY = Math.min(minY, pSet.getMinYVal()); + } + // if (TRACE) System.out.println("min is " + minY); + return (minY > 0); + } + + protected boolean checkLogValidYValue(double x, double y, int graphLabel) { + if (y <= 0.0) { + if (m_log && notifyNegLog) { + System.err.println("Warning: trying to plot value (" + x + "/" + + y + ") with y <= 0 in logarithmic mode!"); + notifyNegLog = false; + } + return false; + } + return true; + } + + private String cleanBlanks(String str, Character rpl) { + return str.replace(' ', rpl); + } + + /** + * + */ + public void clearAll() { + this.removeAllDElements(); + for (int i = 0; i < m_PointSetContainer.size(); i++) + ((GraphPointSet) (m_PointSetContainer.get(i))).removeAllPoints(); + m_PointSetContainer.clear(); + notifyNegLog = true; + } + + /** + * + */ + public void clearGraph(int graphLabel) { + getGraphPointSet(graphLabel).removeAllPoints(); + m_PointSetContainer.remove(getGraphPointSet(graphLabel)); + repaint(); + notifyNegLog = true; + } + + /** + * + */ + public void clearGraph(int x, int y) { + int index = getNearestGraphIndex(x, y); + if (index == -1) + return; + int GraphLabel = ((GraphPointSet) (this.m_PointSetContainer.get(index))) + .getGraphLabel(); + clearGraph(GraphLabel); + updateLegend(); + } + + /** + * Reset the legend clearing all information. + */ + public void clearLegend() { + setLegend(null); + } + + /** + * + */ + protected void createFileChooser() { + m_FileChooser = new JFileChooser(new File("/resources")); + m_FileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + } + + /** + * Plot a circle icon to the function area which is annotated with a char + * and a double value. + * + * @param c + * @param val + * @param position + * @param graphID + */ + public void drawCircle(char c, double val, double[] position, int graphID) { + drawCircle(c + "" + val, position, graphID); + } + + /** + * Plot a circle icon to the function area which is annotated with a char + * and a double value. + * + * @param c + * @param val + * @param position + */ + public void drawCircle(double val, double[] position, int graphID) { + drawCircle("" + val, position, graphID); + } + + public void drawCircle(String label, double xPos, double yPos, int graphID) { + double[] pos = new double[2]; + pos[0] = xPos; + pos[1] = yPos; + drawCircle(label, pos, graphID); + } + + /** + * Plot a circle icon to the function area which is annotated with a char + * and a double value. The color corresponds to the color of the graph with + * given ID + * + * @param label + * @param position + * @param graphID + */ + public void drawCircle(String label, double[] position, int graphID) { + drawIcon(new Chart2DDPointIconCircle(), label, position, graphID); + } + + /** + * Plot a circle icon to the function area which is annotated with a char + * and a double value. The color corresponds to the color of the graph with + * given ID + * + * @param label + * @param position + * @param graphID + */ + public void drawIcon(DPointIcon theIcon, String label, double[] position, + int graphID) { + DPointSet popRep; + popRep = new DPointSet(); + popRep.addDPoint(new DPoint(position[0], position[1])); + DPointIcon icon = new Chart2DDPointIconText(label); + ((Chart2DDPointIconText) icon).setIcon(theIcon); + ((Chart2DDPointIconText) icon).setColor(getGraphPointSet(graphID) + .getColor()); + popRep.setIcon(icon); + addDElement(popRep); + } + + // public void setConnectedPoint(double x, double y, int GraphLabel) { + // if (m_log == true && y <= 0.0) { + // // y = Double.MIN_VALUE; + // if (notifyNegLog) { + // System.err.println("Warning: trying to plot value (" + x + "/" + y + + // ") with y <= 0 in logarithmic mode! Setting y to " + 1e-30); + // notifyNegLog = false; + // } + // y = 1e-30; + // } + // getGraphPointSet(GraphLabel).addDPoint(x, y); + // + // } + + /** + * Plot an icon to the function area which is annotated with a char and a + * double value. The color corresponds to the color of the graph with given + * ID Icon types are 0: circle, 1: cross, otherwise: point. + * + * @param label + * @param position + * @param graphID + */ + public void drawIcon(int iconType, String label, double[] position, + int graphID) { + DPointIcon theIcon; + switch (iconType) { + case 0: + theIcon = new Chart2DDPointIconCircle(); + break; + case 1: + theIcon = new Chart2DDPointIconCross(); + break; + default: + case 2: + theIcon = new Chart2DDPointIconPoint(); + break; + } + drawIcon(theIcon, label, position, graphID); + } + + /** + * Draw a line with given start and end points. + * + * @param p1 + * @param p2 + */ + public void drawLine(double[] p1, double[] p2) { + DPointSet popRep = new DPointSet(); + popRep.setConnected(true); + popRep.addDPoint(new DPoint(p1[0], p1[1])); + popRep.addDPoint(new DPoint(p2[0], p2[1])); + addDElement(popRep); + } + + /** + * Export contained data to standard output. + * + */ + public void exportToAscii() { + exportToAscii((File) null); + } + + /** + * Export contained data to a file or to standard out if null is given. The + * given File will be overwritten! + * + * @param file + * a File instance or null to export to standard out + * @return true if the export succeeded, else false + */ + public boolean exportToAscii(File file) { + String[] s = null; + int maxSize = 0; + DPointSet maxSet = null; + for (int i = 0; i < m_PointSetContainer.size(); i++) { + // find maximum length of all point sets + if (m_PointSetContainer.get(i).getConnectedPointSet().getSize() > maxSize) { + maxSet = m_PointSetContainer.get(i).getConnectedPointSet(); + maxSize = maxSet.getSize(); + } + } + if (maxSize > 0) { // if there is any data, init string array and set x + // value column + s = new String[maxSize + 1]; + s[0] = "calls"; + for (int j = 1; j <= maxSize; j++) + s[j] = "" + maxSet.getDPoint(j - 1).x; + } else { + System.err.println("Error: no data to export"); + return true; + } + for (int i = 0; i < m_PointSetContainer.size(); i++) { + if (m_PointSetContainer.get(i) instanceof GraphPointSet) { + GraphPointSet set = (GraphPointSet) m_PointSetContainer.get(i); + DPointSet pset = set.getConnectedPointSet(); + s[0] = s[0] + " " + cleanBlanks(set.getInfoString(), '_'); // add + // column + // name + for (int j = 1; j < s.length; j++) { // add column data of place + // holder if no value in + // this set + if ((j - 1) < pset.getSize()) + s[j] = s[j] + " " + pset.getDPoint(j - 1).y; + else + s[j] += " #"; + } + } else + System.err.println("error in FunctionArea::exportToAscii"); + } + if (file == null) { + for (int j = 0; j < s.length; j++) { + System.out.println(s[j]); + } + return true; + } else + try { + PrintWriter out = new PrintWriter(new FileOutputStream(file)); + for (int j = 0; j < s.length; j++) + out.println(s[j]); + out.flush(); + out.close(); + return true; + } catch (Exception e) { + System.err.println("Error on data export:" + e.getMessage()); + return false; + } + } + + /** + * Export contained data to a file with a given String as prefix + * + * @param prefix + * file name prefix + * @return true if the export succeeded, else false + */ + public boolean exportToAscii(String prefix) { + SimpleDateFormat formatter = new SimpleDateFormat( + "E'_'yyyy.MM.dd'_'HH.mm.ss"); + String fname = prefix + "PlotExport_" + formatter.format(new Date()) + + ".txt"; + try { + File f = new File(fname); + f.createNewFile(); + return exportToAscii(f); + } catch (Exception e) { + System.err.println("Error:" + e.getMessage()); + return false; + } + + } + + /** + * + */ + public int getContainerSize() { + return m_PointSetContainer.size(); + } + + /** + * + */ + public String getGraphInfo(int x, int y) { + String ret = ""; + if ((m_PointSetContainer == null) || (m_PointSetContainer.size() == 0)) + return ret; + int minindex = getNearestGraphIndex(x, y); + if (minindex >= 0) + return ((GraphPointSet) (m_PointSetContainer.get(minindex))) + .getInfoString(); + else + return "none"; + } + + /** + * + */ + private GraphPointSet getGraphPointSet(int GraphLabel) { + // System.out.println("looping through " + m_PointSetContainer.size() + + // " point sets..."); + for (int i = 0; i < m_PointSetContainer.size(); i++) { + if (m_PointSetContainer.get(i) instanceof GraphPointSet) { + GraphPointSet xx = (GraphPointSet) (m_PointSetContainer.get(i)); + // System.out.println("looking at "+xx.getGraphLabel()); + if (xx.getGraphLabel() == GraphLabel) { + // System.out.println("match!"); + return xx; + } + } + } + // create new GraphPointSet + GraphPointSet NewPointSet = new GraphPointSet(GraphLabel, this); + // System.out.println("adding new point set " + GraphLabel); + // NewPointSet.setStroke(new BasicStroke( (float)1.0 )); + // addGraphPointSet(NewPointSet); already done within GraphPointSet!!! + return NewPointSet; + } + + /** + * + */ + private DPoint getNearestDPoint(int x, int y) { + // get index of nearest Graph + double distmin = 10000000; + DPoint ret = null; + DPoint point1 = getDMeasures().getDPoint(x, y); + DPoint point2 = null; + double dist = 0; + for (int i = 0; i < m_PointSetContainer.size(); i++) { + if (m_PointSetContainer.get(i) instanceof GraphPointSet) { + GraphPointSet pointset = (GraphPointSet) (m_PointSetContainer + .get(i)); + point2 = pointset.getNearestDPoint(point1); + if (point2 == null) + continue; + dist = (point1.x - point2.x) * (point1.x - point2.x) + + (point1.y - point2.y) * (point1.y - point2.y); + // System.out.println("dist="+dist+"i="+i); + if (dist < distmin) { + distmin = dist; + ret = point2; + } + if ((dist == distmin) + && !(ret.getIcon() instanceof Chart2DDPointIconContent) + && !(ret.getIcon() instanceof InterfaceSelectablePointIcon)) { + distmin = dist; + ret = point2; + } + } + } + return ret; + } + + /** + * + */ + private int getNearestGraphIndex(int x, int y) { + // get index of nearest Graph + double distmin = 10000000; + int minindex = -1; + DPoint point1 = getDMeasures().getDPoint(x, y); + DPoint point2 = null; + double dist = 0; + for (int i = 0; i < m_PointSetContainer.size(); i++) { + GraphPointSet pointset = m_PointSetContainer.get(i); + point2 = pointset.getNearestDPoint(point1); + if (point2 == null) + continue; + if (point1 == null) + System.err.println("point1 == null"); + + dist = (point1.x - point2.x) * (point1.x - point2.x) + + (point1.y - point2.y) * (point1.y - point2.y); + // System.out.println("dist="+dist+"i="+i); + if (dist < distmin) { + distmin = dist; + minindex = i; + } + } + return minindex; + } + + /** + * Returns the number of points within the graph of the given label. + * + * @param index + * @return + */ + public int getPointCount(int label) { + return getGraphPointSet(label).getPointCount(); + } + /** * This method returns the selection listener to the PointIcon * @@ -940,6 +720,74 @@ public class FunctionArea extends DArea implements Serializable { return this.m_RefPointListener; } + /** + * + */ + public boolean isStatisticsGraph(int x, int y) { + boolean ret = false; + if ((m_PointSetContainer == null) || (m_PointSetContainer.size() == 0)) + return ret; + int minindex = getNearestGraphIndex(x, y); + ret = ((GraphPointSet) (m_PointSetContainer.get(minindex))) + .isStatisticsGraph(); + return ret; + } + + /** + * Causes all PointSets to interupt the connected painting at the current + * position. + */ + public void jump() { + for (int i = 0; i < m_PointSetContainer.size(); i++) + ((GraphPointSet) (m_PointSetContainer.get(i))).jump(); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + if (legendBox != null && (m_legend)) + legendBox.paintIn(g, m_Border.getInnerRect(this)); + } + + /** + * + */ + public DPointSet[] printPoints() { + DPointSet[] ret = new DPointSet[m_PointSetContainer.size()]; + for (int i = 0; i < m_PointSetContainer.size(); i++) { + System.out.println(""); + System.out.println("GraphPointSet No " + i); + + ret[i] = ((GraphPointSet) m_PointSetContainer.get(i)).printPoints(); + } + return ret; + + } + + public DPointSet printPoints(int i) { + // for (int i = 0; i < m_PointSetContainer.size();i++) { + System.out.println(""); + System.out.println("GraphPointSet No " + i); + + return ((GraphPointSet) m_PointSetContainer.get(i)).printPoints(); + // } + } + + /** + * + * @param x + * @param y + */ + public void removePoint(int x, int y) { + DPoint point = getNearestDPoint(x, y); + int index = getNearestGraphIndex(x, y); + if (index == -1 || point == null) + return; + GraphPointSet pointset = (GraphPointSet) (this.m_PointSetContainer + .get(index)); + pointset.removePoint(point); + } + /** * This method allows to remove the selection listener to the PointIcon */ @@ -947,6 +795,186 @@ public class FunctionArea extends DArea implements Serializable { this.m_RefPointListener = null; } + /** + * + */ + public void setConnectedPoint(double x, double y, int graphLabel) { + if (!checkLogValidYValue(x, y, graphLabel)) { + if (m_log) + toggleLog(); + } + // if (y <= 0.0) { + // // y = Double.MIN_VALUE; + // if (notifyNegLog) { + // System.err.println("Warning: trying to plot value (" + x + "/" + y + + // ") with y <= 0 in logarithmic mode! Setting y to " + 1e-30); + // notifyNegLog = false; + // } + // y = 1e-30; + // } + getGraphPointSet(graphLabel).addDPoint(x, y); + } + + /** + * + */ + public void setConnectedPoint(double[] p, int graphLabel) { + setConnectedPoint(p[0], p[1], graphLabel); + } + + /** + * + * @param GraphLabel + * @param color + */ + public void setGraphColor(int GraphLabel, Color color) { + this.getGraphPointSet(GraphLabel).setColor(color); + } + + // /** + // */ + // public Object openObject() { + // if (m_FileChooser == null) + // createFileChooser(); + // int returnVal = m_FileChooser.showOpenDialog(this); + // if (returnVal == JFileChooser.APPROVE_OPTION) { + // File selected = m_FileChooser.getSelectedFile(); + // try { + // ObjectInputStream oi = new ObjectInputStream(new BufferedInputStream(new + // FileInputStream(selected))); + // Object obj = oi.readObject(); + // oi.close(); + // + // Object[] objects = (Object[]) obj; + // for (int i = 0; i < objects.length; i++) { + // GraphPointSet xx = ((GraphPointSet.SerPointSet) + // objects[i]).getGraphPointSet(); + // xx.initGraph(this); + // addGraphPointSet(xx); + // } + // repaint(); + // return obj; + // } catch (Exception ex) { + // JOptionPane.showMessageDialog(this, + // "Couldn't read object: " + // + selected.getName() + // + "\n" + ex.getMessage(), + // "Open object file", + // JOptionPane.ERROR_MESSAGE); + // } + // } + // return null; + // } + + // /** + // * + // */ + // public void saveObject() { + // Object[] object = new Object[m_PointSetContainer.size()]; + // for (int i = 0; i < m_PointSetContainer.size(); i++) { + // object[i] = ((GraphPointSet) + // m_PointSetContainer.get(i)).getSerPointSet(); + // } + // if (m_FileChooser == null) + // createFileChooser(); + // int returnVal = m_FileChooser.showSaveDialog(this); + // if (returnVal == JFileChooser.APPROVE_OPTION) { + // File sFile = m_FileChooser.getSelectedFile(); + // try { + // ObjectOutputStream oo = new ObjectOutputStream(new + // BufferedOutputStream(new FileOutputStream(sFile))); + // oo.writeObject(object); + // oo.close(); + // } catch (IOException ex) { + // JOptionPane.showMessageDialog(this, + // "Couldn't write to file: " + // + sFile.getName() + // + "\n" + ex.getMessage(), + // "Save object", + // JOptionPane.ERROR_MESSAGE); + // } + // } + // } + + /** + * + * @param GraphLabel + * @param colorindex + */ + public void setGraphColor(int GraphLabel, int colorindex) { + this.getGraphPointSet(GraphLabel).setColorByIndex(colorindex); + } + + /** + * + */ + public void setInfoString(int GraphLabel, String Info, float stroke) { + getGraphPointSet(GraphLabel).setInfoString(Info, stroke); + } + + /** + * Set a legend for the function area. If null is given, the former legend + * is deactivated. + * + * @param lBox + */ + protected void setLegend(GraphPointSetLegend lBox) { + legendBox = lBox; + if (lBox != null && m_legend) + repaint(); + } + + /** + * + */ + public void setUnconnectedPoint(double x, double y, int GraphLabel) { + if (!checkLogValidYValue(x, y, GraphLabel)) { + if (m_log) + toggleLog(); + } + this.getGraphPointSet(GraphLabel).addDPoint(x, y); + this.getGraphPointSet(GraphLabel).setConnectedMode(false); + repaint(); + } + + public void setUnconnectedPoint(double[] p, int GraphLabel) { + setUnconnectedPoint(p[0], p[1], GraphLabel); + } + + private void toggleLegend() { + m_legend = !m_legend; + repaint(); + } + + /** + * + */ + public void toggleLog() { + // System.out.println("ToggleLog log was: "+m_log); + if (!m_log && !checkLoggable()) { + System.err.println("Cant toggle log with values <= 0!"); + return; + } + if (m_log == false) { + setMinRectangle(0.001, 0.001, 1, 1); + // setVisibleRectangle( 0.001, 0.001, 100000, 1000 ); + setYScale(new Exp()); + m_Border.setSrcdY(Math.log(10)); + m_Border.applyPattern(false, "0.###E0"); + m_log = true; + } else { + m_log = false; + setYScale(null); + ScaledBorder buffer = m_Border; + m_Border = new ScaledBorder(); + m_Border.x_label = buffer.x_label; // "App. " + Name + + // " func. calls"; + m_Border.y_label = buffer.y_label; // "fitness"; + setBorder(m_Border); + } + repaint(); + } + /** * Recreate the legend object with the current point sets. * @@ -955,16 +983,4 @@ public class FunctionArea extends DArea implements Serializable { GraphPointSetLegend lb = new GraphPointSetLegend(m_PointSetContainer); setLegend(lb); } - - /** - * Reset the legend clearing all information. - */ - public void clearLegend() { - setLegend(null); - } - - private void toggleLegend() { - m_legend = !m_legend; - repaint(); - } } diff --git a/src/eva2/gui/GraphPointSet.java b/src/eva2/gui/GraphPointSet.java index c64128cf..e0c4620d 100644 --- a/src/eva2/gui/GraphPointSet.java +++ b/src/eva2/gui/GraphPointSet.java @@ -1,4 +1,5 @@ package eva2.gui; + /* * Title: EvA2 * Description: @@ -13,460 +14,557 @@ package eva2.gui; * IMPORTS *==========================================================================*/ -import java.awt.Color; -import java.awt.Graphics; import java.awt.BasicStroke; +import java.awt.Color; import java.io.Serializable; import java.util.ArrayList; -import java.util.Arrays; -import eva2.tools.chart2d.*; +import eva2.tools.chart2d.DArea; +import eva2.tools.chart2d.DMeasures; +import eva2.tools.chart2d.DPoint; +import eva2.tools.chart2d.DPointIcon; +import eva2.tools.chart2d.DPointSet; import eva2.tools.math.Mathematics; - /*==========================================================================* + +/*==========================================================================* * CLASS DECLARATION *==========================================================================*/ - /** +/** * */ public class GraphPointSet { - private String m_InfoString = "Incomplete_Run"; - private int m_GraphLabel; - private int colorOffset = 0; - private ArrayList m_PointSetContainer = new ArrayList(); - private float m_Stroke = (float) 1.0; - private boolean m_isStatisticsGraph = false; -// private DPointSet m_PointSet_1; -// private DPointSet m_PointSet_2; -// private DPointSet m_PointSet_3; - private DPointSetMultiIcon m_ConnectedPointSet; - private DArea m_Area; - private Color m_Color; - private DPointIcon m_Icon; - private int m_CacheIndex = 0; - private int m_CacheSize = 0; - private double [] m_cachex; - private double [] m_cachey; - /** - * - */ - public GraphPointSet (/*int size*/int GraphLabel, DArea Area) { - //System.out.println("Constructor GraphPointSet "+ GraphLabel); - m_cachex = new double[m_CacheSize]; - m_cachey = new double[m_CacheSize]; - m_Area = Area; - m_GraphLabel = GraphLabel; - m_ConnectedPointSet = new DPointSetMultiIcon(100); -// m_PointSet_1 = new DPointSet(100); -// m_PointSet_2 = new DPointSet(100); -// m_PointSet_3 = new DPointSet(100); - // -// DPointIcon icon1 = new DPointIcon(){ -// public void paint( Graphics g ){ -// g.drawLine(-2, 0, 2, 0); -// g.drawLine(0, 0, 0, 4); -// } -// public DBorder getDBorder(){ return new DBorder(4, 4, 4, 4); } -// }; -// DPointIcon icon2 = new DPointIcon(){ -// public void paint( Graphics g ){ -// g.drawLine(-2, 0, 2, 0); -// g.drawLine(0, 0, 0, -4); -// } -// public DBorder getDBorder(){ return new DBorder(4, 4, 4, 4); } -// }; - // - m_ConnectedPointSet.setStroke(new BasicStroke( m_Stroke )); - m_ConnectedPointSet.setConnected(true); - - setColor(indexToColor(GraphLabel)); - initGraph(Area); - } - - private Color indexToColor(int index) { - Color c = Color.black; - int k = index%10; - switch(k) { - case 0: c = Color.black; break; - case 1: c = Color.red; break; - case 2: c = Color.blue; break; - case 3: c = Color.pink; break; - case 4: c = Color.green; break; - case 5: c = Color.gray; break; - case 6: c = Color.magenta; break; - case 7: c = Color.cyan; break; - case 8: c = Color.orange; break; - case 9: c = Color.darkGray; break; - } - return c; - } - - /** - * Increase the color sequentially. - */ - public void incColor() { - colorOffset++; - setColor(indexToColor(m_GraphLabel+colorOffset)); - } - - public void setColorByIndex(int i) { - setColor(indexToColor(i)); - } - - /** - * - */ - private GraphPointSet (int size,int GraphLabel) { - m_GraphLabel = GraphLabel; - m_cachex = new double[m_CacheSize]; - m_cachey = new double[m_CacheSize]; - m_ConnectedPointSet = new DPointSetMultiIcon(100); -// m_PointSet_1 = new DPointSet(100); -// m_PointSet_2 = new DPointSet(100); -// m_PointSet_3 = new DPointSet(100); - // -// DPointIcon icon1 = new DPointIcon(){ -// public void paint( Graphics g ){ -// g.drawLine(-2, 0, 2, 0); -// g.drawLine(0, 0, 0, 4); -// } -// public DBorder getDBorder(){ return new DBorder(4, 4, 4, 4); } -// }; -// DPointIcon icon2 = new DPointIcon(){ -// public void paint( Graphics g ){ -// g.drawLine(-2, 0, 2, 0); -// g.drawLine(0, 0, 0, -4); -// } -// public DBorder getDBorder(){ return new DBorder(4, 4, 4, 4); } -// }; -// m_PointSet_2.setIcon(icon1); -// m_PointSet_3.setIcon(icon1); - // - m_ConnectedPointSet.setStroke(new BasicStroke( m_Stroke )); + private String m_InfoString = "Incomplete_Run"; + private int m_GraphLabel; + private int colorOffset = 0; + private ArrayList m_PointSetContainer = new ArrayList(); + private float m_Stroke = (float) 1.0; + private boolean m_isStatisticsGraph = false; + // private DPointSet m_PointSet_1; + // private DPointSet m_PointSet_2; + // private DPointSet m_PointSet_3; + private DPointSetMultiIcon m_ConnectedPointSet; + private DArea m_Area; + private Color m_Color; + private DPointIcon m_Icon; + private int m_CacheIndex = 0; + private int m_CacheSize = 0; + private double[] m_cachex; + private double[] m_cachey; - m_ConnectedPointSet.setConnected(true); - m_Color = Color.black; + /** + * + */ + public GraphPointSet(/* int size */int GraphLabel, DArea Area) { + // System.out.println("Constructor GraphPointSet "+ GraphLabel); + m_cachex = new double[m_CacheSize]; + m_cachey = new double[m_CacheSize]; + m_Area = Area; + m_GraphLabel = GraphLabel; + m_ConnectedPointSet = new DPointSetMultiIcon(100); + // m_PointSet_1 = new DPointSet(100); + // m_PointSet_2 = new DPointSet(100); + // m_PointSet_3 = new DPointSet(100); + // + // DPointIcon icon1 = new DPointIcon(){ + // public void paint( Graphics g ){ + // g.drawLine(-2, 0, 2, 0); + // g.drawLine(0, 0, 0, 4); + // } + // public DBorder getDBorder(){ return new DBorder(4, 4, 4, 4); } + // }; + // DPointIcon icon2 = new DPointIcon(){ + // public void paint( Graphics g ){ + // g.drawLine(-2, 0, 2, 0); + // g.drawLine(0, 0, 0, -4); + // } + // public DBorder getDBorder(){ return new DBorder(4, 4, 4, 4); } + // }; + // + m_ConnectedPointSet.setStroke(new BasicStroke(m_Stroke)); + m_ConnectedPointSet.setConnected(true); - m_Color = indexToColor(GraphLabel); + setColor(indexToColor(GraphLabel)); + initGraph(Area); + } - m_ConnectedPointSet.setColor(m_Color); + /** + * + * @param index + * @return + */ + private Color indexToColor(int index) { + Color c = Color.black; + int k = index % 10; + switch (k) { + case 0: + c = Color.black; + break; + case 1: + c = Color.red; + break; + case 2: + c = Color.blue; + break; + case 3: + c = Color.pink; + break; + case 4: + c = Color.green; + break; + case 5: + c = Color.gray; + break; + case 6: + c = Color.magenta; + break; + case 7: + c = Color.cyan; + break; + case 8: + c = Color.orange; + break; + case 9: + c = Color.darkGray; + break; + } + return c; + } - } - /** - * - */ - public DPointSet printPoints() { - for (int i = 0; i < m_ConnectedPointSet.getSize();i++) { - DPoint p = m_ConnectedPointSet.getDPoint(i); - double x = p.x; - double y = p.y; - //System.out.println("point "+i+ " x= "+x+"y= "+y); - } - return m_ConnectedPointSet.getDPointSet(); - } - /** - * - */ - public Color getColor() { - return m_ConnectedPointSet.getColor(); - } - /** - * - */ - public void setColor(Color c) { - m_Color=c; - m_ConnectedPointSet.setColor(m_Color); - } - /** - * - */ - public DPointSet getConnectedPointSet() { - return m_ConnectedPointSet.getDPointSet(); - } - public DPointSetMultiIcon getReference2ConnectedPointSet() { - return m_ConnectedPointSet; - } + /** + * Increase the color sequentially. + */ + public void incColor() { + colorOffset++; + setColor(indexToColor(m_GraphLabel + colorOffset)); + } - /** - * - */ - public void initGraph (DArea Area) { - m_Area = Area; - m_Area.addDElement(m_ConnectedPointSet); - ((FunctionArea)m_Area).addGraphPointSet(this); -// m_Area.addDElement(m_PointSet_1); -// m_Area.addDElement(m_PointSet_2); -// m_Area.addDElement(m_PointSet_3); -// DPointIcon icon1 = new DPointIcon(){ -// public void paint( Graphics g ){ -// g.drawLine(-2, 0, 2, 0); -// g.drawLine(0, 0, 0, 4); -// } -// public DBorder getDBorder(){ return new DBorder(4, 4, 4, 4); } -// }; -// DPointIcon icon2 = new DPointIcon(){ -// public void paint( Graphics g ){ -// g.drawLine(-2, 0, 2, 0); -// g.drawLine(0, 0, 0, -4); -// } -// public DBorder getDBorder(){ return new DBorder(4, 4, 4, 4); } -// }; - } - /** - * - */ - public DPoint getNearestDPoint(DPoint p) { - return m_ConnectedPointSet.getNearestDPoint(p); - } - - /** - * Causes the PointSet to interupt the connected painting at the - * current position. - */ - public void jump() { - m_ConnectedPointSet.jump(); - } - /** - * - */ - public void removeAllPoints() { - m_ConnectedPointSet.removeAllPoints(); -// m_PointSet_1.removeAllPoints(); -// m_PointSet_2.removeAllPoints(); -// m_PointSet_3.removeAllPoints(); - } - /** - * - */ - public void addDPoint(double x,double y) { - //System.out.println(" "+x+" "+y); - if (m_CacheIndex==m_CacheSize) { - for (int i=0;iDRectangle in DArea coordinates - */ - public void setVisibleRectangle( DRectangle rect ){ - if( TRACE )System.out.println("DArea.setVisibleRectangle(DRectangle)"); - if( rect.isEmpty() ) throw - new IllegalArgumentException( - "You shopuld never try to set an empty rectangle\n" - + "as the visible rectangle of an DArea" ); - - if( !rect.equals( visible_rect ) && rect.getWidth() > 0 && rect.getHeight() > 0 ){ - auto_focus = false; - visible_rect = (DRectangle)rect.clone(); - repaint(); - } - } - - /** - * sets the minimal rectangle - * - * @param x - * @param y - * @param width - * @param height - */ - public void setMinRectangle( double x, double y, double width, double height ){ - setMinRectangle( new DRectangle( x, y, width, height ) ); - } - - /** - * sets the minimal rectangle - * - * @param rect the visible DRectangle in DArea coordinates - */ - public void setMinRectangle( DRectangle rect ){ - if( rect.isEmpty() ) min_rect = DEFAULT_MIN_RECT; - else min_rect = (DRectangle)rect.clone(); - } - - /** - * method returns the minimal rectangle which is set as the visible when all - * elements are removed and the area is on auto focus - * - * @return the minmal rectangle - */ - public DRectangle getMinRectangle(){ - return (DRectangle)min_rect.clone(); - } - -// /** -// * method sets the maximal rectangle whioch can be viewed with the -// * DArea. This method can be used if the area is used with scale functions -// * which are not invertible on all reals -// * -// * @param x the minmal x value -// * @param y the minmal y value -// * @param width of the maximal rectangle -// * @param height of the maximal rectangle -// */ -// public void setMaxRectangle( double x, double y, double width, double height ){ -// setMaxRectangle( new DRectangle( x, y, width, height ) ); -// } - - -// /** -// * method sets the maximal rectangle whioch can be viewed with the -// * DArea. This method can be used if the area is used with scale functions -// * which are not invertible on all reals -// * -// * @param the rect maximal rectangle of the DArea -// * @deprecated see setMinX, setMinY, setMaxX, setMaxY -// */ -// public void setMaxRectangle( DRectangle rect ){ -// if( !rect.contains( min_rect ) ) throw -// new IllegalArgumentException("Maximal rectangle does not contain minmal rectangle"); -// -// setMinX( rect.x ); -// setMinY( rect.y ); -// setMaxX( rect.x + rect.width ); -// setMaxY( rect.y + rect.height ); -// } - - /** - * method returns the maximal rectangle of the area - * - * @return the maximal rectangle - * @deprecated see getMaxX, getMaxY, getMinX, getMinY - */ - public DRectangle getMaxRectangle(){ - return new DRectangle(min_x.doubleValue(), - min_y.doubleValue(), - max_x.doubleValue() - min_x.doubleValue(), - max_y.doubleValue() - min_y.doubleValue() ); - } - - /** - * method sets the minimal x-value which can be displayed by the DArea - * might be helpful, if scale functions are used which are not defined overall - * - * @param mix the minimal x-value - */ - public void setMinX( double mix ){ - if( mix > min_rect.getX() ) throw - new IllegalArgumentException( - "Mimimal y-value axes intersects minmal rectangle."); - min_x = new Double( mix ); - } - - /** - * method resets the minimal x-value - */ - public void releaseMinX(){ - min_x = null; - } - - /** - * method returns the minmal x-value which can be displayed in the DArea - * - * @return the minmal x-value - */ - public double getMinX(){ - if( min_x != null ) return min_x.doubleValue(); - return 0; - } - - - /** - * method sets the minimal y-value which can be displayed by the DArea - * might be helpful, if scale functions are used which are not defined overall - * - * @param miy the minimal y-value - */ - public void setMinY( double miy ){ - if( miy > min_rect.getY() ) throw - new IllegalArgumentException( - "Mimimal y-value axes intersects minmal rectangle."); - min_y = new Double( miy ); - } - - /** - * method resets the minimal y-value - */ - public void releaseMinY(){ - min_y = null; - } - - /** - * method returns the minmal y-value which can be displayed in the DArea - * - * @return the minmal y-value - */ - public double getMinY(){ - if( min_y != null ) return min_y.doubleValue(); - return 0; - } - - - - /** - * method sets the maximal x-value which can be displayed by the DArea - * might be helpful, if scale functions are used which are not defined overall - * - * @param max the maximal x-value - */ - public void setMaxX( double max ){ - if( max < min_rect.getX() + min_rect.getWidth() ) throw - new IllegalArgumentException( - "Maximal x-value axes intersects minmal rectangle."); - max_x = new Double( max ); - } - - /** - * method resets the maximal x-value - */ - public void releaseMaxX(){ - max_x = null; - } - - /** - * method returns the maxmal x-value which can be displayed in the DArea - * - * @return the maxmal x-value - */ - public double getMaxX(){ - if( max_x != null ) return max_x.doubleValue(); - return 0; - } - - - - /** - * method sets the maximal y-values which can be displayed by the DArea - * might be helpful, if scale functions are used which are not defined overall - * - * @param may the maximal y-value - */ - public void setMaxY( double may ){ - if( may < min_rect.getY() + min_rect.getHeight() ) throw - new IllegalArgumentException( - "Maximal y-value axes intersects minmal rectangle."); - max_y = new Double( may ); - } - - /** - * method resets the maximal y-value - */ - public void releaseMaxY(){ - max_y = null; - } - - /** - * method returns the maximal y-value which can be displayed in the DArea - * - * @return the maximal y-value - */ - public double getMaxY(){ - if( max_y != null ) return max_y.doubleValue(); - return 0; - } - - - /** - * paints the DArea by a Graphics object - * - * @param g the java.awt.Graphics object - */ - public void paint( Graphics g ){ - if( TRACE ) System.out.println("DArea.paint(Graphics)"); - if( auto_focus ) { - container.restore(); - visible_rect = (DRectangle)container.getRectangle().clone(); -// grid.updateDistByRect(visible_rect); - } - if( visible_rect.isEmpty() ) { - visible_rect = (DRectangle)min_rect.clone(); -// grid.updateDistByRect(visible_rect); - } - super.paint( g ); - - measures.setGraphics( g ); - if( grid.isVisible() && !grid_to_front ) paintGrid( measures ); - container.paint( measures ); - if( grid.isVisible() && grid_to_front ) paintGrid( measures ); - } - - /** - * repaints a part of the visible area - * - * @param r the rectangle to repaint - */ - public void repaint( DRectangle r ){ - if( TRACE ) System.out.println("DArea.repaint(DRectangle)"+r); - if( r == null ) throw - new IllegalArgumentException("Cannot repaint a null DRectangle"); - if( r.isAll() || auto_focus ) repaint(); - else{ - Point p1 = measures.getPoint( r.getX(), r.getY() ), - p2 = measures.getPoint( r.getX() + r.getWidth(), r.getY() + r.getHeight()); -// Point p1 = measures.getPoint( r.x, r.y ), -// p2 = measures.getPoint( r.x + r.width, r.y + r.height); - if( p1 == null || p2 == null ) repaint(); - else { - DBorder b = getDBorder(); - repaint( p1.x - b.left, - p2.y - b.top, - p2.x - p1.x + 1 + b.left + b.right, - p1.y - p2.y + 1 + b.top + b.bottom ); - } - } - } - - /** - * adds a new component to the area - * - * @param e the new DElement - */ - public void addDElement( DElement e ){ - container.addDElement( e ); - } - - /** - * removes a certain element from the area - * - * @param e the element to remove - */ - public boolean removeDElement( DElement e ){ - return container.removeDElement( e ); - } - - /** - * removes all elements from the area - */ - public void removeAllDElements() - { - visible_rect = (DRectangle)min_rect.clone(); - container.removeAllDElements(); - } - - /** - * returnes all DElements in the container - * - * @return the elements of the container - */ - public DElement[] getDElements(){ - return container.getDElements(); - } - - /** - * method returns true, if the given element is contained in the container - * - * @param e the element - * @return if it is contained - */ - public boolean contains( DElement e ){ - return container.contains( e ); - } - - - /** - * sets the grid visible or not - * - * @param aFlag visible or not - */ - public void setGridVisible( boolean aFlag ){ - if( TRACE ) System.out.println("DArea.setGridVisisble: "+aFlag); - grid.rectangle = getDRectangle(); - grid.setVisible( aFlag ); - } - - /** - * returns if the grid is visible - * true if the grid is visible or false if not - * - * @return true or false - */ - public boolean isGridVisible(){ - return grid.isVisible(); - } - - /** - * sets the grid to the front - * that means that the grid is painted as last element - * default value is false - * - * @param aFlag grid t front or not - */ - public void setGridToFront( boolean aFlag ){ - boolean old = grid_to_front; - grid_to_front = aFlag; - if( old != aFlag && grid.isVisible() ) repaint(); - } - - /** - * sets the grid's horizontal and vertical distance - * that means that the grid's lines will have these distances - * in area coordinates - * - * @param hor_dist the horizontal distance - * @param ver_dist the vertical distance - */ - public void setGrid( double hor_dist, double ver_dist ){ - grid = new DGrid( visible_rect, hor_dist, ver_dist ); - grid.setDParent( this ); - auto_grid = false; - repaint(); - } - - /** - * sets the auto grid on or off - * if it's on, the grid's distances (@see #setGrid(double, double)) - * are automatically calculated - * - * @param b auto grid on or not - */ - public void setAutoGrid( boolean b ){ - if( b ) { - grid.rectangle = getDRectangle(); - grid.setVisible( true ); - } - if( b == auto_grid ) return; - auto_grid = b; - repaint(); - } - - /** - * returns if the auto grid is switched on - * - * @return true if the grid is on, else false - */ - public boolean hasAutoGrid(){ return auto_grid; } - - /** - * sets the color of the grid - * - * @param java.awt.Color - */ - public void setGridColor( Color color ){ - grid.setColor( color ); - } - - /** - * sets the maximal number of grid lines - * default value is 10 - * - * @param no maximal number of grid lines - */ - public void setMaxGrid( int no ){ - if( no < 1 ) return; - int old = max_grid; - max_grid = no; - if( old != no ) repaint(); - } - - /** - * prints the area and it's content - * @see java.awt.print.Printable and - * @see java.awt.print.PrintJob - * - * @param g the Graphics object - * @param pf the @see java.awt.print.PageFormat - * @param pi the page index - * - * @return int @see java.awt.print.Printable - */ - public int print( Graphics g, PageFormat pf, int pi ){ - if( TRACE ) System.out.println("DArea.print(...)"); - if( pi > 0 ) return Printable.NO_SUCH_PAGE; - - Border sb = getBorder(); - if( !(sb instanceof ScaledBorder) ) sb = null; - else ( (ScaledBorder)sb ).show_outer_border = false; - PagePrinter printer = new PagePrinter( this, g, pf ); - int ret = printer.print(); - if( sb != null ) ( (ScaledBorder)sb ).show_outer_border = true; - return ret; - } - - /** - * sets a new scale function to the x-axis - * That means that not the standard linear scale is shown but the image - * of the linear scale under the given function - * - * @param x_s the scale function for the x-axis - */ - public void setXScale( DFunction x_s ){ - if( x_s == null && measures.x_scale == null ) return; - measures.x_scale = x_s; - repaint(); - } - - - /** - * sets a new scale function to the y-axis - * That means that not the standard linear scale is shown but the image - * of the linear scale under the given function - * - * @param y_s the scale function for the y-axis - */ - public void setYScale( DFunction y_s ){ - if( y_s == null && measures.y_scale == null ) return; - measures.y_scale = y_s; - repaint(); - } - - /** - * returns the measures of the DArea - * The DMeasures object calculates the different coodinates and contains a - * Graphics object to paint the DElements of the area - * - * @return the measures of the DArea - */ - public DMeasures getDMeasures(){ - return measures; - } - - /** - * method 'adds' a certain border around the contained rectangle - * that means that it takes the old border - * and takes the maxima of the old and the new values - * - * @param clip the java.awt.Insets object of the new clip - */ - public void addDBorder( DBorder b ){ - dborder.insert(b); - } - - /** - * method returns the current border around the rectangle - * - * @return the border - */ - public DBorder getDBorder(){ - return dborder; - } - - public void restoreBorder(){ - dborder = container.getDBorder(); - if( TRACE ) System.out.println("DArea.restoreBorder -> "+dborder); - } - - /** - * method paints the grid - * how the method paints the grid depends on whether the area is wrapped in a - * ScaledBorder or not and on the auto_grid option - */ - private void paintGrid( DMeasures m ){ - if( TRACE ) System.out.println("DArea.paintGrid(DMeasures)"); - grid.rectangle = getDRectangle(); - if( auto_grid ){ - Border b = getBorder(); - if( b instanceof ScaledBorder ){ - ScaledBorder sb = (ScaledBorder)b; - paintGrid( sb, m ); - return; - } - else{ - grid.setDistances(ScaledBorder.aBitBigger( grid.rectangle.getWidth() / max_grid ), - ScaledBorder.aBitBigger( grid.rectangle.getHeight() / max_grid )); - } - } - grid.paint( m ); - } - - - /** - * paints the grid when auto_grid is selected and the area is surrounded - * by an instance of ScaledBorder - * - * @param sb the ScaledBorder around the area - * @param m the measures of the area - */ - private void paintGrid(ScaledBorder sb, DMeasures m){ - if( TRACE ) System.out.println("DArea.paintGrid(ScaledBorder, DMeasures)"); - Dimension d = getSize(); - FontMetrics fm = m.getGraphics().getFontMetrics(); - grid.setDistances(sb.getSrcdX(fm, d), sb.getSrcdY(fm, d)); - - if( m.x_scale == null && m.y_scale == null ) grid.paint( m ); - - else{// selber malen - Graphics g = m.g; - g.setColor( grid.getColor() ); - - SlimRect rect = getSlimRectangle(); - SlimRect src_rect = m.getSourceOf( rect ); - - int x = (int)(src_rect.x / grid.getHorDist()), - y = (int)(src_rect.y / grid.getVerDist()); - if( x * grid.getHorDist() < src_rect.x ) x++; - if( y * grid.getVerDist() < src_rect.y ) y++; - -// DPoint min = new DPoint( rect.x, rect.y ), -// max = new DPoint( min.x + rect.width, min.y + rect.height ); - double minx=rect.x, miny=rect.y, maxx=minx+rect.width, maxy=miny+rect.height; - - double pos; - - for( ; (pos = x * grid.getHorDist()) < src_rect.x + src_rect.width; x++ ){ - if( m.x_scale != null ) pos = m.x_scale.getImageOf( pos ); - Point p1 = m.getPoint( pos, miny ), - p2 = m.getPoint( pos, maxy ); - g.drawLine( p1.x, p1.y, p2.x, p2.y ); - } - - for( ; (pos = y * grid.getVerDist()) < src_rect.y + src_rect.height; y++ ){ - if( m.y_scale != null ) pos = m.y_scale.getImageOf( pos ); - Point p1 = m.getPoint( minx, pos ), - p2 = m.getPoint( maxx, pos ); - g.drawLine( p1.x, p1.y, p2.x, p2.y ); - } - } - } + private static final boolean TRACE = false; + + private boolean auto_focus = false, auto_grid = false, + grid_to_front = false; + + /** + * the container in which all DElements of the area are contained except the + * grid + */ + private DContainer container; + + private DBorder dborder = new DBorder(); + + /** + * the grid of the area + */ + private DGrid grid; + + /** + * maximal number of grid lines + */ + private int max_grid = 10; + + /** + * the measures of the area it calculates the coordinates + */ + protected DMeasures measures; + + /** + * min_rectangle is set, when all elements are removed the intersection of + * visible_rect and max_rectangle is the currently visible rectangle + */ + protected DRectangle min_rect = DEFAULT_MIN_RECT, + visible_rect = DEFAULT_MIN_RECT; + + protected Double min_x, min_y, max_x, max_y; + + /** + * initializes the DArea with the initial capacity of 10 components + */ + public DArea() { + this(10); + } + + /** + * initializes the DArea with the specialized initial capacity of components + * (@see java.util.Vector) + * + * @param the + * initial capacity + */ + public DArea(int initial_capacity) { + container = new DContainer(); + container.setDParent(this); + grid = new DGrid(visible_rect, 1, 1); + grid.setVisible(false); + grid.setDParent(this); + measures = new DMeasures(this); + } + + /** + * method 'adds' a certain border around the contained rectangle that means + * that it takes the old border and takes the maxima of the old and the new + * values + * + * @param clip + * the java.awt.Insets object of the new clip + */ + public void addDBorder(DBorder b) { + dborder.insert(b); + } + + /** + * adds a new component to the area + * + * @param e + * the new DElement + */ + public void addDElement(DElement e) { + container.addDElement(e); + } + + /** + * method returns true, if the given element is contained in the container + * + * @param e + * the element + * @return if it is contained + */ + public boolean contains(DElement e) { + return container.contains(e); + } + + /** + * method returns the current border around the rectangle + * + * @return the border + */ + public DBorder getDBorder() { + return dborder; + } + + /** + * returnes all DElements in the container + * + * @return the elements of the container + */ + public DElement[] getDElements() { + return container.getDElements(); + } + + /** + * returns the measures of the DArea The DMeasures object calculates the + * different coodinates and contains a Graphics object to paint the + * DElements of the area + * + * @return the measures of the DArea + */ + public DMeasures getDMeasures() { + return measures; + } + + /** + * returns the currently visible rectangle in DArea coordinates + * + * @return DRectangle the size and position of the visible area + */ + public DRectangle getDRectangle() { + DRectangle rect = (DRectangle) visible_rect.clone(); + if (min_x != null) + rect.setX(Math.max(rect.getX(), getMinX())); + if (min_y != null) + rect.setY(Math.max(rect.getY(), getMinY())); + if (max_x != null) + rect.setWidth(Math.min(rect.getWidth(), getMaxX() - getMinX())); + if (max_y != null) + rect.setHeight(Math.min(rect.getHeight(), getMaxY() - getMinY())); + return rect; + } + + /** + * method returns the maximal rectangle of the area + * + * @return the maximal rectangle + * @deprecated see getMaxX, getMaxY, getMinX, getMinY + */ + public DRectangle getMaxRectangle() { + return new DRectangle(min_x.doubleValue(), min_y.doubleValue(), max_x + .doubleValue() + - min_x.doubleValue(), max_y.doubleValue() + - min_y.doubleValue()); + } + + /** + * method returns the maxmal x-value which can be displayed in the DArea + * + * @return the maxmal x-value + */ + public double getMaxX() { + if (max_x != null) + return max_x.doubleValue(); + return 0; + } + + // /** + // * method sets the maximal rectangle whioch can be viewed with the + // * DArea. This method can be used if the area is used with scale functions + // * which are not invertible on all reals + // * + // * @param x the minmal x value + // * @param y the minmal y value + // * @param width of the maximal rectangle + // * @param height of the maximal rectangle + // */ + // public void setMaxRectangle( double x, double y, double width, double + // height ){ + // setMaxRectangle( new DRectangle( x, y, width, height ) ); + // } + + // /** + // * method sets the maximal rectangle whioch can be viewed with the + // * DArea. This method can be used if the area is used with scale functions + // * which are not invertible on all reals + // * + // * @param the rect maximal rectangle of the DArea + // * @deprecated see setMinX, setMinY, setMaxX, setMaxY + // */ + // public void setMaxRectangle( DRectangle rect ){ + // if( !rect.contains( min_rect ) ) throw + // new + // IllegalArgumentException("Maximal rectangle does not contain minmal rectangle"); + // + // setMinX( rect.x ); + // setMinY( rect.y ); + // setMaxX( rect.x + rect.width ); + // setMaxY( rect.y + rect.height ); + // } + + /** + * method returns the maximal y-value which can be displayed in the DArea + * + * @return the maximal y-value + */ + public double getMaxY() { + if (max_y != null) + return max_y.doubleValue(); + return 0; + } + + /** + * method returns the minimal rectangle which is set as the visible when all + * elements are removed and the area is on auto focus + * + * @return the minmal rectangle + */ + public DRectangle getMinRectangle() { + return (DRectangle) min_rect.clone(); + } + + /** + * method returns the minmal x-value which can be displayed in the DArea + * + * @return the minmal x-value + */ + public double getMinX() { + if (min_x != null) + return min_x.doubleValue(); + return 0; + } + + /** + * method returns the minmal y-value which can be displayed in the DArea + * + * @return the minmal y-value + */ + public double getMinY() { + if (min_y != null) + return min_y.doubleValue(); + return 0; + } + + /** + * returns the currently visible rectangle in DArea coordinates + * + * @return DRectangle the size and position of the visible area + */ + public SlimRect getSlimRectangle() { + SlimRect srect = new SlimRect(visible_rect.getX(), visible_rect.getY(), + visible_rect.getWidth(), visible_rect.getHeight()); + if (min_x != null) + srect.x = Math.max(srect.x, getMinX()); + if (min_y != null) + srect.y = Math.max(srect.y, getMinY()); + if (max_x != null) + srect.width = Math.min(srect.width, getMaxX() - getMinX()); + if (max_y != null) + srect.height = Math.min(srect.height, getMaxY() - getMinY()); + return srect; + } + + /** + * returns if the auto grid is switched on + * + * @return true if the grid is on, else false + */ + public boolean hasAutoGrid() { + return auto_grid; + } + + /** + * returns if the grid is visible true if the grid is visible + * or false if not + * + * @return true or false + */ + public boolean isGridVisible() { + return grid.isVisible(); + } + + /** + * returns whether the DArea's auto focus is on or not + * + * @return true or false + */ + public boolean isOnAutoFocus() { + return auto_focus; + } + + /** + * paints the DArea by a Graphics object + * + * @param g + * the java.awt.Graphics object + */ + public void paint(Graphics g) { + if (TRACE) + System.out.println("DArea.paint(Graphics)"); + if (auto_focus) { + container.restore(); + visible_rect = (DRectangle) container.getRectangle().clone(); + // grid.updateDistByRect(visible_rect); + } + if (visible_rect.isEmpty()) { + visible_rect = (DRectangle) min_rect.clone(); + // grid.updateDistByRect(visible_rect); + } + super.paint(g); + + measures.setGraphics(g); + if (grid.isVisible() && !grid_to_front) + paintGrid(measures); + container.paint(measures); + if (grid.isVisible() && grid_to_front) + paintGrid(measures); + } + + /** + * method paints the grid how the method paints the grid depends on whether + * the area is wrapped in a ScaledBorder or not and on the + * auto_grid option + */ + private void paintGrid(DMeasures m) { + if (TRACE) + System.out.println("DArea.paintGrid(DMeasures)"); + grid.rectangle = getDRectangle(); + if (auto_grid) { + Border b = getBorder(); + if (b instanceof ScaledBorder) { + ScaledBorder sb = (ScaledBorder) b; + paintGrid(sb, m); + return; + } else { + grid.setDistances(ScaledBorder.aBitBigger(grid.rectangle + .getWidth() + / max_grid), ScaledBorder.aBitBigger(grid.rectangle + .getHeight() + / max_grid)); + } + } + grid.paint(m); + } + + /** + * paints the grid when auto_grid is selected and the area is surrounded by + * an instance of ScaledBorder + * + * @param sb + * the ScaledBorder around the area + * @param m + * the measures of the area + */ + private void paintGrid(ScaledBorder sb, DMeasures m) { + if (TRACE) + System.out.println("DArea.paintGrid(ScaledBorder, DMeasures)"); + Dimension d = getSize(); + FontMetrics fm = m.getGraphics().getFontMetrics(); + grid.setDistances(sb.getSrcdX(fm, d), sb.getSrcdY(fm, d)); + + if (m.x_scale == null && m.y_scale == null) + grid.paint(m); + + else {// selber malen + Graphics g = m.g; + g.setColor(grid.getColor()); + + SlimRect rect = getSlimRectangle(); + SlimRect src_rect = m.getSourceOf(rect); + + int x = (int) (src_rect.x / grid.getHorDist()), y = (int) (src_rect.y / grid + .getVerDist()); + if (x * grid.getHorDist() < src_rect.x) + x++; + if (y * grid.getVerDist() < src_rect.y) + y++; + + // DPoint min = new DPoint( rect.x, rect.y ), + // max = new DPoint( min.x + rect.width, min.y + rect.height ); + double minx = rect.x, miny = rect.y, maxx = minx + rect.width, maxy = miny + + rect.height; + + double pos; + + for (; (pos = x * grid.getHorDist()) < src_rect.x + src_rect.width; x++) { + if (m.x_scale != null) + pos = m.x_scale.getImageOf(pos); + Point p1 = m.getPoint(pos, miny), p2 = m.getPoint(pos, maxy); + g.drawLine(p1.x, p1.y, p2.x, p2.y); + } + + for (; (pos = y * grid.getVerDist()) < src_rect.y + src_rect.height; y++) { + if (m.y_scale != null) + pos = m.y_scale.getImageOf(pos); + Point p1 = m.getPoint(minx, pos), p2 = m.getPoint(maxx, pos); + g.drawLine(p1.x, p1.y, p2.x, p2.y); + } + } + } + + /** + * prints the area and it's content + * + * @see java.awt.print.Printable and + * @see java.awt.print.PrintJob + * + * @param g + * the Graphics object + * @param pf + * the @see java.awt.print.PageFormat + * @param pi + * the page index + * + * @return int @see java.awt.print.Printable + */ + public int print(Graphics g, PageFormat pf, int pi) { + if (TRACE) + System.out.println("DArea.print(...)"); + if (pi > 0) + return Printable.NO_SUCH_PAGE; + + Border sb = getBorder(); + if (!(sb instanceof ScaledBorder)) + sb = null; + else + ((ScaledBorder) sb).show_outer_border = false; + PagePrinter printer = new PagePrinter(this, g, pf); + int ret = printer.print(); + if (sb != null) + ((ScaledBorder) sb).show_outer_border = true; + return ret; + } + + /** + * method resets the maximal x-value + */ + public void releaseMaxX() { + max_x = null; + } + + /** + * method resets the maximal y-value + */ + public void releaseMaxY() { + max_y = null; + } + + /** + * method resets the minimal x-value + */ + public void releaseMinX() { + min_x = null; + } + + /** + * method resets the minimal y-value + */ + public void releaseMinY() { + min_y = null; + } + + /** + * removes all elements from the area + */ + public void removeAllDElements() { + visible_rect = (DRectangle) min_rect.clone(); + container.removeAllDElements(); + } + + /** + * removes a certain element from the area + * + * @param e + * the element to remove + */ + public boolean removeDElement(DElement e) { + return container.removeDElement(e); + } + + /** + * repaints a part of the visible area + * + * @param r + * the rectangle to repaint + */ + public void repaint(DRectangle r) { + if (TRACE) + System.out.println("DArea.repaint(DRectangle)" + r); + if (r == null) + throw new IllegalArgumentException( + "Cannot repaint a null DRectangle"); + if (r.isAll() || auto_focus) + repaint(); + else { + Point p1 = measures.getPoint(r.getX(), r.getY()), p2 = measures + .getPoint(r.getX() + r.getWidth(), r.getY() + r.getHeight()); + // Point p1 = measures.getPoint( r.x, r.y ), + // p2 = measures.getPoint( r.x + r.width, r.y + r.height); + if (p1 == null || p2 == null) + repaint(); + else { + DBorder b = getDBorder(); + repaint(p1.x - b.left, p2.y - b.top, p2.x - p1.x + 1 + b.left + + b.right, p1.y - p2.y + 1 + b.top + b.bottom); + } + } + } + + public void restoreBorder() { + dborder = container.getDBorder(); + if (TRACE) + System.out.println("DArea.restoreBorder -> " + dborder); + } + + /** + * switches the auto focus of this DArea on or off + * + * @param b + * on or off + */ + public void setAutoFocus(boolean b) { + boolean old = auto_focus; + auto_focus = b; + if (old != b) + repaint(); + } + + /** + * sets the auto grid on or off if it's on, the grid's distances (@see + * #setGrid(double, double)) are automatically calculated + * + * @param b + * auto grid on or not + */ + public void setAutoGrid(boolean b) { + if (b) { + grid.rectangle = getDRectangle(); + grid.setVisible(true); + } + if (b == auto_grid) + return; + auto_grid = b; + repaint(); + } + + /** + * sets the grid's horizontal and vertical distance that means that the + * grid's lines will have these distances in area coordinates + * + * @param hor_dist + * the horizontal distance + * @param ver_dist + * the vertical distance + */ + public void setGrid(double hor_dist, double ver_dist) { + grid = new DGrid(visible_rect, hor_dist, ver_dist); + grid.setDParent(this); + auto_grid = false; + repaint(); + } + + /** + * sets the color of the grid + * + * @param java + * .awt.Color + */ + public void setGridColor(Color color) { + grid.setColor(color); + } + + /** + * sets the grid to the front that means that the grid is painted as last + * element default value is false + * + * @param aFlag + * grid t front or not + */ + public void setGridToFront(boolean aFlag) { + boolean old = grid_to_front; + grid_to_front = aFlag; + if (old != aFlag && grid.isVisible()) + repaint(); + } + + /** + * sets the grid visible or not + * + * @param aFlag + * visible or not + */ + public void setGridVisible(boolean aFlag) { + if (TRACE) + System.out.println("DArea.setGridVisisble: " + aFlag); + grid.rectangle = getDRectangle(); + grid.setVisible(aFlag); + } + + /** + * sets the maximal number of grid lines default value is 10 + * + * @param no + * maximal number of grid lines + */ + public void setMaxGrid(int no) { + if (no < 1) + return; + int old = max_grid; + max_grid = no; + if (old != no) + repaint(); + } + + /** + * method sets the maximal x-value which can be displayed by the DArea might + * be helpful, if scale functions are used which are not defined overall + * + * @param max + * the maximal x-value + */ + public void setMaxX(double max) { + if (max < min_rect.getX() + min_rect.getWidth()) + throw new IllegalArgumentException( + "Maximal x-value axes intersects minmal rectangle."); + max_x = new Double(max); + } + + /** + * method sets the maximal y-values which can be displayed by the DArea + * might be helpful, if scale functions are used which are not defined + * overall + * + * @param may + * the maximal y-value + */ + public void setMaxY(double may) { + if (may < min_rect.getY() + min_rect.getHeight()) + throw new IllegalArgumentException( + "Maximal y-value axes intersects minmal rectangle."); + max_y = new Double(may); + } + + /** + * sets the minimal rectangle + * + * @param x + * @param y + * @param width + * @param height + */ + public void setMinRectangle(double x, double y, double width, double height) { + setMinRectangle(new DRectangle(x, y, width, height)); + } + + /** + * sets the minimal rectangle + * + * @param rect + * the visible DRectangle in DArea coordinates + */ + public void setMinRectangle(DRectangle rect) { + if (rect.isEmpty()) + min_rect = DEFAULT_MIN_RECT; + else + min_rect = (DRectangle) rect.clone(); + } + + /** + * method sets the minimal x-value which can be displayed by the DArea might + * be helpful, if scale functions are used which are not defined overall + * + * @param mix + * the minimal x-value + */ + public void setMinX(double mix) { + if (mix > min_rect.getX()) + throw new IllegalArgumentException( + "Mimimal y-value axes intersects minmal rectangle."); + min_x = new Double(mix); + } + + /** + * method sets the minimal y-value which can be displayed by the DArea might + * be helpful, if scale functions are used which are not defined overall + * + * @param miy + * the minimal y-value + */ + public void setMinY(double miy) { + if (miy > min_rect.getY()) + throw new IllegalArgumentException( + "Mimimal y-value axes intersects minmal rectangle."); + min_y = new Double(miy); + } + + /** + * sets the visible rectangle to this size + * + * @param x + * the x coordinate of the left border + * @param y + * the y coordinate of the bottom border + * @param width + * the width of the area + * @param height + * the height of the area + */ + public void setVisibleRectangle(double x, double y, double width, + double height) { + // System.out.println("DArea.setVisibleRectangle(...)"); + setVisibleRectangle(new DRectangle(x, y, width, height)); + } + + /** + * sets the visible rectangle + * + * @param rect + * the visible DRectangle in DArea coordinates + */ + public void setVisibleRectangle(DRectangle rect) { + if (TRACE) + System.out.println("DArea.setVisibleRectangle(DRectangle)"); + if (rect.isEmpty()) + throw new IllegalArgumentException( + "You shopuld never try to set an empty rectangle\n" + + "as the visible rectangle of an DArea"); + + if (!rect.equals(visible_rect) && rect.getWidth() > 0 + && rect.getHeight() > 0) { + auto_focus = false; + visible_rect = (DRectangle) rect.clone(); + repaint(); + } + } + + /** + * sets a new scale function to the x-axis That means that not the standard + * linear scale is shown but the image of the linear scale under the given + * function + * + * @param x_s + * the scale function for the x-axis + */ + public void setXScale(DFunction x_s) { + if (x_s == null && measures.x_scale == null) + return; + measures.x_scale = x_s; + repaint(); + } + + /** + * sets a new scale function to the y-axis That means that not the standard + * linear scale is shown but the image of the linear scale under the given + * function + * + * @param y_s + * the scale function for the y-axis + */ + public void setYScale(DFunction y_s) { + if (y_s == null && measures.y_scale == null) + return; + measures.y_scale = y_s; + repaint(); + } } /**************************************************************************** diff --git a/src/eva2/tools/math/Mathematics.java b/src/eva2/tools/math/Mathematics.java index 1459a686..54366be3 100644 --- a/src/eva2/tools/math/Mathematics.java +++ b/src/eva2/tools/math/Mathematics.java @@ -16,160 +16,61 @@ import eva2.tools.math.interpolation.SplineInterpolation; * @author Andreas Dräger */ public class Mathematics { - public static void revertArray(Object[] src, Object[] dst) { - if (dst.length>=src.length) { - for (int i=0; i dblArrList, boolean interpolate) { - java.util.Collections.sort(dblArrList, new DoubleArrayComparator()); - - int len = dblArrList.size(); - if (len % 2 != 0) return dblArrList.get((len-1) / 2); - else { - double[] med = dblArrList.get(len/2).clone(); - if (interpolate) { - vvAdd(med, dblArrList.get((len/2)+1), med); - svDiv(2, med, med); - } - return med; - } - } - - /** - * This method gives a linear interpolation of the function values of the - * given argument/function value pairs. - * - * @param x - * The argument at the point with unknown function value - * @param x0 - * The argument at the last position with a function value - * @param x1 - * The argument at the next known fuction value - * @param f0 - * The function value at the position x0 - * @param f1 - * The function value at the position x1 - * @return The function value at position x given by linear interpolation. - */ - public static double linearInterpolation(double x, double x0, double x1, - double f0, double f1) { - if (x1 == x0) return f0; - return lerp(f0, f1, (x - x0) / (x1 - x0)); - } - - /** - * Computes a hyperbolic interpolation of the two point (x0,f0) and (x1,f1). - * - * @param x - * @param x0 - * @param x1 - * @param f0 - * @param f1 + * @param a * @return */ - public static double hyperbolicInterpolation(double x, double x0, double x1, - double f0, double f1) { - if (x1 == 0) return lerp(f0, f1, (x - x0) / (-x0)); - double l = lerp(x0 / x1, 1, x); - if (l == 0) return linearInterpolation(x, x0, x1, f0, f1); - return lerp(f0, f1, x / l); + public static double[][] adjoint(double[][] a) { + if (a == null) return null; + if (a.length != a[0].length) return null; + double[][] b = new double[a.length][a.length]; + for (int i = 0; i < a.length; i++) + for (int j = 0; j < a.length; j++) + b[i][j] = adjoint(a, i, j); + return b; } - -// <<<<<<< .working -// /** -// * Computes a spline interpolation of the two point (x0,f0) and (x1,f1). -// * -// * @param x -// * @param x0 -// * @param x1 -// * @param f0 -// * @param f1 -// * @return If an error with the spline occurs, a linear interpolation will be -// * returned. -// */ -// /* public static double splineInterpolation(double x, double x0, double x1, -// double f0, double f1) { -// try { -// double[] t = { x0, x1 }, f = { f0, f1 }; -// SplineInterpolation spline = new SplineInterpolation(new BasicDataSet(t, -// f, 1)); -// return spline.getY(x); -// } catch (InterpolationException e) { -// e.printStackTrace(); -// } -// return linearInterpolation(x, x0, x1, f0, f1); -// }*/ -// ======= + /** - * Computes a spline interpolation of the two point (x0,f0) and (x1,f1). + * Computes the adjoint of the matrix element at the position (k, l). * - * @param x - * @param x0 - * @param x1 - * @param f0 - * @param f1 - * @return If an error with the spline occurs, a linear interpolation will be - * returned. - */ - public static double splineInterpolation(double x, double x0, double x1, - double f0, double f1) { - try { - double[] t = {x0, x1}, f = {f0, f1}; - SplineInterpolation spline = new SplineInterpolation(new BasicDataSet(t, - f, 1)); - return spline.getY(x); - } catch (InterpolationException e) { - e.printStackTrace(); - } - return linearInterpolation(x, x0, x1, f0, f1); - } - - /** - * @param f0 - * @param f1 - * @param t + * @param a + * @param k + * @param l * @return */ - private static double lerp(double f0, double f1, double t) { - return f0 + (f1 - f0) * t; + public static double adjoint(double[][] a, int k, int l) { + return Math.pow(-1, k + l + 2) * determinant(submatrix(a, k, l)); } + + /** + * This computes the determinant of the given matrix + * + * @param matrix + * @return The determinant or null if there is no determinant (if the matrix + * is not square). + */ + public static double determinant(double[][] matrix) { + if (matrix == null) return 0; + if (matrix.length != matrix[0].length) return 0; + if (matrix.length == 1) return matrix[0][0]; + if (matrix.length == 2) + return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; + if (matrix.length == 3) + return matrix[0][0] * matrix[1][1] * matrix[2][2] + matrix[0][1] + * matrix[1][2] * matrix[2][0] + matrix[0][2] * matrix[1][0] + * matrix[2][1] - matrix[2][0] * matrix[1][1] * matrix[0][2] + - matrix[2][1] * matrix[1][2] * matrix[0][0] - matrix[2][2] + * matrix[1][0] * matrix[0][1]; + double det = 0; + for (int k = 0; k < matrix.length; k++) { + if (matrix[0][k] != 0) det += matrix[0][k] * adjoint(matrix, 0, k); + } + return det; + } + /** * Computes the root-Distance function. For example root = 2 gives the * Euclidian Distance. @@ -217,475 +118,82 @@ public class Mathematics { d += Math.pow(Math.abs(x[i] - y[i]), 2); return Math.sqrt(d); } - - /** - * Computes the relative distance of vector x to vector y. Therefore the - * difference of x[i] and y[i] is divided by y[i] for every i. If y[i] is - * zero, the default value def is used instead. The sum of these differences - * gives the distance function. - * + +/** + * Expand a vector to a higher dimension (len) by filling it up + * with a constant value. + * * @param x - * A vector - * @param y - * The reference vector - * @param def - * The default value to be use to avoid division by zero. - * @return The relative distance of x to y. - * @throws Exception - */ - public static double relDist(double[] x, double[] y, double def) - throws Exception { - if (x.length != y.length) - throw new Exception("The vectors x and y must have the same dimension"); - double d = 0; - for (int i = 0; i < x.length; i++) - if (y[i] != 0) - d += Math.pow(((x[i] - y[i]) / y[i]), 2); - else d += def; - return d; - } - - /** - * This computes the determinant of the given matrix - * - * @param matrix - * @return The determinant or null if there is no determinant (if the matrix - * is not square). - */ - public static double determinant(double[][] matrix) { - if (matrix == null) return 0; - if (matrix.length != matrix[0].length) return 0; - if (matrix.length == 1) return matrix[0][0]; - if (matrix.length == 2) - return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; - if (matrix.length == 3) - return matrix[0][0] * matrix[1][1] * matrix[2][2] + matrix[0][1] - * matrix[1][2] * matrix[2][0] + matrix[0][2] * matrix[1][0] - * matrix[2][1] - matrix[2][0] * matrix[1][1] * matrix[0][2] - - matrix[2][1] * matrix[1][2] * matrix[0][0] - matrix[2][2] - * matrix[1][0] * matrix[0][1]; - - double det = 0; - for (int k = 0; k < matrix.length; k++) { - if (matrix[0][k] != 0) det += matrix[0][k] * adjoint(matrix, 0, k); - } - return det; - } - - /** - * This computes the submatrix of the given matrix as a result by scraching - * out the row k and the column l. - * - * @param a - * @param k - * @param l + * @param len + * @param v * @return */ - public static double[][] submatrix(double[][] a, int k, int l) { - double b[][] = new double[a.length - 1][a[0].length - 1]; - int i, j, m = 0, n = 0; - - for (i = 0; i < a.length; i++) { - if (i == k) continue; - for (j = 0; j < a[0].length; j++) { - if (j == l) continue; - b[m][n++] = a[i][j]; - } - m++; - n = 0; - } - - return b; + public static double[] expandVector(double[] x, int len, double v) { + if (len <= x.length ) {// not really an error, just perform identity +// System.err.println("Error, invalid length in expandVector, expecting l>" + x.length); + return x; + } else { + double[] expanded = new double[len]; + System.arraycopy(x, 0, expanded, 0, x.length); + for (int i=x.length; irange[i][1])) return false; + public static double hyperbolicInterpolation(double x, double x0, double x1, + double f0, double f1) { + if (x1 == 0) return lerp(f0, f1, (x - x0) / (-x0)); + double l = lerp(x0 / x1, 1, x); + if (l == 0) return linearInterpolation(x, x0, x1, f0, f1); + return lerp(f0, f1, x / l); + } + + /** + * Intersect two ranges resulting in the maximum range contained in both. + * + * @param modRange + * @param makeRange + * @param destRange + */ + public static void intersectRange(double[][] r1, double[][] r2, double[][] destRange) { + for (int i=0; iupper)) return false; return true; } - + /** - * Return the vector of interval length values in any dimension. - * ret[i]=range[i][1]-range[i][0]; - * + * Check whether the given vector lies within the range in every dimension. + * + * @param x * @param range + * @return true if the vector lies within the range, else false + */ + public static boolean isInRange(double[] x, double[][] range) { + for (int i=0; irange[i][1])) return false; + } + return true; + } + + /** + * Returns false if a vector contains NaN, its squared sum is NaN + * or the absolute sum is smaller than 10^-18. + * @param d * @return */ - public static double[] getAbsRange(double[][] range) { - double[] ret = new double[range.length]; - for (int i = 0; i < ret.length; i++) { - ret[i]=range[i][1]-range[i][0]; + public static boolean isValidVec(double[] d) { + double sum = 0; + for (int i = 0; i < d.length; i++) { + if (Double.isNaN(d[i])) return false; + sum += Math.pow(d[i],2); } - return ret; + if (Double.isNaN(sum)) return false; + if (Math.abs(sum) < 0.000000000000000001) return false; + return true; } /** - * Shift bounds by a constant value in every dimension. - * - * @param range + * @param f0 + * @param f1 + * @param t * @return */ - public static void shiftRange(double[][] range, double dist) { - for (int i = 0; i < range.length; i++) { - svAdd(dist, range[i]); + private static double lerp(double f0, double f1, double t) { + return f0 + (f1 - f0) * t; + } + + /** + * This method gives a linear interpolation of the function values of the + * given argument/function value pairs. + * + * @param x + * The argument at the point with unknown function value + * @param x0 + * The argument at the last position with a function value + * @param x1 + * The argument at the next known fuction value + * @param f0 + * The function value at the position x0 + * @param f1 + * The function value at the position x1 + * @return The function value at position x given by linear interpolation. + */ + public static double linearInterpolation(double x, double x0, double x1, + double f0, double f1) { + if (x1 == x0) return f0; + return lerp(f0, f1, (x - x0) / (x1 - x0)); + } + + public static double max(double[] vals) { + double maxVal = vals[0]; + for (int i=1; i dblArrList, boolean interpolate) { + java.util.Collections.sort(dblArrList, new DoubleArrayComparator()); - /** - * Shift bounds by a constant value in every dimension. The dists - * must be of dimensions as the range. - * - * @param range - * @return - */ - public static void shiftRange(double[][] range, double[] dists) { - for (int i = 0; i < range.length; i++) { - svAdd(dists[i], range[i]); + int len = dblArrList.size(); + if (len % 2 != 0) return dblArrList.get((len-1) / 2); + else { + double[] med = dblArrList.get(len/2).clone(); + if (interpolate) { + vvAdd(med, dblArrList.get((len/2)+1), med); + svDiv(2, med, med); + } + return med; } } + public static double min(double[] vals) { + double minVal = vals[0]; + for (int i=1; i1) or reduced (fact<1) by the defined ratio around the center. - * - * @param rangeScaleFact - * @param range - */ - public static void scaleRange(double rangeScaleFact, double[][] range) { - double[] intervalLengths=Mathematics.getAbsRange(range); - double[] tmpInts=Mathematics.svMult(rangeScaleFact, intervalLengths); - Mathematics.vvSub(tmpInts, intervalLengths, tmpInts); // this is what must be added to range interval - for (int i=0; i" + x.length); - return x; - } else { - double[] expanded = new double[len]; - System.arraycopy(x, 0, expanded, 0, x.length); - for (int i=x.length; i=src.length) { + for (int i=0; i1) or reduced (fact<1) by the defined ratio around the center. + * + * @param rangeScaleFact + * @param range + */ + public static void scaleRange(double rangeScaleFact, double[][] range) { + double[] intervalLengths=Mathematics.getAbsRange(range); + double[] tmpInts=Mathematics.svMult(rangeScaleFact, intervalLengths); + Mathematics.vvSub(tmpInts, intervalLengths, tmpInts); // this is what must be added to range interval + for (int i=0; i