Merging MK revs 298:303 - simple plot legend, some additions for statistics on feasibility
This commit is contained in:
parent
52d707f0e0
commit
014258e1a4
@ -30,6 +30,7 @@ import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
@ -57,9 +58,12 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
private ScaledBorder m_Border;
|
||||
private boolean m_log = false;
|
||||
private boolean notifyNegLog = true;
|
||||
private boolean m_legend = true;
|
||||
private int m_x;
|
||||
private int m_y;
|
||||
|
||||
private GraphPointSetLegend legendBox = null;
|
||||
|
||||
private DPointIcon m_CurrentPointIcon;
|
||||
/**
|
||||
*
|
||||
@ -90,6 +94,16 @@ 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.
|
||||
@ -172,7 +186,7 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
popRep.setIcon(icon);
|
||||
addDElement(popRep);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -181,8 +195,8 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
if ((m_PointSetContainer == null) || (m_PointSetContainer.size() == 0))
|
||||
return ret;
|
||||
int minindex = getNearestGraphIndex(x, y);
|
||||
ret = ((GraphPointSet) (m_PointSetContainer.get(minindex))).getInfoString();
|
||||
return ret;
|
||||
if (minindex>=0) return ((GraphPointSet) (m_PointSetContainer.get(minindex))).getInfoString();
|
||||
else return "none";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,8 +210,7 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
ret = ((GraphPointSet) (m_PointSetContainer.get(minindex))).isStatisticsGraph();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -209,20 +222,18 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
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;
|
||||
if (point1 == null)
|
||||
System.err.println("point1 == null");
|
||||
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;
|
||||
}
|
||||
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;
|
||||
@ -350,7 +361,13 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@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) {
|
||||
@ -428,6 +445,7 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
return;
|
||||
int GraphLabel = ((GraphPointSet) (this.m_PointSetContainer.get(index))).getGraphLabel();
|
||||
clearGraph(GraphLabel);
|
||||
updateLegend();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -439,6 +457,7 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
return;
|
||||
int GraphLabel = ((GraphPointSet) (this.m_PointSetContainer.get(index))).getGraphLabel();
|
||||
changeColorGraph(GraphLabel);
|
||||
updateLegend();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -589,7 +608,7 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
//setVisibleRectangle( 0.001, 0.001, 100000, 1000 );
|
||||
setYScale(new Exp());
|
||||
m_Border.setSrcdY(Math.log(10));
|
||||
((java.text.DecimalFormat) m_Border.format_y).applyPattern("0.###E0");
|
||||
m_Border.applyPattern(false, "0.###E0");
|
||||
m_log = true;
|
||||
} else {
|
||||
m_log = false;
|
||||
@ -769,6 +788,14 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
|
||||
}
|
||||
if (FunctionArea.this.m_PointSetContainer.size() > 0) {
|
||||
JMenuItem togLegend = new JMenuItem("Toggle legend");
|
||||
togLegend.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent ee) {
|
||||
toggleLegend();
|
||||
}
|
||||
});
|
||||
GraphMenu.add(togLegend);
|
||||
|
||||
JMenuItem removeGraph = new JMenuItem("Remove graph");
|
||||
removeGraph.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent ee) {
|
||||
@ -776,8 +803,7 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
}
|
||||
});
|
||||
GraphMenu.add(removeGraph);
|
||||
}
|
||||
if (FunctionArea.this.m_PointSetContainer.size() > 0) {
|
||||
|
||||
JMenuItem changecolorGraph = new JMenuItem("Change color");
|
||||
changecolorGraph.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent ee) {
|
||||
@ -785,8 +811,7 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
}
|
||||
});
|
||||
GraphMenu.add(changecolorGraph);
|
||||
}
|
||||
if (FunctionArea.this.m_PointSetContainer.size() > 0) {
|
||||
|
||||
JMenuItem removePoint = new JMenuItem("Remove point");
|
||||
removePoint.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent ee) {
|
||||
@ -795,36 +820,13 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
});
|
||||
GraphMenu.add(removePoint);
|
||||
}
|
||||
// if (isStatisticsGraph(e.getX(),e.getY())==true) {
|
||||
// if (getVar(e.getX(),e.getY())==false) {
|
||||
// JMenuItem showVar = new JMenuItem("Show varianz ");
|
||||
// showVar.addActionListener(new ActionListener() {
|
||||
// //
|
||||
// public void actionPerformed(ActionEvent ee) {
|
||||
// setVar(m_x,m_y,true);
|
||||
// }
|
||||
// });
|
||||
// GraphMenu.add(showVar);
|
||||
|
||||
// }
|
||||
// else {
|
||||
// JMenuItem hideVar = new JMenuItem("Hide varianz ");
|
||||
// hideVar.addActionListener(new ActionListener() {
|
||||
// //
|
||||
// public void actionPerformed(ActionEvent ee) {
|
||||
// setVar(m_x,m_y,false);
|
||||
// }
|
||||
// });
|
||||
// GraphMenu.add(hideVar);
|
||||
// }
|
||||
// }
|
||||
GraphMenu.show(FunctionArea.this, e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** This method allows to add a selection listner to the PointIcon
|
||||
/** This method allows to add a selection listener to the PointIcon
|
||||
* it should need more than one listener to this abstruse event
|
||||
* @param a The selection listener
|
||||
*/
|
||||
@ -832,17 +834,37 @@ public class FunctionArea extends DArea implements Serializable {
|
||||
this.m_RefPointListener = a;
|
||||
}
|
||||
|
||||
/** This method returns the selection listner to the PointIcon
|
||||
/** This method returns the selection listener to the PointIcon
|
||||
* @return InterfaceSelectionListener
|
||||
*/
|
||||
public InterfaceRefPointListener getRefPointSelectionListener() {
|
||||
return this.m_RefPointListener;
|
||||
}
|
||||
|
||||
/** This method allows to remove the selection listner to the PointIcon
|
||||
/** This method allows to remove the selection listener to the PointIcon
|
||||
*/
|
||||
public void removeRefPointSelectionListeners() {
|
||||
this.m_RefPointListener = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreate the legend object with the current point sets.
|
||||
*
|
||||
*/
|
||||
public void updateLegend() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ import java.util.Arrays;
|
||||
*
|
||||
*/
|
||||
public class GraphPointSet {
|
||||
private String m_InfoString = "InfoString";
|
||||
private String m_InfoString = "Incomplete_Run";
|
||||
private int m_GraphLabel;
|
||||
private int colorOffset = 0;
|
||||
private ArrayList m_PointSetContainer = new ArrayList();
|
||||
|
118
src/eva2/gui/GraphPointSetLegend.java
Normal file
118
src/eva2/gui/GraphPointSetLegend.java
Normal file
@ -0,0 +1,118 @@
|
||||
package eva2.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import wsi.ra.chart2d.SlimRect;
|
||||
import eva2.tools.Pair;
|
||||
|
||||
/**
|
||||
* A class representing the legend of a plot. It is created from a list of GraphPointSets as
|
||||
* used in FunctionArea. Painting is done in FunctionArea. As an alternative, an own frame
|
||||
* could be created.
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
*/
|
||||
public class GraphPointSetLegend {
|
||||
Pair<String,Color>[] legendEntries;
|
||||
|
||||
public GraphPointSetLegend(List<GraphPointSet> pointSetContainer) {
|
||||
legendEntries = new Pair[pointSetContainer.size()];
|
||||
for (int i = 0; i < pointSetContainer.size(); i++) {
|
||||
GraphPointSet pointset = pointSetContainer.get(i);
|
||||
legendEntries[i] = new Pair<String,Color>(pointset.getInfoString(), pointset.getColor());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the legend labels to a container.
|
||||
* @param comp
|
||||
*/
|
||||
public void addToContainer(JComponent comp) {
|
||||
for (int i = 0; i < legendEntries.length; i++) {
|
||||
JLabel label = new JLabel(legendEntries[i].head);
|
||||
label.setForeground(legendEntries[i].tail);
|
||||
comp.add(label);
|
||||
}
|
||||
}
|
||||
|
||||
public static JPanel makeLegendPanel(Color bgCol, ArrayList<GraphPointSet> pointSetContainer) {
|
||||
JPanel pan = new JPanel();
|
||||
pan.setBackground(bgCol);
|
||||
pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS));
|
||||
GraphPointSetLegend lBox=new GraphPointSetLegend(pointSetContainer);
|
||||
lBox.addToContainer(pan);
|
||||
return pan;
|
||||
}
|
||||
|
||||
public static JFrame makeLegendFrame(Color bgCol, ArrayList<GraphPointSet> pointSetContainer) {
|
||||
JFrame frame = new JFrame("Legend");
|
||||
// LegendBox lBox = new LegendBox(bgCol, pointSetContainer);
|
||||
frame.add(makeLegendPanel(bgCol, pointSetContainer));
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
return frame;
|
||||
}
|
||||
|
||||
public void paintIn(JComponent component) {
|
||||
Graphics g = component.getGraphics();
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int yOffs=5+fm.getHeight();
|
||||
int xOffs=0;
|
||||
Color origCol = g.getColor();
|
||||
|
||||
for (int i=0; i<legendEntries.length; i++) {
|
||||
g.setColor(legendEntries[i].tail);
|
||||
Rectangle2D rect = fm.getStringBounds(legendEntries[i].head, g);
|
||||
xOffs = (int) (component.getWidth()-rect.getWidth()-5);
|
||||
g.drawString(legendEntries[i].head, xOffs, yOffs);
|
||||
yOffs+=(5+rect.getHeight());
|
||||
}
|
||||
g.setColor(origCol);
|
||||
}
|
||||
|
||||
// public void paintIn(Graphics g, Dimension dim) {
|
||||
// paintIn(g, dim.width);
|
||||
// }
|
||||
//
|
||||
// public void paintIn(Graphics g, Rectangle rect) {
|
||||
// paintIn(g, rect.width);
|
||||
// }
|
||||
//
|
||||
// public void paintIn(Graphics g, DRectangle rect) {
|
||||
// paintIn(g, (int)rect.width);
|
||||
// }
|
||||
|
||||
public void paintIn(Graphics g, SlimRect rect) {
|
||||
paintIn(g, (int)rect.getX(), (int)rect.getY(), (int)rect.getX()+(int)rect.getWidth());
|
||||
}
|
||||
|
||||
private void paintIn(Graphics g, int x, int y, int maxX) {
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
// System.out.println("In LegendBox.paintIn!");
|
||||
int yOffs=5+y+fm.getHeight();
|
||||
int xOffs=x;
|
||||
Color origCol = g.getColor();
|
||||
|
||||
for (int i=0; i<legendEntries.length; i++) {
|
||||
g.setColor(legendEntries[i].tail);
|
||||
Rectangle2D stringBounds = fm.getStringBounds(legendEntries[i].head, g);
|
||||
xOffs = (int) (maxX-stringBounds.getWidth()-5);
|
||||
g.drawString(legendEntries[i].head, xOffs, yOffs);
|
||||
// g.drawString(legendEntries[i].head, 80, 80);
|
||||
yOffs+=(5+stringBounds.getHeight());
|
||||
}
|
||||
g.setColor(origCol);
|
||||
}
|
||||
}
|
@ -68,6 +68,10 @@ public class GraphWindow {
|
||||
return (m_Plotter != null) && (m_Plotter.isValid());
|
||||
}
|
||||
|
||||
public PlotInterface getPlotter() {
|
||||
return m_Plotter;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -101,7 +105,7 @@ public class GraphWindow {
|
||||
*/
|
||||
public Graph getNewGraph(String InfoString) {
|
||||
m_GraphCounter++;
|
||||
if (TRACE) System.out.println("Graph.getNewGraph No:"+m_GraphCounter);
|
||||
if (TRACE) System.out.println("Graph.getNewGraph No:"+m_GraphCounter + " - " + InfoString);
|
||||
return new Graph (InfoString,m_Plotter,m_GraphCounter);
|
||||
}
|
||||
}
|
||||
|
@ -327,6 +327,7 @@ public class Plot implements PlotInterface, Serializable {
|
||||
public void clearAll () {
|
||||
m_PlotArea.clearAll();
|
||||
m_PlotArea.removeAllDElements();
|
||||
m_PlotArea.clearLegend();
|
||||
m_Frame.repaint();
|
||||
}
|
||||
/**
|
||||
@ -443,6 +444,7 @@ public class Plot implements PlotInterface, Serializable {
|
||||
public String getName() {
|
||||
return this.m_PlotName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -50,6 +50,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
private double m_ConstraintViolation = 0;
|
||||
public boolean m_AreaConst4ParallelViolated = false;
|
||||
public boolean m_Marked = false; // is for GUI only!
|
||||
public boolean m_isPenalized = false; // may be set true for penalty based constraints
|
||||
|
||||
protected double[] m_SelectionProbability = new double[1];;
|
||||
public double m_CrossoverProbability = 1.0;
|
||||
@ -144,6 +145,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
m_ConstraintViolation = individual.m_ConstraintViolation;
|
||||
m_AreaConst4ParallelViolated = individual.m_AreaConst4ParallelViolated;
|
||||
m_Marked = individual.m_Marked;
|
||||
m_isPenalized = individual.m_isPenalized;
|
||||
individualIndex = individual.individualIndex;
|
||||
if (individual.parentIDs != null) {
|
||||
parentIDs = new Long[individual.parentIDs.length];
|
||||
@ -447,6 +449,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
* individual
|
||||
*/
|
||||
public void resetConstraintViolation() {
|
||||
m_isPenalized=false;
|
||||
this.m_ConstraintViolation = 0;
|
||||
}
|
||||
|
||||
@ -494,6 +497,21 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
||||
this.m_Marked = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows marking an individual as infeasible if fitness penalty is used.
|
||||
* @return
|
||||
*/
|
||||
public boolean isMarkedPenalized() {
|
||||
return m_isPenalized;
|
||||
}
|
||||
/**
|
||||
* Allows marking an individual as infeasible if fitness penalty is used.
|
||||
* @return
|
||||
*/
|
||||
public void SetMarkPenalized(boolean p) {
|
||||
m_isPenalized=p;
|
||||
}
|
||||
|
||||
/** This method can be used to read the current fitness of the individual.
|
||||
* Please note that the fitness can be based on multiple criteria therefore
|
||||
* double[] is used instead of a single double.
|
||||
|
@ -444,6 +444,50 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
return getIndexOfBestOrWorstIndividual(false, false, fitIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the best feasible individual or null if the population contains
|
||||
* no or only infeasible individuals. This considers both aspects: the constraint setting
|
||||
* as well as penalization. An individual is feasible only if it is both unpenalized and
|
||||
* not violating the constraints.
|
||||
*
|
||||
* @param fitIndex
|
||||
* @return the best feasible individual or null if none is feasible
|
||||
*/
|
||||
public AbstractEAIndividual getBestFeasibleIndividual(int fitIndex) {
|
||||
int index=getIndexOfBestOrWorstFeasibleIndividual(true, fitIndex);
|
||||
if (index<0) return null;
|
||||
else return getEAIndividual(index);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Return the best individual which has a zero penalty value (is feasible concerning
|
||||
// * penalty). If all are penalized, null is returned.
|
||||
// *
|
||||
// * @param fitIndex
|
||||
// * @return
|
||||
// */
|
||||
// public AbstractEAIndividual getBestUnpenalizedIndividual(int fitIndex) {
|
||||
// int result = -1;
|
||||
// double[] curSelFitness = null;
|
||||
// boolean allViolate = true;
|
||||
//
|
||||
// for (int i = 0; i < super.size(); i++) {
|
||||
// if (!(getEAIndividual(i).isMarkedPenalized())) {
|
||||
// allViolate = false;
|
||||
// if ((result<0) || (compareFit(true, getEAIndividual(i).getFitness(), curSelFitness, fitIndex))) {
|
||||
// // fit i is better than remembered
|
||||
// result = i;
|
||||
// curSelFitness = getEAIndividual(i).getFitness(); // remember fit i
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (allViolate) {
|
||||
// return null;
|
||||
// } else {
|
||||
// return getEAIndividual(result);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* This method will return the index of the current best (worst) individual from the
|
||||
* population. If indicated, only those are regarded which do not violate the constraints.
|
||||
@ -485,7 +529,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
minViol = ((AbstractEAIndividual)super.get(i)).getConstraintViolation();
|
||||
}
|
||||
}
|
||||
System.err.println("Population reports: All individuals violate the constraints, choosing smallest constraint violation.");
|
||||
// System.err.println("Population reports: All individuals violate the constraints, choosing smallest constraint violation.");
|
||||
// this is now really reported nicer...
|
||||
} else {
|
||||
// not all violate, maybe all are NaN!
|
||||
// so just select a random one
|
||||
@ -496,6 +541,31 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the population for the best (worst) considering the given criterion (or all criteria
|
||||
* for fitIndex<0) which also does not violate constraints.
|
||||
* Returns -1 if no feasible solution is found, else the index of the best feasible solution.
|
||||
*
|
||||
* @param bBest
|
||||
* @param fitIndex
|
||||
* @return -1 if no feasible solution is found, else the index of the best feasible individual
|
||||
*/
|
||||
public int getIndexOfBestOrWorstFeasibleIndividual(boolean bBest, int fitIndex) {
|
||||
int result = -1;
|
||||
double[] curSelFitness = null;
|
||||
|
||||
for (int i = 0; i < super.size(); i++) {
|
||||
if (!(getEAIndividual(i).violatesConstraint()) && !(getEAIndividual(i).isMarkedPenalized())) {
|
||||
if ((result<0) || (compareFit(bBest, getEAIndividual(i).getFitness(), curSelFitness, fitIndex))) {
|
||||
// fit i is better than remembered
|
||||
result = i;
|
||||
curSelFitness = getEAIndividual(i).getFitness(); // remember fit i
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the current best individual from the population.
|
||||
* If the population is empty, null is returned.
|
||||
|
@ -11,10 +11,20 @@ import eva2.gui.BeanInspector;
|
||||
import eva2.server.go.IndividualInterface;
|
||||
import eva2.server.go.PopulationInterface;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.go.problems.InterfaceAdditionalPopulationInformer;
|
||||
import eva2.tools.Mathematics;
|
||||
|
||||
|
||||
/**
|
||||
* An abstract class handling statistics. Most important stuff happens in startOptPerformed, stopOptPerformed
|
||||
* and createNextGenerationPerformed. Any measures (run based or multi-run based) are reset in startOptPerformed,
|
||||
* updated per iteration in createNextGenerationPerformed and reported to listeners in stopOptPerformed.
|
||||
* Several different verbosity levels are regarded.
|
||||
* The method plotCurrentResults should be implemented to plot further results per iteration.
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractStatistics implements InterfaceTextListener, InterfaceStatistics {
|
||||
private PrintWriter resultOut;
|
||||
public final static boolean TRACE = false;
|
||||
@ -42,14 +52,19 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
protected int functionCalls;
|
||||
protected int functionCallSum;
|
||||
protected int convergenceCnt;
|
||||
protected int feasibleFoundAfter;
|
||||
protected int numOfRunsFeasibleFound;
|
||||
protected double feasibleFoundAfterSum;
|
||||
protected int optRunsPerformed;
|
||||
protected double[] currentBestFit;
|
||||
protected double[] currentBestFeasibleFit;
|
||||
protected double[] meanBestFeasibleFit;
|
||||
protected double[] meanFitness;
|
||||
protected double[] currentWorstFit;
|
||||
protected double[] meanBestOfRunFitness;
|
||||
protected double avgPopDist;
|
||||
protected double maxPopDist;
|
||||
protected IndividualInterface bestCurrentIndividual, bestRunIndividual, bestIndividualAllover;
|
||||
protected IndividualInterface bestCurrentIndividual, bestRunIndividual, bestRunFeasibleIndy, bestIndividualAllover;
|
||||
|
||||
|
||||
private ArrayList<InterfaceTextListener> textListeners;
|
||||
@ -121,11 +136,17 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
initOutput(infoString);
|
||||
bestIndividualAllover = null;
|
||||
meanBestOfRunFitness = null;
|
||||
meanBestFeasibleFit = null;
|
||||
if (refineMultiRuns) meanCollection = new ArrayList<double[][]>();
|
||||
else meanCollection = null;
|
||||
feasibleFoundAfterSum=-1;
|
||||
numOfRunsFeasibleFound=0;
|
||||
}
|
||||
feasibleFoundAfter=-1;
|
||||
bestCurrentIndividual = null;
|
||||
bestRunIndividual = null;
|
||||
currentBestFeasibleFit=null;
|
||||
bestRunFeasibleIndy = null;
|
||||
runIterCnt = 0;
|
||||
if (printRunIntroVerbosity()) printToTextListener("\n****** Multirun "+runNumber);
|
||||
if (params != null) {
|
||||
@ -165,6 +186,32 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
meanBestOfRunFitness=bestRunIndividual.getFitness().clone();
|
||||
} else addMean(meanBestOfRunFitness, bestRunIndividual.getFitness());
|
||||
}
|
||||
if (feasibleFoundAfter>0) {
|
||||
if (printRunStoppedVerbosity()) printToTextListener(" Feasible ind. found after " + feasibleFoundAfter + " evaluations.\n");
|
||||
} else {
|
||||
if (printRunStoppedVerbosity()) printToTextListener(" NO feasible individual found.\n");
|
||||
}
|
||||
if (bestRunFeasibleIndy != null) {
|
||||
if (meanBestFeasibleFit==null) {
|
||||
meanBestFeasibleFit=currentBestFeasibleFit.clone();
|
||||
} else addMean(meanBestFeasibleFit, currentBestFeasibleFit);
|
||||
if (printRunStoppedVerbosity()) {
|
||||
if ((bestRunFeasibleIndy instanceof AbstractEAIndividual) && ((AbstractEAIndividual)bestRunFeasibleIndy).equalGenotypes((AbstractEAIndividual)bestRunIndividual)) {
|
||||
printToTextListener(" Run best feasible individual equals best individual.\n");
|
||||
} else {
|
||||
if (bestRunFeasibleIndy instanceof AbstractEAIndividual) {
|
||||
if (((AbstractEAIndividual)bestRunIndividual).violatesConstraint())
|
||||
printToTextListener(" Run best individual violates constraints by " + ((AbstractEAIndividual)bestRunIndividual).getConstraintViolation() + "\n");
|
||||
if (((AbstractEAIndividual)bestRunIndividual).isMarkedPenalized())
|
||||
printToTextListener(" Run best individual is penalized.\n");
|
||||
}
|
||||
|
||||
printToTextListener(" Run best feasible ind.: " + BeanInspector.toString(bestRunFeasibleIndy) + "\n");
|
||||
printToTextListener(" Feas. solution data : " + AbstractEAIndividual.getDefaultDataString(bestRunFeasibleIndy) + "\n");
|
||||
printToTextListener(" Feas. solution fit : " + BeanInspector.toString(bestRunFeasibleIndy.getFitness()) + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (currentBestFit!= null) {
|
||||
// if (printRunStoppedVerbosity()) printToTextListener(" Best Fitness: " + BeanInspector.toString(currentBestFit) + "\n");
|
||||
// }
|
||||
@ -174,6 +221,12 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
protected void finalizeOutput() {
|
||||
if (printFinalVerbosity()) printToTextListener("*******\n Runs performed: " + optRunsPerformed + ", reached target " + convergenceCnt + " times with threshold " + m_StatsParams.getConvergenceRateThreshold() + ", rate " + convergenceCnt/(double)m_StatsParams.getMultiRuns() + '\n');
|
||||
if (printFinalVerbosity()) printToTextListener(" Average function calls: " + (functionCallSum/optRunsPerformed) + "\n");
|
||||
|
||||
if (printFinalVerbosity() && (feasibleFoundAfterSum>=0.)) {
|
||||
printToTextListener(" Feasible solution found in " + numOfRunsFeasibleFound + " of " + optRunsPerformed + " runs \n");
|
||||
printToTextListener(" Average evaluations until feasible ind. was found in " + numOfRunsFeasibleFound + " runs: " + feasibleFoundAfterSum/numOfRunsFeasibleFound + " evaluations\n");
|
||||
}
|
||||
|
||||
if (printFinalVerbosity() && (bestIndividualAllover != null)) printToTextListener(" Overall best individual: " + BeanInspector.toString(bestIndividualAllover) + '\n');
|
||||
if (printFinalVerbosity() && (bestIndividualAllover != null)) printToTextListener(" Overall solution data : " + AbstractEAIndividual.getDefaultDataString(bestIndividualAllover) + '\n');
|
||||
if (printFinalVerbosity() && (bestIndividualAllover != null)) printToTextListener(" Overall solution fit : " + BeanInspector.toString(bestIndividualAllover.getFitness()) + '\n');
|
||||
@ -181,7 +234,13 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
if (meanBestOfRunFitness!=null) {
|
||||
Mathematics.svDiv((double)optRunsPerformed, meanBestOfRunFitness, meanBestOfRunFitness);
|
||||
if (printFinalVerbosity()) {
|
||||
printToTextListener(" Averaged best fitness per run: " + BeanInspector.toString(meanBestOfRunFitness)+"\n");
|
||||
printToTextListener(" Average best fitness per run: " + BeanInspector.toString(meanBestOfRunFitness)+"\n");
|
||||
}
|
||||
}
|
||||
if (meanBestFeasibleFit!=null) {
|
||||
Mathematics.svDiv((double)numOfRunsFeasibleFound, meanBestFeasibleFit, meanBestFeasibleFit);
|
||||
if (printFinalVerbosity()) {
|
||||
printToTextListener(" Average best feasible fitness in " + numOfRunsFeasibleFound + " runs: " + BeanInspector.toString(meanBestFeasibleFit)+"\n");
|
||||
}
|
||||
}
|
||||
if (refineMultiRuns && (meanCollection != null)) {
|
||||
@ -298,6 +357,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
functionCalls = calls;
|
||||
currentBestFit = bestfit;
|
||||
currentWorstFit = worstfit;
|
||||
currentBestFeasibleFit = null;
|
||||
meanFitness = null;
|
||||
|
||||
if (firstPlot) {
|
||||
@ -336,6 +396,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
initPlots(m_StatsParams.getPlotDescriptions());
|
||||
// if (doTextOutput()) printToTextListener(getOutputHeader(informer, pop)+'\n');
|
||||
firstPlot = false;
|
||||
currentBestFeasibleFit=null;
|
||||
}
|
||||
if ((runIterCnt==0) && printHeaderByVerbosity()) printToTextListener(getOutputHeader(informerList, pop)+'\n');
|
||||
|
||||
@ -361,6 +422,23 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter
|
||||
if (currentBestFit == null) {
|
||||
System.err.println("BestFitness==null !");
|
||||
}
|
||||
if (pop instanceof Population) {
|
||||
AbstractEAIndividual curBestFeasible = ((Population)pop).getBestFeasibleIndividual(-1);
|
||||
|
||||
if (curBestFeasible!=null) { // a feasible ind. was found!
|
||||
if (currentBestFeasibleFit==null) { // feasible indy found for the first time
|
||||
numOfRunsFeasibleFound++;
|
||||
feasibleFoundAfter=((Population)pop).getFunctionCalls();
|
||||
if (feasibleFoundAfterSum<0) feasibleFoundAfterSum=0.; // initial signalling value was -1.
|
||||
feasibleFoundAfterSum+=feasibleFoundAfter;
|
||||
}
|
||||
currentBestFeasibleFit = curBestFeasible.getFitness().clone();
|
||||
if ((bestRunFeasibleIndy==null) || (secondIsBetter(bestRunFeasibleIndy, curBestFeasible))) {
|
||||
bestRunFeasibleIndy=curBestFeasible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
meanFitness = pop.getMeanFitness().clone();
|
||||
currentWorstFit = pop.getWorstIndividual().getFitness().clone();
|
||||
functionCalls = pop.getFunctionCalls();
|
||||
|
@ -18,20 +18,21 @@ import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import wsi.ra.jproxy.MainAdapterClient;
|
||||
import wsi.ra.jproxy.RMIProxyLocal;
|
||||
import wsi.ra.jproxy.RMIProxyRemote;
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.gui.Graph;
|
||||
import eva2.gui.GraphWindow;
|
||||
import eva2.gui.JTextoutputFrame;
|
||||
import eva2.gui.JTextoutputFrameInterface;
|
||||
import eva2.gui.Plot;
|
||||
import eva2.gui.PlotInterface;
|
||||
import eva2.server.EvAServer;
|
||||
import eva2.server.go.PopulationInterface;
|
||||
import eva2.server.go.problems.InterfaceAdditionalPopulationInformer;
|
||||
import eva2.tools.EVAERROR;
|
||||
|
||||
import wsi.ra.jproxy.MainAdapterClient;
|
||||
import wsi.ra.jproxy.RMIProxyLocal;
|
||||
import wsi.ra.jproxy.RMIProxyRemote;
|
||||
|
||||
/*==========================================================================*
|
||||
* CLASS DECLARATION
|
||||
*==========================================================================*/
|
||||
@ -105,39 +106,48 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl
|
||||
|
||||
// m_TextCounter = m_StatisticsParameter.GetTextoutput();
|
||||
m_PlotCounter = m_StatsParams.GetPlotoutput();
|
||||
if ((m_FitnessFrame!=null) && (m_FitnessFrame[0]!=null)) {
|
||||
PlotInterface p = m_FitnessFrame[0].getPlotter();
|
||||
if ((p!=null) && p.isValid()) ((Plot)p).getFunctionArea().clearLegend();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopOptPerformed(boolean normal, String stopMessage) {
|
||||
super.stopOptPerformed(normal, stopMessage);
|
||||
|
||||
|
||||
if (optRunsPerformed > m_StatsParams.getMultiRuns()) {
|
||||
// this may happen if the user reduces the multirun parameter during late multiruns
|
||||
System.err.println("error: more runs performed than defined.");
|
||||
}
|
||||
|
||||
int fullRuns=optRunsPerformed;
|
||||
if (!normal) fullRuns--;
|
||||
|
||||
// unite the graphs only if the break was "normal"
|
||||
if (normal && (m_StatsParams.getMultiRuns() > 1) && (m_StatGraph != null)) {
|
||||
if ((m_StatsParams.getMultiRuns() > 1) && (m_StatGraph != null)) {
|
||||
// unite the point sets for a multirun
|
||||
for (int i = 0; i < m_FitnessGraph.length; i++) {
|
||||
for (int j = 0; j < m_FitnessGraph[i].length; j++) {
|
||||
if (m_FitnessFrame[i].isValid()) {
|
||||
m_StatGraph[i][j].setInfoString(
|
||||
(m_FitnessGraph[i][j].getInfo().length() > 0 ? (m_FitnessGraph[i][j].getInfo() + "_") : "" )
|
||||
+ (m_StatsParams.GetInfoString().length() > 0 ? (m_StatsParams.GetInfoString() + "_") : "" )
|
||||
+ m_StatsParams.GetInfoString()
|
||||
+ "Mean_of_" + fullRuns + " ",
|
||||
(float) 2.0);
|
||||
if (normal && m_FitnessFrame[i].isValid()) {
|
||||
m_StatGraph[i][j].addGraph(m_FitnessGraph[i][j]);
|
||||
m_StatGraph[i][j].setInfoString(
|
||||
(m_FitnessGraph[i][j].getInfo().length() > 0 ? (m_FitnessGraph[i][j].getInfo() + "_") : "" )
|
||||
+ (m_StatsParams.GetInfoString().length() > 0 ? (m_StatsParams.GetInfoString() + "_") : "" )
|
||||
+ m_StatsParams.GetInfoString()
|
||||
+ "Mean_of_" + optRunsPerformed + " ",
|
||||
(float) 2.0);
|
||||
m_FitnessGraph[i][j].clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// this is inconsistent, shouldnt be necessary here but reset in startOpt...
|
||||
// if (optRunsPerformed == m_StatisticsParameter.getMultiRuns()) {
|
||||
// finalizeRuns(m_ConvergenceCnt);
|
||||
// m_OptRunsPerformed = 0;
|
||||
// m_ConvergenceCnt = 0;
|
||||
// }
|
||||
PlotInterface p = m_FitnessFrame[0].getPlotter();
|
||||
if ((optRunsPerformed >= m_StatsParams.getMultiRuns()) || !normal) {
|
||||
// update the legend after the last multirun or after a user break
|
||||
if ((p!=null) && p.isValid()) {
|
||||
((Plot)p).getFunctionArea().updateLegend();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void maybeShowProxyPrinter() {
|
||||
@ -149,13 +159,13 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl
|
||||
|
||||
maybeShowProxyPrinter();
|
||||
int graphCount = description.size();
|
||||
|
||||
// System.out.println("Initializing " + graphCount + " plots (StatisticsWithGUI)");
|
||||
m_FitnessFrame = new GraphWindow[graphCount];
|
||||
for (int i = 0; i < m_FitnessFrame.length; i++) {
|
||||
// m_FitnessFrame[i] = GraphWindow.getInstance(m_MainAdapterClient, m_GraphInfoString + " " + i + " " + " on " + m_MyHostName + ", VM " + EvAServer.m_NumberOfVM, "function calls", "fitness");
|
||||
m_FitnessFrame[i] = GraphWindow.getInstance(m_MainAdapterClient, "Optimization " + i + " " + " on " + m_MyHostName + ", VM " + EvAServer.m_NumberOfVM, "function calls", "fitness");
|
||||
}
|
||||
|
||||
|
||||
m_FitnessGraph = new Graph[graphCount][];
|
||||
// contains one graph for every value to be plotted (best / worst / best+worst)
|
||||
// TODO Im really not sure why this is a 2-dimensional array. shouldnt one be enough?
|
||||
@ -163,7 +173,7 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl
|
||||
m_FitnessGraph[i] = new Graph[((String[]) description.get(i)).length];
|
||||
for (int j = 0; j < m_FitnessGraph[i].length; j++) {
|
||||
String[] d = (String[]) description.get(i);
|
||||
// this is where the column string for ascii export is created!
|
||||
// this is where the column string for ascii export is created! Uah!
|
||||
m_FitnessGraph[i][j] =
|
||||
m_FitnessFrame[i].getNewGraph(d[j] + "_" +
|
||||
m_StatsParams.GetInfoString() +
|
||||
@ -215,12 +225,20 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl
|
||||
m_PlotCounter = m_StatsParams.GetPlotoutput();
|
||||
boolean doPlotBest = (fitnessplot_setting == StatsParameter.PLOT_BEST)
|
||||
|| (fitnessplot_setting == StatsParameter.PLOT_BEST_AND_WORST)
|
||||
|| (fitnessplot_setting == StatsParameter.PLOT_CURBEST_AND_RUNBEST)
|
||||
|| (fitnessplot_setting == StatsParameter.PLOT_BEST_AND_MEASURES);
|
||||
boolean doPlotWorst = (fitnessplot_setting == StatsParameter.PLOT_WORST)
|
||||
|| (fitnessplot_setting == StatsParameter.PLOT_BEST_AND_WORST);
|
||||
boolean doPlotMeasures = (fitnessplot_setting == StatsParameter.PLOT_BEST_AND_MEASURES);
|
||||
boolean doPlotBestFeasible = false;
|
||||
// TODO <-- das hier besser?
|
||||
// Oder erstmal ganz weg und dafür gesamtergebnis berechnen (textfenster)
|
||||
// ZB: wie oft wurde feasible sol. gefunden (analog convergence counter)
|
||||
// Durchschnitt: erste feasible sol., fitness der feasible sol...
|
||||
int subGraph=0;
|
||||
if (doPlotBest) {
|
||||
plotFitnessPoint(0, 0, functionCalls, currentBestFit[0]);
|
||||
plotFitnessPoint(0, subGraph++, functionCalls, currentBestFit[0]);
|
||||
if (fitnessplot_setting == StatsParameter.PLOT_CURBEST_AND_RUNBEST) plotFitnessPoint(0, subGraph++, functionCalls, bestRunIndividual.getFitness()[0]);
|
||||
}
|
||||
if (doPlotWorst) {
|
||||
// schlechteste Fitness plotten
|
||||
@ -229,11 +247,14 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl
|
||||
System.err.println("m_WorstFitness==null in plotStatisticsPerformed");
|
||||
return;
|
||||
}
|
||||
plotFitnessPoint(0, (doPlotBest ? 1 : 0) , functionCalls, currentWorstFit[0]);
|
||||
plotFitnessPoint(0, subGraph++ , functionCalls, currentWorstFit[0]);
|
||||
}
|
||||
if (doPlotMeasures) {
|
||||
plotFitnessPoint(0, 1, functionCalls, avgPopDist);
|
||||
plotFitnessPoint(0, 2, functionCalls, maxPopDist);
|
||||
plotFitnessPoint(0, subGraph++, functionCalls, avgPopDist);
|
||||
plotFitnessPoint(0, subGraph++, functionCalls, maxPopDist);
|
||||
}
|
||||
if (doPlotBestFeasible && currentBestFeasibleFit!=null) {
|
||||
plotFitnessPoint(0, subGraph++, functionCalls, currentBestFeasibleFit[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,11 +33,13 @@ public class StatsParameter implements InterfaceStatisticsParameter, Serializabl
|
||||
public final static int PLOT_WORST = 1;
|
||||
public final static int PLOT_BEST_AND_WORST = 2;
|
||||
public final static int PLOT_BEST_AND_MEASURES = 3;
|
||||
public final static int PLOT_CURBEST_AND_RUNBEST = 4;
|
||||
public final static Tag[] TAGS_PLOT_FITNESS = {
|
||||
new Tag(PLOT_BEST, "plot best fitness"),
|
||||
new Tag(PLOT_WORST, "plot worst fitness"),
|
||||
new Tag(PLOT_BEST_AND_WORST, "both best and worst"),
|
||||
new Tag(PLOT_BEST_AND_MEASURES, "both best and population measures")
|
||||
new Tag(PLOT_BEST_AND_MEASURES, "both best and population measures"),
|
||||
new Tag(PLOT_CURBEST_AND_RUNBEST, "current best and best of run")
|
||||
};
|
||||
|
||||
public final static int VERBOSITY_NONE = 0;
|
||||
@ -113,7 +115,9 @@ public class StatsParameter implements InterfaceStatisticsParameter, Serializabl
|
||||
case StatsParameter.PLOT_BEST_AND_MEASURES:
|
||||
desc.add(new String[] {"Best", "AvgDist", "MaxDist"});
|
||||
break;
|
||||
}
|
||||
case StatsParameter.PLOT_CURBEST_AND_RUNBEST:
|
||||
desc.add(new String[] {"Cur.Best", "Run Best"});
|
||||
break; }
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
@ -88,11 +88,10 @@ private static final boolean TRACE = false;
|
||||
* the measures of the area
|
||||
* it calculates the coordinates
|
||||
*/
|
||||
private DMeasures measures;
|
||||
|
||||
protected DMeasures measures;
|
||||
|
||||
private DBorder dborder = new DBorder();
|
||||
|
||||
|
||||
/**
|
||||
* initializes the DArea with the initial capacity of 10 components
|
||||
*/
|
||||
@ -142,6 +141,7 @@ private static final boolean TRACE = false;
|
||||
if( max_y != null ) srect.height = Math.min(srect.height, getMaxY() - getMinY());
|
||||
return srect;
|
||||
}
|
||||
|
||||
/**
|
||||
* switches the auto focus of this DArea on or off
|
||||
*
|
||||
@ -406,16 +406,20 @@ private static final boolean TRACE = false;
|
||||
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);
|
||||
}
|
||||
if( visible_rect.isEmpty() ) visible_rect = (DRectangle)min_rect.clone();
|
||||
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 );
|
||||
if( grid.isVisible() && grid_to_front ) paintGrid( measures );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* repaints a part of the visible area
|
||||
*
|
||||
@ -685,8 +689,8 @@ private static final boolean TRACE = false;
|
||||
return;
|
||||
}
|
||||
else{
|
||||
grid.hor_dist = ScaledBorder.aBitBigger( grid.rectangle.width / max_grid );
|
||||
grid.ver_dist = ScaledBorder.aBitBigger( grid.rectangle.height / max_grid );
|
||||
grid.setDistances(ScaledBorder.aBitBigger( grid.rectangle.width / max_grid ),
|
||||
ScaledBorder.aBitBigger( grid.rectangle.height / max_grid ));
|
||||
}
|
||||
}
|
||||
grid.paint( m );
|
||||
@ -704,8 +708,7 @@ private static final boolean TRACE = false;
|
||||
if( TRACE ) System.out.println("DArea.paintGrid(ScaledBorder, DMeasures)");
|
||||
Dimension d = getSize();
|
||||
FontMetrics fm = m.getGraphics().getFontMetrics();
|
||||
grid.hor_dist = sb.getSrcdX(fm, d);
|
||||
grid.ver_dist = sb.getSrcdY(fm, d);
|
||||
grid.setDistances(sb.getSrcdX(fm, d), sb.getSrcdY(fm, d));
|
||||
|
||||
if( m.x_scale == null && m.y_scale == null ) grid.paint( m );
|
||||
|
||||
@ -716,10 +719,10 @@ private static final boolean TRACE = false;
|
||||
SlimRect rect = getSlimRectangle();
|
||||
SlimRect src_rect = m.getSourceOf( rect );
|
||||
|
||||
int x = (int)(src_rect.x / grid.hor_dist),
|
||||
y = (int)(src_rect.y / grid.ver_dist);
|
||||
if( x * grid.hor_dist < src_rect.x ) x++;
|
||||
if( y * grid.ver_dist < src_rect.y ) y++;
|
||||
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 );
|
||||
@ -727,14 +730,14 @@ private static final boolean TRACE = false;
|
||||
|
||||
double pos;
|
||||
|
||||
for( ; (pos = x * grid.hor_dist) < src_rect.x + src_rect.width; x++ ){
|
||||
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.ver_dist) < src_rect.y + src_rect.height; 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 );
|
||||
|
@ -31,7 +31,7 @@ public class DGrid extends DComponent
|
||||
/**
|
||||
* the distances between the lines
|
||||
*/
|
||||
double hor_dist, ver_dist;
|
||||
private double hor_dist, ver_dist;
|
||||
|
||||
private Color DEFAULT_COLOR = Color.lightGray;
|
||||
|
||||
@ -68,7 +68,20 @@ public class DGrid extends DComponent
|
||||
this.ver_dist = ver_dist;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public void setDistances(double hor, double ver) {
|
||||
hor_dist=hor;
|
||||
ver_dist=ver;
|
||||
// System.out.println("set new Grid distances " + this.toString());
|
||||
}
|
||||
|
||||
public double getHorDist() {
|
||||
return hor_dist;
|
||||
}
|
||||
|
||||
public double getVerDist() {
|
||||
return ver_dist;
|
||||
}
|
||||
/**
|
||||
* paints the grid...
|
||||
*
|
||||
@ -84,7 +97,7 @@ public class DGrid extends DComponent
|
||||
minX = (int)( rectangle.x / hor_dist );
|
||||
if( minX * hor_dist <= rectangle.x ) minX++;
|
||||
minX *= hor_dist;
|
||||
minY = (int)( rectangle.y / ver_dist );
|
||||
minY = ( rectangle.y / ver_dist );
|
||||
if( minY * ver_dist <= rectangle.y ) minY++;
|
||||
minY *= ver_dist;
|
||||
|
||||
@ -98,16 +111,32 @@ public class DGrid extends DComponent
|
||||
|
||||
p1.x = rectangle.x;
|
||||
p2.x = p1.x + rectangle.width;
|
||||
for( pos = minY; pos<=rectangle.y + rectangle.height; pos += ver_dist ){
|
||||
pos = minY;
|
||||
while ( pos<=rectangle.y + rectangle.height){
|
||||
p1.y = p2.y = pos;
|
||||
l = new DLine( p1, p2, color );
|
||||
l.paint( m );
|
||||
if (pos+ver_dist<=pos) {
|
||||
System.err.println("Overflow error in DGrid!");
|
||||
pos *= 1.01;
|
||||
} else pos += ver_dist;
|
||||
// System.out.println("pos is " + pos + ", loop until " + rectangle.y + rectangle.height);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "chart2d.DGrid[ hor: "+hor_dist+", ver: "+ver_dist+" ]";
|
||||
}
|
||||
|
||||
// public void updateDistByRect(DRectangle rect) {
|
||||
// System.out.println(rect);
|
||||
// if (!rect.isEmpty() && (hor_dist>0 && ver_dist>0)) {
|
||||
// double horRatio = Math.abs(rectangle.x)/hor_dist;
|
||||
// double verRatio = Math.abs(rectangle.y)/ver_dist;
|
||||
//// rectangle = visRect;
|
||||
// setDistances(rect.x*horRatio, rect.y*verRatio);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1,23 +1,5 @@
|
||||
/**
|
||||
* Filename: $RCSfile: ScaledBorder.java,v $
|
||||
* Purpose:
|
||||
* Language: Java
|
||||
* Compiler: JDK 1.3
|
||||
* Authors: Fabian Hennecke
|
||||
* Version: $Revision: 1.1.1.1 $
|
||||
* $Date: 2003/07/03 14:59:42 $
|
||||
* $Author: ulmerh $
|
||||
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package wsi.ra.chart2d;
|
||||
|
||||
/*==========================================================================*
|
||||
* IMPORTS
|
||||
*==========================================================================*/
|
||||
|
||||
import java.awt.* ;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.border.* ;
|
||||
@ -25,13 +7,9 @@ import java.awt.geom.AffineTransform ;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/*==========================================================================*
|
||||
* CLASS DECLARATION
|
||||
*==========================================================================*/
|
||||
|
||||
/**
|
||||
* ScaledBorder puts an border around Components
|
||||
* ( especially around DrawingAreas ) with scaled and labeled axes
|
||||
* ( especially around DrawingAreas ) with scaled and labeled axes.
|
||||
*/
|
||||
public class ScaledBorder implements Border
|
||||
{
|
||||
@ -125,7 +103,7 @@ public class ScaledBorder implements Border
|
||||
* formatters of the x- and y-axis numbers
|
||||
* @see java.text.NumberFormat
|
||||
*/
|
||||
public NumberFormat format_x = new DecimalFormat(),
|
||||
private NumberFormat format_x = new DecimalFormat(),
|
||||
format_y = new DecimalFormat();
|
||||
|
||||
private double src_dX = -1, src_dY = -1;
|
||||
@ -195,6 +173,22 @@ public class ScaledBorder implements Border
|
||||
src_dY = dY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inner rectangle in pixel coordinates.
|
||||
*
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
public SlimRect getInnerRect(Component c) {
|
||||
Insets inner_insets = getBorderInsets(c);
|
||||
Dimension d = c.getSize();
|
||||
int width = d.width - inner_insets.left - inner_insets.right;
|
||||
int height = d.height - inner_insets.top - inner_insets.bottom;
|
||||
|
||||
SlimRect rect=new SlimRect(inner_insets.left, inner_insets.top, width, height);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height){
|
||||
if( under_construction ) System.out.println("ScaledBorder.paintBorder()");
|
||||
if( foreground == null ) foreground = c.getForeground();
|
||||
@ -280,48 +274,68 @@ public class ScaledBorder implements Border
|
||||
inner_insets.top + cd.height );
|
||||
}
|
||||
|
||||
drawYValues( g, inner_insets, cd );
|
||||
drawYValues( g, inner_insets);
|
||||
drawXValues( g, inner_insets, cd );
|
||||
|
||||
g.setColor( old_color );
|
||||
}
|
||||
|
||||
/**
|
||||
* The scaling of the y-axis is defined here.
|
||||
*
|
||||
* @param g
|
||||
* @param insets
|
||||
*/
|
||||
private void drawYValues( Graphics g, Insets insets){
|
||||
if( under_construction ) System.out.println("ScaledBorder.drawYValues()");
|
||||
|
||||
private void drawYValues( Graphics g, Insets insets, Dimension cd ){
|
||||
if( under_construction ) System.out.println("ScaledBorder.drawYValues()");
|
||||
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int n, fontAsc = fm.getAscent(), v2m = fm.stringWidth("0") / y_values2marker;
|
||||
n = (int)( src_rect.y / src_dY );
|
||||
if( n * src_dY < src_rect.y || ( src_rect.x == 0 && src_rect.y == 0 ) ) n++;
|
||||
|
||||
|
||||
double v, minx = src_rect.x;
|
||||
if( x_scale != null ) minx = x_scale.getImageOf( minx );
|
||||
for(; (v = n * src_dY) <= src_rect.y + src_rect.height; n++ ){
|
||||
if( y_scale != null ) v = y_scale.getImageOf( v );
|
||||
String text = format_y.format(v);
|
||||
try{ v = format_y.parse(text).doubleValue(); }
|
||||
catch( java.text.ParseException ex ){ }
|
||||
Point p = m.getPoint( minx, v );
|
||||
if( p != null ){
|
||||
g.drawString( text,
|
||||
insets.left - fm.stringWidth( text ) - v2m - marker_length,
|
||||
p.y + fontAsc / 2 );
|
||||
g.drawLine( insets.left - marker_length, p.y, insets.left, p.y );
|
||||
}
|
||||
}
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int fontAsc = fm.getAscent(), v2m = fm.stringWidth("0") / y_values2marker;
|
||||
int n = (int)( src_rect.y / src_dY );
|
||||
// if( n * src_dY < src_rect.y || ( src_rect.x == 0 && src_rect.y == 0 ) ) n++;
|
||||
if( n * src_dY < src_rect.y || ( src_rect.x == 0 && src_rect.y == 0 ) ) {
|
||||
if (n+1 > n) n++;
|
||||
else System.err.println("Overflow error A in ScaledBorder!");
|
||||
}
|
||||
|
||||
double v, scaledV, minx = src_rect.x;
|
||||
if( x_scale != null ) minx = x_scale.getImageOf( minx );
|
||||
v = n * src_dY;
|
||||
while (v <= src_rect.y + src_rect.height){
|
||||
if( y_scale != null ) scaledV = y_scale.getImageOf( v );
|
||||
else scaledV=v;
|
||||
String text = format_y.format(scaledV);
|
||||
try{ scaledV = format_y.parse(text).doubleValue(); }
|
||||
catch( java.text.ParseException ex ){ }
|
||||
Point p = m.getPoint( minx, scaledV );
|
||||
if( p != null ){
|
||||
g.drawString( text,
|
||||
insets.left - fm.stringWidth( text ) - v2m - marker_length,
|
||||
p.y + fontAsc / 2 );
|
||||
g.drawLine( insets.left - marker_length, p.y, insets.left, p.y );
|
||||
}
|
||||
if (v+src_dY<= v) {
|
||||
System.err.println("Overflow error B in ScaledBorder!");
|
||||
v*=1.01;
|
||||
}
|
||||
v += src_dY;
|
||||
}
|
||||
}
|
||||
|
||||
public double getSrcdY( FontMetrics fm, Dimension cd ){
|
||||
if( under_construction ) System.out.println("ScaledBorder.getSrcdY()");
|
||||
if( (!do_refresh && src_dY != -1) || !auto_scale_y ) return src_dY;
|
||||
int max = cd.height / fm.getHeight();
|
||||
double minsrc_dY = 2 * src_rect.height / (double)max; // die 2 einfach mal so eingesetzt <--------------------------
|
||||
src_dY = aBitBigger( minsrc_dY );
|
||||
if( src_dY < minimal_increment ) src_dY = minimal_increment;
|
||||
return src_dY;
|
||||
return getSrcdY(fm.getHeight(), cd.height);
|
||||
}
|
||||
|
||||
public double getSrcdY( int fontMetricsHeight, int componentHeight ){
|
||||
if( under_construction ) System.out.println("ScaledBorder.getSrcdY()");
|
||||
if( (!do_refresh && src_dY != -1) || !auto_scale_y ) return src_dY;
|
||||
int max = componentHeight / fontMetricsHeight;
|
||||
double minsrc_dY = 2 * src_rect.height / (double)max; // die 2 einfach mal so eingesetzt <--------------------------
|
||||
src_dY = aBitBigger( minsrc_dY );
|
||||
if( src_dY < minimal_increment ) src_dY = minimal_increment;
|
||||
return src_dY;
|
||||
}
|
||||
|
||||
private void drawXValues( Graphics g, Insets insets, Dimension cd ){
|
||||
if( under_construction ) System.out.println("ScaledBorder.drawXValues()");
|
||||
|
||||
@ -418,11 +432,19 @@ public class ScaledBorder implements Border
|
||||
public boolean isBorderOpaque(){
|
||||
return outer_border.isBorderOpaque();
|
||||
}
|
||||
//
|
||||
// private String stringOf( double v ){
|
||||
// if( (int)v == v ) return String.valueOf( (int)v );
|
||||
// return String.valueOf( v );
|
||||
// }
|
||||
|
||||
/**
|
||||
* Apply a decimal format pattern to x (bXorY true) or y (bXorY false) axis.
|
||||
*
|
||||
* @see #java.text.DecimalFormat.applyPattern
|
||||
*
|
||||
* @param bXorY
|
||||
* @param pattern
|
||||
*/
|
||||
public void applyPattern(boolean bXorY, String pattern) {
|
||||
if (bXorY) ((java.text.DecimalFormat)format_x).applyPattern(pattern);
|
||||
else ((java.text.DecimalFormat)format_y).applyPattern(pattern);
|
||||
}
|
||||
|
||||
public Insets getBorderInsets(Component c){
|
||||
if( under_construction ) System.out.println("ScaledBorder.getBorderInsets()");
|
||||
@ -452,17 +474,24 @@ public class ScaledBorder implements Border
|
||||
if( y_label != null ) insets.left += fm.getAscent() + fm.getDescent();
|
||||
insets.left += y_label2values * digit_width;
|
||||
getSrcdY( fm, c.getSize() );
|
||||
int n, maxWidth = 0;
|
||||
n = (int)( src_rect.y / src_dY );
|
||||
if( n * src_dY < src_rect.y ) n++;
|
||||
while( n * src_dY <= src_rect.y + src_rect.height ){
|
||||
double start, n, inc;
|
||||
int maxWidth = 0;
|
||||
start = src_dY*(int)( src_rect.y / src_dY );
|
||||
n=start;
|
||||
if ( n < src_rect.y ) n+=src_dY;
|
||||
|
||||
if (((src_rect.y + src_rect.height)-start)>20) inc = ((src_rect.y + src_rect.height)- start)/20.;
|
||||
else inc = src_dY;
|
||||
|
||||
for (; n <= src_rect.y + src_rect.height; n+=inc ){
|
||||
// TODO here might be a bug for mean values
|
||||
double v = n * src_dY;
|
||||
double v = n;
|
||||
if( y_scale != null ) v = y_scale.getImageOf( v );
|
||||
int w = fm.stringWidth( format_y.format(v) );
|
||||
if( w > maxWidth ) maxWidth = w;
|
||||
n++;
|
||||
// avoid nearly endless loop for large src_rect.y value and small src_dY
|
||||
}
|
||||
|
||||
insets.left += 1 + y_label2border + maxWidth + digit_width / y_values2marker + marker_length;
|
||||
|
||||
// bottom:
|
||||
@ -477,9 +506,9 @@ public class ScaledBorder implements Border
|
||||
if( show_arrows ) insets.right += x_values2arrow + arrow_length;
|
||||
insets.right += axis2border;
|
||||
getSrcdX( fm, c.getSize() );
|
||||
n = (int)( src_rect.x + src_rect.width / src_dX );
|
||||
if( n < 0 ) n ++;
|
||||
int w = fm.stringWidth( format_x.format(n * src_dX) );
|
||||
int k = (int)( src_rect.x + src_rect.width / src_dX );
|
||||
if( k < 0 ) k ++;
|
||||
int w = fm.stringWidth( format_x.format(k * src_dX) );
|
||||
if( w / 2 > insets.right ) insets.right = w / 2;
|
||||
|
||||
old_insets = insets;
|
||||
|
@ -116,4 +116,19 @@ public class SlimRect {
|
||||
public boolean hasEmptyIntersection(SlimRect r){
|
||||
return (getIntersection(r)==null);
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double getWidth() {
|
||||
return width;
|
||||
}
|
||||
public double getHeight() {
|
||||
return height;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user