/** * Get list of series for each sample in array * * @return */ public static ArrayList<ITridasSeries> getSeries(ArrayList<Sample> sampleList) { ArrayList<ITridasSeries> serList = new ArrayList<ITridasSeries>(); for (Sample s : sampleList) { serList.add(s.getSeries()); } return serList; }
public void draw( GraphSettings gInfo, Graphics2D g2, int bottom, Graph g, int thickness, int xscroll) { // cache yearsize, we use this a lot int yearWidth = gInfo.getYearWidth(); // the size of a year, in pixels float unitScale = gInfo.getHundredUnitHeight() / 100.0f; // the size of 1 "unit" in pixels. // set pen boolean dotted = (gInfo.isDottedIndexes() && (g.graph instanceof Index)); g2.setStroke(makeStroke(thickness, dotted)); // left/right int l = g2.getClipBounds().x; int r = l + g2.getClipBounds().width; // Image img1 = // Toolkit.getDefaultToolkit().getImage("/home/pwb48/dev/java5/tellervo-desktop/src/main/resources/Icons/256x256/tellervo-application.png"); // g2.drawImage(img1, 10, 10, null); // baseline if (gInfo.isShowBaselines()) { int y = bottom - (int) (g.yoffset * unitScale); g2.drawLine(xscroll, y, xscroll + 10 * yearWidth, y); // 1 decade wide -- ok? } // hundred percent line if (gInfo.isShowHundredpercentlines() && (g.graph instanceof Sample) && ((Sample) g.graph).isIndexed()) { Color oldcolor = g2.getColor(); g2.setColor(ColorUtils.blend(oldcolor, gInfo.getBackgroundColor())); // x is 0 if we aren't drawing graph names... // x is the pixel at the end of the empty range if we are. int x = (gInfo.isShowGraphNames()) ? yearWidth * (gInfo.getEmptyBounds().getSpan() - 1) : 0; int y = bottom - (int) (yTransform(1000 * g.scale) * unitScale) - (int) (g.yoffset * unitScale); g2.drawLine((x > xscroll) ? x : xscroll, y, r, y); g2.setColor(oldcolor); } // no data? stop. if (g.graph.getRingWidthData().isEmpty()) return; // compare g.getClipBounds() to [x,0]..[x+yearSize*data.size(),bottom] tempRect.x = yearWidth * (g.graph.getStart().diff(gInfo.getDrawBounds().getStart()) + g.xoffset); // REDUNDANT! see x later tempRect.y = 0; // - g.yoffset, IF you're sure there are no negative values (but there are) tempRect.width = yearWidth * (g.graph.getRingWidthData().size() - 1); tempRect.height = bottom; // TODO: compute top/bottom as min/max? // REFACTOR: will this be obsolete with the start/end stuff below? if (!tempRect.intersects(g2.getClipBounds())) { // skip this graph, it's off the screen return; } // compute sapwood int sapwoodIndex, sapwoodCount = 0; if (g.graph instanceof Sample) { Sample sample = (Sample) g.graph; if (sample.meta().hasSapwood()) sapwoodCount = sample.meta().getNumberOfSapwoodRings(); } sapwoodIndex = g.graph.getRingWidthData().size() - sapwoodCount + 1; // my path GeneralPath p = new GeneralPath(); // x-position int x = yearWidth * (g.graph.getStart().diff(gInfo.getDrawBounds().getStart()) + g.xoffset); // move to the first point -- THIS IS NOT REALLY A SPECIAL CASE! int value; try { value = ((Number) g.graph.getRingWidthData().get(0)).intValue(); value = yTransform(value * g.scale); } catch (ClassCastException cce) { value = yTransform(0); // BAD! instead: (1) just continue now, and (2) NEXT point is a move-to. } p.moveTo(x, bottom - (int) (value * unitScale) - (int) (g.yoffset * unitScale)); /* -- i really want to start at year max(graph.start, bounds.start) -- there are 3 things going on: ---- x is the pixel position ---- i is the index into data[] ---- y is the year -- y isn't updated each time through the loop, so that's not too bad -- but: starting y is easy to compute; from that, i and x are easy */ // connect the lines through the rest of the graph int n = g.graph .getRingWidthData() .size(); // THIS is the third time it's called; why not use it above? for (int i = 1; i < n; i++) { // new x-position for this point x += yearWidth; // if we're past the end, draw what we've got, and say goodbye // (go +_yearsize so the line going off the screen is visible) if (x > r + yearWidth) { break; } // sapwood? draw what we've got, and start a new (thicker) path // but only do it if sapwoodThicker() is enabled! if (gInfo.isThickerSapwood() && i == sapwoodIndex) { g2.draw(p); g2.setStroke(makeStroke(2 * thickness, false)); p = new GeneralPath(); p.moveTo( yearWidth * (i - 1 + g.graph.getStart().diff(gInfo.getDrawBounds().getStart()) + g.xoffset), bottom - (int) (value * unitScale) - (int) (g.yoffset * unitScale)); } // y-position for this point try { value = yTransform(((Number) g.graph.getRingWidthData().get(i)).intValue() * g.scale); } catch (ClassCastException cce) { value = yTransform(0); // e.g., if it's being edited, it's still a string // BAD! instead: (1) draw what i've got so far, and (2) NEXT point is a move-to. // -- try to parse String as an integer? } // Try and paint remark icons try { List<TridasRemark> remarks = g.graph.getTridasValues().get(i).getRemarks(); int xcoord = (yearWidth * (i + g.graph.getStart().diff(gInfo.getDrawBounds().getStart()))); int ycoord = (bottom - (int) (value * unitScale) - (int) (g.yoffset * unitScale)); Graph.drawRemarkIcons(g2, gInfo, remarks, g.graph.getTridasValues().get(i), xcoord, ycoord); } catch (Exception e) { log.error("Exception drawing icons to graph: " + e.getClass()); } int y = bottom - (int) (value * unitScale) - (int) (g.yoffset * unitScale); // if we're not where this sample starts, don't bother drawing yet if (x < l - yearWidth) { p.moveTo(x, y); continue; } // if MR, draw a vertical line -- use Sample.MR, for now if (g.graph instanceof Sample && !validValue(value)) g2.drawLine(x, y - 20, x, y + 20); // draw a line to this point p.lineTo(x, y); } // draw it! g2.draw(p); }
/** * Parse the specified legacy data file for series * * @param file * @param fileType */ private void parseFile(File file, AbstractDendroFormat format) { ArrayList<Sample> sampleList = new ArrayList<Sample>(); // Create a reader based on the file type supplied AbstractDendroFileReader reader = TridasIO.getFileReaderFromFormat(format); if (reader == null) { Alert.error(containerFrame, "Error", "Unknown file type"); return; } // Try and load the file try { reader.loadFile(file.getAbsolutePath()); } catch (IOException e) { Alert.errorLoading(file.getAbsolutePath(), e); return; } catch (InvalidDendroFileException e) { Alert.error( containerFrame, "Error", "The selected file is not a valid " + format.getShortName() + " file.\nPlease check and try again"); return; } catch (NullPointerException e) { Alert.error(containerFrame, "Invalid File", e.getLocalizedMessage()); } TridasTridas tc = reader.getTridasContainer(); log.debug("Project count: " + tc.getProjects().size()); Boolean hideWarningsFlag = false; for (TridasProject p : tc.getProjects()) { for (TridasObject o : p.getObjects()) { for (TridasElement e : TridasUtils.getElementList(o)) { log.debug("Element count: " + o.getElements().size()); for (TridasSample s : e.getSamples()) { for (TridasRadius r : s.getRadiuses()) { for (TridasMeasurementSeries ms : r.getMeasurementSeries()) { Sample sample = EditorFactory.createSampleFromSeries(ms, e, file, format, hideWarningsFlag); if (sample == null) { hideWarningsFlag = true; } else { sampleList.add(sample); } } } } } } for (TridasDerivedSeries ds : p.getDerivedSeries()) { Sample sample = EditorFactory.createSampleFromSeries(ds, null, file, format, hideWarningsFlag); if (sample == null) { hideWarningsFlag = true; } else { sampleList.add(sample); } } } Boolean unitsSet = false; for (ITridasSeries ser : getSeries(sampleList)) { for (TridasValues tv : ser.getValues()) { if (tv.isSetUnit()) { if (tv.getUnit().isSetNormalTridas()) { unitsSet = true; } } } } if (unitsSet == false && sampleList.size() > 0 && unitsIfNotSpecified == null) { Object[] possibilities = {"1/1000th mm", "1/100th mm", "1/50th mm", "1/20th mm", "1/10th mm"}; Object s = JOptionPane.showInputDialog( containerFrame, "One or more series has no units defined.\n" + "Please specify units below:", "Set Units", JOptionPane.PLAIN_MESSAGE, null, possibilities, "1/1000th mm"); if (s.equals("1/1000th mm")) { unitsIfNotSpecified = NormalTridasUnit.MICROMETRES; } else if (s.equals("1/100th mm")) { unitsIfNotSpecified = NormalTridasUnit.HUNDREDTH_MM; } else if (s.equals("1/50th mm")) { unitsIfNotSpecified = NormalTridasUnit.FIFTIETH_MM; } else if (s.equals("1/20th mm")) { unitsIfNotSpecified = NormalTridasUnit.TWENTIETH_MM; } else if (s.equals("1/10th mm")) { unitsIfNotSpecified = NormalTridasUnit.TENTH_MM; } else { Alert.error(containerFrame, "Error", "Invalid measurement units specified"); return; } } for (Sample sample : sampleList) { ITridasSeries series = sample.getSeries(); try { for (int i = 0; i < series.getValues().size(); i++) { TridasValues tv = series.getValues().get(i); if (tv.isSetUnit()) { if (!tv.getUnit().isSetNormalTridas()) { tv.getUnit().setNormalTridas(unitsIfNotSpecified); } } else { TridasUnit unit = new TridasUnit(); unit.setNormalTridas(unitsIfNotSpecified); tv.setUnit(unit); tv.setUnitless(null); } tv = UnitUtils.convertTridasValues(NormalTridasUnit.MICROMETRES, tv, true); TridasUnit unit = new TridasUnit(); unit.setNormalTridas(NormalTridasUnit.MICROMETRES); tv.setUnit(unit); series.getValues().set(i, tv); } } catch (NumberFormatException e) { Alert.error("Error", "One or more data values are not numbers."); return; } catch (ConversionWarningException e) { Alert.error("Error", "Error converting units"); return; } } for (Sample s : sampleList) { SeriesIdentity id = new SeriesIdentity(file, format, s); model.addItem(id); } }