Click here to Skip to main content
15,886,518 members
Articles / Programming Languages / Javascript
Article

Visual Modeling Made Easy with the RASON® API and D3.js

1 Mar 2016CPOL8 min read 39.8K   1  
This article explores how to define a model, solve a problem, and generate a visual graph within a single page web application using HTML, JavaScript, the D3.js library, and the RASON REST API.

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Analytics and the insights they provide are considered essential tools in the modern enterprise. Unfortunately, programming solutions to difficult problems traditionally involves complex mathematical formulas and proprietary languages that present tough learning curves for developers who aren’t data scientists or mathematicians. Frontline Solvers® (http://www.solver.com/) addresses this issue through a variety of tools that make it easy and straightforward to define problems and parse solutions with everyday tools like Excel. A new RESTful API called Restful Analytic Solver® Object Notation (or RASON® for short) is a modeling language that leverages JSON to make it easy to create, test, and deploy analytic models using optimization, simulation, and data mining.

The JSON format not only makes it easy to define and solve problems, but also enables developers to parse results and generate visualizations using modern JavaScript libraries. This article explores how to define a model, solve a problem, and generate a visual graph within a single page web application using HTML, JavaScript, the D3.js library, and the RASON REST API. To get started, visit https://rason.com and click the Register button in the upper right to create your free account. This will provide you with full functionality and only limits the size of models and number of API calls you are able to make.

Once you’ve registered and logged in, click the Try It tab to access the interactive online engine that allows you interact with the REST API. The page is divided into three sections. The left top contains a text editor to define the problem you wish to solve, the left bottom displays the results, and the right column provides buttons to easily try out the REST API. In the RASON Examples dropdown choose PortfolioOpt.json under the Quadratic category. This example is designed to optimize your stock portfolio by providing the best percentages for allocations (i.e. given $100, $25 should go to "stock A" and $15 to "Stock B" and so forth). Selecting it will load JSON for the example into the upper left window, as shown in Figure 1.

Image 1

Figure 1: JSON for Model

The first thing you will notice is how easy and readable the notation is. The problem is defined as a simple JSON object with sections that include variables for the model, data used to compute the solution, constraints, and the objective. This JSON is referred to as the optimization "model." When you click a button on the right, the REST API request shown on the button is sent to the RASON server, with the model (text editor contents) as the payload.

The quickest way to solve this model and get results is to click the "Quick run" button that reads: POST rason.net/api/optimize. If you do this, after a second or two you’ll see the JSON response, showing the optimal portfolio, in the results area. But this is a synchronous call, suitable only for simple models. Larger problems can take minutes or even hours to run, and you don’t want your user interface to be blocked. So instead, we’ll use RASON’s asynchronous endpoints.

The first step to solve a problem is to post the model to RASON. To do this, click the button that reads: POST rason.net/api/model. When you click the button you’ll see status in the left bottom window that the AJAX call is being made. The model posts to the server and receives a unique identifier, which appears in the Model Resources dropdown list. This identifier enables you to perform various actions against the model. Click the button that reads: GET rason.net/api/model/id/optimize, which makes this REST API request with the current model identifier in the dropdown list substituted for "id". This call submits the model asynchronously for processing and you receive a notification that it is queued to be optimized. You then poll the progress using GET rason.net/api/model/id/status. Once the status is Complete you fetch the results using GET rason.net/api/model/id/result. All of these actions can be performed in the online engine by clicking the corresponding buttons in the right column. An example of a result is shown in Figure 2.

Image 2

Figure 2: Result JSON

Although it is fun to interact with samples online, you will eventually want to access the APIs from your own apps. RASON makes this incredibly easy to do by generating a reference application for you! At the top of the left window is a button labeled Create App. Click this button and an HTML file will immediately begin to download. This is a single HTML page that contains all of the HTML and JavaScript necessary to interact with the RASON API.

Download the sample app and view the source. The example automatically references jQuery for ease of use and you can update it to use any library you prefer. A JavaScript object named rasonApp is defined with several properties and functions. These include the model id, the model itself (since it’s JSON, it appears literally in your JavaScript code), options for the AJAX calls, including the authorization token you need to make requests with your account, and several functions to perform various actions. Browse the code to learn how to interact with the various APIs.

The quickSolve method, which makes the synchronous call mentioned earlier, attempts to obtain a solution immediately and will work for simpler models. For longer running solutions, the program follows this flow:

  1. startSolve posts the model to the server; its "done" function calls getModelId
  2. getModelId obtains the unique model identifier from the response Location header, uses it to issue the request to optimize, and sets a timer to call status
  3. status checks to see if the solution is complete via checkStatus, and either calls status again on a timer if it’s not ready or results once it is ready
  4. results renders the solution and issues a call to delete the model from the server

Open the page in your favorite browser and run the example. The status appears in the upper window, the available actions are in a row beneath this, and the model itself is output at the bottom of the page. Starting with this example, it is very easy to enhance the application to provide a visualization of the results. This example uses a popular JavaScript library named "D3.js" (http://d3js.org/). At the top of the HTML file, just after the reference to jQuery, add a script reference to include D3.js:

<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

This loads the library directly from the host site. The library uses Scalable Vector Graphics (SVG). After the textarea tag near the bottom of the page that holds the results, add this svg tag:

<svg id="svg_pie" width="600" height="400"></svg>

Next, add a new function to the rasonApp object. To do this, add a comma after the stopped method then add the code for the function shown in Figure 3.

Image 3

Figure 3: Code to Draw a Pie Chart with D3.js

The code defines the size of the pie chart. It expects an array of fractional numbers (percentages) and uses those to build a set of data points and labels. The library works via a combination of attributes and functions that it calls as it iterates through the data. For example, to define an arc, the raw value that represents the percentage of the pie graph to fill is used:

var pie = d3.layout.pie().value(function (d) { return d.value; });

The list of arcs is called with the data element its index, and the provided function sets the fill value to a color from a pre-defined palette. The palette is defined here:

color = d3.scale.category20c()

The function to set the fill is defined on this line (notice it passes the index to get a unique color for each arc or "slice:"

.attr("fill", function (d, i) { return color(i)}).attr("d", arc);

The remaining code applies the text labels. To call the function, add another function that processes the results. This function extracts the allocations for the stocks from the result object and calls the drawPie function:

processResults:
function(data) {
                if (data && data.variables && data.variables.x)
{
                    rasonApp.drawPie(data.variables.x.finalValue);
                }
            },

This function is called when the result is ready. There are two places to make the call. Add this line anywhere in both the results and the quickStatus functions:

rasonApp.processResults(data);

Save your changes, reload the page in your browser and choose either of the optimize buttons. After the result is returned you should see a pie chart similar to the one shown in Figure 4.

Image 4

Figure 4: Pie Chart

The entire process from generating the sample app to producing your first graph can be completed in less than 15 minutes. That’s very powerful! It’s important to note that the same APIs you use to develop in JavaScript are available to backend code as well. The definition and results are stored in the same JSON syntax. The following code (taken from https://rason.com/Home/About#server_based) illustrates the server-side code you’d use in C# (it’s very similar in C++, Java or Python):

Problem prob = new
Problem();
prob.Load("model.json");
prob.Solver.Optimize();
MessageBox.Show(prob.FcnObjective.FinalValue[0].ToString());

As you can see, it is a very straightforward programming model.

This article just scratched the surface of what is possible. Now that you’ve learned how easy it is to set up problems to solve, create optimizations leveraging the RASON API, and visualize the results using libraries like D3.js, the next challenge is yours to take on! Run some of the other examples or create new problems of your own, then generate a starter app and either customize it as needed or pull the provided code into your own apps. Analytics and insights provide tremendous value to your organization, but they don’t have to be complicated! Leveraging tools like RASON makes it easier than ever to implement analytics and visualizations in modern mobile, desktop, and web-based applications.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Program Manager Microsoft
United States United States
Note: articles posted here are independently written and do not represent endorsements nor reflect the views of my employer.

I am a Program Manager for .NET Data at Microsoft. I have been building enterprise software with a focus on line of business web applications for more than two decades. I'm the author of several (now historical) technical books including Designing Silverlight Business Applications and Programming the Windows Runtime by Example. I use the Silverlight book everyday! It props up my monitor to the correct ergonomic height. I have delivered hundreds of technical presentations in dozens of countries around the world and love mentoring other developers. I am co-host of the Microsoft Channel 9 "On .NET" show. In my free time, I maintain a 95% plant-based diet, exercise regularly, hike in the Cascades and thrash Beat Saber levels.

I was diagnosed with young onset Parkinson's Disease in February of 2020. I maintain a blog about my personal journey with the disease at https://strengthwithparkinsons.com/.


Comments and Discussions

 
-- There are no messages in this forum --