Created
April 7, 2016 14:26
-
-
Save ccnixon/353c2a69e0d27af37369450d91bbb4e1 to your computer and use it in GitHub Desktop.
Simple Event Timeline (React)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Datanyze Challenge</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> | |
<style> | |
html * { | |
-webkit-font-smoothing: antialiased; | |
-moz-osx-font-smoothing: grayscale; | |
font-family: 'helvetica' | |
} | |
*, *:after, *:before { | |
-webkit-box-sizing: border-box; | |
-moz-box-sizing: border-box; | |
box-sizing: border-box; | |
} | |
.cd-container { | |
width: 90%; | |
max-width: 1170px; | |
margin: 0 auto; | |
} | |
.cd-container::after { | |
content: ''; | |
display: table; | |
clear: both; | |
} | |
#cd-timeline { | |
position: relative; | |
padding: 2em 0; | |
margin-top: 3em; | |
margin-bottom: 3em; | |
} | |
#cd-timeline::before { | |
/* this is the vertical line */ | |
content: ''; | |
position: absolute; | |
top: 0; | |
left: 30%; | |
height: 100%; | |
width: 4px; | |
background: #d7e4ed; | |
margin-left: -2px; | |
} | |
.cd-timeline-block { | |
position: relative; | |
margin: 4em 0; | |
padding-bottom: 75px; | |
} | |
.cd-timeline-block:after { | |
content: ""; | |
display: table; | |
clear: both; | |
} | |
.cd-timeline-block:first-child { | |
margin-top: 0; | |
} | |
.cd-timeline-block:last-child { | |
margin-bottom: 0; | |
} | |
#timeline-block { | |
margin: 4em 0; | |
} | |
.cd-timeline-img { | |
position: absolute; | |
top: 0; | |
left: 30%; | |
width: 60px; | |
height: 60px; | |
border-radius: 50%; | |
margin-left: -30px; | |
background: #f0f0f5; | |
} | |
.fa { | |
display: block; | |
left: 15%; | |
top: 24%; | |
position: relative; | |
} | |
.cd-timeline-date { | |
text-align: right; | |
right: 80%; | |
left: auto; | |
display: inline-block; | |
position: absolute; | |
width: 100%; | |
top: 6px; | |
float: left; | |
padding: .8em 0; | |
} | |
</style> | |
</head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.min.js"></script> | |
<body> | |
<div class="cd-container"> | |
<section id="cd-timeline"> | |
</section> | |
</div> | |
<script type="text/babel"> | |
window.layoutCommands = function(session, commands){ | |
var Node = React.createClass({ | |
render: function() { | |
var fontAwesome; | |
if(this.props.commandType) { | |
var iClass = `fa fa-${this.props.commandType} fa-2x fa-fw` | |
fontAwesome = <i className={iClass}></i> | |
} else { | |
fontAwesome = '' | |
} | |
return ( | |
<div className="cd-timeline-block"> | |
<span className="cd-timeline-date">{moment(this.props.timestamp).format('h:mm a')}</span> | |
<div className="cd-timeline-img" id={this.props.id} style={this.props.style}> | |
{fontAwesome} | |
</div> | |
</div> | |
) | |
} | |
}); | |
var TimelineImage = React.createClass({ | |
render: function(){ | |
return ( | |
<div>Test</div> | |
) | |
} | |
}) | |
var StartNode = React.createClass({ | |
nodeStyle: { | |
background: 'green' | |
}, | |
render: function() { | |
return ( | |
<Node timestamp={this.props.timestamp} id="start-node" style={this.nodeStyle} /> | |
) | |
} | |
}); | |
var EndNode = React.createClass({ | |
nodeStyle: { | |
background: 'red' | |
}, | |
render: function(){ | |
return ( | |
<Node timestamp={this.props.timestamp} id="end-node" style={this.nodeStyle} /> | |
) | |
} | |
}); | |
var TimelineNode = React.createClass({ | |
componentWillMount: function(){ | |
var compare = function(a, b){ | |
if(a.timestamp < b.timestamp){ | |
return 1 | |
} else if(a.timestamp > b.timestamp) { | |
return -1 | |
} else { | |
return 0 | |
} | |
} | |
this.props.commands.sort(compare) | |
}, | |
render: function() { | |
var nodes = this.props.commands.map(function(node){ | |
var iClass = `fa fa-${node.commandType} fa-2x fa-fw`; | |
return ( | |
<Node timestamp={node.timestamp} key={node.timestamp} commandType={node.commandType} /> | |
) | |
}) | |
return ( | |
<div> | |
{nodes} | |
</div> | |
) | |
} | |
}); | |
ReactDOM.render( | |
<div> | |
<EndNode timestamp={session.startTime} /> | |
<TimelineNode commands={commands} /> | |
<StartNode timestamp={session.endTime} /> | |
</div>, | |
document.getElementById('cd-timeline') | |
); | |
}; | |
var session = { | |
startTime:123456789, | |
endTime:133456999 | |
}; | |
var commands = [ | |
{ | |
timestamp:143456889, | |
commandName:'Chat', | |
commandType:'cutlery' | |
}, | |
{ | |
timestamp:123456799, | |
commandName:'Lock', | |
commandType:'lock' | |
}, | |
{ | |
timestamp:153456810, | |
commandName:'Chat', | |
commandType:'bluetooth' | |
} | |
]; | |
window.layoutCommands(session, commands) | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment