Calculate the actual range, major step interval and set variables for data <-> pixels scaling
()
| 2243 | |
| 2244 | /** Calculate the actual range, major step interval and set variables for data <-> pixels scaling */ |
| 2245 | double[] makeRangeGetSteps() { |
| 2246 | steps = new double[2]; |
| 2247 | logXAxis = hasFlag(X_LOG_NUMBERS); |
| 2248 | logYAxis = hasFlag(Y_LOG_NUMBERS); |
| 2249 | |
| 2250 | for (int i=0; i<currentMinMax.length; i+=2) { //for x and y direction |
| 2251 | boolean logAxis = hasFlag(i==0 ? X_LOG_NUMBERS : Y_LOG_NUMBERS); |
| 2252 | //don't zoom in too much (otherwise finite float precision becomes an issue) |
| 2253 | double range = currentMinMax[i+1]-currentMinMax[i]; |
| 2254 | double mid = 0.5*(currentMinMax[i+1]+currentMinMax[i]); |
| 2255 | double relativeRange = Math.abs(range/mid); |
| 2256 | if (range != 0 && relativeRange<1e-4) { |
| 2257 | currentMinMax[i+1] = mid + 0.5*range*1e-4/relativeRange; |
| 2258 | currentMinMax[i] = mid - 0.5*range*1e-4/relativeRange; |
| 2259 | } |
| 2260 | //no log range if range is too small or not positive values |
| 2261 | if (logAxis) { |
| 2262 | double rangeRatio = currentMinMax[i+1]/currentMinMax[i]; |
| 2263 | if (!(rangeRatio > MIN_LOG_RATIO || 1./rangeRatio > MIN_LOG_RATIO) || |
| 2264 | !(currentMinMax[i] > 10*Float.MIN_VALUE) || !(currentMinMax[i+1] > 10*Float.MIN_VALUE)) |
| 2265 | logAxis = false; |
| 2266 | } |
| 2267 | //for log axes, temporarily work on the logarithm |
| 2268 | if (logAxis) { |
| 2269 | currentMinMax[i] = Math.log10(currentMinMax[i]); |
| 2270 | currentMinMax[i+1] = Math.log10(currentMinMax[i+1]); |
| 2271 | } |
| 2272 | // calculate grid or major tick interval |
| 2273 | if ((i==0 && !simpleXAxis()) || (i==2 && !simpleYAxis())) { |
| 2274 | int minGridspacing = i==0 ? MIN_X_GRIDSPACING : MIN_Y_GRIDSPACING; |
| 2275 | int frameSize = i==0 ? frameWidth : frameHeight; |
| 2276 | double step = Tools.getNumberFromList(pp.frame.options, i==0 ? "xinterval=" : "yinterval="); //user-defined interval |
| 2277 | if (!Double.isNaN(step)) { |
| 2278 | int nSteps = (int)(Math.floor(currentMinMax[i+1]/step+1e-10) - Math.ceil(currentMinMax[i]/step-1e-10)); |
| 2279 | if (nSteps < 1) step = Double.NaN; //user-suppied interval too large, less than two numbers would be shown |
| 2280 | if ((i==0 && nSteps*sc(minGridspacing)*0.5 > frameSize) || i!=0 && nSteps*sc(pp.frame.getFont().getSize()) > frameSize) |
| 2281 | step = Double.NaN; //user-suppied interval too small, too many numbers would be shown |
| 2282 | } |
| 2283 | if (Double.isNaN(step)) { //automatic interval |
| 2284 | step = Math.abs((currentMinMax[i+1] - currentMinMax[i]) * |
| 2285 | Math.max(1.0/maxIntervals, (float)sc(minGridspacing)/frameSize+(maxIntervals>12 ? 0.02 : 0.06))); //the smallest allowable step |
| 2286 | step = niceNumber(step); |
| 2287 | } |
| 2288 | if (logAxis && step < 1) |
| 2289 | step = 1; |
| 2290 | steps[i/2] = step; |
| 2291 | //modify limits to grid or minor ticks if desired |
| 2292 | boolean force2grid = hasFlag(i==0 ? X_FORCE2GRID : Y_FORCE2GRID) && !ignoreForce2Grid; |
| 2293 | if (force2grid) { |
| 2294 | int i1 = (int)Math.floor(Math.min(currentMinMax[i],currentMinMax[i+1])/step+1.e-10); |
| 2295 | int i2 = (int)Math.ceil (Math.max(currentMinMax[i],currentMinMax[i+1])/step-1.e-10); |
| 2296 | if (currentMinMax[i+1] > currentMinMax[i]) { // care about inverted axes with max<min |
| 2297 | currentMinMax[i] = i1 * step; |
| 2298 | currentMinMax[i+1] = i2 * step; |
| 2299 | } else { |
| 2300 | currentMinMax[i] = i2 * step; |
| 2301 | currentMinMax[i+1] = i1 * step; |
| 2302 | } |
no test coverage detected