View Javadoc

1   package org.lsst.ccs.plugin.jas3.trending;
2   
3   import com.sun.jersey.api.client.WebResource;
4   import hep.aida.IAxisStyle;
5   import hep.aida.IBaseHistogram;
6   import hep.aida.IDataPoint;
7   import hep.aida.IPlotterStyle;
8   import hep.aida.ref.histogram.DataPointSet;
9   import hep.aida.ref.plotter.PlotterFactory;
10  import java.util.HashMap;
11  import javax.swing.JMenuItem;
12  import javax.swing.JPopupMenu;
13  import javax.ws.rs.core.MediaType;
14  import org.freehep.application.studio.Studio;
15  import org.freehep.jas.plugin.tree.DefaultFTreeNodeAdapter;
16  import org.freehep.jas.plugin.tree.FTreeNode;
17  import org.freehep.jas.plugin.tree.FTreeNodeObjectProvider;
18  import org.freehep.jas.services.PlotFactory;
19  import org.freehep.jas.services.PlotPage;
20  import org.freehep.jas.services.PlotRegion;
21  import org.freehep.jas.services.Plotter;
22  import org.freehep.util.commanddispatcher.CommandProcessor;
23  import org.freehep.util.commanddispatcher.CommandSourceAdapter;
24  import org.lsst.ccs.localdb.statusdb.server.Data;
25  import org.lsst.ccs.localdb.statusdb.server.DataChannel;
26  import org.lsst.ccs.localdb.statusdb.server.TrendingData;
27  import org.lsst.ccs.plugin.jas3.trending.timeselection.TimeSelection;
28  import org.lsst.ccs.plugin.jas3.trending.timeselection.TimeSelectionComboBox;
29  
30  /**
31   * Defines behavior for tree nodes corresponding to trending channels.
32   * @author turri
33   */
34  class DataChannelTreeAdapter extends DefaultFTreeNodeAdapter {
35  
36      private static HashMap<String, PlotPage> plotPageHash = new HashMap<String, PlotPage>();
37      private Studio app;
38      private FTreeNodeObjectProvider objectProvider = new DataChannelObjectProvider();
39      private WebResource service;
40      private PlotterFactory plotterStyleFactory = new PlotterFactory();
41      private Commands commands = new Commands();
42      private final TimeSelectionComboBox selectedTimeRange;
43  
44      DataChannelTreeAdapter(WebResource service, TimeSelectionComboBox selectedTimeRange) {
45          super(100);
46          this.service = service;
47          this.selectedTimeRange = selectedTimeRange;
48          app = (Studio) Studio.getApplication();
49      }
50  
51      @Override
52      public CommandProcessor commandProcessor(FTreeNode[] selectedNodes) {
53          commands.setSelectedNodes(selectedNodes);
54          return commands;
55      }
56  
57      @Override
58      public JPopupMenu modifyPopupMenu(FTreeNode[] nodes, JPopupMenu menu) {
59          commands.setSelectedNodes(nodes);
60          if (menu.getSubElements().length != 0) {
61              menu.addSeparator();
62          }
63          JMenuItem item = new JMenuItem("Show");
64          app.getCommandTargetManager().add(new CommandSourceAdapter(item));
65          menu.add(item);
66          item = new JMenuItem("Overlay on Current Plot");
67          app.getCommandTargetManager().add(new CommandSourceAdapter(item));
68          menu.add(item);
69          item = new JMenuItem("Add to Current Plot");
70          app.getCommandTargetManager().add(new CommandSourceAdapter(item));
71          menu.add(item);
72          item = new JMenuItem("Show in New Plot");
73          app.getCommandTargetManager().add(new CommandSourceAdapter(item));
74          menu.add(item);
75          item = new JMenuItem("Show on New Page");
76          app.getCommandTargetManager().add(new CommandSourceAdapter(item));
77          menu.add(item);
78          menu.addSeparator();
79          return menu;
80      }
81  
82      @Override
83      public FTreeNodeObjectProvider treeNodeObjectProvider(FTreeNode node) {
84          return objectProvider;
85      }
86  
87      @Override
88      public boolean doubleClick(FTreeNode node) {
89          commands.setSelectedNodes(new FTreeNode[]{node});
90          commands.onShow();
91          return true;
92      }
93  
94      class DataChannelObjectProvider implements FTreeNodeObjectProvider {
95  
96          @Override
97          public Object objectForNode(FTreeNode node, Class clazz) {
98              Object obj = node.value(TimeHistory.class);
99              return obj;
100         }
101     }
102 
103     public class Commands extends CommandProcessor {
104 
105         private FTreeNode[] selectedNodes;
106 
107         void setSelectedNodes(FTreeNode[] selectedNodes) {
108             this.selectedNodes = selectedNodes;
109         }
110 
111         public void onShow() {
112             show(true, false, false, false);
113         }
114 
115         public void onOverlayonCurrentPlot() {
116             show(false, false, true, false);
117         }
118 
119         public void onShowinNewPlot() {
120             show(false, false, false, true);
121         }
122 
123         public void onShowonNewPage() {
124             show(false, true, false, false);
125         }
126 
127         private void show(boolean useExistingPlot, boolean newPage, boolean overlay, boolean newPlot) {
128 
129             FTreeNode[] nodes = selectedNodes;
130             DataChannel chan = dataChannel();
131 
132             if (chan != null) {
133                 PlotRegion region;
134                 PlotPage page;
135 
136                 PlotFactory pf = (PlotFactory) app.getLookup().lookup(PlotFactory.class);
137                 if (newPage) {
138                     page = pf.currentPage();
139                 } else if (useExistingPlot) {
140                     page = plotPageHash.get(chan.getPathAsString());
141                 } else {
142                     page = pf.currentPage();
143                 }
144 
145                 if (page == null) {
146                     page = pf.createPage(chan.getPathAsString());
147                     page.createRegions(1, 1);
148                     page.showPage();
149                     plotPageHash.put(chan.getPathAsString(), page);
150                 }
151                 page.showPage();
152 
153                 region = page.currentRegion();
154                 if (region == null) {
155                     region = page.createRegion(0, 0, 1, 1);
156                 } else if (newPlot) {
157                     region = page.addRegion();
158                 }
159                 Plotter plotter = region.currentPlot();
160 
161                 if (plotter == null) {
162                     plotter = pf.createPlotterFor(IBaseHistogram.class);
163                 }
164 
165                 TimeHistory timeHistory = (TimeHistory) nodes[0].objectForClass(TimeHistory.class);
166                 if (timeHistory == null) {
167                     timeHistory = new TimeHistory(chan);
168                     nodes[0].addKey(TimeHistory.class, timeHistory);
169                 }
170                 TimeSelection selectedTimeSelection = selectedTimeRange.getSelectedTimeWindow();
171                 long t1 = selectedTimeSelection.getLowerEdge();
172                 long t2 = selectedTimeSelection.getUpperEdge();
173 
174                 Data data = getDataChannelData(chan.getId(), t1, t2);
175                 timeHistory.setDataArray(data.getTrendingResult().getTrendingDataArray());
176 
177                 String nameAndTitle = chan.getPathAsString();
178                 DataPointSet pst = new DataPointSet(nameAndTitle, nameAndTitle, 2);
179 
180                 for (int i = 0; i < timeHistory.size(); i++) {
181                     TrendingData d = timeHistory.getData(i);
182 
183                     IDataPoint p = pst.addPoint();
184                     p.coordinate(0).setValue(d.getAxisvalue().getValue() / 1000.);
185                     p.coordinate(1).setValue(d.getValue("value"));
186                 }
187 
188                 IPlotterStyle style = plotterStyleFactory.createPlotterStyle();
189                 final IAxisStyle xAxisStyle = style.xAxisStyle();
190                 xAxisStyle.setParameter("type", "date");
191                 xAxisStyle.setParameter("lowerLimit", String.valueOf(t1 / 1000));
192                 xAxisStyle.setParameter("upperLimit", String.valueOf(t2 / 1000));
193 
194                 plotter.plot(pst, overlay ? Plotter.OVERLAY : Plotter.NORMAL, style, "");
195                 region.showPlot(plotter);
196             }
197         }
198 
199         private DataChannel dataChannel() {
200             FTreeNode[] nodes = selectedNodes;
201             return (DataChannel) nodes[0].objectForClass(DataChannel.class);
202         }
203         /**
204          * Fetch the data for a particular channel. Note this is currently being
205          * called synchronously on the event dispatch thread which is not ideal.
206          * @param id Id of channel to fetch
207          * @param t1 Lower limit of time range to fetch
208          * @param t2 Upper limit of time range to fetch
209          * @return The data for this channel/time range
210          */
211         Data getDataChannelData(long id, long t1, long t2) {
212 
213             WebResource resource = service.path("data").path(String.valueOf(id));
214             resource = resource.queryParam("t1", String.valueOf(t1)).queryParam("t2", String.valueOf(t2)).queryParam("flavor", "raw");
215 
216             return resource.accept(MediaType.TEXT_XML).get(Data.class);
217         }
218     }
219 }