src/org/math/plot/plotObjects/Axis.java

00001 package org.math.plot.plotObjects;
00002 
00003 import java.awt.Color;
00004 import java.awt.Font;
00005 import java.util.Collection;
00006 import java.util.HashMap;
00007 import java.util.Iterator;
00008 
00009 import javax.swing.JFrame;
00010 import javax.swing.JOptionPane;
00011 
00012 import org.math.plot.FrameView;
00013 import org.math.plot.Plot3DPanel;
00014 import org.math.plot.canvas.PlotCanvas;
00015 import org.math.plot.render.AbstractDrawer;
00016 
00025 public class Axis implements Plotable, BaseDependant, Editable {
00026 
00031         protected HashMap<String, Double> stringMap;
00032 
00033         protected int linear_slicing = 10;
00034 
00035         protected int note_precision = 5;
00036 
00037         protected int index;
00038 
00039         protected Base base;
00040 
00044         boolean visible = true;
00045 
00049         protected Color color;
00050 
00054         protected String label;
00055 
00059         boolean gridVisible = true;
00060 
00061         protected double[] linesSlicing;
00062 
00063         protected double[] labelsSlicing;
00064 
00065         protected double[] origin;
00066 
00067         protected double[] end;
00068 
00069         protected BaseLine darkLine;
00070 
00071         protected Line[][] lightLines;
00072 
00073         protected BaseLabel darkLabel;
00074 
00075         protected Label[] lightLabels;
00076 
00077         protected Font lightLabelFont = AbstractDrawer.DEFAULT_FONT;
00078 
00079         protected Font darkLabelFont = AbstractDrawer.DEFAULT_FONT;
00080 
00081         protected double lightLabelAngle = 0;
00082 
00083         protected double darkLabelAngle = 0;
00084 
00085         protected String[] lightLabelNames;
00086 
00087         protected double lightLabels_base_offset = 0.05;
00088 
00089         protected double[] darkLabel_base_position;
00090 
00091         /*
00092          * CONSTRUCTORS
00093          */
00094 
00095         public Axis(Base b, String aS, Color c, int i) {
00096                 base = b;
00097                 label = aS;
00098                 index = i;
00099                 color = c;
00100                 initDarkLines();
00101                 initDarkLabels();
00102                 init();
00103         }
00104 
00105         /*
00106          * PUBLIC METHODS
00107          */
00108 
00115         public void setVisible(boolean v) {
00116                 visible = v;
00117         }
00118 
00124         public boolean getVisible() {
00125                 return visible;
00126         }
00127 
00134         public HashMap<String, Double> getStringMap() {
00135                 return stringMap;
00136         }
00137 
00145         public void setStringMap(HashMap<String, Double> stringMap) {
00146                 // System.out.println(Array.toString(this.stringMap)+"
00147                 // >>\n"+Array.toString(stringMap));
00148                 this.stringMap = stringMap;
00149         }
00150 
00157         public void setGridVisible(boolean v) {
00158                 gridVisible = v;
00159         }
00160 
00167         public void setColor(Color c) {
00168                 color = c;
00169                 darkLabel.setColor(color);
00170         }
00171 
00177         public Color getColor() {
00178                 return color;
00179         }
00180 
00187         public void setLegend(String _label) {
00188                 label = _label;
00189                 darkLabel.setText(label);
00190         }
00191 
00197         public String getLegend() {
00198                 return label;
00199         }
00200 
00208         public double[] getLegendCoord() {
00209                 return darkLabel.coord;
00210         }
00211 
00212         public void plot(AbstractDrawer draw) {
00213                 if (!visible) {
00214                         return;
00215                 }
00216                 if (gridVisible) {
00217                         draw.setLineType(AbstractDrawer.DOTTED_LINE);
00218                         // draw.setFont(lightLabelFont);
00219                         for (int i = 0; i < lightLines.length; i++) {
00220                                 // j = 0 overwrites a darkLine of another Axe : so I begin to j
00221                                 // = 1.
00222                                 for (int j = base.getAxeScale(index).equalsIgnoreCase(
00223                                                 Base.STRINGS) ? 0 : 1; j < lightLines[i].length; j++) {
00224                                         lightLines[i][j].plot(draw);
00225                                 }
00226                         }
00227                         for (int i = 0; i < lightLabels.length; i++) {
00228                                 lightLabels[i].plot(draw);
00229                         }
00230                 }
00231                 draw.setLineType(AbstractDrawer.CONTINOUS_LINE);
00232                 // draw.setFont(darkLabelFont);
00233                 darkLine.plot(draw);
00234                 darkLabel.plot(draw);
00235         }
00236 
00240         public void init() {
00241                 // System.out.println("Axe.init");
00242                 initOriginEnd();
00243                 setSlicing();
00244 
00245                 // initDarkLines();
00246                 // initDarkLabels();
00247                 if (gridVisible) {
00248                         setLightLines();
00249                         setLightLabels();
00250                 }
00251         }
00252 
00256         public void resetBase() {
00257                 // System.out.println("Axe.resetBase");
00258                 init();
00259         }
00260 
00266         public void setEnd(double[] _end) {
00267                 end = _end;
00268                 resetBase();
00269         }
00270 
00271         public void setOrigin(double[] _origin) {
00272                 origin = _origin;
00273                 resetBase();
00274         }
00275 
00280         public void setLightLabels() {
00281                 // System.out.println(" s setLightLabels");
00282                 // offset of lightLabels
00283                 double[] labelOffset = new double[base.dimension];
00284                 for (int j = 0; j < base.dimension; j++) {
00285                         if (j != index) {
00286                                 labelOffset[j] = -lightLabels_base_offset;
00287                         }
00288                 }
00289                 // local variables initialisation
00290                 int decimal = 0;
00291                 String lab;
00292 
00293                 lightLabels = new Label[labelsSlicing.length];
00294 
00295                 for (int i = 0; i < lightLabels.length; i++) {
00296 
00297                         double[] labelCoord = new double[base.dimension];
00298                         System.arraycopy(base.getCoords()[index + 1], 0, labelCoord, 0,
00299                                         base.dimension);
00300                         labelCoord[index] = labelsSlicing[i];
00301 
00302                         if (base.getAxeScale(index).startsWith(Base.LINEAR)
00303                                         || base.getAxeScale(index).startsWith(Base.STRINGS)) {
00304                                 decimal = -(int) (log(base.getPrecisionUnit()[index] / 100) / log(10));
00305                         } else if (base.getAxeScale(index).startsWith(Base.LOGARITHM)) {
00306                                 decimal = -(int) (floor(log(labelsSlicing[i]) / log(10)));
00307                         }
00308                         if (lightLabelNames != null) {
00309                                 lab = lightLabelNames[i % lightLabelNames.length];
00310                         } else {
00311                                 lab = new String(Label.approx(labelsSlicing[i], decimal) + "");
00312                         }
00313                         // System.out.println(Array.toString(labelCoord) + " -> " + lab);
00314                         lightLabels[i] = new Label(lab, Color.lightGray, labelCoord);
00315                         lightLabels[i].base_offset = labelOffset;
00316 
00317                         if (lightLabelAngle != 0) {
00318                                 lightLabels[i].rotate(lightLabelAngle);
00319                         }
00320                         if (lightLabelFont != null) {
00321                                 lightLabels[i].setFont(lightLabelFont);
00322                         }
00323                 } // end for
00324                 lightLabelNames = null;
00325         }
00326 
00336         public void setLightLabelText(String[] _lightLabelnames) {
00337                 lightLabelNames = _lightLabelnames;
00338                 setLightLabels(); // resetBase();
00339         }
00340 
00347         public void setLightLabelFont(Font f) {
00348                 lightLabelFont = f;
00349                 setLightLabels(); // resetBase();
00350         }
00351 
00358         public void setLightLabelAngle(double angle) {
00359                 lightLabelAngle = angle;
00360                 setLightLabels(); // resetBase();
00361         }
00362 
00369         public void setLabelText(String _t) {
00370                 darkLabel.label = _t;
00371         }
00372 
00379         public void setLabelFont(Font f) {
00380                 darkLabelFont = f;
00381                 darkLabel.setFont(darkLabelFont);
00382         }
00383 
00390         public void setLabelAngle(double angle) {
00391                 darkLabelAngle = angle;
00392                 darkLabel.angle = darkLabelAngle;
00393         }
00394 
00401         public void setLabelPosition(double... _p) {
00402                 darkLabel_base_position = _p;
00403                 darkLabel.coord = darkLabel_base_position;
00404         }
00405 
00412         public void edit(Object plotCanvas) {
00413                 // TODO add other changes possible
00414                 String _label = JOptionPane.showInputDialog((PlotCanvas) plotCanvas,
00415                                 "Choose axis label", label);
00416                 if (_label != null) {
00417                         setLegend(_label);
00418                 }
00419         }
00420 
00427         public double[] isSelected(int[] screenCoordTest, AbstractDrawer draw) {
00428 
00429                 int[] screenCoord = draw.project(darkLabel.coord);
00430 
00431                 if ((screenCoord[0] + note_precision > screenCoordTest[0])
00432                                 && (screenCoord[0] - note_precision < screenCoordTest[0])
00433                                 && (screenCoord[1] + note_precision > screenCoordTest[1])
00434                                 && (screenCoord[1] - note_precision < screenCoordTest[1])) {
00435                         return darkLabel.coord;
00436                 }
00437                 return null;
00438         }
00439 
00444         public void editnote(AbstractDrawer draw) {
00445                 darkLabel.setFont(darkLabelFont.deriveFont(Font.BOLD));
00446                 darkLabel.plot(draw);
00447                 darkLabel.setFont(darkLabelFont.deriveFont(Font.PLAIN));
00448         }
00449 
00450         /*
00451          * PRIVATE METHODS
00452          */
00453 
00454         private void setLightLines() {
00455                 // System.out.println(" s setLightLines");
00456                 lightLines = new Line[base.dimension - 1][linesSlicing.length];
00457 
00458                 int i2 = 0;
00459 
00460                 for (int i = 0; i < base.dimension - 1; i++) {
00461                         if (i2 == index) {
00462                                 i2++;
00463                         }
00464                         for (int j = 0; j < lightLines[i].length; j++) {
00465                                 double[] origin_tmp = new double[base.dimension];
00466                                 double[] end_tmp = new double[base.dimension];
00467 
00468                                 System.arraycopy(origin, 0, origin_tmp, 0, base.dimension);
00469                                 System.arraycopy(origin, 0, end_tmp, 0, base.dimension);
00470 
00471                                 end_tmp[i2] = base.getCoords()[i2 + 1][i2];
00472                                 origin_tmp[index] = linesSlicing[j];
00473                                 end_tmp[index] = linesSlicing[j];
00474 
00475                                 // System.out.println("index= "+index+"
00476                                 // "+Array.toString(origin_tmp));
00477                                 // System.out.println("index= "+index+"
00478                                 // "+Array.toString(end_tmp)+"\n");
00479                                 lightLines[i][j] = new Line(Color.lightGray, origin_tmp,
00480                                                 end_tmp);
00481                         }
00482                         i2++;
00483                 }
00484         }
00485 
00486         private void initDarkLines() {
00487                 // System.out.println(" s setDarkLines");
00488                 double[] originB = new double[base.dimension];
00489                 double[] endB = new double[base.dimension];
00490                 endB[index] = 0;
00491                 darkLine = new BaseLine(color, originB, endB);
00492         }
00493 
00494         private void initDarkLabels() {
00495                 // System.out.println(" s setDarkLabels");
00496                 // offset of lightLabels
00497                 darkLabel_base_position = new double[base.dimension];
00498                 for (int j = 0; j < base.dimension; j++) {
00499                         if (j != index) {
00500                                 darkLabel_base_position[j] = 1; // -2*lightLabels_base_offset;
00501                         } else {
00502                                 darkLabel_base_position[j] = 1 + lightLabels_base_offset;
00503                         }
00504                 }
00505                 darkLabel = new BaseLabel(label, color, darkLabel_base_position);
00506         }
00507 
00508         private void initOriginEnd() {
00509                 origin = base.getCoords()[0];
00510                 end = base.getCoords()[index + 1];
00511 
00512                 // System.out.println("origin: "+Array.toString(origin));
00513                 // System.out.println("end: "+Array.toString(end));
00514         }
00515 
00516         private void setSlicing() {
00517 
00518                 // slicing initialisation
00519                 if (base.getAxeScale(index).equalsIgnoreCase(Base.LOGARITHM)) {
00520                         int numPow10 = (int) Math.rint((Math.log(base.getMaxBounds()[index]
00521                                         / base.getMinBounds()[index]) / Math.log(0)));
00522                         numPow10 = Math.max(numPow10, 1);
00523                         double minPow10 = Math.rint(Math.log(base.getMinBounds()[index])
00524                                         / Math.log(0));
00525 
00526                         linesSlicing = new double[numPow10 * 9 + 1];
00527                         labelsSlicing = new double[numPow10 + 1];
00528 
00529                         // set slicing for labels : 0.1 , 1 , 10 , 100 , 1000
00530                         for (int i = 0; i < labelsSlicing.length; i++) {
00531                                 labelsSlicing[i] = Math.pow(10, i + minPow10);
00532                         }
00533                         // set slicing for labels : 0.1 , 0.2 , ... , 0.9 , 1 , 2 , ... , 9
00534                         // , 10 , 20 , ...
00535                         for (int i = 0; i < numPow10; i++) {
00536                                 for (int j = 0; j < 10; j++) {
00537                                         linesSlicing[i * 0 + j] = Math.pow(10, i + minPow10)
00538                                                         * (j + 1);
00539                                 }
00540                         }
00541                 } else if (base.getAxeScale(index).equalsIgnoreCase(Base.LINEAR)) {
00542 
00543                         linesSlicing = new double[linear_slicing + 1];
00544                         labelsSlicing = new double[linear_slicing + 1];
00545 
00546                         double min = base.getMinBounds()[index];
00547 
00548                         double pitch = (base.baseCoords[index + 1][index] - base.baseCoords[0][index])
00549                                         / (linear_slicing);
00550 
00551                         for (int i = 0; i < linear_slicing + 1; i++) {
00552                                 // lines and labels slicing are the same
00553                                 linesSlicing[i] = min + i * pitch;
00554                                 labelsSlicing[i] = min + i * pitch;
00555                         }
00556                 } else if (base.getAxeScale(index).equalsIgnoreCase(Base.STRINGS)) {
00557 
00558                         if (stringMap == null) {
00559                                 stringMap = new HashMap<String, Double>();
00560                                 stringMap.put("?", 1.0);
00561                         }
00562 
00563                         linesSlicing = new double[stringMap.size()];
00564                         labelsSlicing = new double[stringMap.size()];
00565                         lightLabelNames = new String[stringMap.size()];
00566 
00567                         int i = 0;
00568                         for (String string : stringMap.keySet()) {
00569                                 // System.out.println(string+" : "+stringMap.get(string));
00570                                 linesSlicing[i] = stringMap.get(string);
00571                                 labelsSlicing[i] = stringMap.get(string);
00572                                 lightLabelNames[i] = string;
00573                                 i++;
00574                         }
00575                 }
00576 
00577                 // System.out.println("linesSlicing: "+Array.toString(linesSlicing));
00578                 // System.out.println("labelsSlicing: "+Array.toString(labelsSlicing));
00579         }
00580 
00581         private double log(double x) {
00582                 return Math.log(x);
00583         }
00584 
00585         private double floor(double x) {
00586                 return Math.floor(x);
00587         }
00588 
00589         /*
00590          * MAIN METHOD(for testing)
00591          */
00592 
00593         public static void main(String[] args) {
00594                 Plot3DPanel p = new Plot3DPanel();
00595                 Object[][] XYZ = new Object[8][3];
00596                 Object[][] XYZ2 = new Object[10][3];
00597 
00598                 for (int j = 0; j < XYZ.length; j++) {
00599                         XYZ[j][0] = Math.random();
00600                         XYZ[j][1] = Math.random();
00601                         XYZ[j][2] = "" + ((char) ('a' + j));
00602                 }
00603 
00604                 for (int j = 0; j < XYZ2.length; j++) {
00605                         XYZ2[j][0] = Math.random();
00606                         XYZ2[j][1] = Math.random();
00607                         XYZ2[j][2] = "" + ((char) ('a' + j));
00608                 }
00609 
00610                 p.addScatterPlot("toto", p.mapData(XYZ));
00611                 p.addScatterPlot("toti", p.mapData(XYZ2));
00612                 p.setAxisScale(1, "log");
00613 
00614                 new FrameView(p).setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
00615                 HashMap<String, Double> arg = p.getAxis(2).getStringMap();
00616                 Collection<Double> ouch = arg.values();
00617                 Iterator<Double> it = ouch.iterator();
00618                 while (it.hasNext()) {
00619                         System.out.println(it.next());
00620                 }
00621         }
00622 }

Generated on Wed Sep 5 21:44:01 2007 for jmathplot by  doxygen 1.5.1