Scrollable, Sortable HTML Table with Static Headers Using d3.js


This HTML table has several features:
  1. Large amount of data can be displayed because the content is scrollable.
  2. The headers are static on top of the table, even when scrolling.
  3. Clicking on a header sorts the table by that property.
  4. Uses d3.js to append the table together.

I'm illustrating this because this behavior is often desirable but difficult to achieve.

I often see a lot of ugly javascript code where the data is looped through and a table row is appending for each element. It works, but isn't elegant and is inflexible. What if you want to sort the data after? The obvious solution is to sort the data and then redraw the table. d3.js saves us this hassle. Instead of ugly looping code let d3.js do the looping for you. All you need to do is bind the data to the table rows and supply the appropriate sorting functions. The cool thing is the sorting occurs in the DOM and no complete redraw is nessecary.

As for the static headers, this is acheived by using nested tables and works nicely. The trick is to leave room for the scroll bar along side the inner tables.

Code

    var chart = document.getElementById("chart");
	var width = chart.offsetWidth;
	var height = chart.offsetHeight;
	var valueFunc = function(data) { return data.value; }
	var textFunc = function(data) { return data.fullname; }
	var columns = ["State", "Value"];
	drawTable(myData, "#chart", { width: width, height: height }, valueFunc, textFunc, columns);
One function is used to draw the table: drawTable. There are six parameters:

The example above illustrates an example call. Note that the variable myData is declared in a seperate file and can be seen below.

The function assumes the table will have two columns. The first column is string data and the second column is numerical. With a little work you can expand this is to N columns which would be pretty neat.

Here is drawTable code: table.js

Data

The dataset can be viewed here: data, and below..

[
	{
		"fullname" : "Oregon",
		"value" : 10
	},
	{
		"fullname" : "Washington",
		"value" : 12
	},
	{
		"fullname" : "Nevada",
		"value" : 2
	},
	{
		"fullname" : "Florida",
		"value" : 7
	},
	{
		"fullname" : "Texas",
		"value" : 7
	},
	{
		"fullname" : "Maine",
		"value" : 1
	},
	{
		"fullname" : "Idaho",
		"value" : 34
	},
	{
		"fullname" : "New Mexico",
		"value" : 3
	},
		{
		"fullname" : "Georgia",
		"value" : 3
	},
		{
		"fullname" : "Montana",
		"value" : 9
	},
	{
		"fullname" : "Ohio",
		"value" : 13
	},
	{
		"fullname" : "Alaska",
		"value" : 1000
	}
]

Styling

	#chart {
	  width: 500px;
	  height: 500px;
	}

	.bodyTable td {
		white-space: nowrap;
		text-overflow: ellipsis;
		overflow: hidden;
	}

	.bodyTable tr {
		height: 40px;
	}

	.bodyTable tr:hover {
		background-color:grey;
	}

	.headerTable th:hover {
		background-color:grey;
	}

	.scroll {
		overflow: auto;
	}