예제 #1
0
  /**
   * 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;
  }
예제 #2
0
  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;
  }
예제 #3
0
  /**
   * 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];
            }
          });
    }
  }
예제 #4
0
 /**
  * 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);
 }
예제 #5
0
  /**
   * 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));
  }