Microsoft_.NET_Framework_v4.5_logoIn my previous post, I discussed my objective to create a custom dashboard solution in order to meet a number of requirements.  In the process of researching how I would create the solution, I made multiple choices pertaining to the technology and design which would be used to create the dashboard.  I chose to implement both a traditional communications model utilizing web services where the client is responsible for requesting data refreshes as well as the SignalR communications model where the server pushes updates to the client.

To recap, I made the following design decisions for the application:

  • Use a custom developed application instead of an off-the-shelf product
  • Use web-based technologies within the Microsoft ecosystem
  • Use ASP.NET MVC5 with C# and HTML/JavaScript
  • HTML/JavaScript based chart control library — jChartFX

A web-based application such as this has three main components:

  • The data source (in this case a SQL Server OLTP database since we need real time data)
  • The web server which interfaces with the OLTP database and serves summarized data to the client
  • The web client which accesses the web server and displays the content

As the platform is a web application, there is nothing that needs to be done on the client end other than using a modern browser which supports HTML5 and supports JavaScript well (Chrome is my personal preference though the current version of Internet Explorer is also fine).  So, from a client point of view, there’s nothing to do.  The majority of the work is done on the front end web interface which displays the data and the back end interface which acquires and supplies the data.

In the traditional communications model, used here, the web server serves the initial page request to the client.  Following the initial request, the client then periodically polls the web server via web services and on each request, the web server queries the actual data from the database server and returns it to the client.  In this model, the client is wholly responsible for updates and it’s typically only done on a timed basis (since the client has no way of knowing when data changes in the database).  This model is advantageous in that it’s fairly simple and since the client is responsible for requesting updates, it is fairly reliable.  A downside is that it does not scale well.  Each additional client adds additional load to the database server as a new request is made to refresh each client.  Additionally, if multiple clients are showing the same data, they may refresh at slightly different times, making data seem inconsistent between screens.

dashboard_web_model

Laying the Foundation

Throughout this demo, I’ll be using Visual Studio 2013.  Additionally, this won’t be a step-by-step guide, but I’ll try to hit the high points and the full Visual Studio solution, including a sample database, is available here.  So, let’s get started.  I created a new ASP.Net Web Application with an Empty template and MVC references.  Next, I used the NuGet Package Manager to add packages for jQueryJson.NET, and ASP.NET MVC.  jQuery is a foundation component for the front-end and jChartFX, Json.NET provides libraries for JSON data formatting for passing data between the web service and jChartFX, and ASP.NET MVC updates to the framework latest version of MVC.

Additionally, I installed jChartFX.  This is not available via the NuGet Package Manager, so it must be downloaded directly from their website and can then be unzipped and the files added to the project (the files are all JavaScript files and css style sheet components).  The jChartFX download is by default the free version.  The paid version is exactly the same, except a function is used to load the serial number at runtime.  I’m using the free version for this example.  Also not available via NuGet is Date.js which is a simple JavaScript library for date formatting, used in the clock widget.

When building something based on an example, I always appreciate seeing the end result first.  So, without further adieu,  the goal of this post will be to build the following interface which is a simple web page comprised of 5 updating widgets:

gc_dashboard_example

 

Getting Started – The Front-End Client

You could choose to start with the back-end and work to the front, or start with the front-end and work to the back.  I started with the front-end as getting everything to look right will ensure that I know what data I need to pass with the back-end.

For the first step, I want to make sure to include all of my assets in the project so I can easily link to them.  These include:

  • Content folder – Dashboard.css which will be the primary style sheet for my web page and all of the jChartFX default style sheets in a jChartFX suborder.
  • images folder – This folder contains images which will be used on the front end display, which includes icons for cache types, log types, and a background image.
  • Intellisense – This folder contains jChartFX helpers to allow for Intellisense context-sensitive help in the editor.
  • Scripts – This folder contains all of the JavaScript for the front end display, which includes all of the jChartFX components, scripts to create the various widgets, a date formatting script, and the primary application script, Dashboard.js, which is responsible for the data refreshes.

With all of the assets in the project, the next step is getting the front end setup is to create a Controller, which I called HomeController and then to create a View with no model or layout which I called Index (any names can be used for these, but since the default MVC route is /Home/Index I used these names for simplicity)  The Index view will be the page the web client displays which includes all of my dashboard widgets.

Within the Index, we need to do most of the client side work.  As this is a very simple project, the Index will use neither a Layout (template) or a Model (data template).  The Index file contains a link to the Dashboard.css style sheet for color information, defines all of the widget location and sizes, and links to all of the JavaScript that makes it go.  The JavaScript references are the most complex portion of the Index file and perform the following:

  • Loads jQuery, which is a core JavaScript library used for both the widgets themselves as well as the data refreshes.
  • Loads date.js, which is a simple date formatting script used by the clock.
  • Loads various jChartFX libraries which draw the graphical components of the dashboard.
  • Loads the Dashboard.js script which is the primary script responsible for data refreshes.
  • Loads individual JavaScript files for each for creating and setting the style of each widget used.  This helps break the code up a little and make it more reusable.

