Charts

by Kye Hohenberger

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-with-addons.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js"></script>
<script src="https://npmcdn.com/recharts/umd/Recharts.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

CSS

body {
  margin: 0;
}
#container {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  padding: 10px;
  width: 800px;
  height: 800px;
  background-color: #fff;
}

Babel + JSX

const {AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip} = Recharts;

const rawSidewayData = {
  id: '1',
  buckets: {
    '1486459170000': { '1': 2 },
    '1486459185000': { '2': 2 },
    '1486459200000': { '1': 1, '3': 2 },
    '1486459215000': { '2': 1 },
    '1486459230000': { '3': 1 },
    '1486459245000': { '4': 1 },
    '1486459260000': { '5': 1 },
    '1486459275000': { '6': 1 },
    '1486459290000': { '7': 1 },
    '1486459305000': { '8': 1 }
 	}
}

const dateToTimeString = (date) => new Date(date).toLocaleTimeString([], {
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
})

// Needs to look like this
const data = [
  {name: 'Page A', uv: 4000, pv: 2400, amt: 2400},
  {name: 'Page B', uv: 3000, pv: 1398, amt: 2210},
  {name: 'Page C', uv: 2000, pv: 9800, amt: 2290},
  {name: 'Page D', uv: 2780, pv: 3908, amt: 2000},
  {name: 'Page E', uv: 1890, pv: 4800, amt: 2181},
  {name: 'Page F', uv: 2390, pv: 3800, amt: 2500},
  {name: 'Page G', uv: 3490, pv: 4300, amt: 2100},
];

const convertData = ({ buckets }) => {

  const areas = {}

	const formattedData = Object.keys(buckets).map((ts) => {
  	const points = buckets[ts]

    Object.keys(points).forEach((count) => {
    	areas[count] = true
    })

  	return {
    	time: dateToTimeString(parseInt(ts, 10)),
      ...buckets[ts]
    }
  })

  return { data: formattedData, areas }
}

const StackedAreaChart = React.createClass({
	render () {
  	const { data, areas } = convertData(rawSidewayData)
  
  	return (
    	<AreaChart width={600} height={400} data={renderData}
            margin={{top: 10, right: 30, left: 0, bottom: 0}}>
        <XAxis dataKey="name"/>
        <YAxis/>
        <CartesianGrid strokeDasharray="3 3"/>
        <Tooltip/>
        {Object.keys(areas).map((sampleCount, i) => {
        	return (
          	<Area type='monotone' dataKey={sampleCount} stackId="1" stroke='#8884d8' fill='rgba(102,51,153, 0.5)' />
          )
        })}
      </AreaChart>
    );
 ...