├── .babelrc ├── .editorconfig ├── .eslintrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── karma.conf.js ├── package.json ├── rollup.config.js ├── src ├── compat.js ├── empty.js └── index.js └── test └── index.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["es2015", { "loose": true }], 4 | "stage-0", 5 | "react" 6 | ], 7 | "plugins": [ 8 | "transform-node-env-inline", 9 | "transform-react-remove-prop-types", 10 | "transform-class-properties", 11 | "transform-decorators-legacy", 12 | "transform-object-assign", 13 | "lodash" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [{package.json,.*rc,*.yml}] 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "eslint:recommended", 4 | "plugins": [ 5 | "react" 6 | ], 7 | "env": { 8 | "browser": true, 9 | "mocha": true, 10 | "es6": true, 11 | "node": true 12 | }, 13 | "parserOptions": { 14 | "ecmaFeatures": { 15 | "modules": true, 16 | "jsx": true 17 | } 18 | }, 19 | "globals": { 20 | "sinon": true, 21 | "expect": true 22 | }, 23 | "rules": { 24 | "react/jsx-uses-react": 2, 25 | "react/jsx-uses-vars": 2, 26 | "no-unused-vars": [1, { "varsIgnorePattern": "^h$" }], 27 | "no-cond-assign": 1, 28 | "no-empty": 0, 29 | "no-console": 1, 30 | "semi": 2, 31 | "camelcase": 0, 32 | "comma-style": 2, 33 | "comma-dangle": [2, "never"], 34 | "indent": [2, "tab", {"SwitchCase": 1}], 35 | "no-mixed-spaces-and-tabs": [2, "smart-tabs"], 36 | "no-trailing-spaces": [2, { "skipBlankLines": true }], 37 | "max-nested-callbacks": [2, 5], 38 | "no-eval": 2, 39 | "no-implied-eval": 2, 40 | "no-new-func": 2, 41 | "guard-for-in": 2, 42 | "eqeqeq": 0, 43 | "no-else-return": 2, 44 | "no-redeclare": 2, 45 | "no-dupe-keys": 2, 46 | "radix": 2, 47 | "strict": [2, "never"], 48 | "no-shadow": 0, 49 | "callback-return": [1, ["callback", "cb", "next", "done"]], 50 | "no-delete-var": 2, 51 | "no-undef-init": 2, 52 | "no-shadow-restricted-names": 2, 53 | "handle-callback-err": 0, 54 | "no-lonely-if": 2, 55 | "keyword-spacing": 2, 56 | "constructor-super": 2, 57 | "no-this-before-super": 2, 58 | "no-dupe-class-members": 2, 59 | "no-const-assign": 2, 60 | "prefer-spread": 2, 61 | "no-useless-concat": 2, 62 | "no-var": 2, 63 | "object-shorthand": 2, 64 | "prefer-arrow-callback": 2 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | /node_modules 3 | /npm-debug.log 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | !/src 2 | !/dist 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 7 4 | - 6 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Jason Miller 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Precharts 2 | 3 | [![NPM](http://img.shields.io/npm/v/precharts.svg)](https://www.npmjs.com/package/precharts) 4 | [![travis-ci](https://travis-ci.org/developit/precharts.svg)](https://travis-ci.org/developit/precharts) 5 | 6 | Wraps [Recharts] up for [Preact], without using [preact-compat](https://github.com/developit/preact-compat). 7 | 8 | > Think of this as a version of `Precharts` that is pre-aliased to use preact in place of React. 9 | 10 | **See [Webpackbin Example](https://www.webpackbin.com/bins/-L29GdZCQlStSHEgya-c):** 11 | 12 | [![demo](https://i.gyazo.com/9760d4a6d122902dcbd4a5252e745b47.gif)](https://www.webpackbin.com/bins/-L29GdZCQlStSHEgya-c) 13 | 14 | 15 | --- 16 | 17 | 18 | ### Usage Example 19 | 20 | 21 | ```js 22 | import { h, render } from 'preact'; 23 | import { ComposedChart, Area, Line, XAxis, CartesianGrid, Tooltip } from 'precharts'; 24 | 25 | const DATA = [ 26 | { name: 'A', a: 4000, b: 2400 }, 27 | { name: 'B', a: 3000, b: 1398 }, 28 | { name: 'C', a: 2000, b: 9800 }, 29 | { name: 'D', a: 2780, b: 3908 }, 30 | { name: 'E', a: 1890, b: 4800 }, 31 | { name: 'F', a: 2390, b: 3800 }, 32 | { name: 'G', a: 3490, b: 4300 } 33 | ]; 34 | 35 | render(( 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ), document.body); 44 | ``` 45 | 46 | 47 | --- 48 | 49 | 50 | ### License 51 | 52 | [MIT] 53 | 54 | 55 | [recharts]: https://github.com/recharts/recharts 56 | [Preact]: https://github.com/developit/preact 57 | [MIT]: http://choosealicense.com/licenses/mit/ 58 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config) { 2 | config.set({ 3 | frameworks: ['mocha', 'chai-sinon'], 4 | reporters: ['mocha'], 5 | browsers: ['PhantomJS'], 6 | 7 | files: ['test/**/*.js'], 8 | 9 | preprocessors: { 10 | '{src,test}/**/*.js': ['webpack', 'sourcemap'] 11 | }, 12 | 13 | webpack: { 14 | module: { 15 | rules: [{ 16 | test: /\.jsx?$/, 17 | loader: 'babel-loader', 18 | exclude: /\b(node_modules|dist)\b/ 19 | }] 20 | }, 21 | resolve: { 22 | alias: { 23 | src: __dirname+'/src' 24 | } 25 | } 26 | }, 27 | 28 | mochaReporter: { 29 | showDiff: true 30 | }, 31 | 32 | webpackMiddleware: { 33 | noInfo: true 34 | } 35 | }); 36 | }; 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "precharts", 3 | "amdName": "precharts", 4 | "version": "1.4.0", 5 | "description": "Wraps Recharts up for Preact, without preact-compat", 6 | "main": "dist/precharts.js", 7 | "src:main": "src/index.js", 8 | "minified:main": "dist/precharts.min.js", 9 | "scripts": { 10 | "clean": "rimraf dist/", 11 | "build": "NODE_ENV=production npm-run-all clean transpile minify size", 12 | "transpile": "rollup -c rollup.config.js -m ${npm_package_main}.map -f umd -n $npm_package_amdName $npm_package_src_main -o $npm_package_main", 13 | "minify": "uglifyjs $npm_package_main --define NODE_ENV=production --pure-funcs classCallCheck Object.defineProperty Object.freeze invariant warning -c unsafe,collapse_vars,evaluate,screw_ie8,loops,keep_fargs=false,pure_getters,unused,dead_code -m -o $npm_package_minified_main -p relative --in-source-map ${npm_package_main}.map --source-map ${npm_package_minified_main}.map", 14 | "size": "size=$(gzip-size $npm_package_minified_main) && echo \"gzip size: $size / $(pretty-bytes $size)\"", 15 | "test": "NODE_ENV=development npm-run-all lint transpile test:karma", 16 | "lint": "eslint {src,test}", 17 | "test:karma": "karma start --single-run", 18 | "test:watch": "karma start", 19 | "prepublish": "npm-run-all build test", 20 | "release": "npm run build && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish" 21 | }, 22 | "keywords": [ 23 | "preact", 24 | "recharts", 25 | "precharts" 26 | ], 27 | "author": "Jason Miller ", 28 | "license": "MIT", 29 | "repository": { 30 | "type": "git", 31 | "url": "git+https://github.com/developit/precharts.git" 32 | }, 33 | "bugs": { 34 | "url": "https://github.com/developit/precharts/issues" 35 | }, 36 | "homepage": "https://github.com/developit/precharts", 37 | "peerDependencies": { 38 | "preact": ">=5" 39 | }, 40 | "devDependencies": { 41 | "babel-cli": "^6.24.1", 42 | "babel-core": "^6.24.1", 43 | "babel-eslint": "^7.2.3", 44 | "babel-loader": "^7.0.0", 45 | "babel-plugin-external-helpers": "^6.22.0", 46 | "babel-plugin-lodash": "^3.2.11", 47 | "babel-plugin-transform-class-properties": "^6.24.1", 48 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 49 | "babel-plugin-transform-es2015-classes": "^6.24.1", 50 | "babel-plugin-transform-node-env-inline": "^0.0.2", 51 | "babel-plugin-transform-object-assign": "^6.22.0", 52 | "babel-plugin-transform-react-jsx": "^6.24.1", 53 | "babel-plugin-transform-react-remove-prop-types": "^0.4.4", 54 | "babel-preset-es2015": "^6.24.1", 55 | "babel-preset-react": "^6.24.1", 56 | "babel-preset-stage-0": "^6.24.1", 57 | "chai": "^3.5.0", 58 | "diff": "^3.2.0", 59 | "eslint": "^3.19.0", 60 | "eslint-plugin-react": "^7.0.0", 61 | "gzip-size-cli": "^2.0.0", 62 | "karma": "^1.7.0", 63 | "karma-chai-sinon": "^0.1.5", 64 | "karma-mocha": "^1.3.0", 65 | "karma-mocha-reporter": "^2.2.3", 66 | "karma-phantomjs-launcher": "^1.0.4", 67 | "karma-sourcemap-loader": "^0.3.7", 68 | "karma-webpack": "^2.0.3", 69 | "mkdirp": "^0.5.1", 70 | "mocha": "^3.3.0", 71 | "npm-run-all": "^4.0.2", 72 | "phantomjs-prebuilt": "^2.1.14", 73 | "pretty-bytes-cli": "^2.0.0", 74 | "recharts": "^0.21.2", 75 | "rimraf": "^2.6.1", 76 | "rollup": "^0.40.1", 77 | "rollup-plugin-alias": "^1.3.1", 78 | "rollup-plugin-babel": "^2.7.1", 79 | "rollup-plugin-commonjs": "^8.0.2", 80 | "rollup-plugin-memory": "^2.0.0", 81 | "rollup-plugin-replace": "^1.1.1", 82 | "sinon": "^2.2.0", 83 | "sinon-chai": "^2.10.0", 84 | "uglify-js": "^2.8.23", 85 | "webpack": "^2.5.1" 86 | }, 87 | "dependencies": { 88 | "classnames": "^2.2.5", 89 | "core-js": "^2.4.1", 90 | "d3-scale": "^1.0.5", 91 | "d3-shape": "^1.0.6", 92 | "element-resize-detector": "^1.1.12", 93 | "eventemitter3": "^2.0.3", 94 | "lodash": "^4.17.4", 95 | "preact": "^8.1.0", 96 | "preact-compat": "^3.16.0", 97 | "preact-transition-group": "^1.1.1", 98 | "raf": "^3.3.2", 99 | "reduce-css-calc": "^1.3.0" 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import memory from 'rollup-plugin-memory'; 3 | import alias from 'rollup-plugin-alias'; 4 | import commonjs from 'rollup-plugin-commonjs'; 5 | import replace from 'rollup-plugin-replace'; 6 | import babel from 'rollup-plugin-babel'; 7 | 8 | const babelRc = JSON.parse(fs.readFileSync('.babelrc', 'utf8')); 9 | 10 | export default { 11 | exports: 'default', 12 | context: 'window', 13 | useStrict: false, 14 | globals: { 15 | 'classnames': 'classnames', 16 | 'core-js/es6/math': 'coreJs_es6_math', 17 | 'd3-scale': 'd3Scales', 18 | 'd3-shape': 'd3Shape', 19 | 'lodash/isNil': 'lodash', 20 | 'lodash/isString': 'lodash', 21 | 'lodash/isObject': 'lodash', 22 | 'lodash/isFunction': 'lodash', 23 | 'lodash/isArray': 'lodash', 24 | 'lodash/get': 'lodash', 25 | 'lodash/sortBy': 'lodash', 26 | 'lodash/isNaN': 'lodash', 27 | 'lodash/isNumber': 'lodash', 28 | 'lodash/isEqual': 'lodash', 29 | 'lodash/isPlainObject': 'lodash', 30 | 'lodash/intersection': 'lodash', 31 | 'lodash/filter': 'lodash', 32 | 'lodash/debounce': 'lodash', 33 | 'lodash/maxBy': 'lodash', 34 | 'lodash/range': 'lodash', 35 | 'lodash/throttle': 'lodash', 36 | 'lodash/sumBy': 'lodash', 37 | 'lodash/min': 'lodash', 38 | 'preact': 'preact', 39 | 'preact-compat': 'preactCompat', 40 | 'preact-compat/legacy': 'preactCompat', 41 | 'preact-render-to-string': 'preactRenderToString', 42 | 'raf': 'raf', 43 | 'reduce-css-calc': 'reduceCSSCalc' 44 | }, 45 | external: [ 46 | 'classnames', 47 | 'core-js/es6/math', 48 | 'd3-scale', 49 | 'd3-shape', 50 | 'lodash/isNil', 51 | 'lodash/isString', 52 | 'lodash/isObject', 53 | 'lodash/isFunction', 54 | 'lodash/isArray', 55 | 'lodash/get', 56 | 'lodash/sortBy', 57 | 'lodash/isNaN', 58 | 'lodash/isNumber', 59 | 'lodash/isEqual', 60 | 'lodash/isPlainObject', 61 | 'lodash/intersection', 62 | 'lodash/filter', 63 | 'lodash/debounce', 64 | 'lodash/maxBy', 65 | 'lodash/range', 66 | 'lodash/throttle', 67 | 'lodash/sumBy', 68 | 'lodash/min', 69 | 'preact', 70 | 'preact-compat/legacy', 71 | 'raf', 72 | 'reduce-css-calc' 73 | ], 74 | plugins: [ 75 | memory({ 76 | path: 'src/index', 77 | contents: "import * as lib from './index'; export default lib;" 78 | }), 79 | alias({ 80 | 'react-addons-transition-group': __dirname+'/node_modules/preact-transition-group/src/index.js', 81 | 'react-resize-detector': __dirname+'/node_modules/react-resize-detector/lib/index.js', 82 | 'react-smooth': __dirname+'/node_modules/react-smooth/src/index.js', 83 | 'recharts-scale': __dirname+'/node_modules/recharts-scale/src/index.js', 84 | 'recharts': __dirname+'/node_modules/recharts/src/index.js', 85 | 'events': __dirname+'/node_modules/eventemitter3/index.js', 86 | 'react-dom/server': __dirname+'/src/compat.js', 87 | 'react-dom': __dirname+'/src/compat.js', 88 | 'react': __dirname+'/src/compat.js', 89 | 'invariant': __dirname+'/src/empty.js' 90 | }), 91 | commonjs({ 92 | include: 'node_modules/**', 93 | exclude: [ 94 | 'node_modules/recharts/**', 95 | 'node_modules/recharts-scale/**', 96 | 'node_modules/react-smooth/**' 97 | ] 98 | }), 99 | babel({ 100 | babelrc: false, 101 | runtimeHelpers: true, 102 | presets: [ 103 | ['es2015', { 104 | loose: true, 105 | modules: false 106 | }] 107 | ].concat(babelRc.presets.slice(1)), 108 | plugins: babelRc.plugins.concat('external-helpers') 109 | }), 110 | replace({ 111 | 'process.env.NODE_ENV': JSON.stringify('production') 112 | }) 113 | ] 114 | }; 115 | -------------------------------------------------------------------------------- /src/compat.js: -------------------------------------------------------------------------------- 1 | export * from 'preact-compat/legacy'; 2 | export { default } from 'preact-compat/legacy'; 3 | -------------------------------------------------------------------------------- /src/empty.js: -------------------------------------------------------------------------------- 1 | export default function(){} 2 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export * from 'recharts'; 2 | import * as recharts from 'recharts'; 3 | export default recharts; 4 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | /** @jsx h */ 2 | import { h, render } from 'preact'; 3 | import { ComposedChart, Area, Line, XAxis, YAxis, CartesianGrid, Tooltip } from '../'; 4 | 5 | const DATA = [ 6 | { name: 'Page A', uv: 4000, pv: 2400, amt: 2400 }, 7 | { name: 'Page B', uv: 3000, pv: 1398, amt: 2210 }, 8 | { name: 'Page C', uv: 2000, pv: 9800, amt: 2290 }, 9 | { name: 'Page D', uv: 2780, pv: 3908, amt: 2000 }, 10 | { name: 'Page E', uv: 1890, pv: 4800, amt: 2181 }, 11 | { name: 'Page F', uv: 2390, pv: 3800, amt: 2500 }, 12 | { name: 'Page G', uv: 3490, pv: 4300, amt: 2100 } 13 | ]; 14 | 15 | describe('precharts', () => { 16 | let scratch = document.createElement('div'), 17 | Empty = () => null, 18 | $ = s => [].slice.call(scratch.querySelectorAll(s)); 19 | document.body.appendChild(scratch); 20 | afterEach( () => render(, scratch, scratch.lastChild).remove() ); 21 | after( () => document.body.removeChild(scratch) ); 22 | 23 | it('should export ComposedChart, Area, Line, XAxis, YAxis, CartesianGrid, Tooltip', () => { 24 | expect(ComposedChart).to.be.a('function'); 25 | expect(Area).to.be.a('function'); 26 | expect(Line).to.be.a('function'); 27 | expect(XAxis).to.be.a('function'); 28 | expect(YAxis).to.be.a('function'); 29 | expect(CartesianGrid).to.be.a('function'); 30 | expect(Tooltip).to.be.a('function'); 31 | }); 32 | 33 | it('should render the static example', () => { 34 | render(( 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ), scratch); 44 | 45 | // console.log(scratch.innerHTML); 46 | 47 | expect($('.recharts-cartesian-grid-horizontal line[stroke="#ccc"]')).to.have.lengthOf(5); 48 | expect($('.recharts-cartesian-grid-vertical line[stroke="#ccc"]')).to.have.lengthOf(9); 49 | 50 | expect($('circle[stroke="blue"]')).to.have.lengthOf(7); 51 | expect($('circle[stroke="red"]')).to.have.lengthOf(7); 52 | expect($('path[fill="green"]'), 'area paths').to.have.lengthOf(1); 53 | }); 54 | 55 | it('should render the animated example', done => { 56 | render(( 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | ), scratch); 66 | 67 | // wait for the 200ms animation to end. 68 | setTimeout( () => { 69 | expect($('.recharts-cartesian-grid-horizontal line[stroke="#ccc"]')).to.have.lengthOf(5); 70 | expect($('.recharts-cartesian-grid-vertical line[stroke="#ccc"]')).to.have.lengthOf(9); 71 | 72 | expect($('circle[stroke="blue"]')).to.have.lengthOf(7); 73 | expect($('circle[stroke="red"]')).to.have.lengthOf(7); 74 | expect($('path[fill="green"]'), 'area paths').to.have.lengthOf(1); 75 | 76 | done(); 77 | }, 500); 78 | }); 79 | }); 80 | --------------------------------------------------------------------------------