Archive for May, 2012

May 29, 2012

A simple drawing grid with HTML 5

This week, we will build a simple drawing grid using HTML5 and javascript. In the coming weeks we will transform this simple example into a fully functional drawing application. For this demo, the entire browser window will be a canvas and resizing or reloading the window will clear it.
The first step is to define our canvas and add some css that will set the size of the canvas to the size of the browser window.

<!DOCTYPE HTML>
<html>
	<style type="text/css">
	html, body { width: 100%; height: 100%; margin: 0px; }
	</style>
	<body>
		<canvas id="grid">
			<p>Your browser does not support HTML5 canvas</p>
		</canvas>
	</body>
</html>

This is all that is required to create a canvas that consumes the entire browser window. The next step is to add javascript to the page so we can have an interactive drawing surface. We will be using jquery and loading a script named grid.js; which will perform the canvas updates.

<!DOCTYPE HTML>
<html>
	<head>
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
	</head>
	<style type="text/css">
	html, body { width: 100%; height: 100%; margin: 0px;  }
	</style>
	<body>
		<canvas id="grid">
			<p>Your browser does not support HTML5 canvas</p>
		</canvas>
		<script type="text/javascript" src="scripts/grid.js"></script>
	</body>
</html>

The next step is to create a folder named “scripts” and within it create a text file called grid.js using your favorite editor. The grid.js script will be responsible for all of the canvas updating. For starters, we will need to define the callbacks for window events in order to initialize the canvas data. “window.onresize” will be used so that the canvas can be cleared when the window is resized.

window.onload = window.onresize = function() {
	var grid_canvas = document.getElementById("grid");
	var ctx = grid_canvas.getContext("2d");
	var viewWidth = window.innerWidth;
	var viewHeight = window.innerHeight;
	var backgroundColor = "rgb(0,0,255)";

	grid_canvas.style.position = "fixed";
	grid_canvas.setAttribute("width", viewWidth);
	grid_canvas.setAttribute("height", viewHeight);
	grid_canvas.style.top = 0;
	grid_canvas.style.left = 0;

	ctx.clearRect(0,0,viewWidth,viewHeight);
	ctx.fillStyle = backgroundColor;
	ctx.fillRect(0,0,viewWidth,viewHeight);	
}

At this point, the canvas is created, but isn’t very interesting. To draw on the canvas, we will rely on mouse events. In this demo, holding down the left mouse button and dragging will fill in cells of the grid that the mouse is hovering over. Holding any other mouse button down and dragging will be used for an “erase” function. It’s not actually erasing, but coloring the cells in with the defined background color. The following should be added to the window event callback defined above.

var xOffset = $("#grid").offset().left;
var yOffset = $("#grid").offset().top;
var mouseDown = false;
var mouseButton = 0;
var penColor = "rgb(255,255,255)";
var penWeight = 5;

$("#grid").mousedown(function(e) {
	mouseDown = true;
	mouseButton = e.which;
}).bind('mouseup', function() {
	mouseDown = false;
});

$("#grid").mousemove(function(e) {
	if (mouseDown) {
		var x = Math.floor((e.pageX-xOffset) / penWeight);
		var y = Math.floor((e.pageY-yOffset) / penWeight);

		ctx.fillStyle = mouseButton == 1 ? penColor : backgroundColor;
		ctx.fillRect(x*penWeight, y*penWeight, penWeight, penWeight);
	}
});

Loading the page now should result in a functional drawing application. Changing the “penWeight” variable will alter the cell sizes on the hidden grid. As a small optimization, you may consider storing the last cell that was drawn to and skipping a redraw (included in the source example) if the user is still moving with the cell. At smaller cell sizes, this becomes less important.

The demo for the grid can be found here.

May 22, 2012

Using Task for responsive UI in WPF

Blocking of the UI thread in a WPF application causes the application to become unresponsive. It is a common problem with several solutions, but usage of Task is in my opinion the most elegant solution because of readability and code brevity.
For this example we have a simple WPF application with a button that starts a long running loop. A busy indicator is displayed while the loop is running.

_busyIndicator.IsBusy = true;

for (var i = 0; i &lt; 100; i++)
{
  System.Threading.Thread.Sleep(50);
}

_busyIndicator.IsBusy = false;

As written, this code will freeze the app for the duration of the loop since it blocks execution of the UI thread. The solution is to run the loop Asynchronously and using Task is the easiest way to accomplish it in this case.

_busyIndicator.IsBusy = true;

var T = new Task(() =>
{
  for (var i = 0; i &lt; 100; i++)
  {
    System.Threading.Thread.Sleep(50);
  }
});

T.Start();

_busyIndicator.IsBusy = false;

