block by sxywu 570df88e66e420191d33dc5b5650aaf4

Hamilton characters #2

Full Screen

Built with blockbuilder.org

forked from sxywu‘s block: Hamilton: characters

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", true],
      "22": ["Men", "M", true],
      "23": ["Ensemble", "F/M", true],
      "24": ["Company", "F/M", true]
    };
    var width = window.innerWidth;
    var height = window.innerHeight;
    var color = d3.scaleOrdinal(d3.schemeCategory20);
    var radius = 3;
    var radiusScale = d3.scaleLinear()
    	.range([radius, radius * 5]);
    var simulation = d3.forceSimulation()
    	.force('collide', d3.forceCollide().radius(d => d.radius + 3))
//       .force("center", d3.forceCenter(width / 2, height / 2))
    	.force('x', d3.forceX().x(d => d.focusX))
    	.force('y', d3.forceY().y(d => d.focusY))
    	.alphaMin(.01)
    	.alphaDecay(.02);
    
    var svg = d3.select('svg')
    	.attr('width', width).attr('height', height);

    d3.json('characters.json', (characters) => {
      d3.json('lines.json', lines => {
        
        var linesArray = _.values(lines);
        var maxSize = _.maxBy(linesArray, 3)[3];
        var minSize = _.minBy(linesArray, 3)[3];
        radiusScale.domain([minSize, maxSize]);
        
        var allLines = _.chain(lines)
          .map((line, id) => {
            // get all characters from the line
            return _.map(line[1][0], (character) => {
            	return {
                id: character + ':' + id,
                lineId: id,
                characterId: character,
                radius: radiusScale(line[3]),
                x: width / 2,
                y: height / 2,
                data: line,
              };
            });
          }).flatten().value();
        var sortedChars = _.chain(characters.characters)
        	.map((lines, character) => [character, lines.length])
        	// filter it out if it's a group
        	.filter((character) => !charList[character[0]][2])
        	.sortBy((character) => -character[1])
        	.map(0).value();
        sortedChars.push('group');
        
        var perRow = 4;
        var rowWidth = window.innerWidth / (perRow + 1);
        var charPos = _.reduce(sortedChars, (obj, character, i) => {
          obj[character] = {
            id: character,
            name: charList[character] ? charList[character][0] : 'Group',
            x: (i % perRow + 1) * rowWidth,
            y: (Math.floor(i / perRow) + 1) * rowWidth,
          };
          return obj;
        }, {});
        // now assign the character positions to all nodes
        _.each(allLines, line => {
          var pos = charPos[line.characterId] || charPos['group'];
          line.focusX = pos.x;
          line.focusY = pos.y;
        });
        
        
        var circle = svg.append('g')
        	.classed('circles', true)
        	.selectAll('circle')
        	.data(allLines, (d) => d.id)
        	.enter().append('circle')
        	.attr('fill', (d) => color(d.characterId))
        	.attr('r', (d) => d.radius);
        svg.append('g')
        	.classed('texts', true)
        	.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)
        	.on('tick', forceTick);
        
        function forceTick() {
          console.log(simulation.alpha())
          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"]
}