Toolbar


December 5, 2013 Maithilish

6.8. Toolbar

FactTable displays the latest available data for a category, but the user may also like to view data for previous periods, and through ToolbarItem user may navigate Forward or Backward.

Toolbar
Figure 6.11. Toolbar


Following UI declaration adds ToolbarItem to FactTable.
in.fins.client.content/Snapshot.ui.xml

      <g:customCell>
              <f:FactTable captionText="BS" category="BS">
                      <f:FactTable captionText="Holding" category="Shareholding">
                              <f:ToolbarItem type="previous" category="Shareholding" />
                              <f:ToolbarItem type="next" category="Shareholding" />
                      </f:FactTable>
                      <f:ToolbarItem type="previous" category="BS" />
                      <f:ToolbarItem type="next" category="BS" />
              </f:FactTable>
      </g:customCell>

This UI snippet adds ToolbarItem, forward and backward, to outer as well as to inner FactTables.
ToolbarItem is a GWT Image which may be tagged to a event source. Style fins-Toolbar-Image adds margin to the sides of the image
in.fins.client.widget/ToolbarItem.java

public class ToolbarItem extends Image {

        Object eventSource;

        public ToolbarItem(ImageResource imageResource) {
                super(imageResource);
                setStylePrimaryName("fins-Toolbar-Image");
        }

        public void setEventSource(Object eventSource) {
                this.eventSource = eventSource;
        }

UiFactory creates ToolbarItem with different images.
in.fins.client.content/Snapshot.java

        @UiFactory
        public ToolbarItem toolbarItemFactory(String type, String category) {
                FinsResources images = FinsResources.INSTANCE;

                if (type.equals("previous")) {
                          ....
                        ToolbarItem tbi = new ToolbarItem(images.previous());
                          ....
                        return tbi;
                }
                if (type.equals("next")) {
                          ....
                        ToolbarItem tbi = new ToolbarItem(images.next());
                          ....
                        return tbi;
                }
                return null;
        }

FactTable.add() method adds them to HorizontalPanel of FactTable.
in.fins.client.widget/FactTable.java

@Override
        public void add(Widget w) {
                if (w instanceof FactTable) {
                        vPanel.add(w);
                }
                if (w instanceof ToolbarItem) {
                        ToolbarItem ti = (ToolbarItem) w;
                        toolbar.add(w);
                        
                        ....
                }
        }

DataAction and DataEvent

On load, FactTable handles SymbolEvent fired by SymbolAction and displays data for the latest period. SymbolEvent.Symbol holds data for the latest date only as eagerly loading data for all periods is a waste and hence it is of little use for data of other periods. Instead, an action class has to fetch Data for previous or next date when user click ToolbarItem and for this we require DataAction.

On each click, for Forward ToolbarItem, DataAction fetches Data for the next period as offset is set to 1 and Backward does the reverse. Instead of a date, we are using offset because FactTable doesn’t know the next or previous date and it knows only the date for which data is being displayed. Further it is not a good idea to arrive next or previous dates through some date calculation as frequency of data may differ among categories. For example, BS,PL and Cash Flow usually contains yearly data whereas Price, PE or PB has daily or weekly data, and shareholding data is at random intervals. Offset takes care of all these cases.
ToolbarItem UiFactory attaches an instance of DataAction to a ToolbarItem which also sets the direction of DataAction.
in.fins.client.content/Snapshot.java

        @UiFactory
        public ToolbarItem toolbarItemFactory(String type, String category) {
                FinsResources images = FinsResources.INSTANCE;

                if (type.equals("previous")) {
                        DataAction dataAction = new DataAction(category, "Backward",
                                        getFilter(category));
                        EventBus.get().addHandlerToSource(SymbolEvent.TYPE, this,
                                        dataAction);
                        ToolbarItem tbi = new ToolbarItem(images.previous());
                        tbi.addClickHandler(dataAction);
                        tbi.setEventSource(dataAction);
                        return tbi;
                }
                if (type.equals("next")) {
                        DataAction dataAction = new DataAction(category, "Forward",
                                        getFilter(category));
                        EventBus.get().addHandlerToSource(SymbolEvent.TYPE, this,
                                        dataAction);

                        ToolbarItem tbi = new ToolbarItem(images.next());
                        tbi.addClickHandler(dataAction);
                        tbi.setEventSource(dataAction);
                        return tbi;
                }
                return null;
        }

DataAction implements two handlers; SymbolHandler and ClickHandler. It handles the SymbolEvent fired by SymbolAction and assign the Symbol to its field for later reference. ToolbarItem clicks fires ClickEvent and ClickHandler fetches the Data from datastore and fires a DataEvent.
in.fins.client.action/DataAction.java

        @Override
        public void onClick(ClickEvent event) {
                ....
                Data data = SymbolDatabase.getData(symbolName, category, date, offset,filter);
                ....
                EventBus.get().fireEventFromSource(new DataEvent(data), eventSource);
        }

        @Override
        public void onSymbolChange(SymbolEvent symbolEvent) {
                this.symbol = symbolEvent.getSymbol();
        }

All that is left is to handle the DataEvent by FactTable.
in.fins.client.widget/FactTable.java

        @Override
        public void add(Widget w) {
                if (w instanceof FactTable) {
                        vPanel.add(w);
                }
                if (w instanceof ToolbarItem) {
                        ToolbarItem ti = (ToolbarItem) w;
                        toolbar.add(w);
                        EventBus.get().addHandlerToSource(DataEvent.TYPE,
                                        ti.getEventSource(), this);
                }

        @Override
        public void onDataChange(DataEvent dataEvent) {
                Data data = dataEvent.getData();
                log.fine("DataEvent recd - " + data);
                Date date = data.getDate();
                if (date != null) {
                        DateTimeFormat fmt = DateTimeFormat.getFormat("MMM yy");
                        setHeaderText(fmt.format(date));
                        dataProvider.setList(data.getFacts());
                }
                setVisible(true);
        }

FactTable.add() method adds itself as handler for DataEvent, and onDataChange() method sets Fact list from Data to ListDataProvider to display the new data. When you navigate the data using ToolbarItem, you may notice that data is inconsistent for any given period, and this is because, on each access SymbolDatabase generates random values and this gets rectified once we move to proper datastore in the next part.
Events
Figure 6.12. Events


With just an Image and some event wiring, we are able to design a versatile Tool Bar. But having said so, we have to concede these Toolbar items are inadequate for any meaningful data analysis. For easy comparison of facts over a date range, it would be more convenient if the data is presented in a tabular view, and for this, we have to use Pop-up.