/** * Indicates whether it is necessary to calculate the DataBounds for a given PlotState before it * is ready to be used. Iff true is returned, then {@link #configureFromBounds} will be called * later. * * @param state plot state * @return whether configureFromBounds should be called */ protected boolean requiresConfigureFromBounds(PlotState state) { PlotData plotData = state.getPlotData(); /* See if any of the data ranges are missing, and hence need * calculation; if so the answer is true. */ int ndim = plotData.getNdim(); for (int idim = 0; idim < ndim; idim++) { double[] range = state.getRanges()[idim]; if (Double.isNaN(range[0]) || Double.isNaN(range[1])) { return true; } } /* See if any of the plot styles need information from data bounds; * if so the answer is true. */ int nset = plotData.getSetCount(); for (int is = 0; is < nset; is++) { if (requiresAdjustFromData(plotData.getSetStyle(is))) { return true; } } /* If we've got this far, the answer is false. */ return false; }
/** * Updates a plot state generated by this factory with information generated from a first pass * through the data. * * @param state plot state to update * @param bounds data bounds calculated by a pass through the data */ protected void configureFromBounds(PlotState state, DataBounds bounds) throws TaskException { PlotData plotData = state.getPlotData(); int ndim = bounds.getRanges().length; int mainNdim = mainDimNames_.length; /* Update plot state range limits as required. */ for (int idim = 0; idim < ndim; idim++) { boolean logFlag = state.getLogFlags()[idim]; double[] stateRange = state.getRanges()[idim]; double[] calcRange = bounds.getRanges()[idim].getFiniteBounds(logFlag); boolean loCalc = Double.isNaN(stateRange[0]); boolean hiCalc = Double.isNaN(stateRange[1]); String dimName = idim < mainNdim ? mainDimNames_[idim] : "Aux"; if (loCalc) { if (!hiCalc && stateRange[1] <= calcRange[0]) { String msg = "Supplied " + dimName + " upper bound (" + stateRange[1] + ") is less than data lower bound (" + calcRange[0] + ")"; throw new ExecutionException(msg); } stateRange[0] = calcRange[0]; } if (hiCalc) { if (!loCalc && stateRange[0] >= calcRange[1]) { String msg = "Supplied " + dimName + " lower bound (" + stateRange[0] + ") is greater than data upper bound (" + calcRange[1] + ")"; throw new ExecutionException(msg); } stateRange[1] = calcRange[1]; } assert stateRange[0] <= stateRange[1]; /* If lower and upper bounds are equal, nudge them down and up * respectively by an arbitrary amount. */ if (stateRange[0] == stateRange[1]) { double val = stateRange[0]; if (val == Math.floor(val)) { stateRange[0]--; stateRange[1]++; } else { stateRange[0] = Math.floor(val); stateRange[1] = Math.ceil(val); } } /* Otherwise, introduce padding for calculated bounds * for non-auxiliary axes only. */ else { if (idim < mainNdim) { if (logFlag) { double pad = Math.pow(stateRange[1] / stateRange[0], PAD_RATIO); if (loCalc) { stateRange[0] /= pad; } if (hiCalc) { stateRange[1] *= pad; } } else { double pad = (stateRange[1] - stateRange[0]) * PAD_RATIO; if (loCalc) { stateRange[0] -= pad; } if (hiCalc) { stateRange[1] += pad; } } } } assert state.getRanges()[idim][0] < state.getRanges()[idim][1]; } /* Update style configurations as required. */ int nset = plotData.getSetCount(); final Style[] styles = new Style[nset]; int nAdjust = 0; for (int is = 0; is < nset; is++) { Style style = plotData.getSetStyle(is); if (requiresAdjustFromData(style)) { styles[is] = adjustFromData(style, is, bounds); nAdjust++; } else { styles[is] = style; } } if (nAdjust > 0) { state.setPlotData( new WrapperPlotData(plotData) { public Style getSetStyle(int is) { return styles[is]; } }); } }