]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.maps/src/org/simantics/maps/sg/Formatting.java
Optimization of district scene graph node rendering
[simantics/district.git] / org.simantics.district.maps / src / org / simantics / maps / sg / Formatting.java
1 package org.simantics.maps.sg;
2
3 import java.util.Locale;
4
5 /**
6  * @author Tuukka Lehtonen
7  */
8 class Formatting {
9
10     private static final transient double EPSILON = 0.01;
11
12     private static final transient double TRIM_THRESHOLD_MAX_VALUE = Math.pow(10, 4);
13
14     private static final transient String[] SI_UNIT_LARGE_PREFIXES = {
15         "k", "M", "G", "T", "P", "E", "Z", "Y"
16     };
17
18     public static enum FormatMode {
19         LIMIT_DIGITS,
20         LIMIT_DECIMALS,
21     }
22
23     public static String formatValue(double value, int max, boolean removeTrailingZeros, FormatMode formatMode) {
24         return formatValue(value, max, removeTrailingZeros, formatMode, TRIM_THRESHOLD_MAX_VALUE);
25     }
26
27     public static String formatValue(double value, int max, boolean removeTrailingZeros, FormatMode formatMode, double trimThresholdMaxValue) {
28         return formatValue(value, max, removeTrailingZeros, formatMode, trimThresholdMaxValue, true);
29     }
30
31     public static String formatValue(double value, int max, boolean removeTrailingZeros, FormatMode formatMode, double trimThresholdMaxValue, boolean trimLargeValues) {
32         //System.out.println("formatValue(" + value + ", " + max + ", " + removeTrailingZeros + ", " + formatMode + ", " + trimThresholdMaxValue + ", " + trimLargeValues + ")");
33         int allowedDecimals = max;
34         if (formatMode == FormatMode.LIMIT_DIGITS) {
35             int magnitude = (int) Math.ceil(Math.log10(Math.abs(value)));
36             //System.out.println("magnitude(" + value + "): " + magnitude);
37             allowedDecimals -= Math.abs(magnitude);
38             if (allowedDecimals < 0)
39                 allowedDecimals = 0;
40             //System.out.println("allowedDecimals: " + allowedDecimals);
41         }
42
43         String valueStr = String.format(Locale.US, "%." + allowedDecimals + "f", value);
44         if (allowedDecimals > 0) {
45             if (removeTrailingZeros) {
46                 for (int trunc = valueStr.length() - 1; trunc > 0; --trunc) {
47                     char ch = valueStr.charAt(trunc);
48                     if (ch == '.') {
49                         valueStr = valueStr.substring(0, trunc);
50                         break;
51                     }
52                     if (ch != '0') {
53                         valueStr = valueStr.substring(0, trunc + 1);
54                         break;
55                     }
56                 }
57             }
58             if (Math.abs(value) + EPSILON > trimThresholdMaxValue) {
59                 // Cut anything beyond a possible decimal dot out since they
60                 // should not show anyway. This is a complete hack that tries to
61                 // circumvent floating-point inaccuracy problems.
62                 int dotIndex = valueStr.lastIndexOf('.');
63                 if (dotIndex > -1) {
64                     valueStr = valueStr.substring(0, dotIndex);
65                 }
66             }
67         }
68
69         if (valueStr.equals("-0"))
70             valueStr = "0";
71
72         if (trimLargeValues) {
73             double trimValue = value;
74             if (Math.abs(value) + EPSILON >= trimThresholdMaxValue) {
75                 for (int i = 0; Math.abs(trimValue) + EPSILON >= trimThresholdMaxValue; ++i) {
76                     double trim = trimValue / 1000;
77                     if (Math.abs(trim) - EPSILON < trimThresholdMaxValue) {
78                         valueStr = valueStr.substring(0, valueStr.length() - (i + 1) * 3);
79                         valueStr += SI_UNIT_LARGE_PREFIXES[i];
80                         break;
81                     }
82                     trimValue = trim;
83                 }
84             }
85         }
86
87         //System.out.println("formatted result: " + valueStr);
88
89         return valueStr;
90     }
91
92 }