diff --git a/spikes/architecture/d3-revamp/README.md b/spikes/architecture/d3-revamp/README.md new file mode 100644 index 00000000..3818a1a0 --- /dev/null +++ b/spikes/architecture/d3-revamp/README.md @@ -0,0 +1,4 @@ +# Example + +![screenshot from 2016-12-06 17-03-28](https://cloud.githubusercontent.com/assets/524382/20936109/4508ebda-bbd9-11e6-9561-baa1f7fcc80c.png) + diff --git a/spikes/architecture/d3-revamp/index.html b/spikes/architecture/d3-revamp/index.html new file mode 100644 index 00000000..742535ea --- /dev/null +++ b/spikes/architecture/d3-revamp/index.html @@ -0,0 +1,448 @@ + + + + + + diff --git a/spikes/architecture/d3-revamp/services.json b/spikes/architecture/d3-revamp/services.json new file mode 100644 index 00000000..cc8be654 --- /dev/null +++ b/spikes/architecture/d3-revamp/services.json @@ -0,0 +1,15 @@ +{ + "nodes": [ + {"id": "Nginx", "group": 1}, + {"id": "Wordpress", "group": 1}, + {"id": "Memcached", "group": 1}, + {"id": "Percona", "group": 1}, + {"id": "NFS", "group": 1} + ], + "links": [ + {"source": "Nginx", "target": "Wordpress", "value": 1}, + {"source": "Wordpress", "target": "Memcached", "value": 8}, + {"source": "Wordpress", "target": "NFS", "value": 8}, + {"source": "Wordpress", "target": "Percona", "value": 8} + ] +} diff --git a/spikes/architecture/react-d3/.babelrc b/spikes/architecture/react-d3/.babelrc new file mode 100644 index 00000000..82cc857a --- /dev/null +++ b/spikes/architecture/react-d3/.babelrc @@ -0,0 +1,15 @@ +{ + "presets": [ + "react", + "es2015" + ], + "plugins": [ + ["transform-object-rest-spread", { + "useBuiltIns": true + }], + "add-module-exports", + "transform-es2015-modules-commonjs", + "react-hot-loader/babel" + ], + "sourceMaps": "both" +} diff --git a/spikes/architecture/react-d3/.eslintignore b/spikes/architecture/react-d3/.eslintignore new file mode 100644 index 00000000..683e721c --- /dev/null +++ b/spikes/architecture/react-d3/.eslintignore @@ -0,0 +1,3 @@ +/node_modules +coverage +.nyc_output diff --git a/spikes/architecture/react-d3/.eslintrc b/spikes/architecture/react-d3/.eslintrc new file mode 100644 index 00000000..a1e892dc --- /dev/null +++ b/spikes/architecture/react-d3/.eslintrc @@ -0,0 +1,30 @@ +{ + "extends": "semistandard", + "parser": "babel-eslint", + "parserOptions": { + "ecmaVersion": 7, + "ecmaFeatures": { + "jsx": true + }, + "sourceType": "module" + }, + "plugins": [ + "babel", + "react" + ], + "rules": { + "generator-star-spacing": 0, + "babel/generator-star-spacing": 1, + "space-before-function-paren": [2, "never"], + "react/jsx-uses-react": 2, + "react/jsx-uses-vars": 2, + "react/react-in-jsx-scope": 2, + "object-curly-newline": ["error", { + "minProperties": 1 + }], + "sort-vars": ["error", { + "ignoreCase": true + }], + "operator-linebreak": 0 + } +} diff --git a/spikes/architecture/react-d3/.gitignore b/spikes/architecture/react-d3/.gitignore new file mode 100644 index 00000000..c21b0ba0 --- /dev/null +++ b/spikes/architecture/react-d3/.gitignore @@ -0,0 +1,4 @@ +/node_modules +coverage +.nyc_output +npm-debug.log diff --git a/spikes/architecture/react-d3/client/graph.js b/spikes/architecture/react-d3/client/graph.js new file mode 100644 index 00000000..ec911f23 --- /dev/null +++ b/spikes/architecture/react-d3/client/graph.js @@ -0,0 +1,26 @@ +const ReactRedux = require('react-redux'); +const React = require('react'); +const Links = require('./links'); +const Nodes = require('./nodes'); + +const { + connect +} = ReactRedux; + +const Component = (props) => + + + + ; + +const mapStateToProps = ({ + data +}) => { + return { + data + }; +}; + +module.exports = connect( + mapStateToProps +)(Component); diff --git a/spikes/architecture/react-d3/client/index.js b/spikes/architecture/react-d3/client/index.js new file mode 100644 index 00000000..317b0fd5 --- /dev/null +++ b/spikes/architecture/react-d3/client/index.js @@ -0,0 +1,18 @@ +const ReactDOM = require('react-dom'); +const React = require('react'); +const store = require('./store')(); + +const render = () => { + const Root = require('./root'); + + ReactDOM.render( + , + document.getElementById('root') + ); +}; + +render(); + +if (module.hot) { + module.hot.accept('./root', render); +} diff --git a/spikes/architecture/react-d3/client/links.js b/spikes/architecture/react-d3/client/links.js new file mode 100644 index 00000000..c629c3ab --- /dev/null +++ b/spikes/architecture/react-d3/client/links.js @@ -0,0 +1,10 @@ +const React = require('react'); + +const renderLines = (props) => { + return () => ; +}; + +module.exports = (props) => + + { props.data.links.map(renderLines()) } + ; diff --git a/spikes/architecture/react-d3/client/nodes.js b/spikes/architecture/react-d3/client/nodes.js new file mode 100644 index 00000000..1260025c --- /dev/null +++ b/spikes/architecture/react-d3/client/nodes.js @@ -0,0 +1,75 @@ +const React = require('react'); + +function rightRoundedRect(x, y, width, height, radius) { + return 'M' + x + ',' + y // Move to (absolute) + + 'h ' + (width - radius) // Horizontal line to (relative) + + 'a ' + radius + ',' + radius + ' 0 0 1 ' + radius + ',' + radius // Relative arc + + 'v ' + (height - 2 * radius) // Vertical line to (relative) + + 'a ' + radius + ',' + radius + ' 0 0 1 ' + -radius + ',' + radius // Relative arch + + 'h ' + (radius - width) // Horizontal lint to (relative) + + 'z '; // path back to start +} + +function leftRoundedRect(x, y, width, height, radius) { + return 'M' + (x + width) + ',' + y // Move to (absolute) start at top-right + + 'v ' + height // Vertical line to (relative) + + 'h ' + (radius - width) // Horizontal line to (relative) + + 'a ' + radius + ',' + radius + ' 0 0 1 ' + -radius + ',' + -radius // Relative arc + + 'v ' + -(height - 2 * radius) // Vertical line to (relative) + + 'a ' + radius + ',' + radius + ' 0 0 1 ' + radius + ',' + -radius // Relative arch + + 'z '; // path back to start +} + +const InfoBoxContainer = () => + + + + ; + +const InfoBoxAlert = () => + + + {'!'} + ; + +const InfoBoxText = (props) => + {props.id}; + +module.exports = (props) => ( + + { props.data.nodes.map(node => + + + + + + ) + } + +); diff --git a/spikes/architecture/react-d3/client/root.js b/spikes/architecture/react-d3/client/root.js new file mode 100644 index 00000000..2af05235 --- /dev/null +++ b/spikes/architecture/react-d3/client/root.js @@ -0,0 +1,21 @@ +const React = require('react'); +const ReactHotLoader = require('react-hot-loader'); +const ReactRedux = require('react-redux'); +const Graph = require('./graph'); + +const { + AppContainer +} = ReactHotLoader; + +const { + Provider +} = ReactRedux; + +module.exports = ({ + store +}) => + + + + + ; diff --git a/spikes/architecture/react-d3/client/services.json b/spikes/architecture/react-d3/client/services.json new file mode 100644 index 00000000..cc8be654 --- /dev/null +++ b/spikes/architecture/react-d3/client/services.json @@ -0,0 +1,15 @@ +{ + "nodes": [ + {"id": "Nginx", "group": 1}, + {"id": "Wordpress", "group": 1}, + {"id": "Memcached", "group": 1}, + {"id": "Percona", "group": 1}, + {"id": "NFS", "group": 1} + ], + "links": [ + {"source": "Nginx", "target": "Wordpress", "value": 1}, + {"source": "Wordpress", "target": "Memcached", "value": 8}, + {"source": "Wordpress", "target": "NFS", "value": 8}, + {"source": "Wordpress", "target": "Percona", "value": 8} + ] +} diff --git a/spikes/architecture/react-d3/client/store.js b/spikes/architecture/react-d3/client/store.js new file mode 100644 index 00000000..8e5612d5 --- /dev/null +++ b/spikes/architecture/react-d3/client/store.js @@ -0,0 +1,17 @@ +const redux = require('redux'); +const services = require('./services'); + +const { + createStore +} = redux; + +const reducer = (state, action) => { + return { + ...state, + data: services + }; +}; + +module.exports = (state = Object.freeze({})) => { + return createStore(reducer, state); +}; diff --git a/spikes/architecture/react-d3/package.json b/spikes/architecture/react-d3/package.json new file mode 100644 index 00000000..6e83ff22 --- /dev/null +++ b/spikes/architecture/react-d3/package.json @@ -0,0 +1,56 @@ +{ + "name": "chartjs-graphing-spike", + "private": true, + "license": "private", + "main": "server/index.js", + "dependencies": { + "autoprefixer": "^6.5.1", + "babel-eslint": "^7.0.0", + "babel-loader": "^6.2.5", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.16.0", + "babel-plugin-transform-object-rest-spread": "^6.16.0", + "babel-plugin-transform-runtime": "^6.15.0", + "babel-preset-es2015": "^6.16.0", + "babel-preset-react": "^6.16.0", + "babel-preset-react-hmre": "^1.1.1", + "babel-runtime": "^6.11.6", + "build-array": "^1.0.0", + "component-emitter": "^1.2.1", + "css-loader": "^0.25.0", + "hapi": "^15.2.0", + "hapi-webpack-dev-plugin": "^1.1.4", + "inert": "^4.0.2", + "lodash.takeright": "^4.1.1", + "nes": "^6.3.1", + "postcss-loader": "^1.0.0", + "postcss-modules-values": "^1.2.2", + "postcss-nested": "^1.0.0", + "react": "^15.3.2", + "react-dom": "^15.3.2", + "react-hot-loader": "^3.0.0-beta.6", + "react-redux": "^4.4.5", + "redux": "^3.6.0", + "require-dir": "^0.3.1", + "style-loader": "^0.13.1", + "webpack": "^1.13.2", + "webpack-dev-server": "^1.16.2" + }, + "devDependencies": { + "babel-register": "^6.16.3", + "eslint": "^3.8.1", + "eslint-config-semistandard": "^7.0.0", + "eslint-config-standard": "^6.2.0", + "eslint-plugin-babel": "^3.3.0", + "eslint-plugin-promise": "^3.3.0", + "eslint-plugin-react": "^6.4.1", + "eslint-plugin-standard": "^2.0.1", + "json-loader": "^0.5.4" + }, + "ava": { + "require": [ + "babel-register" + ], + "babel": "inherit" + } +} diff --git a/spikes/architecture/react-d3/readme.md b/spikes/architecture/react-d3/readme.md new file mode 100644 index 00000000..fe0718a4 --- /dev/null +++ b/spikes/architecture/react-d3/readme.md @@ -0,0 +1,9 @@ +# ChartJS + +![](http://g.recordit.co/N8vdP8DBk4.gif) + +## summary + + - [x] customisable via js + - [x] fast (handles 100ms updates well) + - [x] easy to update data diff --git a/spikes/architecture/react-d3/server/index.js b/spikes/architecture/react-d3/server/index.js new file mode 100644 index 00000000..b2a6a529 --- /dev/null +++ b/spikes/architecture/react-d3/server/index.js @@ -0,0 +1,29 @@ +const requireDir = require('require-dir'); +const plugins = require('./plugins'); +const routes = requireDir('./routes'); +const Hapi = require('hapi'); +const path = require('path'); +const fs = require('fs'); + +const server = new Hapi.Server(); + +server.connection({ + host: 'localhost', + port: 8000 +}); + +server.register(plugins, (err) => { + if (err) { + throw err; + } + + Object.keys(routes).forEach((name) => { + routes[name](server); + }); + + server.start((err) => { + server.connections.forEach((conn) => { + console.log(`started at: ${conn.info.uri}`); + }); + }); +}); diff --git a/spikes/architecture/react-d3/server/plugins.js b/spikes/architecture/react-d3/server/plugins.js new file mode 100644 index 00000000..84944329 --- /dev/null +++ b/spikes/architecture/react-d3/server/plugins.js @@ -0,0 +1,15 @@ +const webpack = require('webpack'); +const path = require('path'); + +const cfg = require('../webpack.config.js'); + +module.exports = [ + require('inert'), + require('nes'), { + register: require('hapi-webpack-dev-plugin'), + options: { + compiler: webpack(cfg), + devIndex: path.join(__dirname, '../static') + } + } +]; diff --git a/spikes/architecture/react-d3/server/routes/home.js b/spikes/architecture/react-d3/server/routes/home.js new file mode 100644 index 00000000..48ead969 --- /dev/null +++ b/spikes/architecture/react-d3/server/routes/home.js @@ -0,0 +1,11 @@ +const path = require('path'); + +module.exports = (server) => { + server.route({ + method: 'GET', + path: '/', + handler: (request, reply) => { + reply.file(path.join(__dirname, '../../static/index.html')); + } + }); +}; diff --git a/spikes/architecture/react-d3/server/routes/static.js b/spikes/architecture/react-d3/server/routes/static.js new file mode 100644 index 00000000..5a41f602 --- /dev/null +++ b/spikes/architecture/react-d3/server/routes/static.js @@ -0,0 +1,15 @@ +const path = require('path'); + +module.exports = (server) => { + // server.route({ + // method: 'GET', + // path: '/{param*}', + // handler: { + // directory: { + // path: path.join(__dirname, '../../static'), + // redirectToSlash: true, + // index: true + // } + // } + // }); +}; diff --git a/spikes/architecture/react-d3/server/routes/version.js b/spikes/architecture/react-d3/server/routes/version.js new file mode 100644 index 00000000..987747cb --- /dev/null +++ b/spikes/architecture/react-d3/server/routes/version.js @@ -0,0 +1,18 @@ +const Pkg = require('../../package.json'); + +const internals = { + response: { + version: Pkg.version + } +}; + +module.exports = (server) => { + server.route({ + method: 'GET', + path: '/ops/version', + config: { + description: 'Returns the version of the server', + handler: (request, reply) => reply(internals.response) + } + }); +}; diff --git a/spikes/architecture/react-d3/static/index.html b/spikes/architecture/react-d3/static/index.html new file mode 100644 index 00000000..422fc652 --- /dev/null +++ b/spikes/architecture/react-d3/static/index.html @@ -0,0 +1,11 @@ + + + + D3 React Boilerplate + + + +
+ + + diff --git a/spikes/architecture/react-d3/webpack.config.js b/spikes/architecture/react-d3/webpack.config.js new file mode 100644 index 00000000..7295526a --- /dev/null +++ b/spikes/architecture/react-d3/webpack.config.js @@ -0,0 +1,69 @@ +const webpack = require('webpack'); +const path = require('path'); + +const config = { + debug: true, + devtool: 'source-map', + context: path.join(__dirname, './client'), + app: path.join(__dirname, './client/index.js'), + entry: [ + 'webpack-dev-server/client?http://localhost:8080', + 'webpack/hot/only-dev-server', + 'react-hot-loader/patch', + './index.js' + ], + output: { + path: path.join(__dirname, './static'), + publicPath: '/static/', + filename: 'bundle.js' + }, + plugins: [ + new webpack.HotModuleReplacementPlugin(), + new webpack.NoErrorsPlugin() + ], + postcss: () => { + return [ + require('postcss-modules-values'), + require('postcss-nested'), + require('autoprefixer') + ]; + }, + module: { + loaders: [{ + test: /js?$/, + exclude: /node_modules/, + include: [ + path.join(__dirname, './client') + ], + loaders: ['babel'] + }, { + test: /\.json?$/, + exclude: /node_modules/, + include: [ + path.join(__dirname, './client') + ], + loaders: ['json'] + }, { + test: /\.css$/, + exclude: /node_modules/, + include: [ + path.join(__dirname, './client') + ], + loader: 'style-loader!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader' + }] + } +}; + +const devServer = { + hot: true, + compress: true, + lazy: false, + publicPath: config.output.publicPath, + historyApiFallback: { + index: './static/index.html' + } +}; + +module.exports = Object.assign({ + devServer +}, config);