However, this bit of code will crash the application because we have not passed control back to the context of the UI thread. The ‘Task.ContinueWith’ method can be used to serve that purpose.

var T = new Task(() =>
{
  for (var i = 0; i < 100; i++)
  {
    System.Threading.Thread.Sleep(50);
  }
});

T.ContinueWith(antecedent => _busyIndicator.IsBusy = false, TaskScheduler.FromCurrentSynchronizationContext());

Running the application will now result in complete responsiveness. You can move, resize, or perform other operations while the loop is running. However, there are cases where CPU intensive loops may cause the busy indicator to not be displayed. In WPF, the UI render events are queued to prevent issues related to multiple execution of the same event. To prevent this, we want to make sure that the busy indicator is displayed. And for that we can use a timer event.

private System.Windows.Threading.DispatcherTimer _timer = null;
public MainWindow()
{
  InitializeComponent();
  _timer = new DispatcherTimer();
  _timer.IsEnabled = false;
  _timer.Tick += new System.EventHandler(RunTask);
}

private void StartProcess(object sender, RoutedEventArgs e)
{
  _busyIndicator.IsBusy = true;
  _timer.Interval = new TimeSpan(0,0,0,0,100);
  _timer.Start();
  // go back to the user thread, giving the busy indicator a chance to come up before the next timer tick event
}

void RunTask(object sender, System.EventArgs e)
{
  _timer.IsEnabled = false;

  var T = new Task(() =>
  {
    for (var i = 0; i < 100; i++)
    {
      System.Threading.Thread.Sleep(50);
    }
  });

  T.ContinueWith(antecedent => _busyIndicator.IsBusy = false, TaskScheduler.FromCurrentSynchronizationContext());
  T.Start();
}

So, when the user clicks the button, the busy indicator is set to true first, the timer is started, and once it has ticked the Task is called. Using the timer event in this manner ensures that the loop will not be executed until the busy indicator is rendered.

The complete source code for this example can be found in our github repository.

Tags: ,
May 3, 2012

Linear Regression with Excel 2010

Linear regression is a way to determine close two number series of data: x (independent) and y (potentially dependent), fit in a linear function of the form: y = a*x + b.

This is the first of a series of planned posts that will cover how to set up linear regression a variety of different languages. This week, we will discuss the easiest method of performing Linear regression analysis; and that is with Excel 2010.

First, we will need to enable the Analysis ToolPak for Excel:

1)      Click File and select options

2)      Select Add-ins on the left hand menu

3)      Select Excel Add-ins in the drop down list named Manage at the bottom of the pop up

4)      Click the ‘Go’ button

5)      Tick the checkbox for Analysis ToolPak if it is empty

6)      Click the ‘Ok’ button

Once the Add-in is installed, create a table of data similar to the following:

x

y

7

216

12

302

14

431

6

151

22

677

38

958

14

431

9

227

10

308

11

277

To perform the Regression analysis, select a cell and then click the ‘Data’ ribbon tab. Then double-click the Data Analysis section of the ribbon. This will present a popup similar to the following:

 

 
Data Analysis
 

 

Select the Regression option and click the ‘Ok’ button. This will prompt another popup to enter the cell ranges for the data which will be analyzed:

 

 

Select Range

 

 

For the Input Y Range, select all cells in the Y column; including the header. Do the same for the Input X Range using the X column. Be sure to select the Labels checkbox and then click the ‘Ok’ button. Doing so will create the regression analysis within your spreadsheet:

 

 
Summary
 

 

Next week, we will talk a bit about what all of this means, but for right now, we will focus on the R Square value, and the Coefficients of the rows labeled ‘Intercept’ and ‘x’. The best way to demonstrate the significance of these values is to present them in a scatter chart with the linear trend line being rendered. This can be done in the following steps:

1)      Click an empty cell

2)      Select the ‘Insert’ ribbon tab

3)      Select the Scatter Plot and choose ‘Scatter with only Markers’

4)      Right Click in the center of the Chart and choose ‘Select Data’

5)      Highlight your data table  including the column header lines

6)      Click the ‘Ok’ button

Your chart should be displayed similar to the following:

 

 
Scatter Plot

 

 

The following steps can be used to display the linear trend line in the chart:

1)      Left Click any of the plot markers

2)      Right Click and select ‘Add Trendline’

3)      Select Linear in the Trendline Options pop up

4)      Enable the checkbox for ‘Display Equation on chart’

5)      Enable the checkbox for ‘Display R-Squared value on chart’

6)      Click the close button

 

 
Linear Trend

 

 

And there you have it; Linear Regression done simply in Excel 2010. You should notice that the formula given uses the values obtained in the Summary Output of the Data Analysis step. Next week, we will discuss how to perform Regression analysis programmatically in C#.