-
-
Save curran/7c0e42a45ba1a62479a4 to your computer and use it in GitHub Desktop.
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
node_modules |
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> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>Intro to Data Vis with D3</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.13/d3.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"></script> | |
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css"> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" type="text/css"> | |
<link href="styles.css" rel="stylesheet" type="text/css"> | |
</head> | |
<body> | |
<div id="app-container"></div> | |
<script src="main-build.js"></script> | |
</body> | |
</html> |
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
[ | |
{ "title": "Bar Chart Populations", "id": "6cd1e224d76811b68df4" }, | |
{ "title": "Bar Chart Religions", "id": "123f860373b442c7de0e" }, | |
{ "title": "Horizontal Bar Chart", "id": "4df29e2f8c6e20ed2baf" }, | |
{ "title": "Colored Bar Chart", "id": "fea34ca9b3b8886e3ab8" }, | |
{ "title": "Grouped Bar Chart", "id": "d4e2b2854f25429a06aa" }, | |
{ "title": "Bar", "id": "a364f9c0b9a114c90efa" }, | |
{ "title": "Stacked Bar", "id": "ab098389dd80e4a6eb58" }, | |
{ "title": "Stacked Bar Chart", "id": "805413fb3b2efaada1ce" }, | |
{ "title": "Scatter Plot", "id": "134ed87c99257e3f2e31" }, | |
{ "title": "Line Chart", "id": "60b40877ef898f19aeb8" } | |
] |
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
var NavItem = React.createClass({ | |
displayName: "NavItem", | |
click: function (e) { | |
this.props.controller.setCurrentIndex(this.props.item.index); | |
}, | |
render: function () { | |
var item = this.props.item; | |
var blocksUrl = "http://bl.ocks.org/curran/" + item.id; | |
var thumbnailUrl = "http://bl.ocks.org/curran/raw/" + item.id + "/thumbnail.png"; | |
var imgClass = "nav-item-thumbnail" + (this.props.active ? " active" : ""); | |
return React.createElement( | |
"div", | |
{ className: "nav-item", onClick: this.click }, | |
React.createElement( | |
"span", | |
{ className: "nav-item-title" }, | |
item.title | |
), | |
React.createElement("img", { className: imgClass, src: thumbnailUrl }) | |
); | |
} | |
}); | |
var NavList = React.createClass({ | |
displayName: "NavList", | |
render: function () { | |
return React.createElement( | |
"div", | |
{ className: "nav" }, | |
this.props.items.map(item => { | |
return React.createElement(NavItem, { item: item, | |
key: item.index, | |
active: item.index === this.props.currentIndex, | |
controller: this.props.controller }); | |
}) | |
); | |
} | |
}); | |
var ContentPane = React.createClass({ | |
displayName: "ContentPane", | |
render: function () { | |
var blockbuilderUrl = "http://blockbuilder.org/curran/" + this.props.item.id; | |
return React.createElement("iframe", { className: "content", src: blockbuilderUrl }); | |
} | |
}); | |
var App = React.createClass({ | |
displayName: "App", | |
getInitialState() { | |
return { | |
items: [], | |
item: {}, | |
currentIndex: 0 | |
}; | |
}, | |
render() { | |
return React.createElement( | |
"div", | |
{ className: "app" }, | |
React.createElement(NavList, { items: this.state.items, | |
currentIndex: this.state.currentIndex, | |
controller: this.props.controller }), | |
React.createElement(ContentPane, { item: this.state.item }) | |
); | |
} | |
}); | |
var mountNode = document.getElementById("app-container"); | |
var controller = {}; | |
var app = ReactDOM.render(React.createElement(App, { controller: controller }), mountNode); | |
controller.setItems = items => { | |
app.setState(() => { | |
return { items: items }; | |
}); | |
controller.setCurrentIndex(0); | |
}; | |
controller.setCurrentIndex = currentIndex => { | |
app.setState(previousState => { | |
return { | |
currentIndex: currentIndex, | |
item: previousState.items[currentIndex] | |
}; | |
}); | |
}; | |
// Increment (offset == 1) or decrement (offset == -1) the current index. | |
controller.incrementCurrentIndex = offset => { | |
app.setState(previousState => { | |
var currentIndex = previousState.currentIndex + offset; | |
// Guard against going out of bounds. | |
var n = previousState.items.length; | |
currentIndex = currentIndex < 0 ? 0 : currentIndex; | |
currentIndex = currentIndex >= n ? n - 1 : currentIndex; | |
return { | |
currentIndex: currentIndex, | |
item: previousState.items[currentIndex] | |
}; | |
}); | |
}; | |
// Load the file that configures the items and their order. | |
d3.json("items.json", (err, items) => { | |
// Assign an index to each item. | |
items.forEach((item, i) => item.index = i); | |
// Set the state from the loaded data. | |
controller.setItems(items); | |
}); | |
// Set up navigation with arrow keys. | |
window.addEventListener("keydown", function (e) { | |
var offsets = { | |
// Decrement slide on UP (38) and LEFT (37) | |
37: -1, | |
38: -1, | |
// Increment slide on DOWN (40) and RIGHT (39); | |
39: 1, | |
40: 1 | |
}; | |
controller.incrementCurrentIndex(offsets[e.keyCode]); | |
}); |
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
var NavItem = React.createClass({ | |
click: function (e){ | |
this.props.controller.setCurrentIndex(this.props.item.index); | |
}, | |
render: function (){ | |
var item = this.props.item; | |
var blocksUrl = "http://bl.ocks.org/curran/" + item.id; | |
var thumbnailUrl = "http://bl.ocks.org/curran/raw/" + item.id + "/thumbnail.png"; | |
var imgClass = "nav-item-thumbnail" + (this.props.active ? " active" : ""); | |
return ( | |
<div className="nav-item" onClick={this.click} > | |
<span className="nav-item-title">{item.title}</span> | |
<img className={imgClass} src={thumbnailUrl}/> | |
</div> | |
) | |
} | |
}); | |
var NavList = React.createClass({ | |
render: function (){ | |
return ( | |
<div className="nav"> | |
{this.props.items.map((item) => { | |
return <NavItem item={item} | |
key={item.index} | |
active={item.index === this.props.currentIndex} | |
controller={this.props.controller}/> | |
})} | |
</div> | |
); | |
} | |
}); | |
var ContentPane = React.createClass({ | |
render: function (){ | |
var blockbuilderUrl = "http://blockbuilder.org/curran/" + this.props.item.id; | |
return <iframe className="content" src={blockbuilderUrl} />; | |
} | |
}); | |
var App = React.createClass({ | |
getInitialState() { | |
return { | |
items: [], | |
item: {}, | |
currentIndex: 0 | |
}; | |
}, | |
render() { | |
return ( | |
<div className="app"> | |
<NavList items={this.state.items} | |
currentIndex={this.state.currentIndex} | |
controller={this.props.controller}/> | |
<ContentPane item={this.state.item} /> | |
</div> | |
); | |
} | |
}); | |
var mountNode = document.getElementById("app-container"); | |
var controller = {}; | |
var app = ReactDOM.render(<App controller={controller}/>, mountNode); | |
controller.setItems = (items) => { | |
app.setState(() => { | |
return { items: items }; | |
}); | |
controller.setCurrentIndex(0); | |
} | |
controller.setCurrentIndex = (currentIndex) => { | |
app.setState((previousState) => { | |
return { | |
currentIndex: currentIndex, | |
item: previousState.items[currentIndex] | |
}; | |
}); | |
} | |
// Increment (offset == 1) or decrement (offset == -1) the current index. | |
controller.incrementCurrentIndex = (offset) => { | |
app.setState((previousState) => { | |
var currentIndex = previousState.currentIndex + offset; | |
// Guard against going out of bounds. | |
var n = previousState.items.length; | |
currentIndex = (currentIndex < 0) ? 0 : currentIndex; | |
currentIndex = (currentIndex >= n) ? (n - 1) : currentIndex; | |
return { | |
currentIndex: currentIndex, | |
item: previousState.items[currentIndex] | |
}; | |
}); | |
} | |
// Load the file that configures the items and their order. | |
d3.json("items.json", (err, items) => { | |
// Assign an index to each item. | |
items.forEach((item, i) => item.index = i); | |
// Set the state from the loaded data. | |
controller.setItems(items); | |
}); | |
// Set up navigation with arrow keys. | |
window.addEventListener("keydown", function (e){ | |
var offsets = { | |
// Decrement slide on UP (38) and LEFT (37) | |
37: -1, | |
38: -1, | |
// Increment slide on DOWN (40) and RIGHT (39); | |
39: 1, | |
40: 1 | |
}; | |
controller.incrementCurrentIndex(offsets[e.keyCode]); | |
}); |
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
{ | |
"name": "intro-data-vis-d3", | |
"version": "0.0.1", | |
"description": "A React app that displays a presentation.", | |
"main": "index.js", | |
"scripts": { | |
"build": "babel main.js --presets react --out-file=main-build.js" | |
}, | |
"author": "", | |
"license": "ISC", | |
"devDependencies": { | |
"babel-cli": "^6.4.5", | |
"babel-preset-react": "^6.3.13" | |
} | |
} |
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
/* http://www.paulirish.com/2012/box-sizing-border-box-ftw/ */ | |
html { | |
box-sizing: border-box; | |
height: 100%; | |
} | |
*, *:before, *:after { | |
box-sizing: inherit; | |
} | |
body { | |
font-family: "Open Sans", sans-serif; | |
height: 100%; | |
} | |
#app-container { | |
height: 100%; | |
} | |
.app { | |
height: 100%; | |
display: flex; | |
flex-direction: row; | |
} | |
.nav { | |
/* Original bl.ocks.org thumbnails are (230 X 120). */ | |
width: 200px; | |
background-color: rgb(247, 247, 247); | |
overflow-y: scroll; | |
} | |
.nav-item { | |
position: relative; | |
cursor: pointer; | |
margin: 8px; | |
} | |
.nav-item-title { | |
pointer-events:none; | |
position: absolute; | |
top: 2px; | |
/* Center the text inside the box. */ | |
width: 100%; | |
text-align: center; | |
/* This trick adds a heavy white shadow around the text. */ | |
text-shadow: | |
0px 0px 2px white, | |
0px 0px 2px white, | |
0px 0px 2px white, | |
0px 0px 2px white, | |
0px 0px 3px white, | |
0px 0px 3px white, | |
0px 0px 3px white, | |
0px 0px 3px white; | |
} | |
.nav-item-thumbnail { | |
transition: box-shadow 0.3s, border-color 0.3s; | |
width: 100%; | |
border-radius: 5px; | |
border-style: solid; | |
border-color: white; | |
border-width: 1px; | |
box-shadow: 0px 0px 5px #888888; | |
} | |
.nav-item-thumbnail:hover { | |
box-shadow: 1px 1px 5px #888888; | |
} | |
.nav-item-thumbnail.active { | |
border-color: gray; | |
box-shadow: 1px 1px 6px #888888; | |
} | |
.content { | |
width: 100%; | |
height: 100%; | |
} | |
/* Custom scrollbars. Draws from https://css-tricks.com/custom-scrollbars-in-webkit/ */ | |
::-webkit-scrollbar { | |
width: 8px; | |
} | |
::-webkit-scrollbar-track { | |
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); | |
} | |
::-webkit-scrollbar-thumb { | |
border-radius: 5px; | |
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment