forked from curran‘s block:
<!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>
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 + "#embed=true";
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]);
});