PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/mzgraph-browser/trunk/src/main/java/uk/ac/ebi/pride/mzgraph/chart/graph/MzGraphPanel.java

http://pride-toolsuite.googlecode.com/
Java | 416 lines | 330 code | 50 blank | 36 comment | 53 complexity | d2c4f6abe1f80539bbf9a650e24f42e1 MD5 | raw file
  1. package uk.ac.ebi.pride.mzgraph.chart.graph;
  2. import org.jfree.chart.*;
  3. import org.jfree.chart.axis.NumberAxis;
  4. import org.jfree.chart.axis.TickUnitSource;
  5. import org.jfree.chart.axis.ValueAxis;
  6. import org.jfree.chart.plot.DatasetRenderingOrder;
  7. import org.jfree.chart.plot.PlotOrientation;
  8. import org.jfree.chart.plot.XYPlot;
  9. import org.jfree.chart.title.LegendTitle;
  10. import org.jfree.ui.RectangleEdge;
  11. import org.jfree.ui.RectangleInsets;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import uk.ac.ebi.pride.data.Tuple;
  15. import uk.ac.ebi.pride.gui.io.FileExtension;
  16. import uk.ac.ebi.pride.gui.io.SaveComponentUtils;
  17. import uk.ac.ebi.pride.gui.io.SaveImageDialog;
  18. import uk.ac.ebi.pride.mzgraph.chart.legend.LegendFactory;
  19. import javax.swing.*;
  20. import java.awt.*;
  21. import java.awt.event.ActionEvent;
  22. import java.awt.event.ActionListener;
  23. import java.awt.event.InputEvent;
  24. import java.awt.event.MouseEvent;
  25. import java.io.File;
  26. import java.io.FileWriter;
  27. import java.io.IOException;
  28. import java.io.PrintWriter;
  29. import java.util.LinkedHashMap;
  30. import java.util.Map;
  31. /**
  32. * Generic mz graph panel
  33. * <p/>
  34. * User: rwang
  35. * Date: 21-Jun-2010
  36. * Time: 15:35:22
  37. */
  38. public abstract class MzGraphPanel extends JPanel implements ChartMouseListener, ActionListener {
  39. private static final Logger logger = LoggerFactory.getLogger(MzGraphPanel.class);
  40. public static final String GRID_LINE_COMMAND = "GRID_LINE";
  41. public static final String SAVE_AS = "SAVE";
  42. public static final String PRINT_COMMAND = "PRINT";
  43. public static final String EXPORT = "EXPORT";
  44. public static final String ZOOM_OUT = "ZOOM_OUT";
  45. private String title;
  46. private String type;
  47. private String source;
  48. private Comparable id;
  49. private String xAxisLabel;
  50. private String yAxisLabel;
  51. private PlotOrientation orientation;
  52. private boolean legendVisibility;
  53. private boolean gridLineVisibility;
  54. private double xAxisUpperMargin;
  55. private double yAxisUpperMargin;
  56. protected ChartTheme chartTheme;
  57. protected JFreeChart chart;
  58. protected ValueAxis xAxis;
  59. protected ValueAxis yAxis;
  60. protected ChartPanel chartPanel;
  61. protected XYPlot plot;
  62. public MzGraphPanel(String title,
  63. String xAxisLabel,
  64. String yAxisLabel,
  65. PlotOrientation orientation,
  66. boolean legendVisibility,
  67. boolean gridLineVisibility,
  68. double xAxisUpperMargin,
  69. double yAxisUpperMargin,
  70. ChartTheme chartTheme) {
  71. this.title = title;
  72. this.xAxisLabel = xAxisLabel;
  73. this.yAxisLabel = yAxisLabel;
  74. this.orientation = orientation;
  75. this.legendVisibility = legendVisibility;
  76. this.gridLineVisibility = gridLineVisibility;
  77. this.xAxisUpperMargin = xAxisUpperMargin;
  78. this.yAxisUpperMargin = yAxisUpperMargin;
  79. this.chartTheme = chartTheme;
  80. this.chart = null;
  81. this.xAxis = null;
  82. this.yAxis = null;
  83. this.chartPanel = null;
  84. this.plot = null;
  85. // set the layout
  86. this.setLayout(new BorderLayout());
  87. }
  88. /**
  89. * Reset the MzGraphPanel
  90. */
  91. public void reset() {
  92. // This will reset the zoom status of the panel
  93. doZoomOut();
  94. }
  95. public String getTitle() {
  96. return title;
  97. }
  98. public void setTitle(String title) {
  99. this.title = title;
  100. if (chart != null) {
  101. chart.setTitle(title);
  102. }
  103. }
  104. public String getType() {
  105. return type;
  106. }
  107. public void setType(String type) {
  108. this.type = type;
  109. }
  110. public String getSource() {
  111. return source;
  112. }
  113. public void setSource(String source) {
  114. this.source = source;
  115. }
  116. public Comparable getId() {
  117. return id;
  118. }
  119. public void setId(Comparable id) {
  120. this.id = id;
  121. }
  122. public String getxAxisLabel() {
  123. return xAxisLabel;
  124. }
  125. public void setxAxisLabel(String xAxisLabel) {
  126. this.xAxisLabel = xAxisLabel;
  127. if (xAxis != null) {
  128. xAxis.setLabel(xAxisLabel);
  129. }
  130. }
  131. public String getyAxisLabel() {
  132. return yAxisLabel;
  133. }
  134. public void setyAxisLabel(String yAxisLabel) {
  135. this.yAxisLabel = yAxisLabel;
  136. if (yAxis != null) {
  137. yAxis.setLabel(yAxisLabel);
  138. }
  139. }
  140. public PlotOrientation getOrientation() {
  141. return orientation;
  142. }
  143. public void setOrientation(PlotOrientation orientation) {
  144. this.orientation = orientation;
  145. if (plot != null) {
  146. plot.setOrientation(orientation);
  147. }
  148. }
  149. public boolean isLegendVisible() {
  150. return legendVisibility;
  151. }
  152. public void setLegendVisibility(boolean legendVisibility) {
  153. this.legendVisibility = legendVisibility;
  154. // todo: implement update plot
  155. }
  156. public boolean isGridLineVisibility() {
  157. return gridLineVisibility;
  158. }
  159. public void setGridLineVisibility(boolean gridLineVisibility) {
  160. this.gridLineVisibility = gridLineVisibility;
  161. if (plot != null) {
  162. plot.setRangeGridlinesVisible(gridLineVisibility);
  163. plot.setDomainGridlinesVisible(gridLineVisibility);
  164. }
  165. }
  166. public double getxAxisUpperMargin() {
  167. return xAxisUpperMargin;
  168. }
  169. public void setxAxisUpperMargin(double xAxisUpperMargin) {
  170. this.xAxisUpperMargin = xAxisUpperMargin;
  171. if (xAxis != null) {
  172. xAxis.setUpperMargin(xAxisUpperMargin);
  173. }
  174. }
  175. public double getyAxisUpperMargin() {
  176. return yAxisUpperMargin;
  177. }
  178. public void setyAxisUpperMargin(double yAxisUpperMargin) {
  179. this.yAxisUpperMargin = yAxisUpperMargin;
  180. if (yAxis != null) {
  181. yAxis.setUpperMargin(yAxisUpperMargin);
  182. }
  183. }
  184. public void paintGraph() {
  185. // create plot
  186. createGraph();
  187. // set axises
  188. setPlotAxis();
  189. // add datasets
  190. setGraphDataset();
  191. // add renderers
  192. setGraphRenderer();
  193. // setup and configure plot and chart
  194. setupGraph();
  195. }
  196. protected void createGraph() {
  197. plot = new XYPlot();
  198. chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legendVisibility);
  199. chartPanel = new ChartPanel(chart);
  200. chartPanel.setMouseZoomable(true, true);
  201. // chartPanel.setRangeZoomable(false);
  202. //chartPanel.setMouseWheelEnabled(true);
  203. chartPanel.setZoomAroundAnchor(true);
  204. chartPanel.setDisplayToolTips(true);
  205. chartPanel.addChartMouseListener(this);
  206. // change the scaling of the chart
  207. Toolkit toolkit = Toolkit.getDefaultToolkit();
  208. // get screen size
  209. Dimension screenDim = toolkit.getScreenSize();
  210. chartPanel.setMaximumDrawWidth(screenDim.width);
  211. chartPanel.setMaximumDrawHeight(screenDim.height);
  212. // not popup menu
  213. chartPanel.setPopupMenu(null);
  214. this.add(chartPanel);
  215. }
  216. protected void setupGraph() {
  217. chartTheme.apply(chart);
  218. // set plot orientation
  219. plot.setOrientation(orientation);
  220. plot.setBackgroundPaint(Color.white);
  221. plot.setRangeGridlinePaint(Color.lightGray);
  222. plot.setDomainGridlinePaint(Color.lightGray);
  223. setGridLineVisibility(gridLineVisibility);
  224. // set rendering order
  225. plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
  226. }
  227. protected void setPlotAxis() {
  228. // tick unit
  229. TickUnitSource units = NumberAxis.createIntegerTickUnits();
  230. // x axis
  231. xAxis = new NumberAxis(xAxisLabel);
  232. xAxis.setStandardTickUnits(units);
  233. xAxis.setUpperMargin(xAxisUpperMargin);
  234. // todo: remove zero
  235. // y axis
  236. yAxis = new NumberAxis(yAxisLabel);
  237. yAxis.setStandardTickUnits(units);
  238. yAxis.setUpperMargin(yAxisUpperMargin);
  239. // add axis
  240. plot.setDomainAxis(xAxis);
  241. plot.setRangeAxis(yAxis);
  242. // set axis offset
  243. plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
  244. }
  245. protected abstract void setGraphDataset();
  246. protected abstract Number[][] getGraphDataset();
  247. protected abstract void setGraphRenderer();
  248. public void chartMouseClicked(ChartMouseEvent chartMouseEvent) {
  249. MouseEvent mouseEvent = chartMouseEvent.getTrigger();
  250. switch (mouseEvent.getModifiers()) {
  251. case InputEvent.BUTTON3_MASK: {
  252. doZoomOut();
  253. break;
  254. }
  255. }
  256. }
  257. public void chartMouseMoved(ChartMouseEvent chartMouseEvent) {}
  258. public void actionPerformed(ActionEvent event) {
  259. String command = event.getActionCommand();
  260. if (GRID_LINE_COMMAND.equals(command)) {
  261. doHideGridLine();
  262. } else if (SAVE_AS.equals(command)) {
  263. doSave();
  264. } else if (PRINT_COMMAND.equals(command)) {
  265. doPrint();
  266. } else if (EXPORT.equals(command)) {
  267. doExport();
  268. } else if (ZOOM_OUT.equals(command)) {
  269. doZoomOut();
  270. }
  271. }
  272. public void doHideGridLine() {
  273. setGridLineVisibility(!plot.isRangeGridlinesVisible());
  274. }
  275. private void doSave() {
  276. try {
  277. // store existing legend
  278. LegendTitle existingLegend = chart.getLegend();
  279. // create a temporary legend
  280. Map<Tuple<String, String>, Paint> entries = new LinkedHashMap<Tuple<String, String>, Paint>();
  281. if (source != null) {
  282. entries.put(new Tuple<String, String>("Source", source), Color.white);
  283. }
  284. if (id != null) {
  285. // Note: this is hack
  286. String idStr = getType() + " ID";
  287. entries.put(new Tuple<String, String>(idStr, id.toString()), Color.white);
  288. }
  289. if (!entries.isEmpty()) {
  290. LegendTitle tmpLegend = LegendFactory.createLegendFromMap(entries);
  291. tmpLegend.setPosition(RectangleEdge.BOTTOM);
  292. chart.addLegend(tmpLegend);
  293. }
  294. // file chooser
  295. SaveImageDialog saveImageDialog = new SaveImageDialog(new File(System.getProperty("user.home")), id == null ? null : id.toString());
  296. int result = saveImageDialog.showSaveDialog(null);
  297. if (result == JFileChooser.APPROVE_OPTION) {
  298. String outputFile = saveImageDialog.getSelectedFile().getAbsolutePath();
  299. String extensionDesc = saveImageDialog.getFileFilter().getDescription();
  300. if (FileExtension.PDF.getExtensionDescription().equals(extensionDesc)) {
  301. if (!outputFile.endsWith(FileExtension.PDF.getExtension())) {
  302. outputFile += FileExtension.PDF.getExtension();
  303. }
  304. SaveComponentUtils.writeAsPDF(new File(outputFile), this);
  305. } else if (FileExtension.SVG.getExtensionDescription().equals(extensionDesc)) {
  306. if (!outputFile.endsWith(FileExtension.SVG.getExtension())) {
  307. outputFile += FileExtension.SVG.getExtension();
  308. }
  309. SaveComponentUtils.writeAsSVG(new File(outputFile), this);
  310. } else if (FileExtension.PNG.getExtensionDescription().equals(extensionDesc)) {
  311. if (!outputFile.endsWith(FileExtension.PNG.getExtension())) {
  312. outputFile += FileExtension.PNG.getExtension();
  313. }
  314. SaveComponentUtils.writeAsPNG(new File(outputFile), this);
  315. } else if (FileExtension.JPEG.getExtensionDescription().equals(extensionDesc)) {
  316. if (!outputFile.endsWith(FileExtension.JPEG.getExtension())) {
  317. outputFile += FileExtension.JPEG.getExtension();
  318. }
  319. SaveComponentUtils.writeAsJPEG(new File(outputFile), this);
  320. } else if (FileExtension.GIF.getExtensionDescription().equals(extensionDesc)) {
  321. if (!outputFile.endsWith(FileExtension.GIF.getExtension())) {
  322. outputFile += FileExtension.GIF.getExtension();
  323. }
  324. SaveComponentUtils.writeAsGIF(new File(outputFile), this);
  325. }
  326. }
  327. // remove temporary legend
  328. chart.removeLegend();
  329. if (existingLegend != null) {
  330. chart.addLegend(existingLegend);
  331. }
  332. } catch (IOException e) {
  333. logger.warn("Failed to save the graph as an image", e);
  334. }
  335. }
  336. private void doPrint() {
  337. chartPanel.createChartPrintJob();
  338. }
  339. private void doZoomOut() {
  340. chartPanel.restoreAutoBounds();
  341. }
  342. private void doExport() {
  343. JFileChooser chooser = new JFileChooser();
  344. chooser.setMultiSelectionEnabled(false);
  345. int returnVal = chooser.showSaveDialog(this);
  346. if (returnVal == JFileChooser.APPROVE_OPTION) {
  347. File file = chooser.getSelectedFile();
  348. PrintWriter writer = null;
  349. try {
  350. writer = new PrintWriter(new FileWriter(file));
  351. Number[][] dataSet = getGraphDataset();
  352. for (Number[] data : dataSet) {
  353. writer.println(data[0] + "\t" + data[1]);
  354. }
  355. writer.flush();
  356. writer.close();
  357. } catch (IOException e) {
  358. logger.warn("Failed to export the peak list", e);
  359. } finally {
  360. if (writer != null) {
  361. writer.close();
  362. }
  363. }
  364. }
  365. }
  366. }