PageRenderTime 44ms CodeModel.GetById 2ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 0ms

/v3.2/nimbits-tds/src/com/nimbits/client/panels/AnnotatedTimeLinePanel.java

http://nimbits-server.googlecode.com/
Java | 568 lines | 408 code | 108 blank | 52 comment | 46 complexity | edba555a30b81855ac1e1e049ef5d89c MD5 | raw file
  1/*
  2 * Copyright (c) 2010 Tonic Solutions LLC.
  3 *
  4 * http://www.nimbits.com
  5 *
  6 *
  7 * Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
  8 *
  9 * http://www.gnu.org/licenses/gpl.html
 10 *
 11 * Unless required by applicable law or agreed to in writing, software distributed under the license is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 12 */
 13
 14package com.nimbits.client.panels;
 15
 16import com.extjs.gxt.ui.client.dnd.DropTarget;
 17import com.extjs.gxt.ui.client.event.*;
 18import com.extjs.gxt.ui.client.store.TreeStoreModel;
 19import com.extjs.gxt.ui.client.widget.*;
 20import com.extjs.gxt.ui.client.widget.button.Button;
 21import com.extjs.gxt.ui.client.widget.button.ToolButton;
 22import com.extjs.gxt.ui.client.widget.form.NumberField;
 23import com.extjs.gxt.ui.client.widget.form.TextField;
 24import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
 25import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
 26import com.google.gwt.core.client.GWT;
 27import com.google.gwt.i18n.client.DateTimeFormat;
 28import com.google.gwt.user.client.Element;
 29import com.google.gwt.user.client.rpc.AsyncCallback;
 30import com.google.gwt.user.client.ui.AbstractImagePrototype;
 31import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
 32import com.google.gwt.visualization.client.DataTable;
 33import com.google.gwt.visualization.client.VisualizationUtils;
 34import com.google.gwt.visualization.client.visualizations.AnnotatedTimeLine;
 35import com.google.gwt.visualization.client.visualizations.AnnotatedTimeLine.Options;
 36import com.google.gwt.visualization.client.visualizations.AnnotatedTimeLine.WindowMode;
 37import com.nimbits.client.exception.NimbitsException;
 38import com.nimbits.client.icons.Icons;
 39import com.nimbits.client.model.Const;
 40import com.nimbits.client.model.GxtPointModel;
 41import com.nimbits.client.model.common.CommonFactoryLocator;
 42import com.nimbits.client.model.point.Point;
 43import com.nimbits.client.model.point.PointName;
 44import com.nimbits.client.model.timespan.InvalidTimespanException;
 45import com.nimbits.client.model.timespan.Timespan;
 46import com.nimbits.client.model.timespan.TimespanModel;
 47import com.nimbits.client.model.timespan.TimespanServiceClientImpl;
 48import com.nimbits.client.model.value.Value;
 49import com.nimbits.client.service.datapoints.PointService;
 50import com.nimbits.client.service.datapoints.PointServiceAsync;
 51import com.nimbits.client.service.recordedvalues.RecordedValueService;
 52import com.nimbits.client.service.recordedvalues.RecordedValueServiceAsync;
 53
 54import java.util.*;
 55
 56public class AnnotatedTimeLinePanel extends NavigationEventProvider {
 57    private final DateTimeFormat fmt = DateTimeFormat.getFormat(Const.FORMAT_DATE_TIME);
 58
 59    private AnnotatedTimeLine line;
 60    private ContentPanel mainPanel;
 61    private DataTable dataTable = null;
 62
 63    private final Map<PointName, Point> points = new HashMap<PointName, Point>();
 64    private final TextField endDateSelector = new TextField();
 65    private final TextField startDateSelector = new TextField();
 66    private Timespan timespan;
 67    private boolean headerVisible;
 68    private final String name;
 69    private boolean selected;
 70
 71
 72    public AnnotatedTimeLinePanel(boolean showHeader, String name) {
 73        this.headerVisible = showHeader;
 74        this.name = name;
 75    }
 76
 77    public boolean containsPoint(Point point) {
 78        return points.containsKey(point.getName());
 79    }
 80
 81    public void addValue(Point point, Value value) {
 82        if (timespan != null) {
 83            final Date end = (timespan.getEnd().getTime() > value.getTimestamp().getTime()) ? value.getTimestamp() : timespan.getEnd();
 84            final Date start = (timespan.getStart().getTime() < value.getTimestamp().getTime()) ? value.getTimestamp() : timespan.getStart();
 85            this.timespan = new TimespanModel(end, start);
 86            startDateSelector.setValue(fmt.format(this.timespan.getStart()));
 87            endDateSelector.setValue(fmt.format(this.timespan.getEnd()));
 88        }
 89
 90
 91        addPointDataToTable(point, Arrays.asList(value));
 92        GWT.log("timespan is null: " + (timespan == null));
 93        drawChart();
 94    }
 95
 96    private void addPointDataToTable(Point p, List<Value> values) {
 97        int PointColumn;
 98
 99
100        boolean found = false;
101
102        removePointDataFromTable(CommonFactoryLocator.getInstance().createPointName(Const.DEFAULT_EMPTY_COL));
103
104        int r = dataTable.getNumberOfColumns();
105        int CurrentRow = dataTable.getNumberOfRows();
106        PointColumn = dataTable.getNumberOfColumns();
107
108        for (int i = 0; i < r; i++) {
109            String s = dataTable.getColumnLabel(i);
110            if (s.equals(p.getName().getValue())) {
111                PointColumn = i;
112                found = true;
113                break;
114            }
115        }
116
117
118        if (!found) {
119            dataTable.addColumn(ColumnType.NUMBER, p.getName().getValue());
120            dataTable.addColumn(ColumnType.STRING, "title" + r);
121            dataTable.addColumn(ColumnType.STRING, "text" + r);
122        }
123
124        if (values != null) {
125            for (Value v : values) {
126                dataTable.addRow();
127                dataTable.setValue(CurrentRow, 0, v.getTimestamp());
128                dataTable.setValue(CurrentRow, PointColumn, v.getValue());
129
130                String note = v.getNote();
131                String name = p.getName().getValue();
132
133                if (note == null || v.getNote().trim().length() == 0) {
134                    note = null;//"undefined";
135                    name = null;//"undefined";
136                }
137
138                //note = null;
139                dataTable.setValue(CurrentRow, PointColumn + 2, note);
140                dataTable.setValue(CurrentRow, PointColumn + 1, name);
141
142                CurrentRow++;
143            }
144        }
145    }
146
147    private void removePointDataFromTable(PointName pointName) {
148        int r = dataTable.getNumberOfColumns();
149        for (int i = 0; i < r; i++) {
150            String s = dataTable.getColumnLabel(i);
151            if (s.equals(pointName.getValue())) {
152                dataTable.removeColumns(i, i + 2);
153                break;
154            }
155        }
156    }
157
158    private void drawChart() {
159        layout();
160        line.draw(dataTable, createOptions());
161    }
162
163//    public List<Point> getPoints() {
164//        return points;
165//    }
166
167    @Override
168    protected void onRender(final Element parent, final int index) {
169        super.onRender(parent, index);
170
171        mainPanel = new ContentPanel();
172        mainPanel.setBodyBorder(true);
173        mainPanel.setHeaderVisible(headerVisible);
174
175        mainPanel.setFrame(true);
176        mainPanel.setTopComponent(toolbar());
177        //   mainPanel.setLayout(new FillLayout());
178        mainPanel.setHeight(400);
179        if (headerVisible) {
180            mainPanel.getHeader().addTool(
181                    maximizeToolbarButton());
182            mainPanel.getHeader().addTool(
183                    closeToolbarButton());
184        }
185        setDropTarget(mainPanel);
186        add(mainPanel);
187        initChart();
188        //  layout(true);
189    }
190
191    private ToolButton maximizeToolbarButton() {
192        return new ToolButton("x-tool-maximize",
193                new SelectionListener<IconButtonEvent>() {
194                    boolean isMax;
195
196                    @Override
197                    public void componentSelected(final IconButtonEvent ce) {
198                        final Window window = new Window();
199
200                        final AnnotatedTimeLinePanel panel = new AnnotatedTimeLinePanel(false, name);
201
202                        // panel.hideHeader();
203                        window.add(panel);
204                        window.setWidth(800);
205                        window.setHeight(800);
206
207                        window.show();
208                        panel.resize(770, 790);
209                        for (final PointName pointName : points.keySet()) {
210                            panel.addPoint(points.get(pointName));
211                        }
212
213                    }
214                });
215    }
216
217    private ToolButton closeToolbarButton() {
218        return new ToolButton("x-tool-close",
219                new SelectionListener<IconButtonEvent>() {
220                    boolean isMax;
221
222                    @Override
223                    public void componentSelected(final IconButtonEvent ce) {
224                        notifyChartRemovedListener(name);
225                    }
226                });
227    }
228
229
230    private ToolBar toolbar() {
231        final ToolBar toolBar = new ToolBar();
232
233
234        final Button startDateMenu = new Button();
235        startDateMenu.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.calendar()));
236
237
238        startDateSelector.setSelectOnFocus(false);
239        if (timespan != null) {
240            startDateSelector.setValue(fmt.format(timespan.getStart()));
241        }
242        startDateSelector.setToolTip("Start Date");
243
244        startDateSelector.addListener(Events.KeyPress, new Listener<FieldEvent>() {
245            @Override
246            public void handleEvent(FieldEvent be) {
247                if (be.getKeyCode() == 13) {
248                    refreshChart();
249                }
250            }
251        });
252
253
254        if (timespan != null) {
255            endDateSelector.setValue(fmt.format(timespan.getEnd()));
256        }
257        endDateSelector.setSelectOnFocus(false);
258        endDateSelector.setToolTip("End Date");
259        endDateSelector.addListener(Events.KeyPress, new Listener<FieldEvent>() {
260            @Override
261            public void handleEvent(FieldEvent be) {
262                if (be.getKeyCode() == 13) {
263                    refreshChart();
264                }
265            }
266        });
267
268
269        final Button refresh = new Button();
270        refresh.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.refresh2()));
271
272
273        toolBar.add(startDateSelector);
274        // toolBar.add(startDateMenu);
275        //  toolBar.add(new SeparatorToolItem());
276
277        toolBar.add(endDateSelector);
278        //   toolBar.add(new SeparatorToolItem());
279
280        refresh.addListener(Events.OnClick, new Listener<BaseEvent>() {
281            @Override
282            public void handleEvent(final BaseEvent be) {
283                refreshChart();
284            }
285        });
286
287        toolBar.add(refresh);
288
289        toolBar.add(new SeparatorToolItem());
290
291        final NumberField min = new NumberField();
292        final NumberField max = new NumberField();
293        Label minY = new Label("MinY:");
294        Label maxY = new Label("MaxY:");
295        min.setWidth(30);
296        max.setWidth(30);
297
298        min.setValue(0);
299        max.setValue(100);
300
301        toolBar.add(minY);
302        toolBar.add(min);
303        toolBar.add(maxY);
304        toolBar.add(max);
305
306
307        Button refreshRange = new Button();
308        refreshRange.setIcon(AbstractImagePrototype.create(Icons.INSTANCE.refresh2()));
309        refreshRange.addListener(Events.OnClick, new Listener<BaseEvent>() {
310            @Override
311            public void handleEvent(BaseEvent be) {
312                Options options = Options.create();
313                options.setDisplayAnnotations(true);
314                options.setWindowMode(WindowMode.OPAQUE);
315                options.setAllowRedraw(true);
316                options.setDisplayRangeSelector(true);
317                options.setMin(min.getValue().intValue());
318                options.setMax(max.getValue().intValue());
319                line.draw(dataTable, options);
320            }
321        });
322        toolBar.add(refreshRange);
323
324
325        return toolBar;
326    }
327
328    private void refreshChart() {
329        try {
330            timespan = TimespanServiceClientImpl.createTimespan(startDateSelector.getValue().toString(), endDateSelector.getValue().toString());
331            if (line != null && timespan != null) {
332                line.setVisibleChartRange(timespan.getStart(), timespan.getEnd());
333                //setTimespan(timespan);
334                //startDateSelector.setValue(result.getStart());
335                // endDateSelector.setValue(result.getEnd());
336                dataTable = DataTable.create();
337                dataTable.addColumn(ColumnType.DATETIME, "Date");
338
339                for (PointName pointName : points.keySet()) {
340                    addPointToChart(points.get(pointName));
341                }
342            }
343
344            //      }
345            //   });
346        } catch (InvalidTimespanException e) {
347            GWT.log(e.getMessage(), e);
348        }
349    }
350
351    public void addPoint(Point point) {
352        addPointToChart(point);
353    }
354
355    private void addPointToChart(final Point point) {
356        if (!points.containsKey(point.getName())) {
357            points.put(point.getName(), point);
358        }
359
360//            ArrayList<Point> l = new ArrayList<Point>();
361        //     l.add(p);
362        final int start = 0;
363        final int end = 1000;
364
365        if (timespan == null) {
366            loadValuesThatExist(point);
367        } else {
368            loadDataSegment(point, start, end);
369        }
370    }
371
372    private void loadValuesThatExist(final Point p) {
373        final RecordedValueServiceAsync dataService = GWT.create(RecordedValueService.class);
374        // final MessageBox box = MessageBox.wait("Progress",
375        //        "Loading " + p.getName().getValue() + " values ", "Loading...");
376        //box.show();
377
378        dataService.getTopDataSeries(p, 100, new Date(), new AsyncCallback<List<Value>>() {
379            @Override
380            public void onFailure(Throwable caught) {
381                //       box.close();
382            }
383
384            @Override
385            public void onSuccess(final List<Value> result) {
386                Value oldest, newest;
387
388                if (result.size() > 0) {
389                    oldest = result.get(result.size() - 1);
390
391
392                    newest = result.get(0);
393
394
395                    timespan = new TimespanModel(oldest.getTimestamp(), newest.getTimestamp());
396                    setTimespan(timespan);
397                }
398
399
400                addPointDataToTable(p, result);
401
402                drawChart();
403
404
405                // box.close();
406            }
407        });
408    }
409
410//
411//    public void resizePanel(int h, int w) {
412//        mainPanel.setWidth(w);
413//        mainPanel.setHeight(h);
414//        initChart( );
415//        doLayout();
416//    }
417
418    public void setTimespan(Timespan ts) {
419        this.timespan = ts;
420        this.startDateSelector.setValue(fmt.format(ts.getStart()));
421        this.endDateSelector.setValue(fmt.format(ts.getEnd()));
422    }
423
424    private void loadDataSegment(final Point p, final int start, final int end) {
425        final RecordedValueServiceAsync dataService = GWT.create(RecordedValueService.class);
426        final MessageBox box = MessageBox.wait("Progress",
427                "Loading " + p.getName().getValue() + " values " + start + " to " + end, "Loading...");
428        box.show();
429        //   Timespan timespan = new TimespanModel(startDate, endDate);
430        dataService.getPieceOfDataSegment(p, timespan, start, end, new AsyncCallback<List<Value>>() {
431            @Override
432            public void onFailure(final Throwable caught) {
433                box.close();
434            }
435
436            @Override
437            public void onSuccess(final List<Value> result) {
438                addPointDataToTable(p, result);
439                if (result.size() > 0) {
440                    loadDataSegment(p, end + 1, end + 1000);
441                } else {
442                    drawChart();
443                }
444
445                box.close();
446            }
447        });
448    }
449
450    void resize(final int h, final int w) {
451        mainPanel.setHeight(h);
452        mainPanel.setWidth(w);
453        line.setHeight("100%");
454        line.setWidth("100%");
455    }
456
457//    public void hideHeader() {
458////        mainPanel.setHeaderVisible(false);
459//    }
460
461    private void setDropTarget(final Component container) {
462        //    DropTarget target = new DropTarget(container) {
463        new DropTarget(container) {
464            @Override
465            protected void onDragDrop(final DNDEvent event) {
466                super.onDragDrop(event);
467                List<TreeStoreModel> t = event.getData();
468
469                for (final TreeStoreModel a : t) {
470                    final GxtPointModel p = (GxtPointModel) a.getModel();
471
472                    final PointServiceAsync pointService = GWT.create(PointService.class);
473                    try {
474                        pointService.getPointByID(p.getId(), new AsyncCallback<Point>() {
475                            @Override
476                            public void onFailure(final Throwable throwable) {
477
478                            }
479
480                            @Override
481                            public void onSuccess(final Point point) {
482                                points.put(point.getName(), point);
483                                addPointToChart(point);
484                            }
485                        });
486                    } catch (NimbitsException e) {
487                        GWT.log(e.getMessage());
488                    }
489                }
490            }
491        };
492    }
493
494    public void initChart() {
495        Runnable onLoadCallback = new Runnable() {
496            @Override
497            public void run() {
498                if (line != null) {
499                    mainPanel.remove(line);
500                    line = null;
501                }
502
503                dataTable = DataTable.create();
504                dataTable.addColumn(ColumnType.DATETIME, Const.WORD_DATE);
505//                line = new AnnotatedTimeLine(dataTable, createOptions(), w + "px",
506//                        (h - heightMod) + "px");
507                line = new AnnotatedTimeLine(dataTable, createOptions(), "100%", "100%");
508                //  	line.setVisibleChartRange(startDate, endDate);
509                mainPanel.add(line);
510
511                addEmptyDataToTable();
512                //emptyPanel.setLayout(new FillLayout());
513                //  mainPanel.add(h);
514                layout();
515                if (points != null && points.size() > 0) {
516                    refreshChart();
517                }
518            }
519        };
520
521        VisualizationUtils.loadVisualizationApi(onLoadCallback,
522                AnnotatedTimeLine.PACKAGE);
523    }
524
525    private Options createOptions() {
526        Options options = Options.create();
527        options.setDisplayAnnotations(true);
528        options.setWindowMode(WindowMode.OPAQUE);
529        options.setAllowRedraw(true);
530        options.setDisplayRangeSelector(true);
531
532        //options.setDisplayAnnotationsFilter(arg0)
533        return options;
534    }
535
536    private void addEmptyDataToTable() {
537        dataTable.addColumn(ColumnType.NUMBER, Const.DEFAULT_EMPTY_COL);
538        dataTable.addColumn(ColumnType.STRING, "title0");
539        dataTable.addColumn(ColumnType.STRING, "text0");
540    }
541
542    public void removePoint(Point p) {
543        removePointDataFromTable(p.getName());
544        if (points.containsKey(p.getName())) {
545            points.remove(p.getName());
546        }
547        if (points.size() == 0) {
548            removePointDataFromTable(CommonFactoryLocator.getInstance().createPointName(Const.DEFAULT_EMPTY_COL));
549            addEmptyDataToTable();
550        }
551
552        drawChart();
553    }
554
555    public String getName() {
556        return name;
557    }
558
559    public boolean isSelected() {
560        return selected;
561    }
562
563    public void setSelected(boolean selected) {
564        this.selected = selected;
565        setBorders(selected);
566
567    }
568}