Changeset 2137


Ignore:
Timestamp:
Mar 31, 2006, 1:49:41 PM (18 years ago)
Author:
Nicklas Nordborg
Message:

Fixes #124: Plot function for analysed data

Location:
trunk
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/clients/web/net/sf/basedb/clients/web/DynamicUtil.java

    r2102 r2137  
    7070    columns.add(new TableColumn(idPrefix + "column", propertyPrefix+"column", Type.INT, titlePrefix+"Column"));
    7171    columns.add(new TableColumn(idPrefix + "x", propertyPrefix+"x", Type.INT, titlePrefix+"X"));
    72     columns.add(new TableColumn(idPrefix + "x", propertyPrefix+"x", Type.INT, titlePrefix+"Y"));
     72    columns.add(new TableColumn(idPrefix + "y", propertyPrefix+"y", Type.INT, titlePrefix+"Y"));
    7373
    7474    List<RawDataProperty> rdpList = rawDataType.getProperties();
  • trunk/src/clients/web/net/sf/basedb/clients/web/servlet/PlotServlet.java

    r2131 r2137  
    5151import net.sf.basedb.util.jep.RawFunction;
    5252import net.sf.basedb.util.plot.HistogramPlot;
     53import net.sf.basedb.util.plot.PlotAnnotation;
    5354import net.sf.basedb.util.plot.ScatterPlot;
    5455
     
    6970import java.io.IOException;
    7071import java.sql.SQLException;
     72import java.util.Collection;
     73import java.util.Collections;
     74import java.util.HashSet;
    7175import java.util.List;
    7276
     
    139143    String yLabel = Values.getStringOrNull(request.getParameter("yLabel"));
    140144    if (yLog && yLabel != null) yLabel = "log2("+yLabel+")";
     145    final String annotation = Values.getStringOrNull(request.getParameter("annotation"));
     146    final boolean hasAnnotation = annotation != null;
    141147
    142148    // Scatter plot specified parameters
     
    146152    final String yAggregate = Values.getString(request.getParameter("yAggregate"), "count");
    147153    final boolean isCount = "count".equals(yAggregate);
     154    if (!isCount && yLabel != null) yLabel = yLabel + " (" + yAggregate + ")";
     155    final String hiloAggregate = isCount ? null :
     156      Values.getStringOrNull(request.getParameter("hiloAggregate"));
     157   
    148158   
    149159    RenderedImage image = null;
     
    171181        Expression[] x = xFormulas == null ? null : new Expression[xFormulas.length];
    172182        Expression[] y = yFormulas == null ? null : new Expression[yFormulas.length];
     183       
     184        // If we should join the raw data table or not
     185        boolean joinRaw = false;
    173186        if (xFormulas != null)
    174187        {
    175188          for (int i = 0; i < xFormulas.length; ++i)
    176189          {
     190            joinRaw |= xFormulas[i].contains("raw(");
    177191            x[i] = Jep.formulaToExpression(xFormulas[i], ch, raw);
    178192            if (xLog) x[i] = Expressions.log2(x[i]);
     
    183197          for (int i = 0; i < yFormulas.length; ++i)
    184198          {
     199            joinRaw |= yFormulas[i].contains("raw(");
    185200            y[i] = Jep.formulaToExpression(yFormulas[i], ch, raw);
    186201            if (yLog) y[i] = Expressions.log2(y[i]);
     
    188203        }
    189204 
     205        // Get annotations
     206        Collection<PlotAnnotation> annotations = null;
     207        if (hasAnnotation)
     208        {
     209          annotations = new HashSet<PlotAnnotation>();
     210          // TODO - implement other annotations than bioassay
     211          for (BioAssay baa : bas.getBioAssays().list(dc))
     212          {
     213            annotations.add(new PlotAnnotation(baa.getName(),
     214              Collections.singleton(new Integer(baa.getDataCubeColumnNo()))));
     215          }
     216        }
     217       
    190218        // Get the query
    191219        DynamicSpotQuery query = ba != null ? ba.getSpotData() : bas.getSpotData();
     
    197225          {
    198226            query.reset();
    199             query.joinRawData(JoinType.INNER); // TODO - only join if used in query
     227            if (joinRaw) query.joinRawData(JoinType.INNER);
     228            if (hasAnnotation)
     229            {
     230              query.select(Dynamic.select(VirtualColumn.COLUMN));
     231            }
    200232            query.select(Selects.expression(x[i], "x"));
    201233            query.select(Selects.expression(y[i], "y"));
    202             plot.addData(query.iterate(dc), Integer.toString(i));
     234            if (hasAnnotation)
     235            {
     236              plot.addData(query.iterate(dc), annotations);
     237            }
     238            else
     239            {
     240              plot.addData(query.iterate(dc), Integer.toString(i));
     241            }
    203242          }
    204243          chart = plot.getChart();
     
    211250          {
    212251            query.reset();
    213             query.joinRawData(JoinType.INNER); // TODO - only join if used in query
     252            if (joinRaw) query.joinRawData(JoinType.INNER);
     253            if (hasAnnotation)
     254            {
     255              query.select(Dynamic.select(VirtualColumn.COLUMN));
     256            }
    214257            query.select(Selects.expression(x[i], "x"));
    215258            if (!isCount) query.select(Selects.expression(y[i], "y"));
    216             plot.addData(query.iterate(dc), Integer.toString(i), binSize,
    217               HistogramPlot.YAggregate.valueOf(yAggregate.toUpperCase()));
     259            HistogramPlot.YAggregate ya = HistogramPlot.YAggregate.valueOf(yAggregate.toUpperCase());
     260            HistogramPlot.YAggregate hilo = hiloAggregate == null ? null :
     261              HistogramPlot.YAggregate.valueOf(hiloAggregate.toUpperCase());
     262            if (hasAnnotation)
     263            {
     264              plot.addData(query.iterate(dc), annotations, binSize, ya, hilo);
     265            }
     266            else
     267            {
     268              plot.addData(query.iterate(dc), Integer.toString(i), binSize, ya, hilo);
     269            }
    218270          }
    219271          chart = plot.getChart();
     
    222274     
    223275      if (title != null) chart.setTitle(title);
    224       chart.removeLegend();
     276      if (!hasAnnotation) chart.removeLegend();
    225277      image = chart.createBufferedImage(width, height);
    226278     
     
    260312          graphics.clearRect(0, 0, width, height);
    261313          graphics.setColor(Color.RED);
    262           graphics.drawString(t.getMessage(), 50, 50);
     314          String message = t.getMessage();
     315          graphics.drawString(message == null ? "null" : message, 50, 50);
    263316          image = img;
    264317          // TODO - write more of stack trace
  • trunk/src/core/net/sf/basedb/util/plot/HistogramPlot.java

    r2131 r2137  
    2525package net.sf.basedb.util.plot;
    2626
     27import net.sf.basedb.core.BaseException;
    2728import net.sf.basedb.core.query.SqlResult;
    2829import net.sf.basedb.core.query.SqlResultIterator;
     
    3031import org.jfree.chart.JFreeChart;
    3132import org.jfree.chart.axis.NumberAxis;
     33import org.jfree.chart.plot.DatasetRenderingOrder;
     34import org.jfree.chart.plot.SeriesRenderingOrder;
    3235import org.jfree.chart.plot.XYPlot;
    3336import org.jfree.chart.renderer.xy.XYBarRenderer;
     37import org.jfree.chart.renderer.xy.XYStepRenderer;
     38import org.jfree.chart.renderer.xy.YIntervalRenderer;
    3439import org.jfree.data.DomainOrder;
    3540import org.jfree.data.Range;
     
    3742import org.jfree.data.xy.IntervalXYDataset;
    3843
     44import java.awt.geom.Rectangle2D;
    3945import java.sql.SQLException;
    4046import java.util.ArrayList;
     47import java.util.Collection;
     48import java.util.HashMap;
    4149import java.util.List;
     50import java.util.Map;
    4251
    4352/**
     
    5362  private XYPlot plot;
    5463  private HistogramDataset histogram;
     64  private HistogramDataset hilo;
    5565  private JFreeChart chart;
    5666
     
    5969   
    6070    histogram = new HistogramDataset();
     71    hilo = new HistogramDataset();
    6172    NumberAxis domainAxis = new NumberAxis(nameX);
    6273    domainAxis.setAutoRangeIncludesZero(false);
     74    domainRange = new Range(0.0, 0.0);
     75    rangeRange = new Range(0.0, 0.0);
    6376   
    6477      NumberAxis rangeAxis = new NumberAxis(nameY);
     
    6679
    6780      plot = new XYPlot(histogram, domainAxis, rangeAxis, new XYBarRenderer());
    68     chart = new JFreeChart(plot);
     81      plot.setDataset(1, hilo);
     82      YIntervalRenderer yRenderer = new YIntervalRenderer();
     83      yRenderer.setShape(new Rectangle2D.Float(-3, -1, 7, 2));
     84      yRenderer.setSeriesVisibleInLegend(false, false);
     85      plot.setRenderer(1, yRenderer, false);
     86     
     87      plot.setSeriesRenderingOrder(SeriesRenderingOrder.FORWARD);
     88      plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
     89      chart = new JFreeChart(plot);
    6990    chart.setAntiAlias(false);
    7091  }
    7192
    72   public void addData(SqlResultIterator data, String name, float binSize, YAggregate yAggregate)
     93  public void addData(SqlResultIterator data, String name, float binSize, YAggregate yAggregate, YAggregate hiloAggregate)
    7394    throws SQLException
    7495  {
     
    84105      xValues[i++] = r.getFloat(1);
    85106    }
    86     histogram.addSeries(new HistogramSeries(name, xValues, yValues, binSize, yAggregate));
     107    HistogramSeries main = new HistogramSeries(name, xValues, yValues, binSize, yAggregate, Float.NaN, Float.NaN);
     108    histogram.addSeries(main);
     109    if (hiloAggregate != null)
     110    {
     111      hilo.addSeries(new HistogramSeries(name, main, hiloAggregate));
     112    }
     113    adjustRanges();
     114  }
     115 
     116  private void adjustRanges()
     117  {
    87118    domainRange = Range.combine(domainRange, plot.getRenderer().findDomainBounds(histogram));
    88     rangeRange = Range.combine(rangeRange, plot.getRenderer().findRangeBounds(histogram));
     119    if (hilo.getSeriesCount() > 0)
     120    {
     121      rangeRange = Range.combine(rangeRange, plot.getRenderer(1).findRangeBounds(hilo));
     122    }
     123    else
     124    {
     125      rangeRange = Range.combine(rangeRange, plot.getRenderer(0).findRangeBounds(histogram));
     126    }
     127    rangeRange = Range.expand(rangeRange, 0, 0.02);
    89128    plot.getDomainAxis().setRange(domainRange);
    90     plot.getRangeAxis().setRange(0, rangeRange.getUpperBound());
     129    plot.getRangeAxis().setRange(rangeRange);
     130  }
     131 
     132  public void addData(SqlResultIterator data, Collection<PlotAnnotation> annotations, float binSize, YAggregate yAggregate, YAggregate hiloAggregate)
     133    throws SQLException
     134  {
     135    final boolean isCount = yAggregate == YAggregate.COUNT;
     136    Map<Integer, TempSeries> series = new HashMap<Integer, TempSeries>(annotations.size());
     137    List<TempSeries> tempSeries = new ArrayList<TempSeries>(annotations.size());
     138    int meanCount = data.getTotalCount() / annotations.size();
     139    for (PlotAnnotation pa : annotations)
     140    {
     141      TempSeries ts = new TempSeries(pa.getName(), meanCount, !isCount);
     142      tempSeries.add(ts);
     143      for (Integer column : pa.getColumns())
     144      {
     145        if (series.containsKey(column))
     146        {
     147          throw new BaseException("Column " + column + " has already been mapped to another series");
     148        }
     149        series.put(column, ts);
     150      }
     151    }
     152    float maxX = Float.MIN_VALUE;
     153    float minX = Float.MAX_VALUE;
     154    while (data.hasNext())
     155    {
     156      SqlResult r = data.next();
     157      TempSeries ts = series.get(r.getInt(1));
     158      float x = r.getFloat(2);
     159      if (maxX < x) maxX = x;
     160      if (minX > x) minX = x;
     161      ts.x.add(r.getFloat(2));
     162      if (!isCount) ts.y.add(r.getFloat(3));
     163    }
     164   
     165    for (TempSeries ts : tempSeries)
     166    {
     167      HistogramSeries main = new HistogramSeries(ts.name, ts.getX(), ts.getY(), binSize, yAggregate, minX, maxX);
     168      histogram.addSeries(main);
     169      if (hiloAggregate != null)
     170      {
     171        hilo.addSeries(new HistogramSeries(ts.name, main, hiloAggregate));
     172      }
     173    }
     174    adjustRanges();
     175    plot.setRenderer(new XYStepRenderer());
    91176  }
    92177 
     
    94179  {
    95180    return chart;
     181  }
     182 
     183  private static class TempSeries
     184  {
     185    final String name;
     186    final List<Float> x;
     187    final List<Float> y;
     188   
     189    TempSeries(String name, int size, boolean hasY)
     190    {
     191      this.name = name;
     192      this.x = new ArrayList<Float>(size);
     193      this.y = hasY ? new ArrayList<Float>(size) : null;
     194    }
     195   
     196    public float[] getX()
     197    {
     198      if (x == null) return null;
     199      float[] xf = new float[x.size()];
     200      int i = 0;
     201      for (Float f : x)
     202      {
     203        xf[i++] = f.floatValue();
     204      }
     205      return xf;
     206    }
     207   
     208    public float[] getY()
     209    {
     210      if (y == null) return null;
     211      float[] yf = new float[y.size()];
     212      int i = 0;
     213      for (Float f : y)
     214      {
     215        yf[i++] = f.floatValue();
     216      }
     217      return yf;
     218    }
     219   
    96220  }
    97221 
     
    141265    public double getXValue(int series, int item)
    142266    {
    143       return all.get(series).getBin(item).getStartX();
     267      HistogramBin bin = all.get(series).getBin(item);
     268      return (bin.getStartX() + bin.getEndX()) / 2;
    144269    }
    145270
     
    150275    public double getYValue(int series, int item)
    151276    {
    152       return all.get(series).getY(item);
     277      return all.get(series).getMaxY(item);
    153278    }
    154279    // -------------------------------------------
     
    187312    public double getStartYValue(int series, int item)
    188313    {
    189       return 0;
     314      return all.get(series).getMinY(item);
    190315    }
    191316    // -------------------------------------------
    192317   
    193    
    194318    public void addSeries(HistogramSeries s)
    195319    {
     
    197321    }
    198322  }
    199  
     323
    200324 
    201325  private static class HistogramSeries
     
    205329    private final YAggregate yAggregate;
    206330   
    207     private HistogramSeries(String name, float[] xValues, float[] yValues, float binSize, YAggregate yAggregate)
     331    private HistogramSeries(String name, float[] xValues, float[] yValues, float binSize, YAggregate yAggregate, float xMin, float xMax)
    208332    {
    209333      this.name = name;
     
    211335     
    212336      // Find max and min --> number of bins
    213       float xMin = Float.MAX_VALUE;
    214       float xMax = Float.MIN_VALUE;
    215       for (float x : xValues)
    216       {
    217         if (xMax < x) xMax = x;
    218         if (xMin > x) xMin = x;
     337      if (Float.isNaN(xMin) || Float.isNaN(xMax))
     338      {
     339        xMin = Float.MAX_VALUE;
     340        xMax = Float.MIN_VALUE;
     341        for (float x : xValues)
     342        {
     343          if (xMax < x) xMax = x;
     344          if (xMin > x) xMin = x;
     345        }
    219346      }
    220347      int numBins = 1 + (int)((xMax - xMin) / binSize);
     
    243370    }
    244371   
     372    private HistogramSeries(String name, HistogramSeries other, YAggregate yAggregate)
     373    {
     374      this.name = name;
     375      this.bins = other.bins;
     376      this.yAggregate = yAggregate;
     377    }
     378   
    245379    public String getName()
    246380    {
     
    258392    }
    259393   
    260     public float getY(int index)
    261     {
    262       return yAggregate.getY(bins[index]);
     394    public float getMaxY(int index)
     395    {
     396      return yAggregate.getMaxY(bins[index]);
     397    }
     398    public float getMinY(int index)
     399    {
     400      return yAggregate.getMinY(bins[index]);
    263401    }
    264402  }
     
    271409    private int count = 0;
    272410    private float sum = 0.0f;
     411    private float squaredSum = 0.0f;
    273412    private float min = Float.MAX_VALUE;
    274413    private float max = Float.MIN_VALUE;
     
    299438      count++;
    300439      sum += y;
     440      squaredSum += y * y;
    301441      if (y < min) min = y;
    302442      if (y > max) max = y;
     
    326466      return max;
    327467    }
     468    public float getStdev()
     469    {
     470      return (float)Math.sqrt((squaredSum - sum * sum / count) / (count - 1));
     471    }
    328472  }
    329473 
     
    333477    COUNT
    334478    {
    335       public float getY(HistogramBin bin)
     479      public float getMaxY(HistogramBin bin)
    336480      {
    337481        return bin.getCount();
     
    340484    SUM
    341485    {
    342       public float getY(HistogramBin bin)
     486      public float getMaxY(HistogramBin bin)
    343487      {
    344488        return bin.getSum();
     
    347491    MEAN
    348492    {
    349       public float getY(HistogramBin bin)
     493      public float getMaxY(HistogramBin bin)
    350494      {
    351495        return bin.getMean();
     
    354498    MAX
    355499    {
    356       public float getY(HistogramBin bin)
     500      public float getMaxY(HistogramBin bin)
    357501      {
    358502        return bin.getMax();
     
    361505    MIN
    362506    {
    363       public float getY(HistogramBin bin)
     507      public float getMaxY(HistogramBin bin)
    364508      {
    365509        return bin.getMin();
    366510      }
    367     };
    368    
    369     public abstract float getY(HistogramBin bin);
     511    },
     512    STDEV
     513    {
     514      public float getMaxY(HistogramBin bin)
     515      {
     516        return bin.getStdev();
     517      }
     518      public float getMinY(HistogramBin bin)
     519      {
     520        return bin.getMean() - bin.getStdev();
     521      }
     522    },
     523    HILOSTDEV
     524    {
     525      public float getMaxY(HistogramBin bin)
     526      {
     527        return bin.getMean() + bin.getStdev();
     528      }
     529      public float getMinY(HistogramBin bin)
     530      {
     531        return bin.getMean() - bin.getStdev();
     532      }
     533     
     534    },
     535    HILOMAXMIN
     536    {
     537      public float getMaxY(HistogramBin bin)
     538      {
     539        return bin.getMax();
     540      }
     541      public float getMinY(HistogramBin bin)
     542      {
     543        return bin.getMin();
     544      }
     545    }
     546    ;
     547   
     548    public abstract float getMaxY(HistogramBin bin);
     549    public float getMinY(HistogramBin bin)
     550    {
     551      return 0;
     552    }
    370553   
    371554  }
  • trunk/src/core/net/sf/basedb/util/plot/ScatterPlot.java

    r2131 r2137  
    2525package net.sf.basedb.util.plot;
    2626
     27import net.sf.basedb.core.BaseException;
    2728import net.sf.basedb.core.query.SqlResult;
    2829import net.sf.basedb.core.query.SqlResultIterator;
     
    3738
    3839import java.sql.SQLException;
     40import java.util.ArrayList;
     41import java.util.Collection;
     42import java.util.HashMap;
     43import java.util.List;
     44import java.util.Map;
    3945
    4046
     
    6672    chart.setAntiAlias(false);
    6773  }
    68 
     74 
    6975  public void addData(SqlResultIterator data, String... names)
    7076    throws SQLException
     
    7379    for (int i = 0; i < names.length; ++i)
    7480    {
    75       series[i] = new XYSeries(names[i]);
     81      XYSeries s = new XYSeries(names[i]);
     82      s.setNotify(false);
     83      series[i] = s;
    7684    }
    7785    while (data.hasNext())
     
    9098  }
    9199 
     100  public void addData(SqlResultIterator data, Collection<PlotAnnotation> annotations)
     101    throws SQLException
     102  {
     103    Map<Integer, XYSeries> series = new HashMap<Integer, XYSeries>(annotations.size());
     104    List<XYSeries> newSeries = new ArrayList<XYSeries>(annotations.size());
     105    for (PlotAnnotation pa : annotations)
     106    {
     107      XYSeries s = new XYSeries(pa.getName());
     108      s.setNotify(false);
     109      newSeries.add(s);
     110      for (Integer column : pa.getColumns())
     111      {
     112        if (series.containsKey(column))
     113        {
     114          throw new BaseException("Column " + column + " has already been mapped to another series");
     115        }
     116        series.put(column, s);
     117      }
     118    }
     119    while (data.hasNext())
     120    {
     121      SqlResult r = data.next();
     122      XYSeries s = series.get(r.getInt(1));
     123      s.add(r.getFloat(2), r.getFloat(3));
     124    }
     125    for (XYSeries s : newSeries)
     126    {
     127      allSeries.addSeries(s);
     128    }
     129  }
     130 
    92131  public JFreeChart getChart()
    93132  {
  • trunk/www/include/styles/tabcontrol.css

    r2111 r2137  
    3131.tabcontrol, .tabcontrol_bottom {
    3232  border-left: 1px solid #999999;
    33   margin-bottom: 4px;
     33  margin-bottom: 0px;
    3434}
    3535
  • trunk/www/views/experiments/plotter/index.jsp

    r2116 r2137  
    8282    addFormulaOption(formulaOptions, f.getFormula(0), f.getName(), f.getDescription());
    8383  }
     84  addFormulaOption(formulaOptions, "raw('block')", "[Raw] Block", "Block number");
     85  addFormulaOption(formulaOptions, "raw('metaGridX')", "[Raw] Meta grid X", "Meta grid X coordinate");
     86  addFormulaOption(formulaOptions, "raw('metaGridY')", "[Raw] Meta grid Y", "Meta grid Y coordinate");
     87  addFormulaOption(formulaOptions, "raw('row')", "[Raw] Row", "Row number");
     88  addFormulaOption(formulaOptions, "raw('column')", "[Raw] Column", "Column number");
     89  addFormulaOption(formulaOptions, "raw('x')", "[Raw] X", "X coordinate");
     90  addFormulaOption(formulaOptions, "raw('y')", "[Raw] Y", "Y coordinate");
    8491  for (RawDataProperty property : rdt.getProperties())
    8592  {
     
    9198  }
    9299 
     100  // TODO - add extra columns to list of options
    93101 
    94102  String title = HTML.encodeTags("Plot " + (ba == null ? bas.getName() : ba.getName()));
     
    151159    var index = list.selectedIndex;
    152160    formula.value = list[index].value;
    153     label.value = list[index].text;
     161    if (list[index].value != '') label.value = list[index].text;
    154162  }
    155163 
     
    162170    frm.yPresets.disabled = isCount;
    163171    frm.yLog.disabled = isCount;
     172    for (var i = 0; i < frm.hiloAggregate.length; i++)
     173    {
     174      frm.hiloAggregate[i].disabled = isCount;
     175    }
    164176    if (isCount)
    165177    {
    166178      Main.removeClass(frm.yFormula, 'required');
     179      frm.yLabel.value = 'Count';
    167180    }
    168181    else
    169182    {
    170183      Main.addClass(frm.yFormula, 'required');
     184      var yPreset = frm.yPresets[frm.yPresets.selectedIndex];
     185      if (yPreset.value != '') frm.yLabel.value = yPreset.text;
    171186    }
    172187  }
     
    196211        url += '&yLog='+(frm.yLog.checked ? 1 : 0);
    197212        url += '&yLabel='+Main.encodeURI(frm.yLabel.value);
     213        if (frm.annotation)
     214        {
     215          url += '&annotation='+frm.annotation[frm.annotation.selectedIndex].value;
     216        }
    198217      }
    199218      else
     
    211230          url += '&y='+Main.encodeURI(frm.yFormula.value);
    212231          url += '&yLog='+(frm.yLog.checked ? 1 : 0);
     232          url += '&hiloAggregate='+Forms.getCheckedRadio(frm.hiloAggregate).value
    213233        }
    214234        url += '&yLabel='+Main.encodeURI(frm.yLabel.value);
     235        if (frm.annotation)
     236        {
     237          url += '&annotation='+frm.annotation[frm.annotation.selectedIndex].value;
     238        }
    215239      }
    216240      return url;
     
    288312  <div class="boxed">
    289313
    290   <table class="form">
    291   <tr valign="top">
     314  <table class="form" border="0" cellspacing="0" cellpadding="2">
     315  <tr valign="bottom">
    292316    <td width="50%">
    293317   
     
    297321      <td class="prompt">Plot title</td>
    298322      <td colspan="2"><input type="text" class="text" size="30" maxlength="255" name="title"
    299         value="<%=HTML.encodeTags(ba.getName())%>"></td>
     323        value="<%=HTML.encodeTags(ba == null ? bas.getName() : ba.getName())%>"></td>
    300324    </tr>
    301325    <tr>
     
    315339    <p>
    316340
    317     <t:tabcontrol id="plotType" contentstyle="<%="height: "+(int)(scale*260)+"px;"%>">
     341    <t:tabcontrol id="plotType" contentstyle="<%="height: "+(int)(scale*340)+"px;"%>">
    318342    <t:tab id="scatter" title="Scatter plot">
    319343      <form name="scatter">
     
    371395        <td><input type="checkbox" name="xLog" value="1"></td>
    372396      </tr>
     397      <%
     398      if (ba == null)
     399      {
     400        %>
     401        <tr>
     402          <td class="prompt">Annotation</td>
     403          <td>
     404          <select name="annotation">
     405            <option value="">- none -
     406            <option value="bioassay">Bioassay
     407          </select>
     408          </td>
     409        </tr>
     410        <%
     411      }
     412      %>
    373413      </table>
    374414      </form>
     
    383423          <input type="radio" name="yAggregate" value="count" checked onchange="aggregateOnChange()"> Count
    384424          <input type="radio" name="yAggregate" value="mean" onchange="aggregateOnChange()"> Mean
    385           <input type="radio" name="yAggregate" value="max" onchange="aggregateOnChange()"> Max
    386           <input type="radio" name="yAggregate" value="min" onchange="aggregateOnChange()"> Min
     425        </td>
     426      </tr>
     427      <tr>
     428        <td>&nbsp;Hi-lo</td>
     429        <td>
     430          <input type="radio" name="hiloAggregate" value="" checked> None
     431          <input type="radio" name="hiloAggregate" value="hilomaxmin"> Min/Max
     432          <input type="radio" name="hiloAggregate" value="hilostdev"> Stdev
    387433        </td>
    388434      </tr>
     
    444490        <td><input type="text" class="text" name="binSize" value="1"></td>
    445491      </tr>
     492      <%
     493      if (ba == null)
     494      {
     495        %>
     496        <tr>
     497          <td class="prompt">Annotation</td>
     498          <td>
     499          <select name="annotation">
     500            <option value="">- none -
     501            <option value="bioassay">Bioassay
     502          </select>
     503          </td>
     504        </tr>
     505        <%
     506      }
     507      %>
    446508      </table>
    447509      </form>
    448    
    449510    </t:tab>
    450511    </t:tabcontrol>
    451  
    452     <base:buttongroup>
    453       <base:button title="Preview" onclick="previewPlot()" tooltip="Generate a preview of the plot" />
    454       <base:button title="View&hellip;" onclick="viewPlot()" tooltip="View a fullsized version of the plot (in a popup)" />
    455       <base:button title="Download&hellip;" onclick="downloadPlot()" tooltip="Downlad a fullsized version of the plot to you computer" />
    456       <base:button title="Save as&hellip;" onclick="savePlotAs()" tooltip="Save a fullsized version of the plot on the BASE server" />
    457     </base:buttongroup>
    458    
    459512    </td>
    460513    <td width="50%">
    461514      <div style="position: relative; top: 0px; left: 0px; border: 10px solid #00000;">
    462515      <img src="../../../images/plot_empty.png" id="background"
    463         style="position: absolute; top: 0px; left: 0px; z-index: 1;">
     516        style="position: absolute; top: 0px; left: 0px; z-index: 1; border: 1px solid #999999;">
    464517      <img src="../../../images/plot_select.gif" id="preview"
    465         style="position: relative; top: 0px; left: 0px; z-index: 2;">
     518        style="position: relative; top: 0px; left: 0px; z-index: 2; border: 1px solid #999999;">
    466519      </div>
    467520    </td>
    468521  </tr>
    469522  </table>
    470 
    471523  </div>
    472 
    473     <table align="center">
    474     <tr>
    475       <td><base:button onclick="window.close()" title="Close" /></td>
    476     </tr>
    477     </table>
     524    <p>
     525    <div align="center">
     526    <base:buttongroup>
     527      <base:button title="Preview" onclick="previewPlot()"
     528        tooltip="Generate a preview of the plot" />
     529      <base:button title="View&hellip;" onclick="viewPlot()"
     530        tooltip="View a fullsized version of the plot (in a popup)" />
     531      <base:button title="Download&hellip;" onclick="downloadPlot()"
     532        tooltip="Downlad a fullsized version of the plot to you computer" />
     533      <base:button title="Save as&hellip;" onclick="savePlotAs()"
     534        tooltip="Save a fullsized version of the plot on the BASE server" />
     535      <base:button onclick="window.close()" title="Close" />
     536    </base:buttongroup>
     537    </div>
    478538 
    479539  </base:body>
Note: See TracChangeset for help on using the changeset viewer.