Like much of the writing I do these days, the idea for this blog post was sparked by an innocuous-looking tweet from Justin King:
In his tweet, Justin was referring to the Stock History demo we built to showcase Kendo UI DataViz:
The Stock History demo charts and displays stock performance data for Apple, Google, and Amazon from 2007 to 2011.
You can grab the source code from GitHub: kendo-stock-history.
The overall size of the Stock History demo is quite small. Looking at it from the perspective of Kendo UI, it's built using a combination of the DataSource, some framework helper functions, templates, the Chart, and the TabStrip. Using the 3D view of the page inspector in Firefox, you can quickly understand the structure of the application:
Underpinning every widget, data point, and data visualization of the Stock History demo is a single DataSource component; stocksDataSource. This object is bound to stock performance data - available as a simple object array and formatted as JSON - that's hosted on the web server. Here's a small fragment of this data:
[ { "date": "12/30/2011", "close": 405, "volume": 6414369, "open": 403.51, "high": 406.28, "low": 403.49, "symbol": "2. AAPL" }, { "date": "11/30/2011", "close": 382.2, "volume": 14464710, "open": 381.29, "high": 382.276, "low": 378.3, "symbol": "2. AAPL" }, ... ]
At the top of Stock History demo, a TabStrip is used to filter the stock performance of each company by the selected year:
$("#year-filtering-tabs").kendoTabStrip({ dataSource: ["2007", "2008", "2009", "2010", "2011"], change: function(e) { selectedYear = this.value(); $(".selected-year").text(selectedYear); stocksDataSource.read(); } }).data("kendoTabStrip").select(4);
This TabStrip is used to bind stock performance data to the area chart. The change event is triggered when a new date is selected. This results in stocksDataSource requesting the yearly stock performance data - formatted as JSON - from the server. With the new data bound to stocksDataSource, a sequent change event is triggered, which updates all of the data that's displayed.
Here's how stocksDataSource is initialized:
var stocksDataSource = new kendo.data.DataSource({ transport: { read: { url: function() { return "data/stock-data-" + selectedYear + ".json"; }, dataType: "json" } }, group: { field: "symbol" }, sort: { field: "date", dir: "asc" }, schema: { model: { fields: { date: { type: "date" } } } }, change: function() { $("[name=chart-type][value=area]").prop("checked", true); var view = this.view(), index = $("#company-filtering-tabs").data("kendoTabStrip").select().index(); // populate detailed stock prices populateStockPrices(view[index], index); } });
The most interesting part of the code (above) is the change event handler for the DataSource component. This handler invokes a workhorse-like function labelled, populateStockPrices, which is responsible for binding all of the widgets, data points, and data visualizations in the application. This includes a particularly interesting part of the Stock History demo; its use of Kendo UI DataViz to create sparklines:
A sparkline is a tiny graph that's commonly used alongside text or within a confined space such as a grid. They are ideally suited for scenarios where the trends of the data they represent can deliver a more meaningful impact than raw numbers.
The sparklines used in the Stock History demo are created via the Chart of Kendo UI DataViz. Since the Chart emits SVG to the browser, the sparklines retain all of the fidelity of similar charts that are created in a typical use case scenario. In fact, they remain interactive to user input, including touch and mouse interactions. That stated, generating visually-effective sparklines does require some forethought to design. For example, sparlines don't typically include a legend or much of the ancillary axis information that's often associated with a chart/graph; what really matters is the overall trend that's conveyed by the data that the sparkline represents. In the case of the Stock History demo, these sparklines are created with a set number of predefined configuration properties to make them look beautiful:
var sparklineOptions = function(field, color, data) { return { dataSource: data || yearlyStockValues, series: [{ field: field, color: color }], seriesDefaults: { type: "line", markers: { visible: false }, line: { width: 2 } }, axisDefaults: { visible: false, majorGridLines: { visible: false } }, legend: { visible: false } }; };
In the code (above), the sparklineOptions object is used to initialize and configure each sparkline that created with the Chart of Kendo UI DataViz. It's worth noting that the chart axis is hidden, along with the series markers for each data point in the sparkline.
Let's see how we can take this same approach to creating other kinds of sparklines.
This is a win/loss sparkline that's created using the Chart of Kendo UI DataViz, where green bars indicate wins and red bars indicate losses. Here's the code to create this sparkline:
$("#win-loss").kendoChart({ axisDefaults: { visible: false, majorGridLines: { visible: false } }, seriesDefaults: { border: { width: 1 }, gap: 0, markers: { visible: false }, stack: true, type: "column" }, series: [ { color: "#0b0", data: winRecord }, { color: "#e00", data: lossRecord } ] });
In this example, I've created a win/loss sparkline using a couple of arrays; one for wins and one for losses. These are bound to the series as winRecord and lossRecord respectively. I've also set the gap width between each bar to zero (0) in order to have the sparkline as small as possible. Finally, I've restricted the rendering of this sparkline through a custom style defined on the target element, win-loss:
div.sparkline { height: 30px; width: 180px; margin-top: -5px; }
Again, because these sparklines are generated using SVG, we can apply styles against them to match our design goals.
Oh, and in case you were wondering: Yes, you can embed these sparklines in widgets like the Grid of Kendo UI Web:
Pretty neat, eh?
Anyway, I hope this blog posts help to provide some insight on the Stock History demo that we built for Kendo UI DataViz. As always, if you have any questions, please don't hesitate to ask! We're here to help.
John Bristowe is a member of the Developer Relations team at Progress. He specialises in web and mobile app development.