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
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
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
00147
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
00219 for (int i = 0; i < lightLines.length; i++) {
00220
00221
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
00233 darkLine.plot(draw);
00234 darkLabel.plot(draw);
00235 }
00236
00240 public void init() {
00241
00242 initOriginEnd();
00243 setSlicing();
00244
00245
00246
00247 if (gridVisible) {
00248 setLightLines();
00249 setLightLabels();
00250 }
00251 }
00252
00256 public void resetBase() {
00257
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
00282
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
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
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 }
00324 lightLabelNames = null;
00325 }
00326
00336 public void setLightLabelText(String[] _lightLabelnames) {
00337 lightLabelNames = _lightLabelnames;
00338 setLightLabels();
00339 }
00340
00347 public void setLightLabelFont(Font f) {
00348 lightLabelFont = f;
00349 setLightLabels();
00350 }
00351
00358 public void setLightLabelAngle(double angle) {
00359 lightLabelAngle = angle;
00360 setLightLabels();
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
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
00452
00453
00454 private void setLightLines() {
00455
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
00476
00477
00478
00479 lightLines[i][j] = new Line(Color.lightGray, origin_tmp,
00480 end_tmp);
00481 }
00482 i2++;
00483 }
00484 }
00485
00486 private void initDarkLines() {
00487
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
00496
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;
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
00513
00514 }
00515
00516 private void setSlicing() {
00517
00518
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
00530 for (int i = 0; i < labelsSlicing.length; i++) {
00531 labelsSlicing[i] = Math.pow(10, i + minPow10);
00532 }
00533
00534
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
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
00570 linesSlicing[i] = stringMap.get(string);
00571 labelsSlicing[i] = stringMap.get(string);
00572 lightLabelNames[i] = string;
00573 i++;
00574 }
00575 }
00576
00577
00578
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
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 }