001    package nl.cwi.sen1.visplugin.piechart;
002    
003    import java.awt.Font;
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.RElem;
010    import nl.cwi.sen1.relationstores.types.RElemElements;
011    import nl.cwi.sen1.relationstores.types.RTuple;
012    import nl.cwi.sen1.relationstores.types.RType;
013    import nl.cwi.sen1.relationstores.types.idcon.IdCon;
014    import nl.cwi.sen1.visplugin.VisualizationPluginWindow;
015    
016    import org.jfree.chart.ChartFactory;
017    import org.jfree.chart.ChartPanel;
018    import org.jfree.chart.JFreeChart;
019    import org.jfree.chart.plot.PiePlot;
020    import org.jfree.data.general.DefaultPieDataset;
021    
022    /**
023     * PieChart Plugin VisualisationWindow. Shows a pie chart.
024     * 
025     * @author A. Belgraver
026     * @author R. van Remortel
027     * @author Aldert Boerhoop (reviewer)
028     * @author Anton Gerdessen (reviewer)
029     */
030    public class PCVisualizationWindow extends VisualizationPluginWindow {
031    
032        /**
033         * Render the RTuple in a Pie Chart.
034         * 
035         * @param fact
036         *            RTuple with the information
037         * @return JPanel holding the pie chart
038         * @author A. Belgraver
039         * @author R. van Remortel
040         * @author Aldert Boerhoop (reviewer)
041         * @author Anton Gerdessen (reviewer)
042         * @date 07-3-2007
043         */
044        public JPanel render(RTuple fact) {
045            // Check if the fact is a supported Rtype.
046            if (!isTypeSupported(fact)) {
047                // for not supported type show an error message.
048                JPanel jp = new JPanel();
049                jp.add(new JLabel("Not a supported type"+fact.getRtype().toString()));
050                return jp;
051            }
052    
053            // Create and return the piechart.
054            String name = getRTupleName(fact);
055            DefaultPieDataset dataset = convertRTupleToDataset(fact);
056            JFreeChart chart = createPieChart(name, dataset);
057    
058            return new ChartPanel(chart,true,false,true,true,true);
059        }
060    
061        /**
062         * Set a new Factory object, for testing purposes.
063         * 
064         * @param factory
065         *            Factory to use
066         * @author A. Belgraver
067         * @author Aldert Boerhoop (reviewer)
068         * @author Anton Gerdessen (reviewer)
069         * @date 07-3-2007
070         */
071        public void setFactory(Factory factory) {
072            m_factory = factory;
073        }
074    
075        /**
076         * Check if a given RType is supported by this visualisation.
077         * 
078         * @param fact
079         *            The facts for which to verify if the type is supported
080         * @return True if it itype is supported
081         * @author Aldert Boerhoop
082         * @author Anton Gerdessen
083         * 
084         * @date 07-3-2007
085         */
086        public boolean isTypeSupported(RTuple fact) {
087            boolean match = (isRelStrInt(fact) || isRelIntStr(fact) || isRelInt(fact));
088    
089            return match;
090        }
091    
092        /**
093         * Check to see if the RTuple is indeed a str,int relation.
094         * 
095         * @param fact
096         *            RTuple to test
097         * @return True if it is the correct str,int type
098         * @author A. Belgraver
099         * @author R. van Remortel
100         * @author Aldert Boerhoop (reviewer)
101         * @author Anton Gerdessen (reviewer)
102         * @date 20-2-2007
103         * @todo Needs better implementation needs to be resolved reflection, dynamic 
104         * dispatch... in a the base or utility class for all plugins, remark by Anton G.     * 
105         */
106        private boolean isRelStrInt(RTuple fact) {
107            RType rType = m_factory.RTypeFromString("relation([str,int])");
108            boolean match = rType.equals(fact.getRtype());
109            
110            return match;
111        }
112    
113        /**
114         * Check to see if the RTuple is indeed a int relation.
115         * 
116         * @param fact
117         *            RTuple to test
118         * @return True if it is the correct str,int type
119         * @author A. Belgraver
120         * @author R. van Remortel
121         * @author Aldert Boerhoop (reviewer)
122         * @author Anton Gerdessen (reviewer)
123         * @date 20-2-2007
124         * @todo Needs better implementation needs to be resolved reflection, dynamic 
125         * dispatch... in a the base or utility class for all plugins, remark by Anton G. 
126         */
127        private boolean isRelInt(RTuple fact) {
128            RType rType = m_factory.RTypeFromString("relation([int])");
129            boolean match = rType.equals(fact.getRtype());
130    
131            return match;
132        }
133        
134        /**
135           /**
136         * Check to see if the RTuple is indeed a str,int relation.
137         * 
138         * @param fact
139         *            RTuple to test
140         * @return True if it is the correct str,int type
141         * @author A. Belgraver
142         * @author R. van Remortel
143         * @author Aldert Boerhoop (reviewer)
144         * @author Anton Gerdessen (reviewer)
145         * @date 20-2-2007
146         * @todo Needs better implementation needs to be resolved reflection, dynamic 
147         * dispatch... in a the base or utility class for all plugins, remark by Anton G.     * 
148         */
149        private boolean isRelIntStr(RTuple fact) {
150            RType rType = m_factory.RTypeFromString("relation([int,str])");
151            boolean match = rType.equals(fact.getRtype());
152            
153            return match;
154        }
155    
156        /**
157         * Get the name of the RTuple.
158         * 
159         * @param fact
160         *            RTuple holding information
161         * @return String holding the name of the tuple
162         * @author A. Belgraver
163         * @author R. van Remortel
164         * @author Aldert Boerhoop (reviewer)
165         * @author Anton Gerdessen (reviewer)
166         * @date 07-3-2007
167         * @todo Needs better implementation needs to be resolved reflection, dynamic 
168         * dispatch... in a the base or utility class for all plugins, remark by Anton G.
169         */
170        public String getRTupleName(RTuple fact) {
171            IdCon idCon = (IdCon) fact.getVariable();
172            return idCon.getString();
173        }
174    
175        /**
176         * Create the pie chart.
177         * 
178         * @param name
179         *            Name to display on screen
180         * @param dataset
181         *            Dataset to show
182         * @return a JFreeChart chart
183         * @author A. Belgraver
184         * @author R. van Remortel
185         * @author Aldert Boerhoop (reviewer)
186         * @author Anton Gerdessen (reviewer)
187         * @date 07-3-2007
188         */
189        private JFreeChart createPieChart(String name, DefaultPieDataset dataset) {
190            // Initialise the chart.
191            JFreeChart chart = ChartFactory.createPieChart(name, // chart title
192                    dataset, // data
193                    true, // include legend
194                    true, // include tooltips
195                    false); // incluse urls
196    
197            // Set the charts format options.
198            PiePlot plot = (PiePlot) chart.getPlot();
199            plot.setSectionOutlinesVisible(false);
200            plot.setLabelFont(new Font("SansSerif", Font.PLAIN, 12));
201            plot.setNoDataMessage("No data available");
202            plot.setCircular(false);
203            plot.setLabelGap(0.02);
204    
205            return chart;
206        }
207    
208        /**
209         * Convert RTuple into a PieChart Dataset.
210         * 
211         * @param fact
212         *            RTuple with the data
213         * @return PieChart dataset
214         * @author A. Belgraver
215         * @author R. van Remortel
216         * @author Srinivasan Tharmarajah (Fix)
217         * @author Aldert Boerhoop (reviewer)
218         * @author Anton Gerdessen (reviewer)
219         * @date 07-3-2007
220         */
221        public DefaultPieDataset convertRTupleToDataset(RTuple fact) {
222            RElem set = fact.getValue();
223            RElemElements elements = set.getElements();
224            
225            DefaultPieDataset dataset = new DefaultPieDataset();
226            
227            String name = "";
228            nl.cwi.sen1.relationstores.types.Integer value;
229            int counter = 0;
230            
231            while (elements.hasTail()) {
232                RElem headElement = elements.getHead();
233                // Replace the current looping set with: ( set - head ).
234                elements = elements.getTail();
235    
236                // HeadElement itselfs is a tuple <str,int>, <int,str>.
237                RElemElements tuple = headElement.getElements();
238    
239                if (isRelStrInt(fact)) {
240                    name = tuple.getRElemAt(0).getStrCon();
241                    value = tuple.getRElemAt(1).getInteger();
242                }else if (isRelIntStr(fact)) {
243                    name = tuple.getRElemAt(1).getStrCon();
244                    value = tuple.getRElemAt(0).getInteger();
245                }else if (isRelInt(fact)) {
246                    value = tuple.getRElemAt(0).getInteger();
247                    name = new String(++counter + ": " + value);
248                }else{
249                    throw new RuntimeException("Unknown relation type.");
250                }
251                    
252                // Store the current tuple in the dataset.
253                dataset.setValue(name, new Double(value.getNatCon()));
254            }
255            return dataset;
256        }
257    
258     }