block by sxywu 3f496d692e57e906316173a290c3d6d4

Hamilton: characters

Full Screen

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
  <script src="https://npmcdn.com/babel-core@5.8.34/browser.min.js"></script>
  <style>
    body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
  </style>
</head>

<body>
  <svg></svg>
  <script type="text/babel">
    var charList = {
      "1": ["Aaron Burr", "M"],
      "2": ["Alexander Hamilton", "M"],
      "3": ["George Washington", "M"],
      "4": ["John Laurens", "M"],
      "5": ["Marquis de Lafayette", "M"],
      "6": ["Hercules Mulligan", "M"],
      "7": ["Elizabeth Hamilton", "F"],
      "8": ["Angelica Schuyler", "F"],
      "9": ["Peggy Schuyler", "F"],
      "10": ["Thomas Jefferson", "M"],
      "11": ["James Madison", "M"],
      "12": ["King George III", "M"],
      "13": ["Samuel Seabury", "M"],
      "14": ["Charles Lee", "M"],
      "15": ["Phillip Hamilton", "M"],
      "16": ["Maria Reynolds", "F"],
      "17": ["James Reynolds", "M"],
      "18": ["George Eacker", "M"],
      "21": ["Women", "F"],
      "22": ["Men", "M"],
      "23": ["Ensemble", "F/M"],
      "24": ["Company", "F/M"]
    };
    var width = window.innerWidth;
    var height = window.innerHeight;
    var color = d3.scaleOrdinal(d3.schemeCategory20);
    var radius = 2;
    var simulation = d3.forceSimulation()
    	.force('collide', d3.forceCollide(radius * 3))
      .force("center", d3.forceCenter(width / 2, height / 2))
      .stop();
    
    var svg = d3.select('svg')
    	.attr('width', width).attr('height', height);

    d3.json('characters.json', (characters) => {
      d3.json('lines.json', lines => {
        var allLines = _.chain(characters.characters)
          .map((lines, character) => {
            return _.map(lines, (line) => {
            	return {
                id: character + ':' + line,
                character,
                line,
              };
            });
          }).flatten().value();
        var topChars = _.chain(characters.characters)
        	.map((lines, character) => [character, lines.length])
        	.sortBy((character) => -character[1])
        	.map(0).take(8).value();
        topChars.push('other');
        
        var perRow = 3;
        var rowWidth = window.innerWidth / (perRow + 1);
        var charPos = _.reduce(topChars, (obj, character, i) => {
          obj[character] = {
            id: character,
            name: charList[character] ? charList[character][0] : 'Others',
            x: (i % perRow) * rowWidth,
            y: Math.floor(i / perRow) * rowWidth,
          };
          return obj;
        }, {});
        
        var circle = svg.append('g')
        	.classed('circles', true)
        	.selectAll('circle')
        	.data(allLines, (d) => d.id)
        	.enter().append('circle')
        	.attr('fill', (d) => color(d.character))
        	.attr('r', radius);
        svg.append('g')
        	.classed('texts', true)
        	.attr('transform', 'translate(' + [width / 4, height / 4] + ')')
        	.selectAll('text')
        	.data(_.values(charPos), (d) => d.id)
        	.enter().append('text')
        	.attr('x', (d) => d.x)
        	.attr('y', (d) => d.y)
        	.attr('text-anchor', 'middle')
        	.attr('dy', '.35em')
        	.text((d) => d.name);
        
        simulation.nodes(allLines);
        
        _.times(100, () => {
            simulation.tick();
            var k = simulation.alpha() * 0.1;
            _.each(allLines, (node, i) => {
              var pos = charPos[node.character] || charPos['other'];
              node.y += (pos.y - node.y) * k;
              node.x += (pos.x - node.x) * k;
            });
          
            circle
              .attr("cx", function(d) { return d.x; })
              .attr("cy", function(d) { return d.y; });
        });
        
      });
    });
  </script>
</body>

char_list.json

{
	"1": ["Aaron Burr", "M"],
	"2": ["Alexander Hamilton", "M"],
	"3": ["George Washington", "M"],
	"4": ["John Laurens", "M"],
	"5": ["Marquis de Lafayette", "M"],
	"6": ["Hercules Mulligan", "M"],
	"7": ["Elizabeth Hamilton", "F"],
	"8": ["Angelica Schuyler", "F"],
	"9": ["Peggy Schuyler", "F"],
	"10": ["Thomas Jefferson", "M"],
	"11": ["James Madison", "M"],
	"12": ["King George III", "M"],
	"13": ["Samuel Seabury", "M"],
	"14": ["Charles Lee", "M"],
	"15": ["Phillip Hamilton", "M"],
	"16": ["Maria Reynolds", "F"],
	"17": ["James Reynolds", "M"],
	"18": ["George Eacker", "M"],
	"21": ["Women", "F"],
	"22": ["Men", "M"],
	"23": ["Ensemble", "F/M"],
	"24": ["Company", "F/M"]
}