/** * 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; }
public PlotState getPlotState() { PlotState state = super.getPlotState(); /* Modify ranges. This is required because of confusion about what * axes mean between GraphicsWindow and SphereWindow. */ if (state.getValid()) { double[][] bounds = state.getRanges(); int naux = state.getShaders().length; Range[] viewRanges = getViewRanges(); Range[] dataRanges = getDataRanges(); boolean[] logFlags = state.getLogFlags(); boolean[] flipFlags = state.getFlipFlags(); int mainNdim = getMainRangeCount(); for (int i = 0; i < naux; i++) { logFlags[mainNdim + i] = logFlags[3 + i]; flipFlags[mainNdim + i] = flipFlags[3 + i]; Range range = new Range(dataRanges[mainNdim + i]); range.limit(viewRanges[mainNdim + i]); bounds[mainNdim + i] = range.getFiniteBounds(logFlags[mainNdim + i]); } } return state; }
/** * 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]; } }); } }
/** * Calculates data bounds for a given data set as appropriate for the given plot. * * @param state plot state * @param plot plot object */ public DataBounds calculateBounds(PlotState state, TablePlot plot) { return plot.calculateBounds(state.getPlotData(), state); }
/** * Configures a PlotState object by examining parameter values in a given execution environment. * Such an object was presumably previously created by a call to {@link #createPlotState}. * * @param state plot state to configure * @param env execution environment */ protected void configurePlotState(PlotState state, Environment env) throws TaskException { int mainNdim = mainDimNames_.length; state.setMainNdim(mainNdim); String[] paramNames = env.getNames(); /* Work out which parameter suffixes are being used to identify * different tables. This is done by finding all the parameters * which start "table" and pulling off their suffixes. * These suffixes are then applied to other parameter stems * for obtaining other per-table parameter values. */ String tPrefix = TABLE_PREFIX; String[] tableLabels = getSuffixes(paramNames, tPrefix); if (tableLabels.length == 0) { tableLabels = new String[] {""}; } Arrays.sort(tableLabels); int nTable = tableLabels.length; /* Get a list of all the axis names being used. This includes the * main axes and any auxiliary ones. */ List axNameList = new ArrayList(); axNameList.addAll(Arrays.asList(mainDimNames_)); String[] auxLabels; if (useAux_) { auxLabels = AxisParameterSet.getAuxAxisNames(paramNames); Arrays.sort(auxLabels); for (int ia = 0; ia < auxLabels.length; ia++) { axNameList.add("aux" + auxLabels[ia]); } } else { auxLabels = new String[0]; } String[] allAxNames = (String[]) axNameList.toArray(new String[0]); int allNdim = allAxNames.length; /* Assemble parameter groups corresponding to each axis. */ AxisParameterSet[] axParamSets = new AxisParameterSet[allNdim]; for (int idim = 0; idim < allNdim; idim++) { axParamSets[idim] = new AxisParameterSet(allAxNames[idim]); } /* Construct a PlotData object for the data obtained from each table. */ PlotData[] datas = new PlotData[nTable]; String[] coordExprs0 = null; StyleFactory styleFactory = createStyleFactory(STYLE_PREFIX); List setLabelList = new ArrayList(); for (int itab = 0; itab < nTable; itab++) { String tlabel = tableLabels[itab]; StarTable table = getInputTable(env, tlabel); String[] coordExprs = new String[allNdim]; for (int idim = 0; idim < allNdim; idim++) { Parameter coordParam = axParamSets[idim].createCoordParameter(tlabel); if (idim >= mainNdim) { coordParam.setNullPermitted(true); } coordExprs[idim] = coordParam.stringValue(env); } String[] errExprs = new String[errNdim_]; for (int idim = 0; idim < errNdim_; idim++) { errExprs[idim] = createErrorParameter(mainDimNames_[idim], tlabel).stringValue(env); } String labelExpr = useLabel_ ? createLabelParameter(tlabel).stringValue(env) : null; SubsetDef[] subsetDefs = getSubsetDefinitions(env, tlabel, styleFactory); int nset = subsetDefs.length; String[] setExprs = new String[nset]; String[] setNames = new String[nset]; Style[] setStyles = new Style[nset]; for (int is = 0; is < nset; is++) { SubsetDef sdef = subsetDefs[is]; setLabelList.add(sdef.label_); setExprs[is] = sdef.expression_; setNames[is] = sdef.name_; setStyles[is] = sdef.style_; } try { TablePlotData plotData = createPlotData( env, tlabel, table, setExprs, setNames, setStyles, labelExpr, coordExprs, errExprs); plotData.checkExpressions(); datas[itab] = plotData; } catch (CompilationException e) { throw new TaskException(e.getMessage(), e); } if (itab == 0) { coordExprs0 = coordExprs; } } /* Set up a plot data object which is an aggregation of the data * objects from all the input tables. */ PlotData plotData = new MultiPlotData(datas); /* Rearrange the set plot order if required. */ StringBuffer seqbuf = new StringBuffer(); for (Iterator it = setLabelList.iterator(); it.hasNext(); ) { seqbuf.append(it.next()); if (it.hasNext()) { seqbuf.append(seqParam_.getValueSeparator()); } } String seqDefault = seqbuf.toString(); seqParam_.setDefault(seqDefault); String seqString = seqParam_.stringValue(env); if (seqString != null && !seqString.equals(seqDefault)) { String[] setLabels = seqParam_.stringValue(env).split("\\Q" + seqParam_.getValueSeparator() + "\\E"); int nset = setLabels.length; for (int is = 0; is < nset; is++) { setLabels[is] = setLabels[is].trim(); } int[] isets = new int[nset]; for (int is = 0; is < nset; is++) { String label = setLabels[is]; isets[is] = setLabelList.indexOf(label); if (isets[is] < 0) { String msg = "Unknown set identifier \"" + label + "\"; " + "known labels are " + setLabelList; throw new ParameterValueException(seqParam_, msg); } } plotData = new SubsetSelectionPlotData(plotData, isets); } /* Store the calculated plot data object in the plot state. */ state.setPlotData(plotData); /* Configure other per-axis properties. */ boolean[] logFlags = new boolean[allNdim]; boolean[] flipFlags = new boolean[allNdim]; double[][] ranges = new double[allNdim][]; String[] labels = new String[allNdim]; for (int idim = 0; idim < allNdim; idim++) { AxisParameterSet axParamSet = axParamSets[idim]; logFlags[idim] = axParamSet.logParam_.booleanValue(env); flipFlags[idim] = axParamSet.flipParam_.booleanValue(env); ranges[idim] = new double[] { axParamSet.loParam_.doubleValue(env), axParamSet.hiParam_.doubleValue(env), }; String labelDefault = coordExprs0[idim]; if (labelDefault == null || labelDefault.trim().length() == 0) { labelDefault = idim < mainNdim ? mainDimNames_[idim] : "Aux " + (idim - mainNdim + 1); } axParamSet.labelParam_.setDefault(labelDefault); labels[idim] = axParamSet.labelParam_.stringValue(env); } state.setLogFlags(logFlags); state.setFlipFlags(flipFlags); state.setRanges(ranges); state.setAxisLabels(labels); /* Configure per-auxiliary axis properties. */ Shader[] shaders = new Shader[auxLabels.length]; ShaderParameter[] shaderParams = createShaderParameters(auxLabels); for (int ia = 0; ia < auxLabels.length; ia++) { shaders[ia] = shaderParams[ia].shaderValue(env); } state.setShaders(shaders); /* Configure other properties. */ state.setGrid(gridParam_.booleanValue(env)); state.setAntialias(aaParam_.booleanValue(env)); }