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.
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.
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.