001    /**
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: Nov 30, 2002
005     * Time: 7:49:41 PM
006     */
007    
008    package EVolve.visualization.XYViz.ValValViz;
009    
010    import java.awt.*;
011    import java.awt.event.*;
012    import java.util.*;
013    import javax.swing.*;
014    import EVolve.Scene;
015    import EVolve.data.Element;
016    import EVolve.data.Entity;
017    import EVolve.util.DataTrace;
018    import EVolve.util.painters.RandomPainter;
019    import EVolve.util.xmlutils.datastructures.SerializedVisualization;
020    import EVolve.util.equators.*;
021    import EVolve.util.equators.Set;
022    import EVolve.visualization.*;
023    import EVolve.visualization.Dimension;
024    
025    public class DotplotViz extends ValueValueVisualization {
026        private JTextField textInterval,textMatch, textBegin,textEnd;
027        private DataTrace trace;
028        private long event;
029        private JComboBox comboEquator;
030        private Equator[] equatorList;
031        private float percent;
032        private Equator selectedEquator;
033        private JCheckBox chkSelectX, chkSelectTimeFrame;
034        private static JCheckBox selectionOptions[] = null;
035        private static int SELECT_OPTION = 0x0011;
036        private JLabel toEventNo;
037    
038    
039        public DotplotViz() {
040            super();
041    
042            beginCall = 0;
043            endCall = 300;
044            interval = 10;
045            percent = 100;
046    
047    
048            equatorList = new Equator[2];
049            equatorList[0] = new OrderedEquator();
050            equatorList[1] = new UnorderedEquator();
051            selectedEquator = null;
052        }
053    
054        public Dimension[] createDimension() {
055            Dimension [] returnDimension = new Dimension[2];
056    
057            xAxis = new ValueDimension();
058            entityIdFilter = new ReferenceDimension();
059    
060            returnDimension[0] = xAxis;
061            returnDimension[1] = entityIdFilter;
062    
063            return returnDimension;
064        }
065    
066        protected void updateConfiguration() {
067    
068            selectedEquator = equatorList[comboEquator.getSelectedIndex()];
069    
070            try {
071                if (autoInterval != -1) {
072                    interval = autoInterval;
073                    autoInterval = -1;
074                } else {
075                    interval = Integer.parseInt(textInterval.getText());
076                    percent = Float.parseFloat(textMatch.getText());
077                    if ((percent>100)||(percent < 0)) {
078                        Scene.showErrorMessage("Match percent must be between 0 and 100.");
079                        configure();
080                    }
081                    textInterval.setText(String.valueOf(interval));
082                    textMatch.setText(String.valueOf(percent));
083                }
084    
085                beginCall = Integer.parseInt(textBegin.getText());
086                endCall = Integer.parseInt(textEnd.getText());
087                selectedEquator.setInterval(interval);
088                selectedEquator.setMatch(percent);
089    
090                canvas.setName(entityIdFilter.getName(), entityIdFilter.getName());
091                super.updateConfiguration();
092            } catch (NumberFormatException e) {
093                Scene.showErrorMessage("Interval, begin call and end call must be an integer and smaller than "+Integer.MAX_VALUE+".");
094                configure();
095            };
096    
097        }
098    
099        public void restoreConfiguration(SerializedVisualization config) {
100            super.restoreConfiguration(config);
101    
102            beginCall = Long.parseLong(config.BeginEvent);
103            endCall = Long.parseLong(config.EndEvent);
104            percent = Float.parseFloat(config.Threshold);
105    
106            for (int i=0; i<equatorList.length; i++) {
107                if (equatorList[i].getName().equals(config.EqualizerName)) {
108                    selectedEquator = equatorList[i];
109                    comboEquator.setSelectedIndex(i);
110                    selectedEquator.setMatch(percent);
111                    selectedEquator.setInterval(Integer.parseInt(config.EqualizerSetSize));
112                    break;
113                }
114            }
115    
116            textBegin.setText(config.BeginEvent);
117            textEnd.setText(config.EndEvent);
118            textMatch.setText(config.Threshold);
119            interval = Integer.parseInt(config.EqualizerSetSize);
120            textInterval.setText(String.valueOf(interval));
121        }
122    
123        public SerializedVisualization getCurrentConfiguration() {
124            SerializedVisualization data = super.getCurrentConfiguration();
125    
126            data.BeginEvent = String.valueOf(beginCall);
127            data.EndEvent = String.valueOf(endCall);
128            data.Threshold = String.valueOf(percent);
129            data.EqualizerName = selectedEquator.getName();
130            data.EqualizerSetSize = String.valueOf(interval);
131            data.xAxis = xAxis.getName();
132            data.yAxis = entityIdFilter.getName();
133    
134            return data;
135        }
136    
137        public void preVisualize() {
138            image = new AutoImage();
139            trace = selectedEquator.initialDataTrace(interval, Scene.getDataManager().getEntity()[entityIdFilter.getDataFilter().getTargetType()].size());
140            event = 0;
141            getSelection();
142            installPainter();
143            super.preVisualize();
144        }
145    
146        protected void receiveElement(Element element) {
147            if (element.isOptional()) return;
148    
149            long traceId = entityIdFilter.getField(element);
150            long no = xAxis.getField(element) - 1;
151    
152            countEvents(no);
153            if ((no < beginCall)||(no > endCall)) {
154                return;
155            }
156    
157            event++;
158            trace.updateTrace(traceId);
159    
160            ArrayList data = trace.getTrace();
161    
162            if ((event%interval == 0)||(event-endCall==1)) {
163                int size = data.size() - 1;
164                for (int i=size+1; i>1; i--) {
165                    Set set1 = (Set)data.get(size);
166                    Set set2 = (Set)data.get(i-2);
167                    if (selectedEquator.isEqual(set1,set2)) {
168                        painter.paint(image,i-2,size,set1.getHashValue());
169                        painter.paint(image,size,i-2,set1.getHashValue());
170                    }
171                }
172                if (size>=0) {
173                    painter.paint(image,size,size,((Set)data.get(size)).getHashValue());
174                    image.setColor(size,size,Color.black);
175                }
176            }
177        }
178    
179        public void visualize() {
180            canvas.setName("Time - " + xAxis.getDataFilter().getName() + " (" + event +" events)", "Time - " + xAxis.getDataFilter().getName() + " (" + event + " events)");
181            sort();
182        }
183    
184        protected String mouseMove(int x,int y) {
185            if (interval > 1) return null;
186    
187            int X = canvas.getImageX(x);
188            int Y = canvas.getImageY(y);
189            int index = X < Y ? X : Y;
190            if ((index >= 0) && (trace!=null) && (index < trace.size())) {
191                int mappedId = (int)((Set)trace.getTrace().get(index)).getElement(0);
192                Entity entity = entityIdFilter.getEntityFromInt(mappedId);
193                if (shift_pressed && (image.getSortedColor(null,null,X,Y)==null))
194                    Scene.setStatus("  ");
195                else
196                    Scene.setStatus(entity.getName());
197            } else {
198                Scene.setStatus(" ");
199            }
200            return null;
201        }
202    
203        public void makeSelection() {
204            preMakeSelection();
205            if (selectionName==null) return;
206    
207            ArrayList idList = new ArrayList();
208    
209            int x1 = canvas.getStartX();
210            int x2 = canvas.getEndX();
211    
212            if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId()) {
213                Scene.showErrorMessage("The active data source used currently is different from \n" +
214                                       "this visualization, please choose \"" +
215                                       Scene.getDataSourceManager().getUsedDataSourceName(dataSourceId)+"\".");
216                return;
217            }
218    
219            if (((x1<0)&&(x2<0)) || ((x1>=trace.getTrace().size())&&(x2>=trace.getTrace().size())))
220               return;
221    
222            if (x1 < 0) x1 = 0;
223            if (x2 >= trace.getTrace().size()) x2 = trace.getTrace().size()-1;
224    
225            Set unionSet = ((Set)(trace.getTrace().get(x1)));
226            for (int i=x1+1; i<=x2; i++) {
227                Set next = ((Set)(trace.getTrace().get(i)));
228                unionSet = unionSet.union(next);
229            }
230    
231            for (int i=0; i<unionSet.size(); i++) {
232                if (unionSet.getEntityId(i)!=-1)
233                    idList.add(new Long(unionSet.getEntityId(i)));
234            }
235    
236            int selection[] = null;
237            if ((SELECT_OPTION & 0x00f0) == SELECT_OCCURRED_ENTITIES) {
238                selection = new int[idList.size()];
239                for (int i=0; i<selection.length; i++)
240                    selection[i] = ((Long)idList.get(i)).intValue();
241            } else {
242                selection = new int[entityIdFilter.getEntityNumber()];
243                for (int i=0; i<selection.length; i++)
244                    selection[i] = i;
245            }
246    
247    
248            long start = ((long[])timeMap.get(((int)(x1+beginCall/interval))))[1];
249            long end;
250            if (x1==x2) {
251                if (x1+1>trace.getTrace().size()-1)
252                    end = Long.MAX_VALUE;
253                else {
254                    end = ((long[])timeMap.get((int)(x1+1+beginCall/interval)))[1]-1;
255                }
256            } else {
257                end = ((long[])timeMap.get(((int)(x2+beginCall/interval))))[1];
258            }
259            if ((SELECT_OPTION & 0x000f) == 0x0000) {
260                start = 0;
261                end = Long.MAX_VALUE;
262            }
263            entityIdFilter.selectComparator(1);
264            entityIdFilter.makeSelection(selectionName,subjectDefinition.getType(),selection,start,end, timeMap);
265        }
266    
267        protected JPanel createConfigurationPanel() {
268            JPanel returnVal = new JPanel(new GridLayout(1, 1, 5, 5));
269            JPanel panelEvent = new JPanel(new GridLayout(2,2));
270            JPanel equatorBox = new JPanel(new GridLayout(1,2));
271    
272            Box panelBottom = new Box(BoxLayout.Y_AXIS);
273            returnVal.add(panelBottom);
274    
275            textBegin = new JTextField(String.valueOf(beginCall));
276            textEnd = new JTextField(String.valueOf(endCall));
277            panelEvent.add(new JLabel("From Event No:"));
278            panelEvent.add(textBegin);
279    
280            toEventNo = new JLabel("To Event No:");
281            panelEvent.add(toEventNo);
282            panelEvent.add(textEnd);
283            panelBottom.add(panelEvent);
284    
285            comboEquator = new JComboBox();
286            for (int i=0; i<equatorList.length; i++)
287                comboEquator.addItem(equatorList[i].getName());
288            comboEquator.addActionListener(new ActionListener() {
289                public void actionPerformed(ActionEvent e) {
290                    textInterval.setText(String.valueOf(equatorList[comboEquator.getSelectedIndex()].getInterval()));
291                    textMatch.setText(String.valueOf(equatorList[comboEquator.getSelectedIndex()].getMatch()));
292                }
293            });
294    
295            equatorBox.add(new JLabel("Equator:"));
296            equatorBox.add(comboEquator);
297            panelBottom.add(equatorBox);
298    
299            JPanel panelEquator = new JPanel(new GridLayout(2,2));
300    
301            textInterval = new JTextField(String.valueOf(interval));
302            textMatch = new JTextField(String.valueOf(percent));
303    
304            panelEquator.add(new JLabel("Interval:"));
305            panelEquator.add(textInterval);
306            panelEquator.add(new JLabel("Match:"));
307            panelEquator.add(textMatch);
308    
309            panelBottom.add(panelEquator);
310    
311            return returnVal;
312        }
313    
314        protected void installPainter() {
315            painter = new RandomPainter();
316        }
317    
318        public JCheckBox[] createSelectionOptions() {
319            if (selectionOptions != null) return selectionOptions;
320    
321            chkSelectTimeFrame = new JCheckBox("Time Frame");
322            chkSelectTimeFrame.setMnemonic(KeyEvent.VK_T);
323            chkSelectTimeFrame.addActionListener(new ActionListener() {
324                public void actionPerformed(ActionEvent e) {
325                    boolean selected = chkSelectTimeFrame.isSelected();
326                    SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_TIME_FRAME);
327                }
328            });
329            chkSelectTimeFrame.setSelected(true);
330    
331            chkSelectX = new JCheckBox("Occurred Entitiies");
332            chkSelectX.setMnemonic(KeyEvent.VK_O);
333            chkSelectX.addActionListener(new ActionListener() {
334                public void actionPerformed(ActionEvent e) {
335                    boolean selected = chkSelectX.isSelected();
336                    SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_OCCURRED_ENTITIES);
337                }
338            });
339            chkSelectX.setSelected(true);
340    
341            selectionOptions = new JCheckBox[2];
342            selectionOptions[0] = chkSelectTimeFrame;
343            selectionOptions[1] = chkSelectX;
344    
345            return selectionOptions;
346        }
347    
348        protected void updateComboSubject() {
349            super.updateComboSubject();
350            String range = String.valueOf(Scene.getDataManager().getDataSource().getNumberOfEvents(elementDefinition[comboSubject.getSelectedIndex()].getName()));
351            toEventNo.setText("To Event No:("+range+")");
352        }
353    
354        public Object clone() {
355            DotplotViz o = (DotplotViz)super.clone();
356            o.dimension[0] = o.xAxis;
357            o.dimension[1] = o.entityIdFilter;
358            o.trace = (trace == null) ? null : (DataTrace)trace.clone();
359            o.createDialog();
360            o.createMenu();
361    
362            return o;
363        }
364    }