001    package nl.cwi.sen1.visplugin.linechart;
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.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.PlotOrientation;
020    import org.jfree.data.xy.XYSeries;
021    import org.jfree.data.xy.XYSeriesCollection;
022    
023    /**
024     * LineChart Plugin VisualisationWindow. Shows a line chart.
025     * Original code : PieChart plugin ( A. Belgraver, R. van Remortel )
026     * @author Raymond Bergen
027     */
028    public class LCVisualizationWindow extends VisualizationPluginWindow {
029    
030        /**
031         * Render the RTuple in a Line Chart.
032         * 
033         * @param fact
034         *            RTuple with the information
035         * @return JPanel holding the bar chart
036         * @author A. Belgraver
037         * @author R. van Remortel
038         * @author Raymond Bergen
039         * @date 07-3-2007
040         */
041        public JPanel render(RTuple fact) {
042            // Check if the fact is a supported Rtype.
043            if (!isTypeSupported(fact)) {
044                // for not supported type show an error message.
045                JPanel jp = new JPanel();
046                jp.add(new JLabel("Not a supported type"+fact.getRtype().toString()));
047                return jp;
048            }
049    
050            // Create and return the piechart.
051            String graphTitle = "LineChart";
052            XYSeriesCollection dataset = convertRTupleToDataset(fact);
053            JFreeChart chart = createLineChart(graphTitle, dataset);
054    
055            return new ChartPanel(chart,true,false,true,true,true);
056        }
057    
058        /**
059         * Set a new Factory object, for testing purposes.
060         * 
061         * @param factory
062         * Factory to use
063         * @author A. Belgraver
064         * @date 07-3-2007
065         */
066        public void setFactory(Factory factory) {
067            m_factory = factory;
068        }
069    
070        /**
071         * Check if a given RType is supported by this visualisation.
072         * 
073         * @param fact
074         *            The facts for which to verify if the type is supported
075         * @return True if it itype is supported
076         * @author Raymond Bergen
077         * @date 12-03-2007
078         */
079        public boolean isTypeSupported(RTuple fact) {
080            boolean match = isRelIntInt(fact);
081    
082            return match;
083        }
084    
085    
086        private boolean isRelIntInt(RTuple fact) {
087            RType rType = m_factory.RTypeFromString("relation([int,int])");
088            boolean match = rType.equals(fact.getRtype());
089    
090            return match;
091        }
092        /**
093         * Get the name of the RTuple.
094         * 
095         * @param fact
096         *            RTuple holding information
097         * @return String holding the name of the tuple
098         * @author A. Belgraver
099         * @author R. van Remortel
100         * @author Aldert Boerhoop (reviewer)
101         * @author Anton Gerdessen (reviewer)
102         * @date 07-3-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        public String getRTupleName(RTuple fact) {
107            IdCon idCon = (IdCon) fact.getVariable();
108            return idCon.getString();
109        }
110    
111        /**
112         * Create the line chart.
113         * 
114         * @param title
115         *            Name to display on screen
116         * @param dataset
117         *            Dataset to show
118         * @return a JFreeChart chart
119         * @author Raymond Bergen
120         * @date 12-03-2007
121         */
122    private JFreeChart createLineChart(String title, XYSeriesCollection dataset) {
123        // create the chart...
124             final JFreeChart chart = ChartFactory.createXYLineChart(
125                        title,      // chart title
126                        "X",                      // x axis label
127                        "Y",                      // y axis label
128                        dataset,                  // data
129                        PlotOrientation.VERTICAL,
130                        true,                     // include legend
131                        true,                     // tooltips
132                        false                     // urls
133                    );
134    
135        // set the background color for the chart...
136        chart.setBackgroundPaint(Color.white);
137    
138        return chart;
139            
140        }
141    
142        /**
143         * Convert RTuple into a LineChart Dataset.
144         * Supports relation([int,int]) This can be extended to support multiple lines in a chart
145         * 
146         * @param fact
147         *            RTuple with the data
148         * @return LineChart dataset
149         * @author Raymond Bergen
150         * @date 12-03-2007
151         */
152        public XYSeriesCollection convertRTupleToDataset(RTuple fact) {
153            RElem set = fact.getValue();
154            RElemElements elements = set.getElements();
155            
156            String name = getRTupleName(fact);
157            XYSeries series = new XYSeries(name);  
158            
159            while (elements.hasTail()) {
160                RElem headElement = elements.getHead();
161                // Replace the current looping set with: ( set - head ).
162                elements = elements.getTail();
163    
164                // HeadElement itselfs is a tuple <int,int>
165                RElemElements tuple = headElement.getElements();
166    
167                // Disassemble the tuple into its parts.
168                nl.cwi.sen1.relationstores.types.Integer xValue = null;
169                nl.cwi.sen1.relationstores.types.Integer yValue = null;
170                
171                
172                xValue = tuple.getRElemAt(0).getInteger();
173                yValue = tuple.getRElemAt(1).getInteger();
174        
175                // Store the current tuple in the dataset.
176                series.add(Double.valueOf(xValue.getNatCon()),Double.valueOf(yValue.getNatCon()));
177            }
178            
179            final XYSeriesCollection dataset = new XYSeriesCollection();
180            dataset.addSeries(series);
181            
182            return dataset;
183        }
184    }