+ private static double log2 = Math.log(2);
+
+ // Cached dashed line Strokes
+ private static Map<Integer, Stroke> dashedLineLookup = new HashMap<>();
+
+ /**
+ * Returns a dashed line stroke as close to 6-4 pixels as fits within the
+ * charWidth. This allows translations of multiples of charWidth without
+ * disrupting the dashed line. The exact values are 0.6-0.4 proportions of
+ * charWidth for charWidth under 16. For charWidth 16 or over, the number of
+ * dashes doubles as charWidth doubles.
+ *
+ * @param charWidth
+ * @return Stroke with appropriate dashed line fitting exactly within the
+ * charWidth
+ */
+ private static Stroke dashedLine(int charWidth)
+ {
+ if (!dashedLineLookup.containsKey(charWidth))
+ {
+ int power2 = charWidth >= 8 ? (int) (Math.log(charWidth) / log2) : 2;
+ float width = ((float) charWidth) / ((float) Math.pow(2, power2 - 3));
+ float segment1 = width * 0.6f;
+ float segment2 = width - segment1;
+ dashedLineLookup.put(charWidth, new BasicStroke(1,
+ BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 3f, new float[]
+ { segment1, segment2 }, 0f));
+ }
+ return dashedLineLookup.get(charWidth);
+ }
+
+ private static int yValueToPixelHeight(float value, float min,
+ float range, int graphHeight)
+ {
+ return (int) (((value - min) / range) * graphHeight);
+ }
+