Dynamic Visualization LEGO
CoffeeScript JavaScript Other
Switch branches/tags
Nothing to show
Latest commit 25147b6 Apr 19, 2017 @vogievetsky vogievetsky Merge pull request #23 from metamx/webpack
Failed to load latest commit information.
css/smoothness first commit May 19, 2011
d3 reverted d3 version Mar 20, 2013
docs mouse stuff added Jun 30, 2011
examples Using browserify for DVL Jan 10, 2014
lib fixups for new build Jan 10, 2014
logo first commit May 19, 2011
src Mods Apr 18, 2017
test fixups for new build Jan 10, 2014
.gitignore update gitignore Jan 11, 2014
LICENSE re-wrote dropdown Jul 5, 2013
README.md added documentation about dvl.bind Aug 15, 2013
compile Webpacked Apr 18, 2017
dvl.css Mods Apr 18, 2017
dvl.css.map Mods Apr 18, 2017
dvl.js Mods Apr 18, 2017
dvl.js.map Mods Apr 18, 2017
package.json Mods Apr 18, 2017
todo dvl = dvl.def Jun 28, 2012
watch Webpacked Apr 18, 2017
webpack.config.js Webpacked Apr 18, 2017



DVL is a free functionally reactive library written in JavaScript. DVL is based on the idea that data, not control flow is the most important aspect of a program focused on data visualization.

DVL is built on top of D3 to allow for dynamic data binding to the DOM.


The code DVL functionality can be described with the following functions:


Creates a DVL variable with the given initial value. A DVL variable's value can be read and set. When the value is updated it will automatically notify any code that depends on it.

var x = dvl(5);
console.log(x.value()); //=> 5
console.log(x.value()); //=> 7

A DVL variable can take any value that a regular JavaScript variable can take with the exception of undefined since through the virtue of being created a DVL variable is always defined. Setting the value of a DVL variable to undefined will cause it to be null.

console.log(dvl().value()); //=> null
console.log(dvl(null).value()); //=> null
console.log(dvl(undefined).value()); //=> null
console.log(dvl(5).value(undefined).value()); //=> null

A DVL variable is considered invalid if its value is set to null. It is perfectly fine to have variables in an invalid state but some functions will treat invalid variables as a special case.


One of the most useful functions in DVL, the apply function creates a new DVL variable the value of which tracks the result of the given function as applied to the supplied parameters.

var a = dvl(5);
var b = dvl(12);

var c = dvl.apply([a, b], function(_a, _b) {
	return Math.sqrt(_a * _a + _b * _b);

console.log(c.value()) //=> 13

console.log(c.value()) //=> 12.36931687685298

console.log(c.value()) //=> 5

The 'worker function' in the apply gets called with the actual values of the variables.

Note: The suggested convention is to name the 'value parameters' with a leading underscore to aid readability by visually separating the DVL variable form it's actual value. This convention is adopted here.

If any of the arguments to a DVL apply function are invalid (value of null) then the 'worker function' will not be called and instead the result will be set to invalid.

console.log(c.value()) //=> null

console.log(c.value()) //=> 5


Auto invalidation is often the desired behavior and a convenience since the arguments within the 'worker function' will never be null, but sometimes it does make scenes for the result of the apply to be something valid even if some of the arguments are invalid.

var who = dvl('Jason');
var what = dvl('cake');

var likes = dvl.applyAlways([who, what], function(_who, _what) {
  if (_who === null) {
  	return null; // Deal with the case of not having a 'who', set likes to invalid.
	return _who + (_what === null ? ' does not like anything.' : ' likes ' + _what + '!');

console.log(likes.value()) //=> 'Jason likes cake!'

console.log(likes.value()) //=> 'Jason likes flying!'

console.log(likes.value()) //=> 'Jason does not like anything.'

console.log(likes.value()) //=> null


Registers a low level function that registers a function to be called reactively when a DVL variable changes. The apply and applyAlways functions are just convenience wrappers around a register.

var a = dvl(5);
var b = dvl(12);
var c = dvl();

	listen: [a, b],
	change: [c],
	fn: function() {
		var _a = a.value();
		var _b = b.value();
		if (_a !== null && _b !== null) {
			c.value(Math.sqrt(_a * _a + _b * _b));
		} else {

console.log(c.value()); //=> 13

console.log(c.value()); //=> 5

The above example is equvelant to the first dvl.apply example.

We must explicitly declare that the function being registered will be changing c. This is important for DVL to calculate the dependency graph and ensure that it is acyclic. Modifying a variable without specifying that it might be modified will throw an error.


Ties data to DOM elements. If data is in an array format, multiple DOM elements will be created. If you want to create only one DOM element out of an array, use dvl.bindSingle.

Required arguments

  • parent {DVL(DOM elements)}: parent element for the created DOM elements to be attached
  • self {String}: the type of DOM elements for the data to be attached to. The format of the string follow d3 convention.

Optional arguments

A lot of these arguments have similar API's to d3 selections because the internal mechanics of dvl.bind depends on d3. https://github.com/mbostock/d3/wiki/Selections

  • data {DVL(Object)}: data to back the DOM elements.
  • join {Object}: data to join with data.
  • attr {Object}: attributes of DOM elements. It works similar to d3's attr function. One significant difference is that class of the elements are a part of attr
  • style {Object}: styles of DOM elements. It works similar to d3's style function.
  • property {Object}: properties of DOM elements. It works similar to d3's property function.
  • text {Object}: text of DOM elements. It works similar to d3's text function.
  • html {Object}: HTML content of DOM elements. It works similar to d3's html function.
  • on {Object}: Append listeners to DOM events. It works similar to d3's on function.
  • transition


Ties data to a single DOM element. Aside from the name change of the argument 'data' to 'datum', it is very similar to how dvl.bind works.


Vadim Ogievetsky

Barret Schloerke

With invaluable advice from Mike Bostock