One recurring theme in my articles on ADF has been that end users usually do not care about data. They are interested in getting information that helps them answer questions, make decisions and take actions. Data may be the foundation, but information is to be derived from the data. One way therefore to create applications that are more valuable to our end users is by preprocessing data and turning the data into information – or even into answers, proposed decisions and actions. A powerful way of turning data into information is through data visualization. By presenting data in a format that converts it to readily interpretable information, we help our users a lot. Bar charts, line graphs and other traditional charting formats are one of way visualizing data. The DVT library in ADF Faces goes far beyond traditional charts. It provides components such as the Gantt Chart, the Hierarchy Viewer, the Tree Map, Gauge and the TimeLine that help visualize data in natural, informative and attractive ways. This articles discusses the TimeLine component – introduced in ADF 11gR1 PS6 (188.8.131.52) in the Spring of 2013.
The TimeLine visualizes events against a time axis. It is as simple as that. This component is used to visualize data that has a meaningful chronological order. The TimeLine component supports scrolling through time as well as zooming in (to finer grained time periods) and out (to longer periods at higher aggregation levels). Events can be marked on the timeline using various types of display items, graphics and highlighting as well as with support for various interactions – such as click to drill down , drag & drop and popup.
The TimeLine Component is very straightforward to use. It takes as its input a Collection of rows or POJOs of which at least one attribute or property should be a Date value. This property is used to determine the position on the TimeLine of each entry. Other properties can use used to flesh out and decorate the timeline events. One of example of what this TimeLine component allows us to do is this representation of the events in an RSS feed. In this case, the RSS feed is the feed for the AMIS Technology Blog that returns the last 10 articles published on the blog (in the second half of February and March):
This article describes how to use the TimeLine component to visualize the entries in an RSS feed.
First we will create a simple model that captures the RSS feed into a POJO layer that we then expose as a Data Control. I have made grateful use of one of the many great articles by Lars Vogel on his blog www.vogella.com, in this case the RSS Feeds with Java Tutorial. In this article Lars Vogel describes how to use StAX (Streaming API for XML) to parse the XML captured from the URL on which the RSS feed is published.
First, a simple Class FeedMessage is created that will represent an entry in the RSS feed. This class is a POJO with properties for the title, author, link and pubDate of the entry. The pubDate is a string representation (e.g. Fri, 29 Mar 2013 23:04:10 +0000) of the time of publication, that needs to be converted to a java.util.Date that is required by the TimeLine component. A SimpleDataFormat with the format string “EEE, d MMM yyyy HH:mm:ss Z” is used to parse the pubDate string into the timestamp property in FeedMessage. Each FeedMessage will end up as an entry on the TimeLime
Class Feed is created as the container for all FeedMessages in an RSS channel. An RSS URL may publish a channel with multiple messages. The channel is instantiated as a Feed.
The class RSSFeedParser does the real work. The class is instantiated with the URL of an RSS and a property url is initialized. Its method readFeed is invoked to produce the Feed object with its enclosed collection of FeedMessages. The method uses an XMLEventReader for the inputStream created for the url for the RSS feed. It processes the RSS XML document, producing startElement and endElement events that are handled in the loop. Whenever an item element is completed, a new FeedMessage object is created and added to the list. It is all quite straightforward.
Class TestFeedReader has a main method and can be used to quickly test the RSSFeedParser for any URL.
Finally class RssFeedProvider is created to act as the middle man of the business service. This class has a single property – feedURL – and a method getFeedItems() that returns a List of FeedMessages. This class is published as Data Control.
With the Data Control in place, we can turn to the View. The View will consist of a simple JSF page that contains a data bound TimeLine component. This component is bound to the feedItems collection on the RssFeedProvider Data Control. The component is configured to display the title and author of each blog article.
The required steps in the View project are these:
Create a new JSF page, for example called RssFeedTimelineViewer.jspx.
Drag the feedItems collection from the Data Controls palette to this page and drop it as Timeline:
The editor for configuring the timeline series data appears. It already selected the one Date property (timestamp) in the collection’s element as the Item Data Value.
The Item Group is used to identify items that can be grouped together: Timeline items that share a common date can be configured to display as a group that can be expanded or collapsed at runtime. By default, a number counter displaying the number of items in a group is provided in the collapsed view. Clicking the counter opens all items in the collapsed view and clicking in the timeline collapses the expanded view. Figure 28-5 shows a timeline item with a counter opened into an expanded view. The Item Group property is set to a property in the timeline item – am not sure exactly what the meaning is of this selected property.
The Attributes section of this page is used to configure the values that should be displayed in the timeline for each event. Here I have configured four attributes, all using af:outputText. I can easily edit the exact appearance of these values in the page itself.
In the second page, we can customize the appearance – relative size, color, shape – of the markers of the timeline entries. For now I will simply accept the defaults.
The third page is for configuring the start and end time and date for the timeline as well as both the time-axis for the timeline as well as the scale for the overview (bird’s eye view) shown underneath the timelime. I have set them as shown in the next figure.
With these simple, declarative steps we can already run the page and our first timeline displayed:
The page could do with a little refinements: the end date for example should not only take into account the latest timestamp for any of the events, but it should allow for the length of the most recent items – therefore stretching a little farther into the future. There is way to much text in the entries right now. Let’s use the description as the tooltip (shortDesc) for the title and let’s use the link to actually make the title clickable – acting as a hyperlink to the real blog entry:
Rerunning the page – that is: refreshing the page from the browser, as we did not change a data binding or other initialized only once aspect of the application – gives us this result:
Clicking on the title will take me to the AMIS Technology Blog and display the selected article. I wonder, looking at this timeline, why we seem to publish articles in bursts. several close together, then a gap and then another burst.
Zooming in sheds a little more light, showing the actual days of the week of publishing. I thought perhaps there is a link with the weekend or some other pattern. But if there is one, I do not yet detect it:
It seems though that most articles are published around midnight.
Adding a Feed Switcher
This page could be turned into a reusable taskflow that accepts a feed url as an input parameter. Or we can allow the user to select her own RSS feed as input. Then of course we might also want to add date selectors and other filter capabilities.
Let’s start with the simple ability to specify one’s own RSS URL.
The RssFeedSelectorBean class is added to the View project. The bean is configured in adfc-config.xml as view scope managed bean:
This bean has a property rssURL that backs a new inputText item into which the user can enter the URL of an RSS feed:
Note how autoSubmit is set to true: whenever a new value has been entered, the setRssURL() method on the bean is invoked. This method calls the private method resfreshFeed(). This method gets hold of the current binding container. It finds the attribute binding for the feedURL attribute on the RssFeedProvider Data Control and sets its value to the value from the rssURL property. Then its refreshes the iterator binding feedItemsIterator by invoking its executeQuery() operation, which causes the getFeedItems() on the RssFeedProvider POJO in the Model project to be reinvoked. Note that without this explicit executeQuery() the ADF binding framework would continue to use its cached collection of feed items that it retrieved previously from the RssFeedProvider.
The final linking pin is the partialTriggers attribute on the timeline component that has been set to be triggered by the inputText. Note that alternatively we could have set the ChangeEventPolicy on the iterator binding to ppr.
When we next run the page, we can enter our own RSS Feed URLs and then watch the Timeline component trying to visualize its contents:
Dutch News Site nu.nl:
OTN Technical Article Feed:
and BBC Top Stories:
Obviously, I should cater for the different time scales for each of these sites (hours to weeks/months) and the slightly different ways in which they use RSS. But the essence of turning a data stream into a meaningful visualization has been proven as far as I am concerned!
Download the JDeveloper 11gR1 PS6 (184.108.40.206) application: TimelineForRSS.zip.
Parsing RSS Feeds in Java using StAX by Lars Vogel: http://www.vogella.com/articles/RSSFeed/article.html#read_stax