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 }