/**
   * 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;
  }
Пример #2
0
  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);
    }
  }