d3

by Paco86

HTML

<script src="https://d3js.org/d3.v4.js"></script>
<header> 
    <h1>Letter Analyzer</h1>
    <form>
      <input type="text">
      <button type="submit">Count the Letters!</button>
      <button id="reset" type="button">Reset</button>
    </form>
  </header>
  <div>
    <h2 id="phrase"></h2>
    <h4 id="count"></h4>
    <svg
      version="1.1"
      baseProfile="full"
      xmlns="http://www.w3.org/2000/svg"
      id="letters">
    </svg>
  </div>

CSS

body {
  margin: 0;
  text-align: center;
}

header {
  padding: 40px;
  background-color: #5a0071;
  color: white;
  font-family: sans-serif;
}

form > input {
  width: 60%;
  padding: 8px;
  border-radius: 8px;
  border: none;
}

form > button {
  padding: 8px;
  border-radius: 8px;
  background-color: #d0d0f9;
  border: none;
}

form > button:hover {
  cursor: pointer;
  background-color: #6a6a8e;
}

#letters {
  margin: 20px auto 0;
}

.letter rect {
  fill: #ffc800;
}

.new rect {
  fill: #00ff00;
}

.new text {
  font-size: 1.5em;
}

JavaScript

'use strict';

(function(){
	let width = 200;
	let height = 300;
	let binPadding = 10;
	
	d3.select('form').on('submit', function(){
		d3.event.preventDefault();
		
		let svg = d3.select('svg').attr('width', width).attr('height', height);
		
		let input = d3.select('input');
		let data = getCount(input.property('value'));
		let binWidth = width / data.length - binPadding;
		
		//update data
		let letters = svg.selectAll('.letter')
			.data(data, function(d){
				//return any property is OK, just to override index
				return d.character;
			});

		//remove elements: remove()
		letters.classed('new', false).exit().remove();
		
		//add new elements: enter()
		let letterEnter = letters.enter()
			.append('g')
			.classed('letter', true)
			.classed('new', true);
		
		//merge
		letterEnter.append('rect');
		letterEnter.append('text');
		
		letterEnter.merge(letters)
			.select('rect')
			.style('height', function(d){
				return d.count * 20;
			})
			.style('width', binWidth)
			.attr('x', function(d, index){
				return (binWidth + binPadding) * index;
			})
			.attr('y', function(d){
				return height - d.count * 20;
			});
			
		letterEnter.merge(letters)
			.select('text')
			.attr('text-anchor', 'middle')
			.attr('x', function(d, index){
				return (binWidth + binPadding) * index + binWidth / 2;
			})
			.attr('y', function(d){
				return height - d.count * 20 - 5;
			})
			.text(function(d){
				return d.character;
			});	
			
		
		d3.select('#phrase')
			.text('You Enter: ' + input.property('value'));
		console.log(letters.enter());
		d3.select('#count')
			.text('New Letter Count: ' + letters.enter().nodes().length);
		
		input.property('value', '');
	});
	
	
	d3.select('#reset').on('click', function(){
		d3.select('input').property('value', '');
		d3.select('svg').selectAll('g').remove();
		d3.select('#phrase').text('');
		
	})

})();



function getCount(str){
	let arr = str.split('').sort();
	let res = [{
		character: arr[0],
		count: 1
	}];
	for(let i = 1;...