block by micahstubbs 0ad752ff92f0165e88d939efc016ec98

formatting numbers example d3v3

Full Screen

This little tool helps you try out d3.format specifiers on different numbers.

Documentation for format specifiers is here

a friendly fork of the original bl.ock from @zanstrong

this iteration moves the descriptive text to README.md so that the link to the docs is clickable 😄

thanks to guilherme from the d3js slack for suggesting this improvement

index.html

<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<title>formatting numbers example d3v3</title>
<style>
body {
  margin: 20px 0px 0px 50px;
}

.formattext {
  text-align: right;
}

.formatresult {
  text-align: left;
  padding-left: 40px;
}
</style>
</head>
<body>
  Enter a number:<br>
  <input id='userNum' type='string'><br><br>
  Add your own format specifier (ex: .4n):<br>
  <input id='formatSpecifier' type='string'><br>
	<table style='padding-top: 20px;'>
    <thead>
  	  <tr>
        <th class='formattext'>format specifier</th>
    	  <th class='formatresult'>resulting formatted number</th>
  	  </tr>
  	</thead>
  	<tbody>
    </tbody>
  </table>
<script src='//d3js.org/d3.v3.min.js' charset='utf-8'></script>
<script src='showFormatsConstructor.js'></script>
<script>
// define variables
var formatlist = ["", "s", ",%", "+,%", ",.1%", ".4r", ".4f", ".4n", ".3n", ",d", ",.0f", ".0f", ".0e", ".1e"];
var userNum = document.getElementById("userNum");
var colorLow = 'blue'
var colorHigh = 'red'

// add listener to call formatter function when user changes the number
userNum.addEventListener("input",
  function(e) {
    myFormats.changeNumber(userNum.value);
  },
  false
);

// need way to update list
formatSpecifier.addEventListener("change",
  function(e) {
    myFormats.addToList(formatSpecifier.value);
  },
  false
);

// create a little color scale function to make the output look pretty
function setColorScale(max) {
  return d3.scale.linear()
    .domain([0, max])
    .interpolate(d3.interpolateRgb)
    .range([colorLow, colorHigh])
}

// construct code/text pairs from list of formats I could use
var constructFormatObject = function(mylist) {
  var types = [];
  mylist.forEach(function(d) {
    types.push({
      code: d3.format(d),
      text: 'd3.format("' + d + '")'
    })
  })
  return types
}


var myFormats = new ShowFormats(
  formatlist,
  0);
</script>
</body>
</html>

showFormatsConstructor.js

// set up showformats constructor

ShowFormats = function(formatList, number) {
	// list of format specifiers to show
	this.formatList = formatList;
	this.formatObject = constructFormatObject(formatList);
	this.dataset = Array.apply(0,
		Array(this.formatObject.length)).map(function(x, y) {
		return y;
	});;
	// number to format
	this.number = number;
	this.colorScale = setColorScale(this.dataset.length)

	var self = this;

	// set up defaults
	this.selection = d3.select("tbody").selectAll("tr")
		.data(this.dataset)
		.enter()
		.append("tr");

	this.selection
		.append("td")
		.text(function(d) {
			return self.formatObject[d].text;
		})
		.style("color", function(d) {
			return self.colorScale(d)
		})
		.attr("class", "formattext");

	this.selection
		.append("td")
		.text(function(d) {
			return self.formatObject[d].code(self.number);
		})
		.style("color", function(d) {
			return self.colorScale(d)
		})
		.attr("class", "formatresult");
}

ShowFormats.prototype.changeNumber = function(number) {
	this.number = number;
	this.updateFormats();
}

ShowFormats.prototype.addToList = function(specifier) {
	this.formatList.unshift(specifier)
	this.formatObject = constructFormatObject(this.formatList);

	// update dataset array w/ new length
	this.dataset = Array.apply(0,
		Array(this.formatObject.length)).map(function(x, y) {
		return y;
	});;

	this.updateFormats();
}

ShowFormats.prototype.tdtextStyling = function(selection) {
	selection.text(function(d) {
		return self.formatObject[d].text;
	})
		.style("color", function(d) {
			return self.colorScale(d)
		})
		.attr("class", "formattext");
}

ShowFormats.prototype.tdcodeStyling = function(selection) {
	selection.text(function(d) {
		return self.formatObject[d].code(self.number);
	})
		.style("color", function(d) {
			return self.colorScale(d)
		})
		.attr("class", "formatresult");

}

ShowFormats.prototype.updateFormats = function() {
	self = this;

	// bind with current dataset
	this.selection = d3.selectAll("tbody").selectAll("tr")
		.data(self.dataset);

	// enter elements
	var k = this.selection.enter().append("tr")

	k.append("td")
		.call(self.tdtextStyling);

	k.append("td")
		.call(self.tdcodeStyling);

	// update elements
	this.selection
		.selectAll("td")
		.text(function(d, i) {
			if (i == 0) {
				return self.formatObject[d].text;
			}
			if (i == 1) {
				return self.formatObject[d].code(self.number);
			}
		})
		.style("color", function(d) {
			return self.colorScale(d)
		})
		.attr("class", function(d, i) {
			if (i == 0) {
				return "formattext"
			} else {
				return "formatresult"
			}
		})
}