Finally, once the document is fully loaded into the browser, it calls the “loadDashboard()” function within the Dashboard.js JavaScript file which begins the data refresh cycle.  The flow, showing the primary components — the client side Index View, the client side, Dashboard.js script, and the server side DataService.asmx (which we’ll cover shortly) can be seen as follows:

dashboard_web_model_flow

Front-End:  jChartFX Components

The various widgets on the dashboard are primarily made with the jChartFX library.  For simplicity, I’ve encapsulated each widget into its own JavaScript file which I’ve stored in the Components subfolder.

With jChartFX, there are two options for styling a widget.  Widgets can be styled either using CSS or by using JavaScript methods.  While using CSS can make for cleaner styling and allow for each of changing themes, I tend to prefer the JavaScript method of styling.  A major benefit to styling via JavaScript is that colors can be changed programmatic ally whereas when CSS styling is used for the widgets, it will override any JavaScript styling.  More information regarding using style sheets for styling can be found in the jChartFX documentation.

As a quick example, the title text on the find rate gauge can be set either via JavaScript code with the following:

Or via CSS with the following:

 

Front-End:  Dashboard.js

Dashboard.js is the true workhorse of the front-end.  This JavaScript file “ties it all together” and is responsible for performing the timed data refresh requests to the back-end via the web services URLs.

The primary function within the Dashboard.js script is the loadDashboard function which is responsible for starting the client-side timers for the clock update and the widgets.

The loadDashboard function in turn calls two functions, startClock and startDataUpdater which launch the timers to perform the data refreshes. In this example, the clock runs on a different timer than the data components so it can refresh far more quickly (since the data is gathered client side rather than from a database).

The startDataUpdater function in turn calls the updateData function which in turns calls a function for each widget which is designed to actually perform the data query to the back-end web service and update the display component with the updated data.

The bulk of the code in each read function is for error handling. Essentially, using jQuery, the timer sends a request to the web service URL (with a unique URL for each widget). The web service passes back a JSON object containing the data which can be parsed and loaded into the chart component natively thanks to jChartFX.

 

The Back-End (Web Services)

Without the back-end component, you are limited to displaying only static information or client-side data (like the time and date).  Not very useful.  in order for things to be really useful, we need to be able to access data in the database and return it to the client.  That’s where the Web Services come in.

At first, I was frightened of the idea of developing web services.  A pretty foreign concept which I had no experience with.  Probably pretty hard to do, right?  Well, it turns out not very hard at all.  And one bit of good news — while we were bouncing around between languages on the front end:  HTML, CSS, JavaScript, jChartFX libraries, on the back-end we use C# almost exclusively with a dash of T-SQL and a little bit of JSON thrown in.

A little bit of a disclaimer — there are lots of ways to right web services.  For jChartFX, it was critical that my services return JSON formatted data (as opposed to XML or something else).  Additionally, this is a simple implementation designed for a low traffic internal environment with non-privileged data.  For use in a more secure environment, you’ll want to use encryption via SSL/TLS and HTTPS as well as authentication.  Additionally, due to the simplicity of this application, I’m not relying on a framework such as Entity Framework for my data access, but instead am performing my own database connections.

To kick things off on the back end, I created a utility method to perform my data accesses.  I like keeping my T-SQL code separate from my C# code as much as possible, so for this example, I’ve created stored procedures within the SQL Server database for each of my data access methods.  These procedures require no parameters so I can pass in the text of the SQL code I wish to execute (which is just the name of the stored procedure) and re-use this block of code frequently.

Each Web Service has a “Web Method” decoration to indicate that it is a web service. Additionally, since I’ve abstrated all of my data access to the above function, the code for each individual web service method is pretty sure. All it has to do is identify the name of the stored procedure, call the database access function, and return a JSON string. Simple!

 

Conclusion

And believe it or not, that’s all there is to it!  The front-end client utilizes a combination of HTML, CSS, JavaScript, and the jChartFX libraries in order to draw graphical widgets within a web browser.  jQuery JavaScript functions are then used to call Web Services written in C# to retrieve data and update the widgets.  The Web Services utilize standard database calls to query stored procedures within the source SQL Server and we now have a self-updating dashboard ready for display.

As the above article only reference code snippets, the full project solution can be found here.

In Part 3 of this article, I’ll be recreating the same application but instead using SignalR technology for data refresh instead of the more traditional Web Services approach.

 

Resources