<main></main>
textarea {
  display: block;
}

table {
  width: 100%;  
  max-width: 300px;
}

th {
  text-align: left;
}

svg {
  background: lightblue;
}
const { useState } = React;

function FrequencyData(props) {
  const { data } = props;
  return <pre>{JSON.stringify(data)}</pre>
}

function FrequencyGraph(props) {
  const { data } = props;
  const totalWords = Object.values(data).reduce((a, b) => a + b, 0)
  const height = Object.keys(data).length * 30 + 50;
  return (
    <svg class="chart" width="420" height={height} aria-labelledby="title desc" role="img">
      {Object.keys(data).map((word, index) => (
      <g class="bar">
        <rect y={10 + index * 30} width={data[word] / totalWords * 200} height="19"></rect>
        <text x={(data[word] / totalWords * 200) + 10} y={20 + index * 30} dy=".35em">{word} [{data[word]}]</text>
      </g>
      ))}      
    </svg>
  )
}

function FrequencyTable(props) {
  const { data } = props;
  return (
    <table>
      <tr><th>Word</th><th>Count</th></tr>
      {Object.keys(data).map(word => (
        <tr><td>{word}</td><td>{data[word]}</td></tr>
      ))}
        
    </table>
  )
}

function App(props) {
  const [text, setText] = useState('');
  const frequencies = _.countBy(text.split(/\W+/).filter(x => x.length > 0));

  return (
    <div>
      <label>Type Text Here:
        <textarea value={text} onChange={(e) => setText(e.target.value)}></textarea>
      </label>    
      <FrequencyData data={frequencies} />
      <FrequencyTable data={frequencies} />
      <FrequencyGraph data={frequencies} />
    </div>
  )
}
      
ReactDOM.render(<App />, document.querySelector('main'));
      
      
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js