mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-31 03:18:43 -06:00
Merge pull request #590 from rafael-atticlabs/pitchmapJS2
Update pitchmap to js2
This commit is contained in:
@@ -16,6 +16,12 @@ before_script:
|
||||
- npm run build
|
||||
- npm test
|
||||
- popd
|
||||
- pushd clients/pitchmap/ui
|
||||
- npm install
|
||||
- ./link.sh
|
||||
- npm run build
|
||||
- npm test
|
||||
- popd
|
||||
script:
|
||||
- export GODEBUG=invalidptr=0
|
||||
- go test ./...
|
||||
|
||||
BIN
clients/pitchmap/index/index
Executable file
BIN
clients/pitchmap/index/index
Executable file
Binary file not shown.
11
clients/pitchmap/ui/.babelrc
Normal file
11
clients/pitchmap/ui/.babelrc
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"optional": ["asyncToGenerator"],
|
||||
"blacklist": [
|
||||
"es6.blockScoping",
|
||||
"es6.constants",
|
||||
"es6.forOf",
|
||||
"es6.properties.computed",
|
||||
"es6.properties.shorthand",
|
||||
"es6.templateLiterals"
|
||||
]
|
||||
}
|
||||
35
clients/pitchmap/ui/.eslintrc
Normal file
35
clients/pitchmap/ui/.eslintrc
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"parser": "babel-eslint",
|
||||
"rules": {
|
||||
"array-bracket-spacing": [2, "never"],
|
||||
"camelcase": 2,
|
||||
"eqeqeq": 2,
|
||||
"indent": [2, 2, {"SwitchCase": 1}],
|
||||
"linebreak-style": [2, "unix"],
|
||||
"no-multi-spaces": 2,
|
||||
"no-new-wrappers": 2,
|
||||
"no-throw-literal": 2,
|
||||
"no-var": 2,
|
||||
"object-curly-spacing": [2, "never"],
|
||||
"quotes": [2, "single"],
|
||||
"radix": 2,
|
||||
"semi": 2,
|
||||
"space-after-keywords": 2,
|
||||
"space-before-function-paren": [2, "never"],
|
||||
"space-infix-ops": 2,
|
||||
"space-in-parens": [2, "never"]
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"browser": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true,
|
||||
"experimentalObjectRestSpread": true
|
||||
},
|
||||
"plugins": [
|
||||
"react"
|
||||
]
|
||||
}
|
||||
11
clients/pitchmap/ui/.flowconfig
Normal file
11
clients/pitchmap/ui/.flowconfig
Normal file
@@ -0,0 +1,11 @@
|
||||
[ignore]
|
||||
.*/node_modules/react/.*
|
||||
.*/node_modules/fbjs/flow/.*
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
|
||||
[options]
|
||||
unsafe.enable_getters_and_setters=true
|
||||
munge_underscores=true
|
||||
117
clients/pitchmap/ui/heat_map.js
Normal file
117
clients/pitchmap/ui/heat_map.js
Normal file
@@ -0,0 +1,117 @@
|
||||
/* @flow */
|
||||
|
||||
'use strict';
|
||||
|
||||
import React from 'react'; //eslint-disable-line no-unused-lets
|
||||
import {readValue, HttpStore, Ref, Struct} from 'noms';
|
||||
|
||||
const IMAGE_WIDTH_PX = 286;
|
||||
const IMAGE_HEIGHT_PX = 324;
|
||||
const BASE_PX = 72;
|
||||
const BASE_FEET = 1 + 5 / 12;
|
||||
|
||||
const ORIGIN_X_PIXELS = IMAGE_WIDTH_PX / 2;
|
||||
const ORIGIN_Z_PIXELS = IMAGE_HEIGHT_PX - 41;
|
||||
|
||||
function feetToPixels(f: number): number {
|
||||
// TODO: Find more accurate image/dimensions.
|
||||
return 0.8 * f * BASE_PX / BASE_FEET;
|
||||
}
|
||||
|
||||
type Props = {
|
||||
pitchListRef: Ref,
|
||||
httpStore: HttpStore
|
||||
};
|
||||
|
||||
type State = {
|
||||
loaded: boolean,
|
||||
pitchList: ?Array<Struct>
|
||||
};
|
||||
|
||||
export default class HeatMap extends React.Component {
|
||||
static defaultProps: {};
|
||||
props: Props;
|
||||
state: State;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
loaded: false,
|
||||
pitchList: null
|
||||
};
|
||||
}
|
||||
|
||||
setState(state: State) {
|
||||
super.setState(state);
|
||||
}
|
||||
|
||||
async loadIfNeeded(): Promise<void> {
|
||||
if (this.state.loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
let pitchList = await readValue(this.props.pitchListRef, this.props.httpStore);
|
||||
if (Array.isArray(pitchList)) {
|
||||
this.setState({
|
||||
loaded: true,
|
||||
pitchList: pitchList
|
||||
});
|
||||
} else {
|
||||
throw new Error('Unexpected type of pitchList');
|
||||
}
|
||||
}
|
||||
|
||||
render(): React.Element {
|
||||
this.loadIfNeeded();
|
||||
|
||||
let points = this.getPoints();
|
||||
let fillStyle = {
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: 0
|
||||
};
|
||||
return <div style={ {
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
width: IMAGE_WIDTH_PX,
|
||||
height: IMAGE_HEIGHT_PX
|
||||
} }>
|
||||
<img src="background.jpg" style={fillStyle}/>
|
||||
<div style={fillStyle}>
|
||||
{points}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
getPoints(): Array<any> {
|
||||
if (!this.state.loaded) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!this.state.pitchList) {
|
||||
throw new Error('pitchList not loaded');
|
||||
}
|
||||
|
||||
return this.state.pitchList.map(p => {
|
||||
let w = 2;
|
||||
let h = 2;
|
||||
let x = - w / 2 + ORIGIN_X_PIXELS + feetToPixels(p.get('X'));
|
||||
let y = - h / 2 + ORIGIN_Z_PIXELS - feetToPixels(p.get('Z'));
|
||||
return <div style={
|
||||
{
|
||||
position: 'absolute',
|
||||
left: x,
|
||||
top: y,
|
||||
background: 'rgba(0,255,0,0.4)',
|
||||
width: w,
|
||||
height: h,
|
||||
boxShadow: '0px 0px 16px 16px rgba(0,255,0,0.4)',
|
||||
borderRadius: '50%'
|
||||
}
|
||||
}/>;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pushd ../../../js
|
||||
pushd ../../../js2
|
||||
npm install
|
||||
npm run build
|
||||
./link.sh
|
||||
popd
|
||||
|
||||
@@ -1,54 +1,81 @@
|
||||
/* @flow */
|
||||
|
||||
'use strict';
|
||||
|
||||
var noms = require('noms');
|
||||
var React = require('react');
|
||||
var Map = require('./map.js');
|
||||
import HeatMap from './heat_map.js';
|
||||
import React from 'react'; //eslint-disable-line no-unused-lets
|
||||
import ReactDOM from 'react-dom';
|
||||
import {readValue, HttpStore, Ref} from 'noms';
|
||||
|
||||
noms.getRoot()
|
||||
.then(ref => {
|
||||
var pRoot = noms.readValue(ref, noms.getChunk);
|
||||
return noms.getDataset(pRoot, 'mlb/heatmap');
|
||||
})
|
||||
.then(getPitchers)
|
||||
.then(renderPitchersList);
|
||||
let httpStore: HttpStore;
|
||||
let renderNode: ?HTMLElement;
|
||||
|
||||
function getPitchers(datasetRootRef) {
|
||||
return datasetRootRef.deref()
|
||||
.then(datasetRoot => datasetRoot.get('value').deref());
|
||||
}
|
||||
window.addEventListener('load', async () => {
|
||||
renderNode = document.getElementById('heatmap');
|
||||
httpStore = new HttpStore('http://localhost:8000');
|
||||
let rootRef = await httpStore.getRoot();
|
||||
let datasets = await readValue(rootRef, httpStore);
|
||||
let commitRef = datasets.get('mlb/heatmap');
|
||||
let commit = await readValue(commitRef, httpStore);
|
||||
let pitchersMap = commit.get('value');
|
||||
renderPitchersMap(pitchersMap);
|
||||
});
|
||||
|
||||
var PitcherList = React.createClass({
|
||||
getInitialState() {
|
||||
var pitchers = this.props.data.map((v, key) => key).toArray();
|
||||
type Props = {
|
||||
pitchersMap: Map<string, Ref>
|
||||
};
|
||||
|
||||
type State = {
|
||||
currentPitcher: string,
|
||||
pitchers: Array<string>
|
||||
};
|
||||
|
||||
class PitcherList extends React.Component {
|
||||
static defaultProps: {};
|
||||
props: Props;
|
||||
state: State;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
let pitchers = [];
|
||||
this.props.pitchersMap.forEach((ref, pitcher) => {
|
||||
pitchers.push(pitcher);
|
||||
});
|
||||
pitchers.sort();
|
||||
|
||||
return {
|
||||
this.state = {
|
||||
currentPitcher: pitchers[0],
|
||||
pitchers: pitchers
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
onChangePitcher(e) {
|
||||
this.setState({ currentPitcher: e.target.value });
|
||||
},
|
||||
setState(state: State) {
|
||||
super.setState(state);
|
||||
}
|
||||
|
||||
render() {
|
||||
var currentPitcher = this.state.currentPitcher;
|
||||
var locations = this.props.data.get(currentPitcher);
|
||||
let currentPitcher = this.state.currentPitcher;
|
||||
let pitchListRef = this.props.pitchersMap.get(currentPitcher);
|
||||
|
||||
let onChangePitcher = e => {
|
||||
this.setState({
|
||||
currentPitcher: e.target.value,
|
||||
pitchers: this.state.pitchers
|
||||
});
|
||||
};
|
||||
|
||||
return <div>
|
||||
<select onChange={this.onChangePitcher} defaultValue={currentPitcher}>{
|
||||
this.state.pitchers.map((pitcher) => {
|
||||
var isCurrent = currentPitcher === pitcher;
|
||||
return <option key={pitcher} value={pitcher}>{pitcher}</option>
|
||||
<select onChange={onChangePitcher} defaultValue={currentPitcher}>{
|
||||
this.state.pitchers.map(pitcher => {
|
||||
return <option key={pitcher} value={pitcher}>{pitcher}</option>;
|
||||
})
|
||||
}</select>
|
||||
<Map key={currentPitcher} points={locations}/>
|
||||
</div>
|
||||
<HeatMap key={currentPitcher} pitchListRef={pitchListRef} httpStore={httpStore}/>
|
||||
</div>;
|
||||
}
|
||||
});
|
||||
|
||||
function renderPitchersList(list) {
|
||||
var target = document.getElementById('heatmap');
|
||||
React.render(<PitcherList data={list}/>, target);
|
||||
}
|
||||
|
||||
function renderPitchersMap(map: Map) {
|
||||
ReactDOM.render(<PitcherList pitchersMap={map}/>, renderNode);
|
||||
}
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
||||
const IMAGE_WIDTH_PX = 286;
|
||||
const IMAGE_HEIGHT_PX = 324;
|
||||
const BASE_PX = 72;
|
||||
const BASE_FEET = 1 + 5 / 12;
|
||||
const FEETS_TO_PIXELS = BASE_PX / BASE_FEET;
|
||||
|
||||
const ORIGIN_X_PIXELS = IMAGE_WIDTH_PX / 2;
|
||||
const ORIGIN_Z_PIXELS = IMAGE_HEIGHT_PX - 41;
|
||||
|
||||
function feetToPixels(f) {
|
||||
// TODO: Find more accurate image/dimensions.
|
||||
return 0.8 * f * BASE_PX / BASE_FEET;
|
||||
}
|
||||
|
||||
var Map = React.createClass({
|
||||
propTypes: {
|
||||
points: React.PropTypes.object.isRequired,
|
||||
},
|
||||
|
||||
loadIfNeeded() {
|
||||
if (this.state.loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.points.deref().then((list) => {
|
||||
return Promise.all(list.map(p => p.deref()))
|
||||
}).then((points) => {
|
||||
this.setState({
|
||||
points: points,
|
||||
loaded: true
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
loaded: false,
|
||||
points: null
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
this.loadIfNeeded();
|
||||
var points = this.getPoints();
|
||||
var fillStyle = {
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: 0,
|
||||
};
|
||||
return <div style={ {
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
width: IMAGE_WIDTH_PX,
|
||||
height: IMAGE_HEIGHT_PX,
|
||||
} }>
|
||||
<img src="background.jpg" style={fillStyle}/>
|
||||
<div style={fillStyle}>
|
||||
{points}
|
||||
</div>
|
||||
</div>;
|
||||
},
|
||||
|
||||
getPoints: function() {
|
||||
if (!this.state.loaded) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.state.points.map((p) => {
|
||||
var w = 2;
|
||||
var h = 2;
|
||||
var x = - w / 2 + ORIGIN_X_PIXELS + feetToPixels(p.get('X'));
|
||||
var y = - h / 2 + ORIGIN_Z_PIXELS - feetToPixels(p.get('Z'));
|
||||
return <div style={ {
|
||||
position: 'absolute',
|
||||
left: x,
|
||||
top: y,
|
||||
background: 'rgba(0,255,0,0.4)',
|
||||
width: w,
|
||||
height: h,
|
||||
boxShadow: '0px 0px 16px 16px rgba(0,255,0,0.4)',
|
||||
borderRadius: '50%',
|
||||
} }/>;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = Map;
|
||||
@@ -1,17 +1,22 @@
|
||||
{
|
||||
"name": "noms-pitchmap-ui",
|
||||
"dependencies": {
|
||||
"react": "^0.12.0",
|
||||
"immutable": "^3.7.4"
|
||||
"react": "^0.14.1",
|
||||
"react-dom": "^0.14.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel": "^5.6.23",
|
||||
"babel-eslint": "^4.1.3",
|
||||
"babelify": "^6.1.3",
|
||||
"browserify": "^6.2.0",
|
||||
"uglify-js": "~2.4.15",
|
||||
"watchify": "^2.1.1"
|
||||
"browserify": "^12.0.1",
|
||||
"eslint": "^1.7.3",
|
||||
"eslint-plugin-react": "^3.6.3",
|
||||
"flow-bin": "^0.18.1",
|
||||
"watchify": "^3.6"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "watchify -o out.js -t babelify -v -d main.js",
|
||||
"build": "NODE_ENV=production browserify main.js -t babelify | uglifyjs -cm > out.js"
|
||||
"build": "NODE_ENV=production browserify main.js -t babelify > out.js",
|
||||
"test": "rm -f out.js && eslint *.js && flow"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user