/** * This draws the standard legend text for a BELOW legend. * * @param g2 * @param legentTextX * @param legendTextY * @param fontFamily * @param labelHeightPixels * @param shortBoldLines must be valid (if null, nothing will be drawn, and return value will be * legendTextY unchanged) * @param shortLines from makeShortLines * @return the new legendTextY (adjusted so there is a gap after the current text). */ public static int belowLegendText( Graphics2D g2, int legendTextX, int legendTextY, String fontFamily, int labelHeightPixels, StringArray shortBoldLines, StringArray shortLines) { // String2.log("belowLegendText boldTitle=" + boldTitle); if (shortBoldLines == null) return legendTextY; // draw the boldShortLines int n = shortBoldLines.size(); for (int i = 0; i < n; i++) legendTextY = drawHtmlText( g2, legendTextX, legendTextY, 0, fontFamily, labelHeightPixels, false, "<b>" + encodeAsHtml(shortBoldLines.get(i)) + "</b>"); // draw the shortLines n = shortLines.size(); for (int i = 0; i < n; i++) legendTextY = drawHtmlText( g2, legendTextX, legendTextY, 0, fontFamily, labelHeightPixels, i == n - 1, encodeAsHtml(shortLines.get(i))); return legendTextY; }
/** * This is used when called from within a program. If args is null or args.length is 0, this * loops; otherwise it returns when done. * * @param args if args has values, they are used to answer the questions. * @returns the contents of outFileName (will be "" if trouble) */ public String doIt(String args[], boolean loop) throws Throwable { File2.safeRename(logFileName, logFileName + ".previous"); if (File2.isFile(outFileName)) { try { File2.rename(outFileName, outFileName + ".previous"); } catch (Throwable t) { File2.delete(outFileName); } } String2.setupLog( true, false, // toSystemOut, toSystemErr logFileName, false, // logToStringBuffer true, 20000000); // append String2.log( "*** Starting DasDds " + Calendar2.getCurrentISODateTimeStringLocal() + "\n" + "logFile=" + String2.logFileName() + "\n" + String2.standardHelpAboutMessage()); outFile = new FileWriter(outFileName); // default charset // delete the old log files (pre 1.48 names) File2.delete(EDStatic.fullLogsDirectory + "DasDdsLog.txt"); File2.delete(EDStatic.fullLogsDirectory + "DasDdsLog.txt.previous"); String datasetID = ""; if (args == null) args = new String[0]; // look for -verbose (and remove it) boolean verbose = false; // actually controls reallyVerbose int vi = String2.indexOf(args, "-verbose"); if (vi >= 0) { String2.log("verbose=true"); verbose = true; StringArray sa = new StringArray(args); sa.remove(vi); args = sa.toArray(); } do { // get the EDD type // EDD.reallyVerbose = false; //sometimes while testing datasetID = get( args, 0, "\n*** DasDds ***\n" + "This generates the DAS and DDS for a dataset and puts it in\n" + outFileName + "\n" + "Press ^D or ^C to exit at any time.\n\n" + "Which datasetID", datasetID); if (datasetID == null) { String2.flushLog(); outFile.flush(); outFile.close(); return String2.readFromFile(outFileName)[1]; } // delete the datasetInfo files for this datasetID (in case incorrect info) try { String dir = EDD.datasetDir(datasetID); String2.log( "dataset dir=" + dir + "\n" + "dataset n files not deleted = " + RegexFilenameFilter.regexDelete(dir, ".*", false)); } catch (Throwable t) { String2.log( "\n*** An error occurred while deleting the old info for " + datasetID + ":\n" + MustBe.throwableToString(t)); } try { printToBoth(EDD.testDasDds(datasetID, verbose)); } catch (Throwable t) { String2.log( "\n*** An error occurred while trying to load " + datasetID + ":\n" + MustBe.throwableToString(t)); } String2.flushLog(); } while (loop && args.length == 0); outFile.flush(); outFile.close(); String ret = String2.readFromFile(outFileName)[1]; String2.returnLoggingToSystemOut(); return ret; }
/** * If the line is short, this adds the line to StringArray. If the line is long, this splits the * line in 2 and adds both to StringArray. * * @param limit is the maximum number of characters per line * @param stringArray to capture the parts of s * @param s the string to be split (if needed) (if s == null or "", stringArray is unchanged). */ private static void splitLine(int limit, StringArray stringArray, String s) { int limit10 = limit * 10; while (true) { if (s == null || s.length() == 0) return; int sLength = s.length(); if (sLength <= limit * 2 / 3) { // short line is okay even if all caps stringArray.add(s); return; } // count through chars noting more width of cap letters and digits, than avg letter int lastSpace = -1; int lastNonDigitChar = -1; int po = 0; int sum10 = 0; while (po < sLength && sum10 < limit10) { char ch = s.charAt(po); if (String2.isDigit(ch)) { sum10 += 14; } else if (String2.isLetter(ch)) { sum10 += ch == 'C' || ch == 'M' || ch == 'S' || ch == 'W' ? 16 : ch == 'c' || ch == 'm' || ch == 's' || ch == 'w' || ch == Character.toUpperCase(ch) ? 15 : 10; } else if (ch == ' ') { sum10 += 8; lastSpace = po; lastNonDigitChar = po; } else if ("<>=_".indexOf(ch) >= 0) { sum10 += 17; } else { sum10 += 10; lastNonDigitChar = po; } po++; } // po == sLength is success // if just a few chars more, let it go if (po + 4 >= sLength) { stringArray.add(s); return; } // break at last space (or nonDigitLetter) before limit po = lastSpace >= limit * 3 / 4 ? lastSpace : // preferred lastNonDigitChar >= limit / 2 ? lastNonDigitChar : // next best po; // worst case // add the string stringArray.add(s.substring(0, po + 1)); // revamp s s = s.substring(po + 1).trim(); // remove leading space, if any } }
/** This tests SgtUtil. */ public static void test() throws Exception { // test splitLine String2.log("\n*** SgtUtil.test"); StringArray sa = new StringArray(); // wide sa.clear(); splitLine(38, sa, "This is a test of splitline."); Test.ensureEqual(sa.size(), 1, ""); Test.ensureEqual(sa.get(0), "This is a test of splitline.", ""); // narrow sa.clear(); splitLine(12, sa, "This is a test of splitline."); Test.ensureEqual(sa.size(), 3, ""); Test.ensureEqual(sa.get(0), "This is a ", ""); Test.ensureEqual(sa.get(1), "test of ", ""); Test.ensureEqual(sa.get(2), "splitline.", ""); // narrow and can't split, so chop at limit sa.clear(); splitLine(12, sa, "This1is2a3test4of5splitline."); Test.ensureEqual(sa.size(), 3, ""); Test.ensureEqual(sa.get(0), "This1is2a3t", ""); Test.ensureEqual(sa.get(1), "est4of5split", ""); Test.ensureEqual(sa.get(2), "line.", ""); // caps sa.clear(); splitLine(12, sa, "THESE ARE a a REALLY WIDE."); Test.ensureEqual(sa.size(), 3, ""); Test.ensureEqual(sa.get(0), "THESE ARE ", ""); Test.ensureEqual(sa.get(1), "a a REALLY ", ""); Test.ensureEqual(sa.get(2), "WIDE.", ""); // test suggestPaletteRange Test.ensureEqual( suggestPaletteRange(.3, 8.9), new double[] {0, 10}, ""); // typical Rainbow Linear Test.ensureEqual( suggestPaletteRange(.11, 890), new double[] {.1, 1000}, ""); // typical Rainbow Log Test.ensureEqual( suggestPaletteRange(-7, 8), new double[] {-10, 10}, ""); // typical BlueWhiteRed Linear symmetric // test suggestPalette Test.ensureEqual( suggestPalette(.3, 8.9), "WhiteRedBlack", ""); // small positive, large positive Test.ensureEqual(suggestPalette(300, 890), "Rainbow", ""); // typical Rainbow Log Test.ensureEqual( suggestPalette(-7, 8), "BlueWhiteRed", ""); // typical BlueWhiteRed Linear symmetric // test suggestPaletteScale Test.ensureEqual(suggestPaletteScale(.3, 8.9), "Linear", ""); // typical Rainbow Linear Test.ensureEqual(suggestPaletteScale(.11, 890), "Log", ""); // typical Rainbow Log Test.ensureEqual( suggestPaletteScale(-7, 8), "Linear", ""); // typical BlueWhiteRed Linear symmetric BufferedImage bi = ImageIO.read(new File(String2.unitTestDataDir + "graphs/erdBAssta5day.png")); long time = System.currentTimeMillis(); Test.ensureEqual(findGraph(bi), new int[] {24, 334, 150, 21}, ""); String2.log("findGraph time=" + (System.currentTimeMillis() - time)); }