001 package nl.cwi.sen1.visplugin.barchart; 002 003 import java.awt.Color; 004 005 import javax.swing.JLabel; 006 import javax.swing.JPanel; 007 008 import nl.cwi.sen1.relationstores.Factory; 009 import nl.cwi.sen1.relationstores.types.Integer; 010 import nl.cwi.sen1.relationstores.types.RElem; 011 import nl.cwi.sen1.relationstores.types.RElemElements; 012 import nl.cwi.sen1.relationstores.types.RTuple; 013 import nl.cwi.sen1.relationstores.types.RType; 014 import nl.cwi.sen1.relationstores.types.idcon.IdCon; 015 import nl.cwi.sen1.visplugin.VisualizationPluginWindow; 016 017 import org.jfree.chart.ChartFactory; 018 import org.jfree.chart.ChartPanel; 019 import org.jfree.chart.JFreeChart; 020 import org.jfree.chart.axis.CategoryAxis; 021 import org.jfree.chart.axis.CategoryLabelPositions; 022 import org.jfree.chart.axis.NumberAxis; 023 import org.jfree.chart.plot.CategoryPlot; 024 import org.jfree.chart.plot.PlotOrientation; 025 import org.jfree.chart.renderer.category.CategoryItemRenderer; 026 import org.jfree.data.category.CategoryDataset; 027 import org.jfree.data.category.DefaultCategoryDataset; 028 029 /** 030 * BarChart Plugin VisualisationWindow. Shows a bar chart. 031 * Original code : PieChart plugin ( A. Belgraver, R. van Remortel ) 032 * @author Srinivasan Tharmarajah 033 */ 034 public class BCVisualizationWindow extends VisualizationPluginWindow { 035 036 /** 037 * Render the RTuple in a Bar Chart. 038 * 039 * @param fact 040 * RTuple with the information 041 * @return JPanel holding the bar chart 042 * @author A. Belgraver 043 * @author R. van Remortel 044 * @author Srinivasan Tharmarjah 045 * @date 07-3-2007 046 */ 047 public JPanel render(RTuple fact) { 048 // Check if the fact is a supported Rtype. 049 if (!isTypeSupported(fact)) { 050 // for not supported type show an error message. 051 JPanel jp = new JPanel(); 052 jp.add(new JLabel("Not a supported type"+fact.getRtype().toString())); 053 return jp; 054 } 055 056 // Create and return the piechart. 057 String name = getRTupleName(fact); 058 CategoryDataset dataset = convertRTupleToDataset(fact); 059 JFreeChart chart = createPieChart(name, dataset); 060 061 return new ChartPanel(chart,true,false,true,true,true); 062 } 063 064 /** 065 * Set a new Factory object, for testing purposes. 066 * 067 * @param factory 068 * Factory to use 069 * @author A. Belgraver 070 * @date 07-3-2007 071 */ 072 public void setFactory(Factory factory) { 073 m_factory = factory; 074 } 075 076 /** 077 * Check if a given RType is supported by this visualisation. 078 * 079 * @param fact 080 * The facts for which to verify if the type is supported 081 * @return True if it itype is supported 082 * @author Aldert Boerhoop 083 * @author Anton Gerdessen 084 * @author Srinivasan Tharmarajah 085 * @date 12-03-2007 086 */ 087 public boolean isTypeSupported(RTuple fact) { 088 boolean match = (isRelIntStr(fact) || isRelStrInt(fact) || isRelIntInt(fact) ); 089 090 return match; 091 } 092 093 /** 094 * Check to see if the RTuple is indeed a str,int relation. 095 * 096 * @param fact 097 * RTuple to test 098 * @return True if it is the correct str,int type 099 * @author A. Belgraver 100 * @author R. van Remortel 101 * @author Srinivasan Tharmarajah 102 * @author Aldert Boerhoop (reviewer) 103 * @author Anton Gerdessen (reviewer) 104 * @date 20-2-2007 105 * @todo Needs better implementation needs to be resolved reflection, dynamic 106 * dispatch... in a the base or utility class for all plugins, remark by Anton G. * 107 */ 108 private boolean isRelIntStr(RTuple fact) { 109 RType rType = m_factory.RTypeFromString("relation([int,str])"); 110 boolean match = rType.equals(fact.getRtype()); 111 112 return match; 113 } 114 115 /** 116 * Check to see if the RTuple is indeed a str,int relation. 117 * 118 * @param fact 119 * RTuple to test 120 * @return True if it is the correct str,int type 121 * @author A. Belgraver 122 * @author R. van Remortel 123 * @author Srinivasan Tharmarajah 124 * @author Aldert Boerhoop (reviewer) 125 * @author Anton Gerdessen (reviewer) 126 * @date 20-2-2007 127 * @todo Needs better implementation needs to be resolved reflection, dynamic 128 * dispatch... in a the base or utility class for all plugins, remark by Anton G. * 129 */ 130 private boolean isRelStrInt(RTuple fact) { 131 RType rType = m_factory.RTypeFromString("relation([str,int])"); 132 boolean match = rType.equals(fact.getRtype()); 133 134 return match; 135 } 136 137 /** 138 * Get the name of the RTuple. 139 * 140 * @param fact 141 * RTuple holding information 142 * @return String holding the name of the tuple 143 * @author A. Belgraver 144 * @author R. van Remortel 145 * @author Aldert Boerhoop (reviewer) 146 * @author Anton Gerdessen (reviewer) 147 * @date 07-3-2007 148 * @todo Needs better implementation needs to be resolved reflection, dynamic 149 * dispatch... in a the base or utility class for all plugins, remark by Anton G. 150 */ 151 public String getRTupleName(RTuple fact) { 152 IdCon idCon = (IdCon) fact.getVariable(); 153 return idCon.getString(); 154 } 155 156 /** 157 * Create the bar chart. 158 * 159 * @param title 160 * Name to display on screen 161 * @param dataset 162 * Dataset to show 163 * @return a JFreeChart chart 164 * @author Srinivasan Tharmarajah 165 * @date 12-03-2007 166 */ 167 private JFreeChart createPieChart(String title, CategoryDataset dataset) { 168 169 // create the chart... 170 final JFreeChart chart = ChartFactory.createBarChart( 171 title, // chart title 172 "Fact", // domain axis label 173 "Value", // range axis label 174 dataset, // data 175 PlotOrientation.VERTICAL, // orientation 176 false, // include legend 177 true, // tooltips? 178 false // URLs? 179 ); 180 181 // set the background color for the chart... 182 chart.setBackgroundPaint(Color.white); 183 184 // get a reference to the plot for further customisation... 185 final CategoryPlot plot = chart.getCategoryPlot(); 186 plot.setBackgroundPaint(Color.lightGray); 187 plot.setDomainGridlinePaint(Color.white); 188 plot.setRangeGridlinePaint(Color.white); 189 190 // set the range axis to display integers only... 191 final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); 192 rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); 193 rangeAxis.setUpperMargin(0.15); 194 195 // disable bar outlines... 196 final CategoryItemRenderer renderer = plot.getRenderer(); 197 renderer.setSeriesItemLabelsVisible(0, Boolean.TRUE); 198 199 final CategoryAxis domainAxis = plot.getDomainAxis(); 200 domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); 201 202 return chart; 203 204 } 205 206 /** 207 * Convert RTuple into a BarChart Dataset. 208 * 209 * @param fact 210 * RTuple with the data 211 * @return BarChart dataset 212 * @author A. Belgraver 213 * @author R. van Remortel 214 * @author Srinivasan Tharmarajah 215 * @date 12-03-2007 216 */ 217 public CategoryDataset convertRTupleToDataset(RTuple fact) { 218 RElem set = fact.getValue(); 219 RElemElements elements = set.getElements(); 220 221 final DefaultCategoryDataset dataset = new DefaultCategoryDataset(); 222 223 while (elements.hasTail()) { 224 RElem headElement = elements.getHead(); 225 // Replace the current looping set with: ( set - head ). 226 elements = elements.getTail(); 227 228 // HeadElement itselfs is a tuple <str,int> or <int,str>. 229 RElemElements tuple = headElement.getElements(); 230 231 // Disassemble the tuple into its parts. 232 String name = ""; 233 nl.cwi.sen1.relationstores.types.Integer value; 234 235 if (isRelStrInt(fact)) { 236 name = tuple.getRElemAt(0).getStrCon(); 237 value = tuple.getRElemAt(1).getInteger(); 238 } 239 else if (isRelIntStr(fact)) { 240 name = tuple.getRElemAt(1).getStrCon(); 241 value = tuple.getRElemAt(0).getInteger(); 242 } 243 else if (isRelIntInt(fact)) { 244 Integer i = tuple.getRElemAt(1).getInteger(); 245 if (i.isNatCon()) { 246 name = "" + i.getNatCon(); 247 } 248 else if (i.isNegative()) { 249 name = "-" + i.getNatCon(); 250 } 251 else if (i.isPositive()) { 252 name = "+" + i.getNatCon(); 253 } 254 value = tuple.getRElemAt(0).getInteger(); 255 } 256 else{ 257 throw new RuntimeException("Unknown relation type."); 258 } 259 260 // Store the current tuple in the dataset. 261 dataset.addValue(Double.valueOf(value.getNatCon()), name, name); 262 } 263 return dataset; 264 } 265 266 private boolean isRelIntInt(RTuple fact) { 267 RType rType = m_factory.RTypeFromString("relation([int,int])"); 268 boolean match = rType.equals(fact.getRtype()); 269 270 return match; 271 } 272 273 }