diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/AbstractTabularDataGraph.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/AbstractTabularDataGraph.java index 7c71c49e460b92be682cbc3760b10e92fd58f6ee..aaa28abc6d7b1b214f29337da55a73329f49ba2c 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/AbstractTabularDataGraph.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/AbstractTabularDataGraph.java @@ -222,8 +222,6 @@ abstract class AbstractTabularDataGraph<T extends TabularDataGraphConfiguration> chart.setBackgroundPaint(Color.WHITE); XYPlot plot = (XYPlot) chart.getPlot(); - // setAxisLabelFontSize(plot.getDomainAxis()); - // setAxisLabelFontSize(plot.getRangeAxis()); plot.setBackgroundPaint(Color.WHITE); plot.setDomainGridlinesVisible(false); plot.setRangeGridlinesVisible(true); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/HeatmapDataset.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/HeatmapDataset.java new file mode 100644 index 0000000000000000000000000000000000000000..52af2ea9b112f1f898c85f4d1c5b7a8847fbd925 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/HeatmapDataset.java @@ -0,0 +1,154 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.dss.generic.server.graph; + +import java.util.List; + +import org.jfree.data.DomainOrder; +import org.jfree.data.Range; +import org.jfree.data.general.DatasetChangeListener; +import org.jfree.data.general.DatasetGroup; +import org.jfree.data.xy.DefaultXYZDataset; +import org.jfree.data.xy.XYZDataset; + +/** + * @author Chandrasekhar Ramakrishnan + */ +public class HeatmapDataset implements XYZDataset +{ + DefaultXYZDataset wrappedDataset; + + Range range; + + List<String> yLabels; + + public HeatmapDataset(DefaultXYZDataset dataset) + { + wrappedDataset = dataset; + } + + /** + * The range of the z values + */ + public Range getRange() + { + return range; + } + + /** + * Set the range of the z-values + */ + public void setRange(Range range) + { + this.range = range; + } + + /** + * The labels for the y axis. + */ + public List<String> yLabels() + { + return yLabels; + } + + /** + * Set the labels for the y axis. + */ + public void setYLabels(List<String> yLabels) + { + this.yLabels = yLabels; + } + + // XYZDataset + public Number getZ(int series, int item) + { + return wrappedDataset.getZ(series, item); + } + + public double getZValue(int series, int item) + { + return wrappedDataset.getZValue(series, item); + } + + public DomainOrder getDomainOrder() + { + return wrappedDataset.getDomainOrder(); + } + + public int getItemCount(int series) + { + return wrappedDataset.getItemCount(series); + } + + public Number getX(int series, int item) + { + return wrappedDataset.getX(series, item); + } + + public double getXValue(int series, int item) + { + return wrappedDataset.getXValue(series, item); + } + + public Number getY(int series, int item) + { + return wrappedDataset.getY(series, item); + } + + public double getYValue(int series, int item) + { + return wrappedDataset.getYValue(series, item); + } + + public int getSeriesCount() + { + return wrappedDataset.getSeriesCount(); + } + + // The JFreeChart interface does not use generics + @SuppressWarnings("unchecked") + public Comparable getSeriesKey(int series) + { + return wrappedDataset.getSeriesKey(series); + } + + @SuppressWarnings("unchecked") + public int indexOf(Comparable seriesKey) + { + return wrappedDataset.indexOf(seriesKey); + } + + public void addChangeListener(DatasetChangeListener arg0) + { + wrappedDataset.addChangeListener(arg0); + } + + public DatasetGroup getGroup() + { + return wrappedDataset.getGroup(); + } + + public void removeChangeListener(DatasetChangeListener arg0) + { + wrappedDataset.removeChangeListener(arg0); + } + + public void setGroup(DatasetGroup arg0) + { + wrappedDataset.setGroup(arg0); + } +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/TabularDataHeatmap.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/TabularDataHeatmap.java index 364e0f3185aed980b944ac6fe299e9a8451e15f9..a25ea9023ad3b8eb40935e62ad7ef5651d4b81ab 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/TabularDataHeatmap.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/TabularDataHeatmap.java @@ -20,8 +20,6 @@ import java.awt.Color; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; @@ -29,10 +27,11 @@ import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.NumberTickUnit; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; -import org.jfree.chart.renderer.GrayPaintScale; +import org.jfree.chart.renderer.LookupPaintScale; import org.jfree.chart.renderer.PaintScale; import org.jfree.chart.renderer.xy.XYBlockRenderer; import org.jfree.chart.title.PaintScaleLegend; +import org.jfree.data.Range; import org.jfree.data.general.Dataset; import org.jfree.data.xy.DefaultXYZDataset; import org.jfree.data.xy.XYZDataset; @@ -40,6 +39,7 @@ import org.jfree.ui.RectangleAnchor; import org.jfree.ui.RectangleEdge; import org.jfree.ui.RectangleInsets; +import ch.systemsx.cisd.bds.hcs.Location; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.DatasetFileLines; /** @@ -48,8 +48,6 @@ import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.DatasetFileLine public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeatmapConfiguration> { - private final Pattern xySplitterPattern; - /** * @param configuration */ @@ -57,7 +55,6 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat DatasetFileLines fileLines, OutputStream out) { super(configuration, fileLines, out); - xySplitterPattern = Pattern.compile("([A-Z])([0-9]*)"); } @Override @@ -77,8 +74,10 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat HeatmapData data = parseData(xColumn, yColumn, zColumn); double[][] dataArray = convertHeatmapDataToArray(data); - DefaultXYZDataset dataset = new DefaultXYZDataset(); - dataset.addSeries(getTitle(), dataArray); + DefaultXYZDataset simpleDataset = new DefaultXYZDataset(); + simpleDataset.addSeries(getTitle(), dataArray); + HeatmapDataset dataset = new HeatmapDataset(simpleDataset); + dataset.setRange(new Range(data.minZ, data.maxZ)); return dataset; } @@ -88,7 +87,7 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat JFreeChart chart = createHeatmap(getTitle(), // title configuration.getXAxisColumn(), // x-axis label configuration.getYAxisColumn(), // y-axis label - (XYZDataset) dataset, // data + (HeatmapDataset) dataset, // data PlotOrientation.HORIZONTAL, // plot orientation false, // create legend? false, // generate tooltips? @@ -99,7 +98,7 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat } private static JFreeChart createHeatmap(String title, String xAxisLabel, String yAxisLabel, - XYZDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, + HeatmapDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) { if (orientation == null) @@ -114,7 +113,7 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat XYBlockRenderer renderer = new XYBlockRenderer(); renderer.setBlockAnchor(RectangleAnchor.BOTTOM_LEFT); - PaintScale paintScale = new GrayPaintScale(); + PaintScale paintScale = getPaintScale(dataset); renderer.setPaintScale(paintScale); XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null); @@ -122,13 +121,14 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat plot.setForegroundAlpha(0.5f); plot.setRenderer(renderer); plot.setBackgroundPaint(Color.WHITE); - plot.setRangeGridlinePaint(Color.LIGHT_GRAY); + plot.setRangeGridlinePaint(Color.BLACK); plot.setAxisOffset(new RectangleInsets(5, 5, 5, 5)); JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend); ChartFactory.getChartTheme().apply(chart); NumberAxis scaleAxis = new NumberAxis("Scale"); + scaleAxis.setRange(dataset.getRange()); PaintScaleLegend psl = new PaintScaleLegend(paintScale, scaleAxis); psl.setMargin(new RectangleInsets(5, 5, 5, 5)); psl.setPosition(RectangleEdge.RIGHT); @@ -137,6 +137,54 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat return chart; } + /** + * Create a LookupPaintScale based on the <a href="http://colorbrewer.org/">Color Brewer</a> + * RdBu color scheme. + */ + private static PaintScale getPaintScale(HeatmapDataset dataset) + { + LookupPaintScale paintScale = new LookupPaintScale(); + // Use the Color Brewer RdBu color scheme with 11 steps + Range range = dataset.getRange(); + double binMin = range.getLowerBound(); + double binStep = range.getLength() / 11; + // 0 + paintScale.add(0, new Color(255, 255, 255)); + // 1 + paintScale.add(binMin, new Color(5, 48, 97)); + // 2 + binMin += binStep; + paintScale.add(binMin, new Color(33, 102, 172)); + // 3 + binMin += binStep; + paintScale.add(binMin, new Color(67, 147, 195)); + // 4 + binMin += binStep; + paintScale.add(binMin, new Color(146, 197, 222)); + // 5 + binMin += binStep; + paintScale.add(binMin, new Color(209, 229, 240)); + // 6 + binMin += binStep; + paintScale.add(binMin, new Color(247, 247, 247)); + // 7 + binMin += binStep; + paintScale.add(binMin, new Color(253, 219, 199)); + // 8 + binMin += binStep; + paintScale.add(binMin, new Color(244, 165, 130)); + // 9 + binMin += binStep; + paintScale.add(binMin, new Color(214, 96, 77)); + // 10 + binMin += binStep; + paintScale.add(binMin, new Color(178, 24, 43)); + // 11 + binMin += binStep; + paintScale.add(binMin, new Color(103, 0, 31)); + return paintScale; + } + private HeatmapData parseData(int xColumn, int yColumn, int zColumn) { HeatmapData heatmapData = new HeatmapData(); @@ -144,6 +192,7 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat // Note what the max x and max y values are, so we can convert to an array heatmapData.maxX = 0; heatmapData.maxY = 0; + boolean areZBoundsInitialized = false; List<String[]> lines = fileLines.getDataLines(); for (String[] line : lines) { @@ -154,9 +203,18 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat element.y = Integer.parseInt(line[yColumn]); } else { - splitColumnIntoXandY(line[xColumn], element); + Location loc = Location.tryCreateLocationFromMatrixCoordinate(line[xColumn]); + // transpose the x and y here + element.x = loc.getY(); + element.y = loc.getX(); } element.z = Double.parseDouble(line[zColumn]); + if (false == areZBoundsInitialized) + { + heatmapData.minZ = element.z; + heatmapData.maxZ = element.z; + areZBoundsInitialized = true; + } heatmapData.elements.add(element); if (element.x > heatmapData.maxX) @@ -167,24 +225,19 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat { heatmapData.maxY = element.y; } + if (element.z < heatmapData.minZ) + { + heatmapData.minZ = element.z; + } + if (element.z > heatmapData.maxZ) + { + heatmapData.maxZ = element.z; + } } return heatmapData; } - private void splitColumnIntoXandY(String string, HeatmapElement element) - { - Pattern p = xySplitterPattern; - Matcher m = p.matcher(string); - if (m.matches()) - { - String wellX = m.group(1); - // The x index is the index of the letter minus the index of 'A' - element.x = (wellX.charAt(0) - 'A') + 1; - element.y = Integer.parseInt(m.group(2)); - } - } - private double[][] convertHeatmapDataToArray(HeatmapData data) { double[][] dataArray = new double[3][]; @@ -220,6 +273,10 @@ public class TabularDataHeatmap extends AbstractTabularDataGraph<TabularDataHeat private int maxY; + private double minZ = 0; + + private double maxZ = 0; + private final ArrayList<HeatmapElement> elements = new ArrayList<HeatmapElement>(); } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/TabularDataHistogram.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/TabularDataHistogram.java index 32cfaf119d6b111c4ac1e8843035fc42e031b9e8..afeadce9c611932dd2cbad17244ebd1fc3b74200 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/TabularDataHistogram.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/graph/TabularDataHistogram.java @@ -21,6 +21,10 @@ import java.io.OutputStream; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.StandardXYBarPainter; +import org.jfree.chart.renderer.xy.XYBarRenderer; +import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.general.Dataset; import org.jfree.data.statistics.HistogramDataset; @@ -80,6 +84,14 @@ public class TabularDataHistogram extends false // generate URLs? ); + XYItemRenderer r = ((XYPlot) chart.getPlot()).getRenderer(); + if (r instanceof XYBarRenderer) + { + XYBarRenderer renderer = (XYBarRenderer) r; + renderer.setShadowVisible(false); + renderer.setBarPainter(new StandardXYBarPainter()); + } + return chart; } }