001    /**
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: Nov 27, 2002
005     * Time: 5:00:08 PM
006     */
007    
008    package EVolve.visualization.XYViz.ValRefViz.HotSpotViz;
009    
010    import java.awt.Color;
011    import java.awt.FlowLayout;
012    import java.awt.GridLayout;
013    import java.awt.event.ActionEvent;
014    import java.awt.event.ActionListener;
015    import java.awt.event.KeyEvent;
016    import java.util.ArrayList;
017    
018    import javax.swing.JCheckBox;
019    import javax.swing.JComboBox;
020    import javax.swing.JLabel;
021    import javax.swing.JMenuItem;
022    import javax.swing.JPanel;
023    import javax.swing.JTextField;
024    
025    import EVolve.Scene;
026    import EVolve.data.Element;
027    import EVolve.util.painters.DefaultPainter;
028    import EVolve.util.painters.Painter;
029    import EVolve.util.painters.RandomPainter;
030    import EVolve.util.phasedetectors.HotspotPhaseDetector;
031    import EVolve.util.xmlutils.datastructures.SerializedVisualization;
032    import EVolve.visualization.AutoImage;
033    import EVolve.visualization.XYViz.ValRefViz.ValueReferenceVisualization;
034    
035    public class HotSpotVisualization extends ValueReferenceVisualization {
036        protected JTextField textInterval; // input for interval
037        protected JComboBox comboPainter;
038        protected Painter painters[];
039        protected int selectedPainter;
040        protected JPanel configurationPanel;
041        private JCheckBox chkSelectTimeFrame, chkSelectOccurredEntities, chkSelectAllEntities;
042        private JMenuItem itemSelectPhase;
043        protected static JCheckBox selectionOptions[] = null;
044        protected static int SELECT_OPTION = 0x0011;
045    
046    
047        public HotSpotVisualization() {
048            interval = 10000;
049            painters = new Painter[2];
050            painters[0] = new DefaultPainter();
051            painters[1] = new RandomPainter();
052            selectedPainter = 0;
053            phaseDetector = new HotspotPhaseDetector(this);
054        }
055    
056        protected JPanel createConfigurationPanel() {
057            JPanel panelBottom = new JPanel(new GridLayout(2,2));
058            panelBottom.add(new JLabel("Interval: "));
059    
060            textInterval = new JTextField(String.valueOf(interval), 10);
061            panelBottom.add(textInterval);
062    
063            comboPainter = new JComboBox();
064            for (int i = 0; i < painters.length; i++) {
065                comboPainter.addItem(painters[i].getName());
066            }
067            comboPainter.addActionListener(new ActionListener() {
068                public void actionPerformed(ActionEvent e) {
069                    selectedPainter = comboPainter.getSelectedIndex();
070                }
071            });
072            panelBottom.add(new JLabel("Painter used:  "));
073            panelBottom.add(comboPainter);
074    
075    
076            if (configurationPanel == null)
077                configurationPanel = new JPanel(new FlowLayout());
078            configurationPanel.add(panelBottom);
079    
080            return configurationPanel;
081        }
082    
083        public void restoreConfiguration(SerializedVisualization config) {
084            for (int i=0; i<painters.length; i++) {
085                if (painters[i].getName().equals(config.PainterName)) {
086                    comboPainter.setSelectedIndex(i);
087                    selectedPainter = i;
088                    break;
089                }
090            }
091            textInterval.setText(config.Interval);
092            super.restoreConfiguration(config);
093        }
094    
095        public SerializedVisualization getCurrentConfiguration() {
096            SerializedVisualization data = super.getCurrentConfiguration();
097    
098            data.PainterName = painters[selectedPainter].getName();
099            return data;
100        }
101    
102        public void preVisualize() {
103            xMax = 0;
104            imageMap.clear();
105            currentThread = -1;
106            image = new AutoImage();
107            xOffset = -1;
108            adjustTimeAxis();
109            installPainter();
110            timeMap.clear();
111            phaseDetector.reset();
112        }
113    
114        public void receiveElement(Element element) {
115            if (element.isOptional()) return;
116    
117            long x = xAxis.getField(element);
118            long y = yAxis.getField(element);
119    
120            paint(x,y,y);
121        }
122    
123        public void visualize() {
124            yAxis.selectComparator(comboSortSchemes[0].getSelectedItem().toString());
125            sort();
126        }
127    
128        public void makeSelection() {
129            int x1 = canvas.getStartX();
130            int x2 = canvas.getEndX();
131            int y1 = canvas.getEndY();
132            int y2 = canvas.getStartY();
133            select(x1,y1,x2,y2);
134        }
135    
136        public void paint(long x, long y, long z) {
137            long temp = x;
138            if (x > xMax) {
139                xMax = x;
140            }
141    
142            if (xOffset == -1) xOffset = x/interval;
143    
144            phaseDetector.collectData(x/interval-xOffset,y);
145    
146            x = x/interval;
147            painter.paint(image,x-xOffset,y,z);
148    
149            countEvents(temp);
150        }
151    
152        protected void updateConfiguration() {
153            try {
154                if (autoInterval == -1)
155                    interval = Integer.parseInt(textInterval.getText());
156                else {
157                    interval = autoInterval;
158                    autoInterval = -1;
159                    textInterval.setText(String.valueOf(interval));
160                }
161                super.updateConfiguration();
162    
163            } catch (Exception e) {
164                Scene.showErrorMessage("Interval must be an integer");
165                configure();
166            }
167        }
168    
169        public JCheckBox[] createSelectionOptions() {
170            if (selectionOptions != null) return selectionOptions;
171    
172            chkSelectTimeFrame = new JCheckBox("Time Frame");
173            chkSelectTimeFrame.setMnemonic(KeyEvent.VK_T);
174            chkSelectTimeFrame.addActionListener(new ActionListener() {
175                public void actionPerformed(ActionEvent e) {
176                    boolean selected = chkSelectTimeFrame.isSelected();
177                    SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_TIME_FRAME);
178                }
179            });
180            chkSelectTimeFrame.setSelected(true);
181    
182            chkSelectOccurredEntities = new JCheckBox("Occurred Entities");
183            chkSelectOccurredEntities.setMnemonic(KeyEvent.VK_O);
184            chkSelectOccurredEntities.addActionListener(new ActionListener() {
185                public void actionPerformed(ActionEvent e) {
186                    boolean selected = chkSelectOccurredEntities.isSelected();
187                    SELECT_OPTION = switchOption(selected,SELECT_OPTION, SELECT_OCCURRED_ENTITIES);
188                }
189            });
190            chkSelectOccurredEntities.setSelected(true);
191    
192            chkSelectAllEntities = new JCheckBox("All Entities");
193            chkSelectAllEntities.setMnemonic(KeyEvent.VK_A);
194            chkSelectAllEntities.addActionListener(new ActionListener() {
195                public void actionPerformed(ActionEvent e) {
196                    boolean selected = chkSelectAllEntities.isSelected();
197                    SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_ALL_ENTITIES);
198    
199                    if (chkSelectOccurredEntities.isSelected() && selected) {
200                        SELECT_OPTION = switchOption(false,SELECT_OPTION, SELECT_OCCURRED_ENTITIES);
201                        chkSelectOccurredEntities.setSelected(false);
202                    }
203                }
204            });
205            chkSelectAllEntities.setSelected(true);
206    
207            selectionOptions = new JCheckBox[2];
208            selectionOptions[0] = chkSelectTimeFrame;
209            selectionOptions[1] = chkSelectOccurredEntities;
210    
211            return selectionOptions;
212        }
213    
214        protected void installPainter() {
215            painter = painters[selectedPainter];
216        }
217    
218        protected void createMenu() {
219            super.createMenu();
220    
221            itemSelectPhase = new JMenuItem("Select current phase ...");
222            itemSelectPhase.setMnemonic(KeyEvent.VK_S);
223            itemSelectPhase.addActionListener(new ActionListener() {
224                public void actionPerformed(ActionEvent e) {
225                    ArrayList phases = phaseDetector.getPhase();
226                    int mousePosition = canvas.getImageX(mouseX);
227                    int lastPhase = 0, currentPhase = 0;
228                    if (phases.size() == 0) {
229                        Scene.showErrorMessage("No phase information available.");
230                        return;
231                    }
232                    for (int i=0; i<phases.size(); i++) {
233                        currentPhase = ((Integer)phases.get(i)).intValue();
234                        if (mousePosition < currentPhase) break;
235                        lastPhase = currentPhase;
236                    }
237                    if (lastPhase==currentPhase) {
238                        currentPhase = Integer.MAX_VALUE;
239                    }
240                    select(lastPhase,0,currentPhase,yAxis.getEntityNumber()-1);
241                }
242            });
243    
244            popup.add(itemSelectPhase);
245        }
246    
247        private void select(int X1, int Y1, int X2, int Y2) {
248            preMakeSelection();
249            if (selectionName == null) return;
250    
251            if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId()) {
252                Scene.showErrorMessage("The active data source used currently is different from \n" +
253                                       "this visualization, please choose \"" +
254                                       Scene.getDataSourceManager().getUsedDataSourceName(dataSourceId)+"\".");
255                return;
256            }
257    
258            int x1 = X1;//canvas.getStartX();
259            int x2 = X2;//canvas.getEndX();
260            int y1 = Y1;//canvas.getEndY();
261            int y2 = Y2;//canvas.getStartY();
262    
263            if (!normalOrientation) {
264                int temp;
265                temp = x1;
266                x1 = y1;
267                y1 = temp;
268                temp = x2;
269                x2 = y2;
270                y2 = temp;
271            }
272    
273            if (((x1<0)&&(x2<0)) || ((x1>=timeMap.size()))&&(x2>=timeMap.size()) ||
274                ((y1<0)&&(y2<0)) || ((y1>=yAxis.getEntityNumber())&&(y2>=yAxis.getEntityNumber())))
275               return;
276    
277            /*if (x1==x2) {
278                x2++;
279            }*/
280    
281            if (x1 < 0) {
282                x1 = 0;
283            }
284    
285            if (x1 > (timeMap.size() - 1)) {
286                x1 = timeMap.size() - 1;
287            }
288    
289            if (x2 > (timeMap.size() - 1)) {
290                x2 = timeMap.size() - 1;
291            }
292    
293            if (y1 < 0) {
294                y1 = 0;
295            }
296    
297            if (y1 > (yAxis.getEntityNumber() - 1)) {
298                y1 = yAxis.getEntityNumber() - 1;
299            }
300    
301            if (y2 > (yAxis.getEntityNumber() - 1)) {
302                y2 = yAxis.getEntityNumber() - 1;
303            }
304    
305            long start = ((long[])timeMap.get(x1))[1];
306            long end = ((long[])timeMap.get(x2))[1];
307    
308            if (((SELECT_OPTION & 0x000f) != SELECT_TIME_FRAME)||((x2==x1)&&(x1==0))) { // do not select time frame
309                start = 0;
310                end = Long.MAX_VALUE;
311            } else {
312                /*if (x2==x1) {
313                    x1--;
314                }
315                start = ((long[])timeMap.get(x1))[1];*/
316                if (x1==x2) {
317                    if (x2+1<timeMap.size()) {
318                        end = ((long[])timeMap.get(x2+1))[1];
319                    } else
320                        end = Long.MAX_VALUE;
321                }
322            }
323    
324            int[] selection = null;
325            switch (SELECT_OPTION & 0x0ff0) {
326                case 0x0100: // select all entities in the draw box
327                    selection = new int[y2 - y1 + 1];
328                    for (int i = y1; i <= y2; i++) {
329                        selection[i - y1] = i;
330                    }
331                    break;
332                case 0x0010: // select occurred entities
333                    ArrayList idList = new ArrayList();
334                    for (int i=y1; i<=y2; i++) {
335                        for (int j=x1; j<=x2; j++) {
336                            Color color = (Color)image.getSortedColor(null,yAxis,j,i);
337                            if (color != null) {
338                                idList.add(new Integer(i));
339                                break;
340                            }
341                        }
342                    }
343    
344                    selection = new int[idList.size()];
345                    for (int i=0; i<idList.size(); i++) {
346                        selection[i] = ((Integer)idList.get(i)).intValue();
347                    }
348                    break;
349                case 0x0000: // no selection on entities
350                    y1 = 0;
351                    y2 = yAxis.getEntityNumber() - 1;
352                    selection = new int[y2 - y1 + 1];
353                    for (int i = y1; i <= y2; i++) {
354                        selection[i - y1] = i;
355                    }
356                    break;
357            }
358    
359            yAxis.makeSelection(selectionName, subjectDefinition.getType(),selection,start,end,timeMap);
360        }
361    
362        public Object clone() {
363            HotSpotVisualization o = (HotSpotVisualization) super.clone();
364            o.configurationPanel = null;
365            o.panelConfiguration = o.createConfigurationPanel();
366            o.createDialog();
367            return o;
368        }
369    }