diff --git a/.gitignore b/.gitignore index ebbb5ed80..e9355dfd2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ logs node_modules .idea /lib +/es npm-debug.log* diff --git a/README.md b/README.md index ef39bfb36..842e49497 100644 --- a/README.md +++ b/README.md @@ -8,30 +8,36 @@ **nivo** provides supercharged React components to easily build dataviz apps, it's built on top of d3. +Several libraries already exist for React d3 integration, but just a few provide server side rendering ability and fully declarative charts. + ## Features -- use d3 v4 +- supports [d3 v4](https://github.com/d3/d3/blob/master/CHANGES.md) - composable +- [responsive charts](http://nivo.rocks/#/components?term=responsive) (`` components) - highly customizable -- motion/transitions +- motion/transitions, even the non-d3 based components (DOM managed by React) support transitions within the help of [react-motion](https://github.com/chenglou/react-motion) - [component playground](http://nivo.rocks) - [exhaustive documentation](http://nivo.rocks) - isomorphic rendering -- support for SVG and HTML -- placeholder components for advanced customization +- support for SVG and [HTML](http://nivo.rocks/#/components?term=html) (I'm also considering canvas support) +- [placeholder components](http://nivo.rocks/#/components?term=placeholder) for advanced customization (`<*Placeholders />` components) - [server side rendering API](https://github.com/plouc/nivo-api) ## Components -- Bars - - [``](http://nivo.rocks/#/bars/react) - - [``](http://nivo.rocks/#/bars/react) +- Bar + - [``](http://nivo.rocks/#/bar) + - [``](http://nivo.rocks/#/bar) - Line - - [``](http://nivo.rocks/#/line/react) - - [``](http://nivo.rocks/#/line/react) + - [``](http://nivo.rocks/#/line) + - [``](http://nivo.rocks/#/line) +- Pie + - [``](http://nivo.rocks/#/pie) + - [``](http://nivo.rocks/#/pie) - Bubble - - [``](http://nivo.rocks/#/bubble/react) - - [``](http://nivo.rocks/#/bubble/react) + - [``](http://nivo.rocks/#/bubble) + - [``](http://nivo.rocks/#/bubble) - [``](http://nivo.rocks/#/bubble/placeholders) - [``](http://nivo.rocks/#/bubble/placeholders) - TreeMap @@ -41,10 +47,22 @@ it's built on top of d3. - [``](http://nivo.rocks/#/treemap/html) - [``](http://nivo.rocks/#/treemap/placeholders) - [``](http://nivo.rocks/#/treemap/placeholders) +- Calendar + - [``](http://nivo.rocks/#/calendar) + - [``](http://nivo.rocks/#/calendar) - Chord - [``](http://nivo.rocks/#/chord) - [``](http://nivo.rocks/#/chord) +## [HTTP API](https://github.com/plouc/nivo-api) + +- [``](https://nivo-api.herokuapp.com/samples/bar) +- [``](https://nivo-api.herokuapp.com/samples/line) +- [``](https://nivo-api.herokuapp.com/samples/pie) +- [``](https://nivo-api.herokuapp.com/samples/bubble) +- [``](https://nivo-api.herokuapp.com/samples/treemap) +- [``](https://nivo-api.herokuapp.com/samples/chord) + ## Guides - [colors](http://nivo.rocks/#/guides/colors) @@ -53,6 +71,7 @@ it's built on top of d3. - [nivo](https://github.com/plouc/nivo) - the nivo library - [nivo-api](https://github.com/plouc/nivo-api) - the nivo http api +- [nivo-api-docker](https://github.com/plouc/nivo-api-docker) - a Docker image for the nivo http api - [nivo-generators](https://github.com/plouc/nivo-generators) - the data generators used for nivo-website and http API samples - [nivo-website](https://github.com/plouc/nivo-website) - the source for the nivo website @@ -66,7 +85,7 @@ it's built on top of d3. [license-image]: https://img.shields.io/github/license/plouc/nivo.svg?style=flat-square [license-url]: https://github.com/plouc/nivo/blob/master/LICENSE.md -[npm-image]: https://img.shields.io/npm/v/nivo.svg?style=flat-square +[npm-image]: [npm-image]: https://img.shields.io/npm/v/nivo.svg?style=flat-square [npm-url]: https://www.npmjs.com/package/nivo [travis-image]: https://img.shields.io/travis/plouc/nivo.svg?style=flat-square [travis-url]: https://travis-ci.org/plouc/nivo diff --git a/package.json b/package.json index e8cafdeae..ef3677443 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nivo", - "version": "1.0.0-alpha.4", + "version": "1.0.0-alpha.8", "author": { "name": "Raphaël Benitte", "url": "https://github.com/plouc" @@ -10,9 +10,11 @@ "d3": "4.2.6", "d3-scale-chromatic": "1.0.2", "invariant": "2.2.1", - "lodash": "4.11.1", + "lodash": "4.16.3", + "prop-types": "^15.5.10", "react-dimensions": "1.3.0", - "react-motion": "0.4.5" + "react-measure": "^2.0.2", + "react-motion": "^0.5.0" }, "devDependencies": { "ava": "0.14.0", @@ -21,6 +23,7 @@ "babel-preset-es2015": "6.6.0", "babel-preset-react": "6.5.0", "babel-preset-stage-0": "6.5.0", + "cross-env": "^5.0.1", "expect": "1.18.0", "karma": "0.13.22", "karma-chrome-launcher": "0.2.3", @@ -29,22 +32,27 @@ "karma-sourcemap-loader": "0.3.7", "karma-webpack": "1.7.0", "mocha": "2.4.5", - "react": "15.3.2", - "react-dom": "15.3.2", + "prettier": "^1.5.3", + "react": "^15.4.1", + "react-dom": "^15.4.1", "webpack": "1.13.0" }, "peerDependencies": { - "react": "^15.0.0" + "react": "^15.4.1" }, - "main": "lib", + "main": "./lib/index.js", + "module": "es/index.js", + "jsnext:main": "es/index.js", "scripts": { - "watch": "babel src --watch --out-dir lib", "watch-test": "ava --watch", "test": "npm run test-unit && npm run test-func", "test-unit": "ava", "test-func": "karma start", - "build": "rm -rf lib/* && babel src --no-comments --out-dir lib", - "prebublish": "npm run build" + "build:commonjs": "cross-env BABEL_ENV=commonjs babel src --out-dir lib", + "build:es": "cross-env BABEL_ENV=es babel src --out-dir es", + "build": "npm run build:commonjs && npm run build:es", + "prebublish": "npm run build", + "format": "prettier --tab-width=4 --bracket-spacing --no-semi --trailing-comma es5 --single-quote --write 'src/**/*.js' 'specs/**/*.js' 'test/**/*.js'" }, "ava": { "files": [ diff --git a/specs/Pie.spec.js b/specs/Pie.spec.js index f0f95db39..ecf30b5cf 100644 --- a/specs/Pie.spec.js +++ b/specs/Pie.spec.js @@ -1,74 +1,79 @@ -import expect, { spyOn } from 'expect'; -import React, { Component } from 'react'; -import { render } from 'react-dom'; -import { Chart, Pie } from '../src/'; +import expect, { spyOn } from 'expect' +import React, { Component } from 'react' +import { render } from 'react-dom' +import { Chart, Pie } from '../src/' +describe('', function() { + this.timeout(10000) -describe('', function () { - this.timeout(10000); - - let node; + let node beforeEach(() => { - node = document.createElement('div'); - document.body.appendChild(node); - }); + node = document.createElement('div') + document.body.appendChild(node) + }) afterEach(() => { - document.body.removeChild(node); - }); + document.body.removeChild(node) + }) const data = [ { label: 'a', value: 2 }, { label: 'b', value: 2 }, - { label: 'c', value: 2 } - ]; + { label: 'c', value: 2 }, + ] it('should render a slice for each datum', done => { - render(( + render(
-
- ), node, () => { - setTimeout(() => { - const slices = node.getElementsByClassName('nivo_pie_slice'); - expect(slices).toNotBe(null); - expect(slices.length).toBe(data.length); + , + node, + () => { + setTimeout(() => { + const slices = node.getElementsByClassName('nivo_pie_slice') + expect(slices).toNotBe(null) + expect(slices.length).toBe(data.length) - done(); - }, 400); - }) - }); + done() + }, 400) + } + ) + }) it(`should support donut mode by using 'innerRadius' property`, done => { - render(( + render(
-
- ), node, () => { - setTimeout(() => { - const slices = node.getElementsByClassName('nivo_pie_slice'); - expect(slices).toNotBe(null); - expect(slices.length).toBe(data.length); + , + node, + () => { + setTimeout(() => { + const slices = node.getElementsByClassName('nivo_pie_slice') + expect(slices).toNotBe(null) + expect(slices.length).toBe(data.length) - console.log(slices.length); + console.log(slices.length) - done(); - }, 400); - }) - }); -}); + done() + }, 400) + } + ) + }) +}) diff --git a/specs/RadialStack.spec.js b/specs/RadialStack.spec.js index d9d7e96ea..d554f82e2 100644 --- a/specs/RadialStack.spec.js +++ b/specs/RadialStack.spec.js @@ -1,47 +1,71 @@ -import expect, { spyOn } from 'expect'; -import React, { Component } from 'react'; -import { render } from 'react-dom'; -import { Chart, RadialStack } from '../src/'; +import expect, { spyOn } from 'expect' +import React, { Component } from 'react' +import { render } from 'react-dom' +import { Chart, RadialStack } from '../src/' +describe('', function() { + this.timeout(10000) -describe('', function () { - this.timeout(10000); - - let node; + let node beforeEach(() => { - node = document.createElement('div'); - document.body.appendChild(node); - }); + node = document.createElement('div') + document.body.appendChild(node) + }) afterEach(() => { - document.body.removeChild(node); - }); + document.body.removeChild(node) + }) const data = [ - [{ x: 0, y: 10 }, { x: 1, y: 20 }, { x: 2, y: 30 }, { x: 3, y: 2 }, { x: 4, y: 80 }, { x: 5, y: 30 }], - [{ x: 0, y: 10 }, { x: 1, y: 20 }, { x: 2, y: 30 }, { x: 3, y: 2 }, { x: 4, y: 20 }, { x: 5, y: 30 }], - [{ x: 0, y: 10 }, { x: 1, y: 20 }, { x: 2, y: 30 }, { x: 3, y: 2 }, { x: 4, y: 40 }, { x: 5, y: 30 }] - ]; - - ['zero', 'wiggle', 'silhouette', 'expand'].forEach(offsetMode => { + [ + { x: 0, y: 10 }, + { x: 1, y: 20 }, + { x: 2, y: 30 }, + { x: 3, y: 2 }, + { x: 4, y: 80 }, + { x: 5, y: 30 }, + ], + [ + { x: 0, y: 10 }, + { x: 1, y: 20 }, + { x: 2, y: 30 }, + { x: 3, y: 2 }, + { x: 4, y: 20 }, + { x: 5, y: 30 }, + ], + [ + { x: 0, y: 10 }, + { x: 1, y: 20 }, + { x: 2, y: 30 }, + { x: 3, y: 2 }, + { x: 4, y: 40 }, + { x: 5, y: 30 }, + ], + ] + ;['zero', 'wiggle', 'silhouette', 'expand'].forEach(offsetMode => { it(`should support "${offsetMode}" offset mode`, done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const areas = node.getElementsByClassName('nivo_radial-stack_area'); - expect(areas).toNotBe(null); - expect(areas.length).toBe(data.length); + />, + node, + () => { + setTimeout(() => { + const areas = node.getElementsByClassName( + 'nivo_radial-stack_area' + ) + expect(areas).toNotBe(null) + expect(areas.length).toBe(data.length) - done(); - }, 400); - }); - }); - }); -}); + done() + }, 400) + } + ) + }) + }) +}) diff --git a/specs/Stack.spec.js b/specs/Stack.spec.js index b0feaf66f..1081e80e9 100644 --- a/specs/Stack.spec.js +++ b/specs/Stack.spec.js @@ -1,31 +1,29 @@ -import expect, { spyOn } from 'expect'; -import React, { Component } from 'react'; -import { render } from 'react-dom'; -import { Chart, Stack } from '../src/'; +import expect, { spyOn } from 'expect' +import React, { Component } from 'react' +import { render } from 'react-dom' +import { Chart, Stack } from '../src/' +describe('', function() { + this.timeout(10000) -describe('', function () { - this.timeout(10000); - - let node; + let node beforeEach(() => { - node = document.createElement('div'); - document.body.appendChild(node); - }); + node = document.createElement('div') + document.body.appendChild(node) + }) afterEach(() => { - document.body.removeChild(node); - }); + document.body.removeChild(node) + }) const data = [ [{ x: 10, y: 10 }, { x: 20, y: 20 }, { x: 20, y: 30 }], [{ x: 10, y: 10 }, { x: 20, y: 20 }, { x: 20, y: 30 }], - [{ x: 10, y: 10 }, { x: 20, y: 20 }, { x: 20, y: 30 }] - ]; - - ['zero', 'wiggle', 'silhouette', 'expand'].forEach(offsetMode => { + [{ x: 10, y: 10 }, { x: 20, y: 20 }, { x: 20, y: 30 }], + ] + ;['zero', 'wiggle', 'silhouette', 'expand'].forEach(offsetMode => { it(`should support "${offsetMode}" offset mode`, done => { - render(( + render(
', function () { transitionDuration={0} /> -
- ), node, () => { - setTimeout(() => { - const areas = node.getElementsByClassName('nivo_stack_area'); - expect(areas).toNotBe(null); - expect(areas.length).toBe(data.length); + , + node, + () => { + setTimeout(() => { + const areas = node.getElementsByClassName( + 'nivo_stack_area' + ) + expect(areas).toNotBe(null) + expect(areas.length).toBe(data.length) - done(); - }, 400); - }); - }); - }); -}); + done() + }, 400) + } + ) + }) + }) +}) diff --git a/specs/Tree.spec.js b/specs/Tree.spec.js index f880636af..7a90429db 100644 --- a/specs/Tree.spec.js +++ b/specs/Tree.spec.js @@ -1,39 +1,47 @@ -import expect, { spyOn } from 'expect'; -import React, { Component } from 'react'; -import { render } from 'react-dom'; -import { Tree } from '../src/'; +import expect, { spyOn } from 'expect' +import React, { Component } from 'react' +import { render } from 'react-dom' +import { Tree } from '../src/' +describe('', function() { + this.timeout(10000) -describe('', function () { - this.timeout(10000); - - let node; + let node beforeEach(() => { - node = document.createElement('div'); - document.body.appendChild(node); - }); + node = document.createElement('div') + document.body.appendChild(node) + }) afterEach(() => { - document.body.removeChild(node); - }); + document.body.removeChild(node) + }) - const root = { id: 'nivo', children: [ - { id: 'charts', children: [ - { id: 'Pie', loc: 74467 }, - { id: 'Stack', loc: 74467 }, - { id: 'Tree', loc: 74467 }, - { id: 'Bubble', loc: 74467 } - ]}, - { id: 'utils', children: [ - { id: 'Colors', loc: 74467 }, - { id: 'Arcs', loc: 74467 }, - { id: 'Data', loc: 74467 }, - { id: 'Animation', loc: 74467 } - ]} - ]}; + const root = { + id: 'nivo', + children: [ + { + id: 'charts', + children: [ + { id: 'Pie', loc: 74467 }, + { id: 'Stack', loc: 74467 }, + { id: 'Tree', loc: 74467 }, + { id: 'Bubble', loc: 74467 }, + ], + }, + { + id: 'utils', + children: [ + { id: 'Colors', loc: 74467 }, + { id: 'Arcs', loc: 74467 }, + { id: 'Data', loc: 74467 }, + { id: 'Animation', loc: 74467 }, + ], + }, + ], + } it('should render a path for each link', done => { - render(( + render(
', function () { identity={d => `${d.parent ? d.parent.id : 'root'}.${d.id}`} transitionDuration={0} /> -
- ), node, () => { - setTimeout(() => { - const links = node.getElementsByClassName('nivo_tree_link'); - expect(links).toNotBe(null); - expect(links.length).toBe(10); + , + node, + () => { + setTimeout(() => { + const links = node.getElementsByClassName('nivo_tree_link') + expect(links).toNotBe(null) + expect(links.length).toBe(10) - done(); - }, 400); - }) - }); + done() + }, 400) + } + ) + }) it(`should support 'horizontal-reverse' direction `, done => { - render(( + render(
', function () { identity={d => `${d.parent ? d.parent.id : 'root'}.${d.id}`} transitionDuration={0} /> -
- ), node, () => { - setTimeout(() => { - const links = node.getElementsByClassName('nivo_tree_link'); - expect(links).toNotBe(null); - expect(links.length).toBe(10); + , + node, + () => { + setTimeout(() => { + const links = node.getElementsByClassName('nivo_tree_link') + expect(links).toNotBe(null) + expect(links.length).toBe(10) - done(); - }, 400); - }) - }); + done() + }, 400) + } + ) + }) it(`should support 'vertical' direction `, done => { - render(( + render(
', function () { identity={d => `${d.parent ? d.parent.id : 'root'}.${d.id}`} transitionDuration={0} /> -
- ), node, () => { - setTimeout(() => { - const links = node.getElementsByClassName('nivo_tree_link'); - expect(links).toNotBe(null); - expect(links.length).toBe(10); + , + node, + () => { + setTimeout(() => { + const links = node.getElementsByClassName('nivo_tree_link') + expect(links).toNotBe(null) + expect(links.length).toBe(10) - done(); - }, 400); - }) - }); + done() + }, 400) + } + ) + }) it(`should support 'vertical-reverse' direction `, done => { - render(( + render(
', function () { identity={d => `${d.parent ? d.parent.id : 'root'}.${d.id}`} transitionDuration={0} /> -
- ), node, () => { - setTimeout(() => { - const links = node.getElementsByClassName('nivo_tree_link'); - expect(links).toNotBe(null); - expect(links.length).toBe(10); + , + node, + () => { + setTimeout(() => { + const links = node.getElementsByClassName('nivo_tree_link') + expect(links).toNotBe(null) + expect(links.length).toBe(10) - done(); - }, 400); - }) - }); -}); + done() + }, 400) + } + ) + }) +}) diff --git a/specs/bubble/Bubble.spec.js b/specs/bubble/Bubble.spec.js index 125e44446..61ab53f04 100644 --- a/specs/bubble/Bubble.spec.js +++ b/specs/bubble/Bubble.spec.js @@ -6,45 +6,49 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; +'use strict' -import expect, { spyOn } from 'expect'; -import React, { Component } from 'react'; -import { render } from 'react-dom'; -import { Bubble } from '../../src/'; -import bubbleData from './bubbleData'; +import expect, { spyOn } from 'expect' +import React, { Component } from 'react' +import { render } from 'react-dom' +import { Bubble } from '../../src/' +import bubbleData from './bubbleData' +describe('', function() { + this.timeout(10000) -describe('', function () { - this.timeout(10000); - - let node; + let node beforeEach(() => { - node = document.createElement('div'); - document.body.appendChild(node); - }); + node = document.createElement('div') + document.body.appendChild(node) + }) afterEach(() => { - document.body.removeChild(node); - }); + document.body.removeChild(node) + }) it('should render a circle for each leaf', done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const circles = node.getElementsByClassName('nivo_bubble_node'); - expect(circles).toNotBe(null); - expect(circles.length).toBe(11); + />, + node, + () => { + setTimeout(() => { + const circles = node.getElementsByClassName( + 'nivo_bubble_node' + ) + expect(circles).toNotBe(null) + expect(circles.length).toBe(11) - done(); - }, 400); - }) - }); -}); + done() + }, 400) + } + ) + }) +}) diff --git a/specs/bubble/BubbleD3.spec.js b/specs/bubble/BubbleD3.spec.js index 6fa44e60e..5c8a80338 100644 --- a/specs/bubble/BubbleD3.spec.js +++ b/specs/bubble/BubbleD3.spec.js @@ -6,45 +6,49 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; +'use strict' -import expect, { spyOn } from 'expect'; -import React, { Component } from 'react'; -import { render } from 'react-dom'; -import { BubbleD3 } from '../../src/'; -import bubbleData from './bubbleData'; +import expect, { spyOn } from 'expect' +import React, { Component } from 'react' +import { render } from 'react-dom' +import { BubbleD3 } from '../../src/' +import bubbleData from './bubbleData' +describe('', function() { + this.timeout(10000) -describe('', function () { - this.timeout(10000); - - let node; + let node beforeEach(() => { - node = document.createElement('div'); - document.body.appendChild(node); - }); + node = document.createElement('div') + document.body.appendChild(node) + }) afterEach(() => { - document.body.removeChild(node); - }); + document.body.removeChild(node) + }) it('should render a circle for each leaf', done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const circles = node.getElementsByClassName('nivo_bubble_node'); - expect(circles).toNotBe(null); - expect(circles.length).toBe(11); + />, + node, + () => { + setTimeout(() => { + const circles = node.getElementsByClassName( + 'nivo_bubble_node' + ) + expect(circles).toNotBe(null) + expect(circles.length).toBe(11) - done(); - }, 400); - }) - }); -}); + done() + }, 400) + } + ) + }) +}) diff --git a/specs/bubble/bubbleData.js b/specs/bubble/bubbleData.js index e83dbf1dc..5b72d795d 100644 --- a/specs/bubble/bubbleData.js +++ b/specs/bubble/bubbleData.js @@ -6,36 +6,36 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; +'use strict' export default { - name: 'nivo', + name: 'nivo', children: [ { - name: 'charts', + name: 'charts', children: [ - { name: 'Pie', loc: 1000 }, - { name: 'Stack', loc: 1000 }, - { name: 'Tree', loc: 6000 }, - { name: 'Bubble', loc: 1000 } - ] + { name: 'Pie', loc: 1000 }, + { name: 'Stack', loc: 1000 }, + { name: 'Tree', loc: 6000 }, + { name: 'Bubble', loc: 1000 }, + ], }, { - name: 'utils', + name: 'utils', children: [ - { name: 'Colors', loc: 1000 }, - { name: 'Arcs', loc: 4000 }, - { name: 'Data', loc: 1000 }, - { name: 'Animation', loc: 7000 } - ] + { name: 'Colors', loc: 1000 }, + { name: 'Arcs', loc: 4000 }, + { name: 'Data', loc: 1000 }, + { name: 'Animation', loc: 7000 }, + ], }, { - name: 'generator', + name: 'generator', children: [ - { name: 'tree', loc: 3000 }, + { name: 'tree', loc: 3000 }, { name: 'serie', loc: 2000 }, - { name: 'geo', loc: 1000 } - ] - } - ] -}; \ No newline at end of file + { name: 'geo', loc: 1000 }, + ], + }, + ], +} diff --git a/specs/calendar/Calendar.spec.js b/specs/calendar/Calendar.spec.js index 43c7d773a..1ff6b8662 100644 --- a/specs/calendar/Calendar.spec.js +++ b/specs/calendar/Calendar.spec.js @@ -6,125 +6,150 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; +'use strict' -import expect, { spyOn } from 'expect'; -import React, { Component } from 'react'; -import { render } from 'react-dom'; -import { Calendar } from '../../src/'; +import expect, { spyOn } from 'expect' +import React, { Component } from 'react' +import { render } from 'react-dom' +import { Calendar } from '../../src/' +describe('', function() { + this.timeout(10000) -describe('', function () { - this.timeout(10000); - - let node; + let node beforeEach(() => { - node = document.createElement('div'); - document.body.appendChild(node); - }); + node = document.createElement('div') + document.body.appendChild(node) + }) afterEach(() => { - document.body.removeChild(node); - }); + document.body.removeChild(node) + }) it('should render all years days', done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const days = node.getElementsByClassName('nivo_calendar_day'); - expect(days).toNotBe(null); - expect(days.length).toBe(365 * 2); + />, + node, + () => { + setTimeout(() => { + const days = node.getElementsByClassName( + 'nivo_calendar_day' + ) + expect(days).toNotBe(null) + expect(days.length).toBe(365 * 2) - done(); - }, 400); - }) - }); + done() + }, 400) + } + ) + }) it('should render all years months', done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const months = node.getElementsByClassName('nivo_calendar_month'); - expect(months).toNotBe(null); - expect(months.length).toBe(12 * 2); + />, + node, + () => { + setTimeout(() => { + const months = node.getElementsByClassName( + 'nivo_calendar_month' + ) + expect(months).toNotBe(null) + expect(months.length).toBe(12 * 2) - const monthLegends = node.getElementsByClassName('nivo_calendar_month_legend'); - expect(monthLegends).toNotBe(null); - expect(monthLegends.length).toBe(12 * 2); + const monthLegends = node.getElementsByClassName( + 'nivo_calendar_month_legend' + ) + expect(monthLegends).toNotBe(null) + expect(monthLegends.length).toBe(12 * 2) - done(); - }, 400); - }) - }); + done() + }, 400) + } + ) + }) it('should render a label for each year', done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const legends = node.getElementsByClassName('nivo_calendar_year_legend'); - expect(legends).toNotBe(null); - expect(legends.length).toBe(2); + />, + node, + () => { + setTimeout(() => { + const legends = node.getElementsByClassName( + 'nivo_calendar_year_legend' + ) + expect(legends).toNotBe(null) + expect(legends.length).toBe(2) - done(); - }, 400); - }) - }); + done() + }, 400) + } + ) + }) it('should support vertical layout', done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const days = node.getElementsByClassName('nivo_calendar_day'); - expect(days).toNotBe(null); - expect(days.length).toBe(365 * 2); + />, + node, + () => { + setTimeout(() => { + const days = node.getElementsByClassName( + 'nivo_calendar_day' + ) + expect(days).toNotBe(null) + expect(days.length).toBe(365 * 2) - done(); - }, 400); - }) - }); -}); + done() + }, 400) + } + ) + }) +}) diff --git a/specs/calendar/CalendarD3.spec.js b/specs/calendar/CalendarD3.spec.js index 155736cee..797b40fe5 100644 --- a/specs/calendar/CalendarD3.spec.js +++ b/specs/calendar/CalendarD3.spec.js @@ -6,129 +6,158 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; +'use strict' -import expect, { spyOn } from 'expect'; -import React, { Component } from 'react'; -import { render } from 'react-dom'; -import { CalendarD3 } from '../../src/'; +import expect, { spyOn } from 'expect' +import React, { Component } from 'react' +import { render } from 'react-dom' +import { CalendarD3 } from '../../src/' +describe('', function() { + this.timeout(10000) -describe('', function () { - this.timeout(10000); - - let node; + let node beforeEach(() => { - node = document.createElement('div'); - document.body.appendChild(node); - }); + node = document.createElement('div') + document.body.appendChild(node) + }) afterEach(() => { - document.body.removeChild(node); - }); + document.body.removeChild(node) + }) it('should render all years days', done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const days = node.getElementsByClassName('nivo_calendar_day'); - expect(days).toNotBe(null); - expect(days.length).toBe(365 * 2); + transitionDuration={0} + transitionStaggering={0} + />, + node, + () => { + setTimeout(() => { + const days = node.getElementsByClassName( + 'nivo_calendar_day' + ) + expect(days).toNotBe(null) + expect(days.length).toBe(365 * 2) - done(); - }, 400); - }) - }); + done() + }, 400) + } + ) + }) it('should render all years months', done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const months = node.getElementsByClassName('nivo_calendar_month'); - expect(months).toNotBe(null); - expect(months.length).toBe(12 * 2); + transitionDuration={0} + transitionStaggering={0} + />, + node, + () => { + setTimeout(() => { + const months = node.getElementsByClassName( + 'nivo_calendar_month' + ) + expect(months).toNotBe(null) + expect(months.length).toBe(12 * 2) - const monthLegends = node.getElementsByClassName('nivo_calendar_month_legend'); - expect(monthLegends).toNotBe(null); - expect(monthLegends.length).toBe(12 * 2); + const monthLegends = node.getElementsByClassName( + 'nivo_calendar_month_legend' + ) + expect(monthLegends).toNotBe(null) + expect(monthLegends.length).toBe(12 * 2) - done(); - }, 400); - }) - }); + done() + }, 400) + } + ) + }) it('should render a label for each year', done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const legends = node.getElementsByClassName('nivo_calendar_year_legend'); - expect(legends).toNotBe(null); - expect(legends.length).toBe(2); + transitionDuration={0} + transitionStaggering={0} + />, + node, + () => { + setTimeout(() => { + const legends = node.getElementsByClassName( + 'nivo_calendar_year_legend' + ) + expect(legends).toNotBe(null) + expect(legends.length).toBe(2) - done(); - }, 400); - }) - }); + done() + }, 400) + } + ) + }) it('should support vertical layout', done => { - render(( + render( - ), node, () => { - setTimeout(() => { - const days = node.getElementsByClassName('nivo_calendar_day'); - expect(days).toNotBe(null); - expect(days.length).toBe(365 * 2); + transitionDuration={0} + transitionStaggering={0} + />, + node, + () => { + setTimeout(() => { + const days = node.getElementsByClassName( + 'nivo_calendar_day' + ) + expect(days).toNotBe(null) + expect(days.length).toBe(365 * 2) - done(); - }, 400); - }) - }); -}); + done() + }, 400) + } + ) + }) +}) diff --git a/specs/treemap/TreeMap.spec.js b/specs/treemap/TreeMap.spec.js index 4ffb5ec43..a38463bde 100644 --- a/specs/treemap/TreeMap.spec.js +++ b/specs/treemap/TreeMap.spec.js @@ -1,77 +1,94 @@ -import expect, { spyOn } from 'expect'; -import React, { Component } from 'react'; -import { render } from 'react-dom'; -import { TreeMapD3 } from '../src/'; +import expect, { spyOn } from 'expect' +import React, { Component } from 'react' +import { render } from 'react-dom' +import { TreeMapD3 } from '../src/' +describe('', function() { + this.timeout(10000) -describe('', function () { - this.timeout(10000); - - let node; + let node beforeEach(() => { - node = document.createElement('div'); - document.body.appendChild(node); - }); + node = document.createElement('div') + document.body.appendChild(node) + }) afterEach(() => { - document.body.removeChild(node); - }); + document.body.removeChild(node) + }) - const root = { name: 'nivo', children: [ - { name: 'charts', children: [ - { name: 'Pie', loc: 74467 }, - { name: 'Stack', loc: 74467 }, - { name: 'Tree', loc: 74467 }, - { name: 'Bubble', loc: 74467 } - ]}, - { name: 'utils', children: [ - { name: 'Colors', loc: 74467 }, - { name: 'Arcs', loc: 74467 }, - { name: 'Data', loc: 74467 }, - { name: 'Animation', loc: 74467 } - ]} - ]}; + const root = { + name: 'nivo', + children: [ + { + name: 'charts', + children: [ + { name: 'Pie', loc: 74467 }, + { name: 'Stack', loc: 74467 }, + { name: 'Tree', loc: 74467 }, + { name: 'Bubble', loc: 74467 }, + ], + }, + { + name: 'utils', + children: [ + { name: 'Colors', loc: 74467 }, + { name: 'Arcs', loc: 74467 }, + { name: 'Data', loc: 74467 }, + { name: 'Animation', loc: 74467 }, + ], + }, + ], + } it('should render a treemap', done => { - render(( + render( d.loc} colors="nivo" transitionDuration={0} - /> - ), node, () => { - setTimeout(() => { - const nodes = node.getElementsByClassName('nivo_treemap_node'); - expect(nodes).toNotBe(null); - expect(nodes.length).toBe(11); - - done(); - }, 400); - }) - }); + />, + node, + () => { + setTimeout(() => { + const nodes = node.getElementsByClassName( + 'nivo_treemap_node' + ) + expect(nodes).toNotBe(null) + expect(nodes.length).toBe(11) - ['squarify', 'slice', 'dice', 'slice-dice'].forEach(mode => { + done() + }, 400) + } + ) + }) + ;['squarify', 'slice', 'dice', 'slice-dice'].forEach(mode => { it(`should support "${mode}" mode`, done => { - render(( + render( d.loc} colors="nivo" transitionDuration={0} - /> - ), node, () => { - setTimeout(() => { - const nodes = node.getElementsByClassName('nivo_treemap_node'); - expect(nodes).toNotBe(null); - expect(nodes.length).toBe(11); + />, + node, + () => { + setTimeout(() => { + const nodes = node.getElementsByClassName( + 'nivo_treemap_node' + ) + expect(nodes).toNotBe(null) + expect(nodes.length).toBe(11) - done(); - }, 400); - }); - }); - }); -}); + done() + }, 400) + } + ) + }) + }) +}) diff --git a/src/ArcUtils.js b/src/ArcUtils.js index 8162b49d0..ff990954e 100644 --- a/src/ArcUtils.js +++ b/src/ArcUtils.js @@ -6,15 +6,11 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; +import d3 from 'd3' -import d3 from 'd3'; - - -export const degreesToRadians = degrees => degrees * Math.PI / 180; - -export const radiansToDegrees = radians => 180 * radians / Math.PI; +export const degreesToRadians = degrees => degrees * Math.PI / 180 +export const radiansToDegrees = radians => 180 * radians / Math.PI /** * Try to get a neighbor arc, otherwise, returns null. @@ -26,24 +22,24 @@ export const radiansToDegrees = radians => 180 * radians / Math.PI; * @returns {{startAngle: *, endAngle: *}} */ export const findNeighbor = (i, identity, prevData, newData) => { - const preceding = findPreceding(i, identity, prevData, newData); + const preceding = findPreceding(i, identity, prevData, newData) if (preceding) { return { startAngle: preceding.endAngle, - endAngle: preceding.endAngle - }; + endAngle: preceding.endAngle, + } } - const following = findFollowing(i, identity, prevData, newData); + const following = findFollowing(i, identity, prevData, newData) if (following) { return { startAngle: following.startAngle, - endAngle: following.startAngle - }; + endAngle: following.startAngle, + } } - return null; -}; + return null +} /** * Find the element in prevData that joins the highest preceding element in newData. @@ -55,18 +51,18 @@ export const findNeighbor = (i, identity, prevData, newData) => { * @returns {*} */ export const findPreceding = (i, identity, prevData, newData) => { - const m = prevData.length; + const m = prevData.length while (--i >= 0) { - let k = identity(newData[i]); + let k = identity(newData[i]) for (let j = 0; j < m; ++j) { if (identity(prevData[j]) === k) { - return prevData[j]; + return prevData[j] } } } -}; +} /** * Find the element in prevData that joins the lowest following element in newData. @@ -78,19 +74,19 @@ export const findPreceding = (i, identity, prevData, newData) => { * @returns {*} */ export const findFollowing = (i, identity, prevData, newData) => { - const n = newData.length; - const m = prevData.length; + const n = newData.length + const m = prevData.length while (++i < n) { - let k = identity(newData[i]); + let k = identity(newData[i]) for (let j = 0; j < m; ++j) { if (identity(prevData[j]) === k) { - return prevData[j]; + return prevData[j] } } } -}; - +} -export const midAngle = arc => arc.startAngle + (arc.endAngle - arc.startAngle) / 2; +export const midAngle = arc => + arc.startAngle + (arc.endAngle - arc.startAngle) / 2 diff --git a/src/ColorUtils.js b/src/ColorUtils.js index 902f87580..76c40986a 100644 --- a/src/ColorUtils.js +++ b/src/ColorUtils.js @@ -6,9 +6,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import _ from 'lodash' +import _ from 'lodash' import { spring } from 'react-motion' import { scaleOrdinal, @@ -39,10 +37,12 @@ export const getColorGenerator = instruction => { } if (instruction === 'inherit') { - return d => (d.color || d.data.color) + return d => d.color || d.data.color } - const inheritMatches = instruction.match(/inherit:(darker|brighter)\(([0-9.]+)\)/) + const inheritMatches = instruction.match( + /inherit:(darker|brighter)\(([0-9.]+)\)/ + ) if (inheritMatches) { const method = inheritMatches[1] const amount = inheritMatches[2] @@ -53,7 +53,6 @@ export const getColorGenerator = instruction => { return instruction } - export const getColorStyleObject = (instruction, property) => { const style = {} @@ -77,37 +76,47 @@ export const extractRGB = (_color, springConfig) => { } return { - colorR: spring(color.r, Object.assign({}, springConfig, { precision: 1 })), - colorG: spring(color.g, Object.assign({}, springConfig, { precision: 1 })), - colorB: spring(color.b, Object.assign({}, springConfig, { precision: 1 })), + colorR: spring( + color.r, + Object.assign({}, springConfig, { precision: 1 }) + ), + colorG: spring( + color.g, + Object.assign({}, springConfig, { precision: 1 }) + ), + colorB: spring( + color.b, + Object.assign({}, springConfig, { precision: 1 }) + ), } } const d3Colors = { - d310: scaleOrdinal(schemeCategory10), - d320: scaleOrdinal(schemeCategory20), - d320b: scaleOrdinal(schemeCategory20b), - d320c: scaleOrdinal(schemeCategory20c), - accent: scaleOrdinal(schemeAccent), - dark2: scaleOrdinal(schemeDark2), - paired: scaleOrdinal(schemePaired), + d310: scaleOrdinal(schemeCategory10), + d320: scaleOrdinal(schemeCategory20), + d320b: scaleOrdinal(schemeCategory20b), + d320c: scaleOrdinal(schemeCategory20c), + accent: scaleOrdinal(schemeAccent), + dark2: scaleOrdinal(schemeDark2), + paired: scaleOrdinal(schemePaired), pastel1: scaleOrdinal(schemePastel1), pastel2: scaleOrdinal(schemePastel2), - set1: scaleOrdinal(schemeSet1), - set2: scaleOrdinal(schemeSet2), - set3: scaleOrdinal(schemeSet3), + set1: scaleOrdinal(schemeSet1), + set2: scaleOrdinal(schemeSet2), + set3: scaleOrdinal(schemeSet3), } -export const nivoCategoricalColors = () => scaleOrdinal([ - '#e8c1a0', - '#f47560', - '#f1e15b', - '#e8a838', - '#61cdbb', - '#97e3d5', -]) +export const nivoCategoricalColors = () => + scaleOrdinal([ + '#e8c1a0', + '#f47560', + '#f1e15b', + '#e8a838', + '#61cdbb', + '#97e3d5', + ]) -const dataColor = d => (d.color || d.data.color) +const dataColor = d => d.color || d.data.color export const getColorRange = instruction => { if (instruction === 'data') { @@ -130,5 +139,5 @@ export const getColorRange = instruction => { return scaleOrdinal(instruction) } - throw new Error('Unable to determine color range') -} \ No newline at end of file + return () => instruction +} diff --git a/src/DataUtils.js b/src/DataUtils.js index c10f3b478..5ddcd0b22 100644 --- a/src/DataUtils.js +++ b/src/DataUtils.js @@ -6,15 +6,17 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import _ from 'lodash'; - +import _ from 'lodash' const recursiveFlattener = (stack, node, identityProperty, parentId) => { if (node.children) { node.children.forEach(child => { - recursiveFlattener(stack, child, identityProperty, node[identityProperty]); + recursiveFlattener( + stack, + child, + identityProperty, + node[identityProperty] + ) }) } else { stack.push(_.assign({}, node, { parentId })) @@ -22,7 +24,7 @@ const recursiveFlattener = (stack, node, identityProperty, parentId) => { } export const flatten = (root, identityProperty) => { - const nodes = []; + const nodes = [] recursiveFlattener(nodes, root, identityProperty) diff --git a/src/HierarchyUtils.js b/src/HierarchyUtils.js index 58fab0a9e..8ea01d493 100644 --- a/src/HierarchyUtils.js +++ b/src/HierarchyUtils.js @@ -6,19 +6,16 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -export const HIERARCHICAL_NODE_TYPE_ROOT = 'root'; -export const HIERARCHICAL_NODE_TYPE_INTERMEDIATE = 'intermediate'; -export const HIERARCHICAL_NODE_TYPE_LEAF = 'leaf'; - +export const HIERARCHICAL_NODE_TYPE_ROOT = 'root' +export const HIERARCHICAL_NODE_TYPE_INTERMEDIATE = 'intermediate' +export const HIERARCHICAL_NODE_TYPE_LEAF = 'leaf' export const getHierarchicalNodeType = node => { if (node.depth === 0) { - return HIERARCHICAL_NODE_TYPE_ROOT; + return HIERARCHICAL_NODE_TYPE_ROOT } else if (!node.children || node.children.length === 0) { - return HIERARCHICAL_NODE_TYPE_LEAF; + return HIERARCHICAL_NODE_TYPE_LEAF } - return HIERARCHICAL_NODE_TYPE_INTERMEDIATE; -}; + return HIERARCHICAL_NODE_TYPE_INTERMEDIATE +} diff --git a/src/Nivo.js b/src/Nivo.js index 385797736..819730a64 100644 --- a/src/Nivo.js +++ b/src/Nivo.js @@ -6,30 +6,42 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' -import { scaleOrdinal } from 'd3' -import { schemeSet3 } from 'd3-scale-chromatic' +import { scaleOrdinal } from 'd3' +import { schemeSet3 } from 'd3-scale-chromatic' import { nivoCategoricalColors } from './ColorUtils' const defaults = { transitionDuration: 600, - transitionEasing: 'cubic-out', - motionStiffness: 120, - motionDamping: 10, - colorRange: scaleOrdinal(schemeSet3), - margin: { - top: 0, - right: 0, + transitionEasing: 'cubic-out', + motionStiffness: 120, + motionDamping: 10, + colorRange: scaleOrdinal(schemeSet3), + margin: { + top: 0, + right: 0, bottom: 0, - left: 0, + left: 0, }, -}; +} +export const defaultTheme = { + axis: { + textColor: '#000', + fontSize: '11px', + tickColor: '#000', + legendColor: '#000', + legendFontSize: '11px', + }, + grid: { + stroke: '#000', + strokeDasharray: '3,6', + }, +} export default { defaults, colors: { - nivoCategoricalColors - } -}; + nivoCategoricalColors, + }, +} diff --git a/src/PropTypes.js b/src/PropTypes.js index 57654328d..fa7adc829 100644 --- a/src/PropTypes.js +++ b/src/PropTypes.js @@ -6,37 +6,35 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import { PropTypes } from 'react' +import PropTypes from 'prop-types' const { number, string, array, shape, oneOf } = PropTypes export const lineInterpolation = oneOf([ - 'linear', // piecewise linear segments, as in a polyline. - 'linear-closed', // close the linear segments to form a polygon. - 'step', // alternate between horizontal and vertical segments, as in a step function. - 'step-before', // alternate between vertical and horizontal segments, as in a step function. - 'step-after', // alternate between horizontal and vertical segments, as in a step function. - 'basis', // a B-spline, with control point duplication on the ends. - 'basis-open', // an open B-spline; may not intersect the start or end. - 'basis-closed', // a closed B-spline, as in a loop. - 'bundle', // equivalent to basis, except the tension parameter is used to straighten the spline. - 'cardinal', // a Cardinal spline, with control point duplication on the ends. - 'cardinal-open', // an open Cardinal spline; may not intersect the start or end, but will intersect other control points. + 'linear', // piecewise linear segments, as in a polyline. + 'linear-closed', // close the linear segments to form a polygon. + 'step', // alternate between horizontal and vertical segments, as in a step function. + 'step-before', // alternate between vertical and horizontal segments, as in a step function. + 'step-after', // alternate between horizontal and vertical segments, as in a step function. + 'basis', // a B-spline, with control point duplication on the ends. + 'basis-open', // an open B-spline; may not intersect the start or end. + 'basis-closed', // a closed B-spline, as in a loop. + 'bundle', // equivalent to basis, except the tension parameter is used to straighten the spline. + 'cardinal', // a Cardinal spline, with control point duplication on the ends. + 'cardinal-open', // an open Cardinal spline; may not intersect the start or end, but will intersect other control points. 'cardinal-closed', // a closed Cardinal spline, as in a loop. - 'monotone' // cubic interpolation that preserves monotonicity in y. + 'monotone', // cubic interpolation that preserves monotonicity in y. ]) export const scale = shape({ - type: string.isRequired, + type: string.isRequired, domain: array.isRequired, - range: array.isRequired, + range: array.isRequired, }) export const margin = shape({ - top: number, - right: number, + top: number, + right: number, bottom: number, - left: number, + left: number, }).isRequired diff --git a/src/components/Chart.js b/src/components/Chart.js deleted file mode 100644 index 6bc3aa0a4..000000000 --- a/src/components/Chart.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of the nivo project. - * - * (c) Raphaël Benitte - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import Dimensions from 'react-dimensions'; -import _ from 'lodash'; -import Nivo from '../Nivo'; - - -class Chart extends Component { - render() { - const { - containerWidth, - containerHeight, - children - } = this.props; - - const margin = _.assign({}, Nivo.defaults.margin, this.props.margin); - const width = containerWidth - margin.left - margin.right; - const height = containerHeight - margin.top - margin.bottom; - - return ( - - - {React.Children.map(children, child => ( - React.cloneElement(child, { width, height }) - ))} - - - ); - } -} - -Chart.displayName = 'Chart'; - -Chart.propTypes = { - containerWidth: PropTypes.number.isRequired, - containerHeight: PropTypes.number.isRequired, - margin: PropTypes.shape({ - top: PropTypes.number, - right: PropTypes.number, - bottom: PropTypes.number, - left: PropTypes.number - }).isRequired -}; - -Chart.defaultProps = { - margin: Nivo.defaults.margin -}; - - -export default Dimensions()(Chart); diff --git a/src/components/axes/Axis.js b/src/components/axes/Axis.js index f609f7ba7..3969b2c15 100644 --- a/src/components/axes/Axis.js +++ b/src/components/axes/Axis.js @@ -6,14 +6,12 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component, PropTypes } from 'react' -import { TransitionMotion, spring } from 'react-motion' -import { max } from 'd3' -import Nivo from '../../Nivo' -import AxisTick from './AxisTick' - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { TransitionMotion, spring } from 'react-motion' +import { max } from 'd3' +import Nivo from '../../Nivo' +import AxisTick from './AxisTick' const center = scale => { let offset = scale.bandwidth() / 2 @@ -22,13 +20,47 @@ const center = scale => { return d => scale(d) + offset } +export default class Axis extends Component { + static propTypes = { + width: PropTypes.number.isRequired, + height: PropTypes.number.isRequired, + orient: PropTypes.oneOf(['top', 'right', 'bottom', 'left']), + position: PropTypes.oneOf(['top', 'right', 'bottom', 'left']) + .isRequired, + scale: PropTypes.func.isRequired, + // ticks + tickSize: PropTypes.number.isRequired, + tickPadding: PropTypes.number.isRequired, + format: PropTypes.func, + // legend + legend: PropTypes.string, + legendPosition: PropTypes.oneOf(['start', 'center', 'end']).isRequired, + legendOffset: PropTypes.number.isRequired, + theme: PropTypes.object.isRequired, + // motion + animate: PropTypes.bool.isRequired, + motionStiffness: PropTypes.number.isRequired, + motionDamping: PropTypes.number.isRequired, + } + + static defaultProps = { + // ticks + tickSize: 5, + tickPadding: 5, + // legend + legendPosition: 'end', + legendOffset: 0, + // motion + animate: true, + motionStiffness: Nivo.defaults.motionStiffness, + motionDamping: Nivo.defaults.motionDamping, + } -class Axis extends Component { willEnter() { return { opacity: 0, - x: 0, - y: 0, + x: 0, + y: 0, } } @@ -37,20 +69,29 @@ class Axis extends Component { return { opacity: spring(0), - x: spring(style.x.val), - y: spring(style.y.val), + x: spring(style.x.val), + y: spring(style.y.val), } } render() { const { - orient, scale, + width, + height, + position: _position, + orient: _orient, tickSize, tickPadding, + format, + legend: _legend, + legendPosition, + legendOffset, + theme, animate, - motionStiffness, motionDamping, - } = this.props + motionStiffness, + motionDamping, + } = this.props let values if (scale.ticks) { @@ -59,62 +100,115 @@ class Axis extends Component { values = scale.domain() } - const position = (scale.bandwidth ? center(scale) : scale) + const orient = _orient || _position + const position = scale.bandwidth ? center(scale) : scale + let x = 0 + let y = 0 let translate let textAnchor let textDY const tickLine = { x2: 0, y2: 0 } - const textXY = { x: 0, y: 0 } + const textXY = { x: 0, y: 0 } if (['top', 'bottom'].includes(orient)) { translate = d => ({ x: position(d), y: 0 }) textAnchor = 'middle' - textDY = orient === 'top' ? '0em' : '0.71em' - textXY.y = (tickSize + tickPadding) * (orient === 'bottom' ? 1 : -1) + textDY = orient === 'top' ? '0em' : '0.71em' + textXY.y = (tickSize + tickPadding) * (orient === 'bottom' ? 1 : -1) tickLine.y2 = tickSize * (orient === 'bottom' ? 1 : -1) + + if (orient === 'bottom') y = height } else if (['left', 'right'].includes(orient)) { translate = d => ({ x: 0, y: position(d) }) textAnchor = orient === 'left' ? 'end' : 'start' - textDY = '0.32em' - textXY.x = (tickSize + tickPadding) * (orient === 'right' ? 1 : -1) + textDY = '0.32em' + textXY.x = (tickSize + tickPadding) * (orient === 'right' ? 1 : -1) tickLine.x2 = tickSize * (orient === 'right' ? 1 : -1) + + if (orient === 'right') x = width } - const ticks = values.map(v => { - return { - key: v, - ...translate(v), + let legend = null + if (_legend !== undefined) { + let legendX = 0 + let legendY = 0 + let legendRotation = 0 + let textAnchor + + if (['left', 'right'].includes(_position)) { + legendRotation = -90 + legendX = legendOffset + if (legendPosition === 'start') { + textAnchor = 'start' + legendY = height + } else if (legendPosition === 'center') { + textAnchor = 'middle' + legendY = height / 2 + } else if (legendPosition === 'end') { + textAnchor = 'end' + } + } else { + legendY = legendOffset + if (legendPosition === 'start') { + textAnchor = 'start' + } else if (legendPosition === 'center') { + textAnchor = 'middle' + legendX = width / 2 + } else if (legendPosition === 'end') { + textAnchor = 'end' + legendX = width + } } - }) + + legend = ( + + {_legend} + + ) + } + + const ticks = values.map(v => ({ + key: v, + ...translate(v), + })) const springConfig = { stiffness: motionStiffness, - damping: motionDamping, + damping: motionDamping, } return ( - + + {legend} { return { - key: `${tick.key}`, - data: tick.key, + key: `${tick.key}`, + data: tick.key, style: { - opacity: spring(1, springConfig), - x: spring(tick.x, springConfig), - y: spring(tick.y, springConfig), - } + opacity: spring(1, springConfig), + x: spring(tick.x, springConfig), + y: spring(tick.y, springConfig), + }, } })} > - {interpolatedStyles => ( + {interpolatedStyles => {interpolatedStyles.map(interpolatedStyle => { const { key, style } = interpolatedStyle @@ -122,43 +216,19 @@ class Axis extends Component { ) })} - - )} + } ) } } - -Axis.propTypes = { - orient: PropTypes.oneOf(['top', 'right', 'bottom', 'left']).isRequired, - scale: PropTypes.any.isRequired, - tickSize: PropTypes.number.isRequired, - tickPadding: PropTypes.number.isRequired, - - // motion - animate: PropTypes.bool.isRequired, - motionStiffness: PropTypes.number.isRequired, - motionDamping: PropTypes.number.isRequired, -} - -Axis.defaultProps = { - tickSize: 5, - tickPadding: 5, - - // motion - animate: true, - motionStiffness: Nivo.defaults.motionStiffness, - motionDamping: Nivo.defaults.motionDamping, -} - - -export default Axis diff --git a/src/components/axes/AxisTick.js b/src/components/axes/AxisTick.js index 89a910202..a0197e98b 100644 --- a/src/components/axes/AxisTick.js +++ b/src/components/axes/AxisTick.js @@ -6,40 +6,45 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component, PropTypes } from 'react' +import React, { Component } from 'react' +import PropTypes from 'prop-types' +export default class AxisTick extends Component { + static propTypes = { + format: PropTypes.func, + theme: PropTypes.object.isRequired, + } -class AxisTick extends Component { render() { const { - value, - x, y, + value: _value, + x, + y, + format, opacity, tickLine, textXY, textDY, textAnchor, + theme, } = this.props + let value = _value + if (format !== undefined) { + value = format(value) + } + return ( - - + + {value} @@ -47,13 +52,3 @@ class AxisTick extends Component { ) } } - -AxisTick.propTypes = { -} - -AxisTick.defaultProps = { -} - - - -export default AxisTick diff --git a/src/components/axes/AxisX.js b/src/components/axes/AxisX.js index b29e7600b..1073ff0ad 100644 --- a/src/components/axes/AxisX.js +++ b/src/components/axes/AxisX.js @@ -6,11 +6,10 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import { findDOMNode } from 'react-dom'; -import d3 from 'd3'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { findDOMNode } from 'react-dom' +import d3 from 'd3' class AxisX extends Component { renderD3(props) { @@ -21,20 +20,20 @@ class AxisX extends Component { tickPadding, height, transitionDuration, - transitionEasing - } = props; + transitionEasing, + } = props - const element = d3.select(findDOMNode(this)); - element.attr('transform', `translate(0, ${height})`); + const element = d3.select(findDOMNode(this)) + element.attr('transform', `translate(0, ${height})`) - const axis = d3.svg.axis() + const axis = d3.svg + .axis() .scale(xScale) .tickPadding(tickPadding) .orient(orient) - ; if (tickMode === 'grid') { - axis.tickSize(-height); + axis.tickSize(-height) } element @@ -42,42 +41,40 @@ class AxisX extends Component { .duration(transitionDuration) .ease(transitionEasing) .call(axis) - ; - return false; + return false } componentDidMount() { - this.renderD3(this.props); + this.renderD3(this.props) } shouldComponentUpdate(nextProps) { - this.renderD3(nextProps); + this.renderD3(nextProps) - return false; + return false } render() { - return ; + return } } -AxisX.displayName = 'AxisX'; +AxisX.displayName = 'AxisX' AxisX.propTypes = { - orient: PropTypes.oneOf(['top', 'bottom']).isRequired, - xScale: PropTypes.func.isRequired, - tickMode: PropTypes.oneOf(['normal', 'grid']).isRequired, - tickPadding: PropTypes.number.isRequired -}; + orient: PropTypes.oneOf(['top', 'bottom']).isRequired, + xScale: PropTypes.func.isRequired, + tickMode: PropTypes.oneOf(['normal', 'grid']).isRequired, + tickPadding: PropTypes.number.isRequired, +} AxisX.defaultProps = { - orient: 'bottom', + orient: 'bottom', transitionDuration: 600, - transitionEasing: 'cubic-out', - tickMode: 'normal', - tickPadding: 3 -}; - + transitionEasing: 'cubic-out', + tickMode: 'normal', + tickPadding: 3, +} -export default AxisX; +export default AxisX diff --git a/src/components/axes/AxisY.js b/src/components/axes/AxisY.js index 345713330..a6a47d39e 100644 --- a/src/components/axes/AxisY.js +++ b/src/components/axes/AxisY.js @@ -6,11 +6,10 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import { findDOMNode } from 'react-dom'; -import d3 from 'd3'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { findDOMNode } from 'react-dom' +import d3 from 'd3' class AxisY extends Component { renderD3(props) { @@ -23,28 +22,28 @@ class AxisY extends Component { tickPadding, width, transitionDuration, - transitionEasing - } = props; + transitionEasing, + } = props - const element = d3.select(findDOMNode(this)); + const element = d3.select(findDOMNode(this)) - const axis = d3.svg.axis() + const axis = d3.svg + .axis() .scale(yScale) .tickPadding(tickPadding) .orient(orient) .tickFormat(d3.format('s')) - ; if (tickCount >= 0) { - axis.ticks(tickCount); + axis.ticks(tickCount) } if (tickFormat) { - axis.tickFormat(d3.format(tickFormat)); + axis.tickFormat(d3.format(tickFormat)) } if (tickMode === 'grid') { - axis.tickSize(-width); + axis.tickSize(-width) } element @@ -52,44 +51,42 @@ class AxisY extends Component { .duration(transitionDuration) .ease(transitionEasing) .call(axis) - ; - return false; + return false } componentDidMount() { - this.renderD3(this.props); + this.renderD3(this.props) } shouldComponentUpdate(nextProps) { - this.renderD3(nextProps); + this.renderD3(nextProps) - return false; + return false } render() { - return ; + return } } -AxisY.displayName = 'AxisY'; +AxisY.displayName = 'AxisY' AxisY.propTypes = { - orient: PropTypes.oneOf(['left', 'right']).isRequired, - yScale: PropTypes.func.isRequired, - tickCount: PropTypes.number.isRequired, - tickMode: PropTypes.oneOf(['normal', 'grid']).isRequired, - tickPadding: PropTypes.number.isRequired -}; + orient: PropTypes.oneOf(['left', 'right']).isRequired, + yScale: PropTypes.func.isRequired, + tickCount: PropTypes.number.isRequired, + tickMode: PropTypes.oneOf(['normal', 'grid']).isRequired, + tickPadding: PropTypes.number.isRequired, +} AxisY.defaultProps = { - orient: 'left', + orient: 'left', transitionDuration: 600, - transitionEasing: 'cubic-out', - tickCount: -1, - tickMode: 'normal', - tickPadding: 3 -}; - + transitionEasing: 'cubic-out', + tickCount: -1, + tickMode: 'normal', + tickPadding: 3, +} -export default AxisY; +export default AxisY diff --git a/src/components/axes/Grid.js b/src/components/axes/Grid.js index be05ef61f..d7eac17e8 100644 --- a/src/components/axes/Grid.js +++ b/src/components/axes/Grid.js @@ -6,13 +6,11 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component, PropTypes } from 'react' -import Nivo from '../../Nivo' -import GridLines from './GridLines' -import GridLine from './GridLine' - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Nivo from '../../Nivo' +import GridLines from './GridLines' +import GridLine from './GridLine' const center = scale => { let offset = scale.bandwidth() / 2 @@ -21,91 +19,102 @@ const center = scale => { return d => scale(d) + offset } +export default class Grid extends Component { + static propTypes = { + width: PropTypes.number.isRequired, + height: PropTypes.number.isRequired, + xScale: PropTypes.func, + yScale: PropTypes.func, + theme: PropTypes.object.isRequired, + // motion + animate: PropTypes.bool.isRequired, + motionStiffness: PropTypes.number.isRequired, + motionDamping: PropTypes.number.isRequired, + } + + static defaultProps = { + // motion + animate: true, + motionStiffness: Nivo.defaults.motionStiffness, + motionDamping: Nivo.defaults.motionDamping, + } -class Grid extends Component { render() { const { - width, height, - xScale, yScale, + width, + height, + scales, + xScale, + yScale, + theme, animate, - motionStiffness, motionDamping, + motionStiffness, + motionDamping, } = this.props - let xValues - if (xScale.ticks) { - xValues = xScale.ticks() - } else { - xValues = xScale.domain() - } + let xLines + if (xScale) { + let xValues + if (xScale.ticks) { + xValues = xScale.ticks() + } else { + xValues = xScale.domain() + } - const xPosition = (xScale.bandwidth ? center(xScale) : xScale) + const xPosition = xScale.bandwidth ? center(xScale) : xScale - let yValues - if (yScale.ticks) { - yValues = yScale.ticks() - } else { - yValues = yScale.domain() + xLines = xValues.map(v => { + return { + key: `${v}`, + x1: xPosition(v), + x2: xPosition(v), + y2: height, + } + }) } - const yPosition = (yScale.bandwidth ? center(yScale) : yScale) - - const xLines = xValues.map(v => { - return { - key: `${v}`, - x1: xPosition(v), - x2: xPosition(v), - y2: height, + let yLines + if (yScale) { + let yValues + if (yScale.ticks) { + yValues = yScale.ticks() + } else { + yValues = yScale.domain() } - }) - const yLines = yValues.map(v => { - return { - key: `${v}`, - x2: width, - y1: yPosition(v), - y2: yPosition(v), - } - }) + const yPosition = yScale.bandwidth ? center(yScale) : yScale + + yLines = yValues.map(v => { + return { + key: `${v}`, + x2: width, + y1: yPosition(v), + y2: yPosition(v), + } + }) + } return ( - - - + + {xLines && + } + {yLines && + } ) } } - -Grid.propTypes = { - width: PropTypes.number.isRequired, - height: PropTypes.number.isRequired, - xScale: PropTypes.any.isRequired, - yScale: PropTypes.any.isRequired, - // motion - animate: PropTypes.bool.isRequired, - motionStiffness: PropTypes.number.isRequired, - motionDamping: PropTypes.number.isRequired, -} - -Grid.defaultProps = { - // motion - animate: true, - motionStiffness: Nivo.defaults.motionStiffness, - motionDamping: Nivo.defaults.motionDamping, -} - - - -export default Grid diff --git a/src/components/axes/GridLine.js b/src/components/axes/GridLine.js index a3e553cf6..cf28eb8fc 100644 --- a/src/components/axes/GridLine.js +++ b/src/components/axes/GridLine.js @@ -6,18 +6,10 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' +import React from 'react' +import PropTypes from 'prop-types' -import React, { PropTypes } from 'react' - - -const GridLine = props => ( - -) +const GridLine = props => GridLine.propTypes = { x1: PropTypes.number.isRequired, @@ -33,5 +25,4 @@ GridLine.defaultProps = { y2: 0, } - export default GridLine diff --git a/src/components/axes/GridLines.js b/src/components/axes/GridLines.js index 4a58bb099..d2441a5f8 100644 --- a/src/components/axes/GridLines.js +++ b/src/components/axes/GridLines.js @@ -6,15 +6,31 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component, PropTypes } from 'react' -import { TransitionMotion, spring } from 'react-motion' -import Nivo from '../../Nivo' -import GridLine from './GridLine' - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { TransitionMotion, spring } from 'react-motion' +import Nivo from '../../Nivo' +import GridLine from './GridLine' + +export default class GridLines extends Component { + static propTypes = { + type: PropTypes.oneOf(['x', 'y']).isRequired, + lines: PropTypes.arrayOf( + PropTypes.shape({ + key: PropTypes.string.isRequired, + x1: PropTypes.number, + x2: PropTypes.number, + y1: PropTypes.number, + y2: PropTypes.number, + }) + ).isRequired, + theme: PropTypes.object.isRequired, + // motion + animate: PropTypes.bool.isRequired, + motionStiffness: PropTypes.number.isRequired, + motionDamping: PropTypes.number.isRequired, + } -class GridLines extends Component { constructor(props) { super(props) @@ -27,10 +43,10 @@ class GridLines extends Component { return { opacity: 0, - x1: type === 'x' ? 0 : style.x1.val, - x2: type === 'x' ? 0 : style.x2.val, - y1: type === 'y' ? 0 : style.y1.val, - y2: type === 'y' ? 0 : style.y2.val, + x1: type === 'x' ? 0 : style.x1.val, + x2: type === 'x' ? 0 : style.x2.val, + y1: type === 'y' ? 0 : style.y1.val, + y2: type === 'y' ? 0 : style.y2.val, } } @@ -38,15 +54,15 @@ class GridLines extends Component { const { motionStiffness, motionDamping } = this.props const springConfig = { stiffness: motionStiffness, - damping: motionDamping, + damping: motionDamping, } return { - opacity: spring(0, springConfig), - x1: spring(style.x1.val, springConfig), - x2: spring(style.x2.val, springConfig), - y1: spring(style.y1.val, springConfig), - y2: spring(style.y2.val, springConfig), + opacity: spring(0, springConfig), + x1: spring(style.x1.val, springConfig), + x2: spring(style.x2.val, springConfig), + y1: spring(style.y1.val, springConfig), + y2: spring(style.y2.val, springConfig), } } @@ -54,20 +70,22 @@ class GridLines extends Component { const { lines, animate, - motionStiffness, motionDamping, + motionStiffness, + motionDamping, + theme, } = this.props if (!animate) { return ( - {lines.map(line => ())} + {lines.map(line => )} ) } const springConfig = { stiffness: motionStiffness, - damping: motionDamping, + damping: motionDamping, } return ( @@ -76,18 +94,18 @@ class GridLines extends Component { willLeave={this.willLeave} styles={lines.map(line => { return { - key: line.key, + key: line.key, style: { - opacity: spring(1, springConfig), - x1: spring(line.x1 || 0, springConfig), - x2: spring(line.x2 || 0, springConfig), - y1: spring(line.y1 || 0, springConfig), - y2: spring(line.y2 || 0, springConfig), - } + opacity: spring(1, springConfig), + x1: spring(line.x1 || 0, springConfig), + x2: spring(line.x2 || 0, springConfig), + y1: spring(line.y1 || 0, springConfig), + y2: spring(line.y2 || 0, springConfig), + }, } })} > - {interpolatedStyles => ( + {interpolatedStyles => {interpolatedStyles.map(interpolatedStyle => { const { key, style } = interpolatedStyle @@ -95,38 +113,13 @@ class GridLines extends Component { return ( ) })} - - )} + } ) } } - -GridLines.propTypes = { - type: PropTypes.oneOf(['x', 'y']).isRequired, - lines: PropTypes.arrayOf(PropTypes.shape({ - key: PropTypes.string.isRequired, - x1: PropTypes.number, - x2: PropTypes.number, - y1: PropTypes.number, - y2: PropTypes.number, - })).isRequired, - // motion - animate: PropTypes.bool.isRequired, - motionStiffness: PropTypes.number.isRequired, - motionDamping: PropTypes.number.isRequired, -} - -GridLines.defaultProps = { - // motion - animate: true, - motionStiffness: Nivo.defaults.motionStiffness, - motionDamping: Nivo.defaults.motionDamping, -} - - -export default GridLines diff --git a/src/components/axes/index.js b/src/components/axes/index.js index eece72117..d13b0cf28 100644 --- a/src/components/axes/index.js +++ b/src/components/axes/index.js @@ -6,8 +6,5 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - - export Axis from './Axis' export Grid from './Grid' diff --git a/src/components/charts/Chart.js b/src/components/charts/Chart.js new file mode 100644 index 000000000..1c9255b0f --- /dev/null +++ b/src/components/charts/Chart.js @@ -0,0 +1,130 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import _ from 'lodash' +import Nivo from '../../Nivo' +import { margin as marginPropType } from '../../PropTypes' +import Scale from '../scales/Scale' + +const defaultTheme = { + axis: { + textColor: '#000', + fontSize: '11px', + tickColor: '#000', + legendColor: '#000', + legendFontSize: '11px', + }, + grid: { + stroke: '#000', + strokeDasharray: '3,6', + }, +} + +export default class Chart extends Component { + static propTypes = { + // dimensions + width: PropTypes.number.isRequired, + height: PropTypes.number.isRequired, + margin: marginPropType, + // composition + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node, + ]), + // data + data: PropTypes.arrayOf(PropTypes.object).isRequired, + // motion + animate: PropTypes.bool.isRequired, + motionStiffness: PropTypes.number.isRequired, + motionDamping: PropTypes.number.isRequired, + } + + static defaultProps = { + // dimensions + margin: Nivo.defaults.margin, + // motion + animate: true, + motionStiffness: Nivo.defaults.motionStiffness, + motionDamping: Nivo.defaults.motionDamping, + } + + static childContextTypes = { + nivoTheme: PropTypes.object.isRequired, + } + + getChildContext() { + const theme = _.merge({}, defaultTheme, this.props.theme || {}) + + return { nivoTheme: theme } + } + + render() { + const { + data, + children, + margin: _margin, + width: _width, + height: _height, + animate, + motionStiffness, + motionDamping, + } = this.props + + const animationProps = { + animate, + motionStiffness, + motionDamping, + } + + const margin = Object.assign({}, Nivo.defaults.margin, _margin) + const width = _width - margin.left - margin.right + const height = _height - margin.top - margin.bottom + + const scales = {} + const axes = [] + const items = [] + + React.Children.forEach(children, (child, i) => { + if (child.type === Scale) { + scales[child.props.id] = Scale.create( + child.props, + data, + width, + height + ) + } else { + const item = React.cloneElement(child, { + ...child.props, + ...animationProps, + key: i, + data, + scales, + width, + height, + }) + + items.push(item) + } + }) + + return ( + + + {axes} + {items} + + + ) + } +} diff --git a/src/components/charts/Markers.js b/src/components/charts/Markers.js new file mode 100644 index 000000000..c778bea3b --- /dev/null +++ b/src/components/charts/Markers.js @@ -0,0 +1,234 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import _ from 'lodash' +import Nivo from '../../../Nivo' +import { getColorRange } from '../../../ColorUtils' +import { convertGetter } from '../../../lib/propertiesConverters' +import BarItem from './BarItem' +import BarItemLabel from './BarItemLabel' + +export default class Markers extends Component { + static propTypes = { + colors: PropTypes.any.isRequired, + scales: PropTypes.object, + width: PropTypes.number, + height: PropTypes.number, + // labels + enableLabels: PropTypes.bool.isRequired, + // motion + animate: PropTypes.bool.isRequired, + motionStiffness: PropTypes.number.isRequired, + motionDamping: PropTypes.number.isRequired, + } + + static defaultProps = { + colors: Nivo.defaults.colorRange, + // labels + enableLabels: true, + // motion + animate: true, + motionStiffness: Nivo.defaults.motionStiffness, + motionDamping: Nivo.defaults.motionDamping, + } + + render() { + const { + data, + scales, + xScale: _xScale, + yScale: _yScale, + width, + height, + color, + x, + y, + } = this.props + + const xScale = scales[_xScale] + const yScale = scales[_yScale] + + const getX = _.isFunction(x) ? x : d => d[x] + const getY = _.isFunction(y) ? y : d => d[y] + + const rects = [] + data.forEach((d, i) => { + let x + let y + let barWidth + let barHeight + + if (xScale.bandwidth) { + barWidth = xScale.bandwidth() // / series.length + x = xScale(getX(d)) // + barWidth * serieIndex + } else { + x = 0 + barWidth = xScale(getX(d)) + } + + if (yScale.bandwidth) { + barHeight = yScale.bandwidth() // / series.length + y = yScale(getY(d)) // + barHeight * serieIndex + } else { + y = yScale(getY(d)) + barHeight = height - y + } + + if (barWidth > 0 && barHeight > 0) { + rects.push({ + key: `bar.${i}`, + //value, + x, + y, + width: barWidth, + height: barHeight, + color: color, //'#fff', //color(serieIndex), + }) + } + }) + + return ( + + {rects.map(d => )} + + ) + /* + const { + data, + groupMode, + identity: _identity, + margin: _margin, + width: _width, height: _height, + colors, + scales: _scales, + series, + axes, + enableGridX, enableGridY, + enableLabels, + animate, motionStiffness, motionDamping, + } = this.props + + const margin = Object.assign({}, Nivo.defaults.margin, _margin) + const width = _width - margin.left - margin.right + const height = _height - margin.top - margin.bottom + + const color = getColorRange(colors) + + const rects = [] + series.forEach((serie, serieIndex) => { + const xScale = scales[serie.xScale] + const yScale = scales[serie.yScale] + + const getX = _.isFunction(serie.x) ? serie.x : d => d[serie.x] + const getY = _.isFunction(serie.y) ? serie.y : d => d[serie.y] + + data.forEach((d, i) => { + let x + let y + let barWidth + let barHeight + + if (xScale.bandwidth) { + barWidth = xScale.bandwidth() / series.length + x = xScale(getX(d)) + barWidth * serieIndex + } else { + x = 0 + barWidth = xScale(getX(d)) + } + + if (yScale.bandwidth) { + barHeight = yScale.bandwidth() / series.length + y = yScale(getY(d)) + barHeight * serieIndex + } else { + y = yScale(getY(d)) + barHeight = height - y + } + + if (barWidth > 0 && barHeight > 0) { + rects.push({ + key: `${serieIndex}.${i}`, + //value, + x, y, + width: barWidth, + height: barHeight, + color: color(serieIndex), + }) + } + }) + }) + + /* + if (groupMode === 'stacked') { + const series = stack().keys(keys)(data) + + y.domain([0, max(series[series.length - 1], d => d[1])]) + + series.forEach(serie => { + serie.forEach(d => { + rects.push({ + key: `${serie.key}.${identity(d.data)}`, + value: d[1], + x: x(identity(d.data)), + y: y(d[1]), + width: x.bandwidth(), + height: y(d[0]) - y(d[1]), + color: color(serie.key), + }) + }) + }) + } else { + y.domain([0, max(data, d => max(_.values(_.pick(d, keys))))]) + + const barWidth = x.bandwidth() / keys.length + + data.forEach(bucket => { + let index = 0 + _.forOwn(_.pick(bucket, keys), (value, key) => { + rects.push({ + key: `${key}.${identity(bucket)}`, + value, + x: x(identity(bucket)) + barWidth * index, + y: y(value), + width: barWidth, + height: height - y(value), + color: color(key), + }) + index++ + }) + }) + } + + const { props } = this + + return ( + + + {rects.map(d => { + return ( + + ) + })} + {enableLabels && rects.map(d => { + return ( + + ) + })} + {['top', 'right', 'bottom', 'left'].map(orient => { + return getAxis(axes, scales, orient, width, height, props) + })} + + + ) + */ + } +} diff --git a/src/components/charts/ResponsiveChart.js b/src/components/charts/ResponsiveChart.js new file mode 100644 index 000000000..3a3b03938 --- /dev/null +++ b/src/components/charts/ResponsiveChart.js @@ -0,0 +1,48 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import React, { Component } from 'react' +import Measure from 'react-measure' +import Chart from './Chart' + +export default class ResponsiveChart extends Component { + state = { + dimensions: { + width: -1, + height: -1, + }, + } + + render() { + const { width, height } = this.state.dimensions + + const shouldRender = width > 0 && height > 0 + + return ( + { + this.setState({ dimensions: contentRect.bounds }) + }} + > + {({ measureRef }) => +
+ {shouldRender && + } +
} +
+ ) + } +} diff --git a/src/components/charts/ResponsiveWrapper.js b/src/components/charts/ResponsiveWrapper.js new file mode 100644 index 000000000..92bb90339 --- /dev/null +++ b/src/components/charts/ResponsiveWrapper.js @@ -0,0 +1,47 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Measure from 'react-measure' + +export default class ResponsiveWrapper extends Component { + static propTypes = { + children: PropTypes.func.isRequired, + } + + state = { + dimensions: { + width: -1, + height: -1, + }, + } + + render() { + const { width, height } = this.state.dimensions + + const shouldRender = width > 0 && height > 0 + + return ( + { + this.setState({ dimensions: contentRect.bounds }) + }} + > + {({ measureRef }) => +
+ {shouldRender && this.props.children({ width, height })} +
} +
+ ) + } +} diff --git a/src/components/charts/SvgWrapper.js b/src/components/charts/SvgWrapper.js new file mode 100644 index 000000000..1d9ee7877 --- /dev/null +++ b/src/components/charts/SvgWrapper.js @@ -0,0 +1,10 @@ +import React from 'react' + +const SvgWrapper = ({ width, height, margin, children }) => + + + {children} + + + +export default SvgWrapper diff --git a/src/components/charts/Tree.js b/src/components/charts/Tree.js index ae5bbbf03..6e425992e 100644 --- a/src/components/charts/Tree.js +++ b/src/components/charts/Tree.js @@ -6,212 +6,235 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import { findDOMNode } from 'react-dom'; -import Dimensions from 'react-dimensions'; -import _ from 'lodash'; -import d3 from 'd3'; -import Nivo from '../../Nivo'; -import { margin as marginPropType } from '../../PropTypes'; -import { getColorRange } from '../../ColorUtils'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { findDOMNode } from 'react-dom' +import Dimensions from 'react-dimensions' +import _ from 'lodash' +import d3 from 'd3' +import Nivo from '../../Nivo' +import { margin as marginPropType } from '../../PropTypes' +import { getColorRange } from '../../ColorUtils' import makeLabel, { LABEL_POSITION_TOP, LABEL_POSITION_RIGHT, LABEL_POSITION_BOTTOM, - LABEL_POSITION_LEFT -} from '../../lib/charts/labels'; + LABEL_POSITION_LEFT, +} from '../../lib/charts/labels' import { HIERARCHICAL_NODE_TYPE_ROOT, HIERARCHICAL_NODE_TYPE_LEAF, - getHierarchicalNodeType -} from '../../HierarchyUtils'; + getHierarchicalNodeType, +} from '../../HierarchyUtils' +const horizontalDiagonal = d3.svg.diagonal().projection(d => [d.y, d.x]) +const verticalDiagonal = d3.svg.diagonal().projection(d => [d.x, d.y]) -const horizontalDiagonal = d3.svg.diagonal().projection(d => [d.y, d.x]); -const verticalDiagonal = d3.svg.diagonal().projection(d => [d.x, d.y]); +const horizontalTransform = d => `translate(${d.y},${d.x})` +const verticalTransform = d => `translate(${d.x},${d.y})` -const horizontalTransform = d => `translate(${d.y},${d.x})`; -const verticalTransform = d => `translate(${d.x},${d.y})`; - -const horizontalLabelTextAnchor = d => d.children ? 'end' : 'start'; -const horizontalReverseLabelTextAnchor = d => d.children ? 'start' : 'end'; -const verticalLabelTextAnchor = 'middle'; +const horizontalLabelTextAnchor = d => (d.children ? 'end' : 'start') +const horizontalReverseLabelTextAnchor = d => (d.children ? 'start' : 'end') +const verticalLabelTextAnchor = 'middle' const labelPositions = { root: { - 'horizontal': LABEL_POSITION_LEFT, + horizontal: LABEL_POSITION_LEFT, 'horizontal-reverse': LABEL_POSITION_RIGHT, - 'vertical': LABEL_POSITION_TOP, - 'vertical-reverse': LABEL_POSITION_BOTTOM + vertical: LABEL_POSITION_TOP, + 'vertical-reverse': LABEL_POSITION_BOTTOM, }, intermediate: { - 'horizontal': LABEL_POSITION_LEFT, + horizontal: LABEL_POSITION_LEFT, 'horizontal-reverse': LABEL_POSITION_RIGHT, - 'vertical': LABEL_POSITION_TOP, - 'vertical-reverse': LABEL_POSITION_BOTTOM + vertical: LABEL_POSITION_TOP, + 'vertical-reverse': LABEL_POSITION_BOTTOM, }, leaf: { - 'horizontal': LABEL_POSITION_RIGHT, + horizontal: LABEL_POSITION_RIGHT, 'horizontal-reverse': LABEL_POSITION_LEFT, - 'vertical': LABEL_POSITION_LEFT, - 'vertical-reverse': LABEL_POSITION_RIGHT - } -}; - + vertical: LABEL_POSITION_LEFT, + 'vertical-reverse': LABEL_POSITION_RIGHT, + }, +} -const computeLabelPositions = ({ direction, rootLabelPosition, intermediateLabelPosition, leafLabelPosition }) => { - rootLabelPosition = rootLabelPosition || labelPositions.root[direction]; - intermediateLabelPosition = intermediateLabelPosition || labelPositions.intermediate[direction]; - leafLabelPosition = leafLabelPosition || labelPositions.leaf[direction]; +const computeLabelPositions = ({ + direction, + rootLabelPosition, + intermediateLabelPosition, + leafLabelPosition, +}) => { + rootLabelPosition = rootLabelPosition || labelPositions.root[direction] + intermediateLabelPosition = + intermediateLabelPosition || labelPositions.intermediate[direction] + leafLabelPosition = leafLabelPosition || labelPositions.leaf[direction] return { rootLabelPosition, intermediateLabelPosition, - leafLabelPosition - }; -}; + leafLabelPosition, + } +} const labelRotations = { root: { - 'horizontal': 0, + horizontal: 0, 'horizontal-reverse': 0, - 'vertical': 0, - 'vertical-reverse': 0 + vertical: 0, + 'vertical-reverse': 0, }, intermediate: { - 'horizontal': 0, + horizontal: 0, 'horizontal-reverse': 0, - 'vertical': 0, - 'vertical-reverse': 0 + vertical: 0, + 'vertical-reverse': 0, }, leaf: { - 'horizontal': 0, + horizontal: 0, 'horizontal-reverse': 0, - 'vertical': -90, - 'vertical-reverse': -90 - } -}; + vertical: -90, + 'vertical-reverse': -90, + }, +} -const computeLabelRotations = ({ direction, rootLabelRotation, intermediateLabelRotation, leafLabelRotation }) => { - rootLabelRotation = rootLabelRotation || labelRotations.root[direction]; - intermediateLabelRotation = intermediateLabelRotation || labelRotations.intermediate[direction]; - leafLabelRotation = leafLabelRotation || labelRotations.leaf[direction]; +const computeLabelRotations = ({ + direction, + rootLabelRotation, + intermediateLabelRotation, + leafLabelRotation, +}) => { + rootLabelRotation = rootLabelRotation || labelRotations.root[direction] + intermediateLabelRotation = + intermediateLabelRotation || labelRotations.intermediate[direction] + leafLabelRotation = leafLabelRotation || labelRotations.leaf[direction] return { rootLabelRotation, intermediateLabelRotation, - leafLabelRotation - }; -}; - + leafLabelRotation, + } +} class Tree extends Component { renderD3(nextProps) { const { - root, identity, labelFn, - containerWidth, containerHeight, + root, + identity, + labelFn, + containerWidth, + containerHeight, direction, - colors, nodeRadius, - transitionDuration, transitionEasing, - labelOffset, labelPaddingX, labelPaddingY - } = nextProps; + colors, + nodeRadius, + transitionDuration, + transitionEasing, + labelOffset, + labelPaddingX, + labelPaddingY, + } = nextProps - const margin = _.assign({}, Nivo.defaults.margin, this.props.margin); + const margin = _.assign({}, Nivo.defaults.margin, this.props.margin) - const width = containerWidth - margin.left - margin.right; - const height = containerHeight - margin.top - margin.bottom; + const width = containerWidth - margin.left - margin.right + const height = containerHeight - margin.top - margin.bottom const element = d3.select(findDOMNode(this)).attr({ - width: containerWidth, - height: containerHeight - }); + width: containerWidth, + height: containerHeight, + }) - let position; - let size; - let diagonal; - let transformer; - let labelTextAnchor; + let position + let size + let diagonal + let transformer + let labelTextAnchor switch (direction) { case 'horizontal': - position = [margin.left, margin.top]; - size = [height, width]; - diagonal = horizontalDiagonal; - transformer = horizontalTransform; - labelTextAnchor = horizontalLabelTextAnchor; - break; + position = [margin.left, margin.top] + size = [height, width] + diagonal = horizontalDiagonal + transformer = horizontalTransform + labelTextAnchor = horizontalLabelTextAnchor + break case 'horizontal-reverse': - position = [margin.left + width, margin.top]; - size = [height, -width]; - diagonal = horizontalDiagonal; - transformer = horizontalTransform; - labelTextAnchor = horizontalReverseLabelTextAnchor; - break; + position = [margin.left + width, margin.top] + size = [height, -width] + diagonal = horizontalDiagonal + transformer = horizontalTransform + labelTextAnchor = horizontalReverseLabelTextAnchor + break case 'vertical': - position = [margin.left, margin.top]; - size = [width, height]; - diagonal = verticalDiagonal; - transformer = verticalTransform; - labelTextAnchor = verticalLabelTextAnchor; - break; + position = [margin.left, margin.top] + size = [width, height] + diagonal = verticalDiagonal + transformer = verticalTransform + labelTextAnchor = verticalLabelTextAnchor + break case 'vertical-reverse': - position = [margin.left, margin.top + height]; - size = [width, -height]; - diagonal = verticalDiagonal; - transformer = verticalTransform; - labelTextAnchor = verticalLabelTextAnchor; - break; + position = [margin.left, margin.top + height] + size = [width, -height] + diagonal = verticalDiagonal + transformer = verticalTransform + labelTextAnchor = verticalLabelTextAnchor + break } - const wrapper = element.select('.nivo_tree_wrapper').attr({ width, height }); - const previousNodes = _.cloneDeep(wrapper.selectAll('.nivo_tree_circle').data()); + const wrapper = element + .select('.nivo_tree_wrapper') + .attr({ width, height }) + const previousNodes = _.cloneDeep( + wrapper.selectAll('.nivo_tree_circle').data() + ) wrapper //.transition() //.duration(transitionDuration) //.ease(transitionEasing) .attr('transform', `translate(${position[0]},${position[1]})`) - ; - const cluster = d3.layout.cluster().size(size); + const cluster = d3.layout.cluster().size(size) - const color = getColorRange(colors); + const color = getColorRange(colors) // prevents mutation on the original object by cloning original dataset // add color to each datum const nodes = cluster.nodes(_.cloneDeep(root)).map(node => { - node.hierarchicalType = getHierarchicalNodeType(node); + node.hierarchicalType = getHierarchicalNodeType(node) if (node.depth <= 1) { - node.color = color(node.name); + node.color = color(node.name) } else if (node.depth > 1) { - node.color = node.parent.color; + node.color = node.parent.color } - return node; - }); - - const links = cluster.links(nodes); + return node + }) + const links = cluster.links(nodes) // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— // Links // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const link = wrapper.selectAll('.nivo_tree_link').data(links, d => `${identity(d.source)}.${identity(d.target)}`); + const link = wrapper + .selectAll('.nivo_tree_link') + .data(links, d => `${identity(d.source)}.${identity(d.target)}`) link - .enter().append('path') + .enter() + .append('path') .attr('fill', 'none') .style('stroke', d => d.target.color) .attr('class', 'nivo_tree_link') .attr('d', diagonal) - .attr('stroke-dasharray', function () { return this.getTotalLength(); }) - .attr('stroke-dashoffset', function () { return this.getTotalLength(); }) - ; + .attr('stroke-dasharray', function() { + return this.getTotalLength() + }) + .attr('stroke-dashoffset', function() { + return this.getTotalLength() + }) link .transition() @@ -219,29 +242,35 @@ class Tree extends Component { .duration(transitionDuration) .ease(transitionEasing) .attr('d', diagonal) - .attr('stroke-dasharray', function () { return this.getTotalLength(); }) + .attr('stroke-dasharray', function() { + return this.getTotalLength() + }) .attr('stroke-dashoffset', 0) - ; - link.exit() + link + .exit() .transition() .duration(transitionDuration) .ease(transitionEasing) - .attr('stroke-dashoffset', function () { return this.getTotalLength(); }) + .attr('stroke-dashoffset', function() { + return this.getTotalLength() + }) .remove() - ; // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— // Circles // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const circle = wrapper.selectAll('.nivo_tree_circle').data(nodes, identity); + const circle = wrapper + .selectAll('.nivo_tree_circle') + .data(nodes, identity) - circle.enter().append('circle') + circle + .enter() + .append('circle') .attr('class', 'nivo_tree_circle') .style('fill', d => d.color) .attr('transform', transformer) .attr('r', 0) - ; circle .transition() @@ -250,59 +279,61 @@ class Tree extends Component { .ease(transitionEasing) .attr('transform', transformer) .attr('r', nodeRadius) - ; - circle.exit() - .remove() - ; + circle.exit().remove() // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— // Labels // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const label = wrapper.selectAll('.nivo_tree_label').data(nodes, identity); + const label = wrapper + .selectAll('.nivo_tree_label') + .data(nodes, identity) const { rootLabelPosition, intermediateLabelPosition, - leafLabelPosition - } = computeLabelPositions(nextProps); + leafLabelPosition, + } = computeLabelPositions(nextProps) const { rootLabelRotation, intermediateLabelRotation, - leafLabelRotation - } = computeLabelRotations(nextProps); + leafLabelRotation, + } = computeLabelRotations(nextProps) - label.enter().append('g') + label + .enter() + .append('g') .attr('class', 'nivo_tree_label') .style('opacity', 0) - .each(function (d) { - const el = d3.select(this); + .each(function(d) { + const el = d3.select(this) - let position; - let rotation; + let position + let rotation if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_ROOT) { - position = rootLabelPosition; - rotation = rootLabelRotation; + position = rootLabelPosition + rotation = rootLabelRotation } else if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_LEAF) { - position = leafLabelPosition; - rotation = leafLabelRotation; + position = leafLabelPosition + rotation = leafLabelRotation } else { - position = intermediateLabelPosition; - rotation = intermediateLabelRotation; + position = intermediateLabelPosition + rotation = intermediateLabelRotation } - el.attr('transform', `${transformer(d)} rotate(${rotation})`); - - el.call(makeLabel({ - text: d.name, - position, - labelOffset: 0, - labelPaddingX, - labelPaddingY - })); + el.attr('transform', `${transformer(d)} rotate(${rotation})`) + + el.call( + makeLabel({ + text: d.name, + position, + labelOffset: 0, + labelPaddingX, + labelPaddingY, + }) + ) }) - ; label .transition() @@ -311,50 +342,51 @@ class Tree extends Component { .ease(transitionEasing) .style('opacity', 1) .attr('transform', d => { - const translate = transformer(d); + const translate = transformer(d) - let rotation; + let rotation if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_ROOT) { - rotation = rootLabelRotation; + rotation = rootLabelRotation } else if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_LEAF) { - rotation = leafLabelRotation; + rotation = leafLabelRotation } else { - rotation = intermediateLabelRotation; + rotation = intermediateLabelRotation } - return `${translate} rotate(${rotation})`; + return `${translate} rotate(${rotation})` }) - .each(function (d) { - const el = d3.select(this); + .each(function(d) { + const el = d3.select(this) - let position; + let position if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_ROOT) { - position = rootLabelPosition; + position = rootLabelPosition } else if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_LEAF) { - position = leafLabelPosition; + position = leafLabelPosition } else { - position = intermediateLabelPosition; + position = intermediateLabelPosition } - el.call(makeLabel({ - text: d.name, - position, - labelOffset, - labelPaddingX, - labelPaddingY - })); + el.call( + makeLabel({ + text: d.name, + position, + labelOffset, + labelPaddingX, + labelPaddingY, + }) + ) }) - ; } shouldComponentUpdate(nextProps) { - this.renderD3(nextProps); + this.renderD3(nextProps) - return false; + return false } componentDidMount() { - this.renderD3(this.props); + this.renderD3(this.props) } render() { @@ -362,48 +394,52 @@ class Tree extends Component { - ); + ) } } -const { object, number, string, func, any, oneOf } = PropTypes; +const { object, number, string, func, any, oneOf } = PropTypes Tree.propTypes = { - containerWidth: number.isRequired, - containerHeight: number.isRequired, - margin: marginPropType, - root: object.isRequired, - identity: func.isRequired, - labelFn: func.isRequired, - direction: oneOf(['horizontal', 'horizontal-reverse', 'vertical', 'vertical-reverse']).isRequired, - colors: any.isRequired, - nodeRadius: number.isRequired, - transitionDuration: number.isRequired, - transitionEasing: string.isRequired, - labelOffset: number.isRequired, - labelPaddingX: number.isRequired, - labelPaddingY: number.isRequired, - rootLabelPosition: string, - intermediateLabelPosition: string, - leafLabelPosition: string, - rootLabelRotation: number, - intermediateLabelRotation: number, - leafLabelRotation: number -}; + containerWidth: number.isRequired, + containerHeight: number.isRequired, + margin: marginPropType, + root: object.isRequired, + identity: func.isRequired, + labelFn: func.isRequired, + direction: oneOf([ + 'horizontal', + 'horizontal-reverse', + 'vertical', + 'vertical-reverse', + ]).isRequired, + colors: any.isRequired, + nodeRadius: number.isRequired, + transitionDuration: number.isRequired, + transitionEasing: string.isRequired, + labelOffset: number.isRequired, + labelPaddingX: number.isRequired, + labelPaddingY: number.isRequired, + rootLabelPosition: string, + intermediateLabelPosition: string, + leafLabelPosition: string, + rootLabelRotation: number, + intermediateLabelRotation: number, + leafLabelRotation: number, +} Tree.defaultProps = { - margin: Nivo.defaults.margin, - labelFn: d => d.name, - direction: 'horizontal', - identity: d => `${d.parent ? d.parent.name : 'root'}.${d.name}.${d.depth}`, - colors: Nivo.defaults.colorRange, - labelOffset: 8, - labelPaddingX: 8, - labelPaddingY: 4, - nodeRadius: 6, + margin: Nivo.defaults.margin, + labelFn: d => d.name, + direction: 'horizontal', + identity: d => `${d.parent ? d.parent.name : 'root'}.${d.name}.${d.depth}`, + colors: Nivo.defaults.colorRange, + labelOffset: 8, + labelPaddingX: 8, + labelPaddingY: 4, + nodeRadius: 6, transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing -}; - + transitionEasing: Nivo.defaults.transitionEasing, +} -export default Dimensions()(Tree); +export default Dimensions()(Tree) diff --git a/src/components/charts/bars/Bar.js b/src/components/charts/bars/Bar.js new file mode 100644 index 000000000..c0c0e92db --- /dev/null +++ b/src/components/charts/bars/Bar.js @@ -0,0 +1,287 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import _ from 'lodash' +import Nivo, { defaultTheme } from '../../../Nivo' +import { margin as marginPropType } from '../../../PropTypes' +import { getColorRange } from '../../../ColorUtils' +import SvgWrapper from '../SvgWrapper' +import Axis from '../../axes/Axis' +import Grid from '../../axes/Grid' +import BarItem from './BarItem' +import BarItemLabel from './BarItemLabel' +import { scaleBand, scaleLinear, stack } from 'd3' + +const axisPropType = PropTypes.shape({ + tickSize: PropTypes.number, + tickPadding: PropTypes.number, + format: PropTypes.func, +}) + +const getAxis = ( + axes, + scale, + position, + width, + height, + theme, + { animate, motionStiffness, motionDamping } +) => { + if (!axes[position]) return null + + const axis = axes[position] + + return ( + + ) +} + +export default class Bar extends Component { + static propTypes = { + // data + data: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + data: PropTypes.arrayOf( + PropTypes.shape({ + x: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string, + ]).isRequired, + y: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string, + ]).isRequired, + }) + ).isRequired, + }) + ).isRequired, + + groupMode: PropTypes.oneOf(['stacked', 'grouped']).isRequired, + + width: PropTypes.number.isRequired, + height: PropTypes.number.isRequired, + margin: marginPropType, + xPadding: PropTypes.number.isRequired, + + // axes + axes: PropTypes.shape({ + top: axisPropType, + right: axisPropType, + bottom: axisPropType, + left: axisPropType, + }), + enableGridX: PropTypes.bool.isRequired, + enableGridY: PropTypes.bool.isRequired, + + // labels + enableLabels: PropTypes.bool.isRequired, + + // interactions + onClick: PropTypes.func, + + theme: PropTypes.object.isRequired, + colors: PropTypes.any.isRequired, + + // motion + animate: PropTypes.bool.isRequired, + motionStiffness: PropTypes.number.isRequired, + motionDamping: PropTypes.number.isRequired, + } + + static defaultProps = { + margin: Nivo.defaults.margin, + groupMode: 'stacked', + colors: Nivo.defaults.colorRange, + xPadding: 0.1, + enableLabels: true, + axes: { + left: {}, + bottom: {}, + }, + enableGridX: false, + enableGridY: true, + theme: {}, + animate: true, + motionStiffness: Nivo.defaults.motionStiffness, + motionDamping: Nivo.defaults.motionDamping, + } + + render() { + const { + data, + groupMode, + margin: _margin, + width: _width, + height: _height, + colors, + xPadding, + axes, + enableGridX, + enableGridY, + enableLabels, + theme: _theme, + animate, + motionStiffness, + motionDamping, + } = this.props + + const margin = Object.assign({}, Nivo.defaults.margin, _margin) + const width = _width - margin.left - margin.right + const height = _height - margin.top - margin.bottom + + const theme = _.merge({}, defaultTheme, _theme) + const color = getColorRange(colors) + + // determining x scale + const xLengths = _.uniq(data.map(({ data }) => data.length)) + if (xLengths.length > 1) { + throw new Error( + [ + `Found inconsitent data for x,`, + `expecting all series to have same length`, + `but found: ${xLengths.join(', ')}`, + ].join(' ') + ) + } + const xScale = scaleBand() + .rangeRound([0, width]) + .domain(data[0].data.map(({ x }) => x)) + .padding(xPadding) + + // determining y scale, depending on `groupMode` + let maxY + if (groupMode === 'stacked') { + maxY = _.max( + _.range(xLengths).map(i => + _.sumBy(data, serie => serie.data[i].y) + ) + ) + } else if (groupMode === 'grouped') { + maxY = _.maxBy( + data.reduce((acc, serie) => [...acc, ...serie.data], []), + 'y' + ).y + } else { + throw new TypeError( + [ + `'${groupMode}' is not a valid group mode,`, + `must be one of: 'grouped', 'stacked'`, + ].join(' ') + ) + } + const yScale = scaleLinear().rangeRound([height, 0]).domain([0, maxY]) + + const rects = [] + if (groupMode === 'grouped') { + data.forEach(({ id, data: serie }, serieIndex) => { + serie.forEach(d => { + const barWidth = xScale.bandwidth() / data.length + const x = xScale(d.x) + barWidth * serieIndex + const y = yScale(d.y) + const barHeight = height - y + + const value = d.y + + if (barWidth > 0 && barHeight > 0) { + rects.push({ + key: `${id}.${d.x}`, + value, + x, + y, + width: barWidth, + height: barHeight, + color: color(id), + }) + } + }) + }) + } else if (groupMode === 'stacked') { + const stackedData = data.map(({ id }) => ({ + id, + data: [], + })) + _.range(xLengths).forEach(index => { + data.forEach(({ data: serie }, serieIndex) => { + const d = serie[index] + + let y0 = 0 + let y1 = d.y + if (serieIndex > 0) { + y0 = stackedData[serieIndex - 1].data[index].y1 + y1 = d.y + y0 + } + + stackedData[serieIndex].data[index] = Object.assign({}, d, { + y0, + y1, + }) + }) + }) + + console.log(stackedData) + + stackedData.forEach(({ id, data: serie }) => { + serie.forEach(d => { + const x = xScale(d.x) + const barWidth = xScale.bandwidth() + const y = yScale(d.y1) + const barHeight = yScale(d.y0) - y + + const value = d.y + + if (barWidth > 0 && barHeight > 0) { + rects.push({ + key: `${id}.${d.x}`, + value, + x, + y, + width: barWidth, + height: barHeight, + color: color(id), + }) + } + }) + }) + } + + const motionProps = { + animate, + motionDamping, + motionStiffness, + } + + return ( + + + {['left', 'right'].map(position => + getAxis(axes, yScale, position, width, height, theme, motionProps) + )} + {['top', 'bottom'].map(position => + getAxis(axes, xScale, position, width, height, theme, motionProps) + )} + {rects.map(d => )} + {enableLabels && + rects.map(d => )} + + ) + } +} diff --git a/src/components/charts/bars/BarGroup.js b/src/components/charts/bars/BarGroup.js new file mode 100644 index 000000000..b4a2f0c25 --- /dev/null +++ b/src/components/charts/bars/BarGroup.js @@ -0,0 +1,129 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import React, { Component } from 'react' +import _ from 'lodash' +import PropTypes from 'prop-types' +import ResponsiveWrapper from '../ResponsiveWrapper' +import SvgWrapper from '../SvgWrapper' +import Nivo, { defaultTheme } from '../../../Nivo' +import { margin as marginPropType } from '../../../PropTypes' +import { getColorRange } from '../../../ColorUtils' +import Bar from './Bars' +import { scalesPropType, scalesFromObject } from '../../../lib/scale' + +const MODE_GROUPED = 'group' +const MODE_STACKED = 'stack' + +export default class BarGroup extends Component { + static propTypes = { + scales: scalesPropType, + data: PropTypes.arrayOf(PropTypes.object), + keys: PropTypes.arrayOf( + PropTypes.oneOfType([PropTypes.string, PropTypes.number]) + ).isRequired, + mode: PropTypes.oneOf([MODE_GROUPED, MODE_STACKED]).isRequired, + colors: PropTypes.any.isRequired, + children: PropTypes.func.isRequired, + margin: marginPropType, + theme: PropTypes.object.isRequired, + } + + static defaultProps = { + mode: 'stack', + colors: Nivo.defaults.colorRange, + theme: {}, + children: () => null, + } + + render() { + return ( + + {({ width: _width, height: _height }) => { + const { + data, + margin: _margin, + keys, + xScale, + x, + yScale, + scales: _scales, + colors, + children, + theme: _theme, + } = this.props + + const margin = Object.assign( + {}, + Nivo.defaults.margin, + _margin + ) + const width = _width - margin.left - margin.right + const height = _height - margin.top - margin.bottom + + const theme = _.merge({}, defaultTheme, _theme) + const scales = scalesFromObject( + _scales, + width, + height, + data + ) + const getColor = getColorRange(colors) + + const barData = data.map(d => + keys.reduce((acc, key, index) => { + let y0 = 0 + let y1 = d[key] + if (index > 0) { + y0 = acc[keys[index - 1]][1] + y1 += y0 + } + + return Object.assign(acc, { + [key]: [y0, y1], + }) + }, d) + ) + + return ( + + {children({ + data, + barData, + scales, + width, + height, + theme, + })} + + {keys.map(key => + + )} + + + ) + }} + + ) + } +} diff --git a/src/components/charts/bars/BarItem.js b/src/components/charts/bars/BarItem.js new file mode 100644 index 000000000..50944224f --- /dev/null +++ b/src/components/charts/bars/BarItem.js @@ -0,0 +1,42 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import React, { Component } from 'react' +import PropTypes from 'prop-types' + +class BarItem extends Component { + render() { + const { x, y, width, height, color } = this.props + + return ( + + ) + } +} + +BarItem.propTypes = { + //value: PropTypes.number.isRequired, + x: PropTypes.number.isRequired, + y: PropTypes.number.isRequired, + width: PropTypes.number.isRequired, + height: PropTypes.number.isRequired, + color: PropTypes.string.isRequired, +} + +BarItem.defaultProps = {} + +export default BarItem diff --git a/src/components/charts/bars/BarItemLabel.js b/src/components/charts/bars/BarItemLabel.js new file mode 100644 index 000000000..1acf8b6bc --- /dev/null +++ b/src/components/charts/bars/BarItemLabel.js @@ -0,0 +1,55 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import React, { Component } from 'react' +import PropTypes from 'prop-types' + +const safeSize = 20 + +export default class BarItemLabel extends Component { + static propTypes = { + value: PropTypes.number.isRequired, + x: PropTypes.number.isRequired, + y: PropTypes.number.isRequired, + width: PropTypes.number.isRequired, + height: PropTypes.number.isRequired, + color: PropTypes.string.isRequired, + } + + static defaultProps = {} + + render() { + const { x: _x, y: _y, width, height, color, value } = this.props + + let x = _x + let y = _y + let textX + let line + let textAnchor + if (height < safeSize) { + textX = -13 + textAnchor = 'end' + y = _y + height / 2 + line = + } else { + textX = 0 + textAnchor = 'middle' + x = _x + width / 2 + y = _y + height / 2 + } + + return ( + + {line} + + {value} + + + ) + } +} diff --git a/src/components/charts/bars/Bars.js b/src/components/charts/bars/Bars.js index 4759cc11a..4d5bcd46c 100644 --- a/src/components/charts/bars/Bars.js +++ b/src/components/charts/bars/Bars.js @@ -6,203 +6,107 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component, PropTypes } from 'react' -import _ from 'lodash' -import Nivo from '../../../Nivo' -import { margin as marginPropType } from '../../../PropTypes' -import { getColorRange } from '../../../ColorUtils' -import { convertGetter } from '../../../lib/propertiesConverters' -import Axis from '../../axes/Axis' -import Grid from '../../axes/Grid' -import { - scaleBand, - scaleLinear, - stack, - max, -} from 'd3' +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import _ from 'lodash' +import Nivo from '../../../Nivo' +import { getColorRange } from '../../../ColorUtils' +import { getAccessorFor } from '../../../lib/propertiesConverters' +import BarItem from './BarItem' +import BarItemLabel from './BarItemLabel' + +export default class Bars extends Component { + static propTypes = { + data: PropTypes.arrayOf(PropTypes.object), + colors: PropTypes.any.isRequired, + scales: PropTypes.object, + width: PropTypes.number.isRequired, + height: PropTypes.number.isRequired, + // labels + enableLabels: PropTypes.bool.isRequired, + // motion + animate: PropTypes.bool.isRequired, + motionStiffness: PropTypes.number.isRequired, + motionDamping: PropTypes.number.isRequired, + } + static defaultProps = { + colors: Nivo.defaults.colorRange, + // labels + enableLabels: true, + // motion + animate: true, + motionStiffness: Nivo.defaults.motionStiffness, + motionDamping: Nivo.defaults.motionDamping, + } -class Bars extends Component { render() { const { data, - keys, - groupMode, - identity: _identity, - margin: _margin, - width: _width, height: _height, - spacing, + scales, + xScale: _xScale, + yScale: _yScale, + height, colors, - xAxis, xAxisOrientation, xAxisTickSize, xAxisTickPadding, - yAxis, yAxisOrientation, yAxisTickSize, yAxisTickPadding, - animate, - motionStiffness, motionDamping, + x: _x, + y: _y, } = this.props - const identity = convertGetter(_identity) - - const margin = Object.assign({}, Nivo.defaults.margin, _margin) - const width = _width - margin.left - margin.right - const height = _height - margin.top - margin.bottom - - const color = getColorRange(colors) - - const x = scaleBand() - .rangeRound([0, width]) - .padding(spacing) + const xScale = scales[_xScale] + const yScale = scales[_yScale] - const y = scaleLinear() - .rangeRound([height, 0]) + const getXValue = getAccessorFor(_x) + const getYValue = getAccessorFor(_y) - x.domain(data.map(identity)) + const getColor = getColorRange(colors) const rects = [] - - if (groupMode === 'stacked') { - const series = stack().keys(keys)(data) - - y.domain([0, max(series[series.length - 1], d => d[1])]) - - series.forEach(serie => { - serie.forEach(d => { - rects.push({ - key: `${serie.key}.${identity(d.data)}`, - x: x(identity(d.data)), - y: y(d[1]), - width: x.bandwidth(), - height: y(d[0]) - y(d[1]), - color: color(serie.key), - }) - }) - }) - } else { - y.domain([0, max(data, d => max(_.values(_.pick(d, keys))))]) - - const barWidth = x.bandwidth() / keys.length - - data.forEach(bucket => { - let index = 0 - _.forOwn(_.pick(bucket, keys), (value, key) => { - rects.push({ - key: `${key}.${identity(bucket)}`, - x: x(identity(bucket)) + barWidth * index, - y: y(value), - width: barWidth, - height: height - y(value), - color: color(key), - }) - index++ + data.forEach((d, i) => { + let x + let y + let barWidth + let barHeight + + const xValue = getXValue(d) + const yValue = getYValue(d) + + if (xScale.bandwidth) { + barWidth = xScale.bandwidth() + x = xScale(xValue) + } else { + x = 0 + barWidth = xScale(xValue) + } + + if (yScale.bandwidth) { + barHeight = yScale.bandwidth() + y = yScale(getYValue(d)) + } else { + if (Array.isArray(yValue)) { + y = yScale(yValue[1]) + barHeight = yScale(yValue[0]) - y + } else { + y = yScale(yValue) + barHeight = height - y + } + } + + if (barWidth > 0 && barHeight > 0) { + rects.push({ + key: `bar.${i}`, + x, + y, + width: barWidth, + height: barHeight, + color: getColor(d), }) - }) - } + } + }) return ( - - - - {rects.map(d => { - return ( - - ) - })} - {xAxis && ( - - - - )} - {yAxis && ( - - - - )} - - + + {rects.map(d => )} + ) } } - -const { number, bool, string, func, any, object, oneOf, oneOfType, arrayOf, shape } = PropTypes - -Bars.propTypes = { - width: number.isRequired, - height: number.isRequired, - margin: marginPropType, - data: arrayOf(object).isRequired, - keys: arrayOf(string).isRequired, - identity: oneOfType([string, func]).isRequired, - groupMode: oneOf(['stacked', 'grouped']).isRequired, - spacing: number, - colors: any.isRequired, - - // axes - xAxis: bool.isRequired, - xAxisOrientation: oneOf(['top', 'bottom']).isRequired, - xAxisTickSize: number, - xAxisTickPadding: number, - yAxis: bool.isRequired, - yAxisOrientation: oneOf(['left', 'right']).isRequired, - yAxisTickSize: number, - yAxisTickPadding: number, - - // motion - animate: PropTypes.bool.isRequired, - motionStiffness: PropTypes.number.isRequired, - motionDamping: PropTypes.number.isRequired, -} - -Bars.defaultProps = { - margin: Nivo.defaults.margin, - groupMode: 'stacked', - spacing: 0.1, - colors: Nivo.defaults.colorRange, - - // axes - xAxis: true, - xAxisOrientation: 'bottom', - yAxis: true, - yAxisOrientation: 'left', - - // motion - animate: true, - motionStiffness: Nivo.defaults.motionStiffness, - motionDamping: Nivo.defaults.motionDamping, -} - - - -export default Bars diff --git a/src/components/charts/bars/BarsD3.js b/src/components/charts/bars/BarsD3.js index daae625ed..3a73a644d 100644 --- a/src/components/charts/bars/BarsD3.js +++ b/src/components/charts/bars/BarsD3.js @@ -6,115 +6,120 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import { findDOMNode } from 'react-dom'; -import d3 from 'd3'; -import _ from 'lodash'; -import Nivo from '../../../Nivo'; -import { getColorRange, getColorGenerator } from '../../../ColorUtils'; -import { margin as marginPropType } from '../../../PropTypes'; -import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren'; - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { findDOMNode } from 'react-dom' +import d3 from 'd3' +import _ from 'lodash' +import Nivo from '../../../Nivo' +import { getColorRange, getColorGenerator } from '../../../ColorUtils' +import { margin as marginPropType } from '../../../PropTypes' +import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren' class BarsD3 extends Component { renderD3(props) { const { groupMode, onBarClick, - colors, classify, - transitionDuration, transitionEasing, transitionStaggering - } = props; + colors, + classify, + transitionDuration, + transitionEasing, + transitionStaggering, + } = props - const element = d3.select(findDOMNode(this)); - const wrapper = element.select('.nivo_bars_wrapper'); + const element = d3.select(findDOMNode(this)) + const wrapper = element.select('.nivo_bars_wrapper') - const margin = _.assign({}, Nivo.defaults.margin, props.margin); - const width = props.width - margin.left - margin.right; - const height = props.height - margin.top - margin.bottom; + const margin = _.assign({}, Nivo.defaults.margin, props.margin) + const width = props.width - margin.left - margin.right + const height = props.height - margin.top - margin.bottom - let data = []; + let data = [] props.data.forEach(d => { d.values.forEach((value, i) => { const datum = _.assign({}, value, { stackIndex: i, - x: d.x, - xId: d.id, - }); + x: d.x, + xId: d.id, + }) if (i === 0) { - datum.y0 = 0; - datum.y1 = value.y; + datum.y0 = 0 + datum.y1 = value.y } else { - datum.y0 = data[data.length - 1].y1; - datum.y1 = datum.y0 + value.y; + datum.y0 = data[data.length - 1].y1 + datum.y1 = datum.y0 + value.y } - data.push(datum); - }); - }); + data.push(datum) + }) + }) element.attr({ - width: props.width, - height: props.height - }); - wrapper.attr('transform', `translate(${margin.left},${margin.top})`); - - const xScale = d3.scale.ordinal() - .rangeRoundBands([0, width], .2) + width: props.width, + height: props.height, + }) + wrapper.attr('transform', `translate(${margin.left},${margin.top})`) + + const xScale = d3.scale + .ordinal() + .rangeRoundBands([0, width], 0.2) .domain(data.map((d, i) => d.x)) - ; - let maxYValue; + let maxYValue if (groupMode === 'stacked') { - maxYValue = d3.max(data, d => d.y1); + maxYValue = d3.max(data, d => d.y1) } else { - maxYValue = d3.max(data, d => d.y); + maxYValue = d3.max(data, d => d.y) } - const maxGroupLength = d3.max(props.data, d => d.values.length); + const maxGroupLength = d3.max(props.data, d => d.values.length) - const yScale = d3.scale.linear() + const yScale = d3.scale + .linear() .rangeRound([height, 0]) .domain([0, maxYValue]) - ; - const color = getColorRange(colors); + const color = getColorRange(colors) data = data.map(d => { - let rendered; + let rendered if (groupMode === 'stacked') { rendered = { - x: xScale(d.x), - y: yScale(d.y1), - width: xScale.rangeBand(), + x: xScale(d.x), + y: yScale(d.y1), + width: xScale.rangeBand(), height: yScale(d.y0) - yScale(d.y1), - - }; + } } else { rendered = { - x: xScale(d.x) + d.stackIndex * xScale.rangeBand() / maxGroupLength, - y: yScale(d.y), - width: xScale.rangeBand() / maxGroupLength, + x: + xScale(d.x) + + d.stackIndex * xScale.rangeBand() / maxGroupLength, + y: yScale(d.y), + width: xScale.rangeBand() / maxGroupLength, height: height - yScale(d.y), } } d.render = { - color: color(d.id), - ...rendered - }; + color: color(d.id), + ...rendered, + } - return d; - }); + return d + }) //console.log(data); - const rects = wrapper.selectAll('.nivo_bars_bar').data(data, d => `${d.xId}${d.id}`); + const rects = wrapper + .selectAll('.nivo_bars_bar') + .data(data, d => `${d.xId}${d.id}`) - rects.enter() + rects + .enter() .append('rect') .classed('nivo_bars_bar', true) .attr('width', d => d.render.width) @@ -123,7 +128,6 @@ class BarsD3 extends Component { .attr('height', 0) .style('fill', d => d.render.color) .on('click', onBarClick) - ; if (groupMode === 'stacked') { rects @@ -131,91 +135,106 @@ class BarsD3 extends Component { .delay((d, i) => i * transitionStaggering) .duration(transitionDuration) .ease(transitionEasing) - .style('fill', d => d.render.color) - .attr('y', d => d.render.y) - .attr('height', d => d.render.height) + .style('fill', d => d.render.color) + .attr('y', d => d.render.y) + .attr('height', d => d.render.height) .transition() .duration(transitionDuration) .ease(transitionEasing) - .attr('x', d => d.render.x) - .attr('width', d => d.render.width) - ; + .attr('x', d => d.render.x) + .attr('width', d => d.render.width) } else { rects .transition() .delay((d, i) => i * transitionStaggering) .duration(transitionDuration) .ease(transitionEasing) - .style('fill', d => d.render.color) - .attr('x', d => d.render.x) - .attr('width', d => d.render.width) + .style('fill', d => d.render.color) + .attr('x', d => d.render.x) + .attr('width', d => d.render.width) .transition() .duration(transitionDuration) .ease(transitionEasing) - .attr('y', d => d.render.y) - .attr('height', d => d.render.height) - ; + .attr('y', d => d.render.y) + .attr('height', d => d.render.height) } - this.decorators.forEach(decorator => { - }); + this.decorators.forEach(decorator => {}) } shouldComponentUpdate(nextProps, nextState) { - this.decorators = decoratorsFromReactChildren(nextProps.children, 'decorateBars'); + this.decorators = decoratorsFromReactChildren( + nextProps.children, + 'decorateBars' + ) - this.renderD3(nextProps, nextState); + this.renderD3(nextProps, nextState) - return false; + return false } componentDidMount() { - this.decorators = decoratorsFromReactChildren(this.props.children, 'decorateBars'); + this.decorators = decoratorsFromReactChildren( + this.props.children, + 'decorateBars' + ) - this.renderD3(this.props, this.state); + this.renderD3(this.props, this.state) } render() { return ( - + - ); + ) } } -const { number, string, func, any, oneOf, oneOfType, arrayOf, shape } = PropTypes; +const { + number, + string, + func, + any, + oneOf, + oneOfType, + arrayOf, + shape, +} = PropTypes BarsD3.propTypes = { - width: number.isRequired, - height: number.isRequired, - margin: marginPropType, - data: arrayOf(shape({ - x: number.isRequired, - id: oneOfType([number, string]).isRequired, - values: arrayOf(shape({ + width: number.isRequired, + height: number.isRequired, + margin: marginPropType, + data: arrayOf( + shape({ + x: number.isRequired, id: oneOfType([number, string]).isRequired, - y: number.isRequired, - })).isRequired - })).isRequired, - groupMode: oneOf(['stacked', 'grouped']), - onBarClick: func.isRequired, - colors: any.isRequired, - classify: func, - transitionDuration: number.isRequired, - transitionEasing: string.isRequired, + values: arrayOf( + shape({ + id: oneOfType([number, string]).isRequired, + y: number.isRequired, + }) + ).isRequired, + }) + ).isRequired, + groupMode: oneOf(['stacked', 'grouped']), + onBarClick: func.isRequired, + colors: any.isRequired, + classify: func, + transitionDuration: number.isRequired, + transitionEasing: string.isRequired, transitionStaggering: number.isRequired, -}; +} BarsD3.defaultProps = { - margin: Nivo.defaults.margin, - groupMode: 'stacked', - onBarClick: () => {}, - colors: Nivo.defaults.colorRange, - transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, + margin: Nivo.defaults.margin, + groupMode: 'stacked', + onBarClick: () => {}, + colors: Nivo.defaults.colorRange, + transitionDuration: Nivo.defaults.transitionDuration, + transitionEasing: Nivo.defaults.transitionEasing, transitionStaggering: 10, -}; - +} -export default BarsD3; +export default BarsD3 diff --git a/src/components/charts/bars/ResponsiveBar.js b/src/components/charts/bars/ResponsiveBar.js new file mode 100644 index 000000000..0e058ce71 --- /dev/null +++ b/src/components/charts/bars/ResponsiveBar.js @@ -0,0 +1,22 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import React, { Component } from 'react' +import ResponsiveWrapper from '../ResponsiveWrapper' +import Bar from './Bar' + +export default class ResponsiveBar extends Component { + render() { + return ( + + {({ width, height }) => + } + + ) + } +} diff --git a/src/components/charts/bars/ResponsiveBars.js b/src/components/charts/bars/ResponsiveBars.js deleted file mode 100644 index 82b4bd7c2..000000000 --- a/src/components/charts/bars/ResponsiveBars.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the nivo project. - * - * (c) 2016 Raphaël Benitte - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -'use strict' - -import React, { Component, PropTypes } from 'react' -import Dimensions from 'react-dimensions' -import Bars from './Bars' - - -class ResponsiveBars extends Component { - render() { - const { containerWidth, containerHeight } = this.props - - return ( - - ) - } -} - - -export default Dimensions()(ResponsiveBars) diff --git a/src/components/charts/bars/ResponsiveBarsD3.js b/src/components/charts/bars/ResponsiveBarsD3.js index 56ebc0307..51a8f41e9 100644 --- a/src/components/charts/bars/ResponsiveBarsD3.js +++ b/src/components/charts/bars/ResponsiveBarsD3.js @@ -6,16 +6,14 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import Dimensions from 'react-dimensions'; -import BarsD3 from './BarsD3'; - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Dimensions from 'react-dimensions' +import BarsD3 from './BarsD3' class ResponsiveBarsD3 extends Component { render() { - const { containerWidth, containerHeight } = this.props; + const { containerWidth, containerHeight } = this.props return ( - ); + ) } } - -export default Dimensions()(ResponsiveBarsD3); +export default Dimensions()(ResponsiveBarsD3) diff --git a/src/components/charts/bars/barsDataSchema.js b/src/components/charts/bars/barsDataSchema.js index 567b15930..621f589a3 100644 --- a/src/components/charts/bars/barsDataSchema.js +++ b/src/components/charts/bars/barsDataSchema.js @@ -1,6 +1,5 @@ const barsDataSchema = { - type: 'array' -}; + type: 'array', +} - -export default barsDataSchema; +export default barsDataSchema diff --git a/src/components/charts/bars/index.js b/src/components/charts/bars/index.js index 38ec04726..0b25ab7a5 100644 --- a/src/components/charts/bars/index.js +++ b/src/components/charts/bars/index.js @@ -6,7 +6,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -export Bars from './Bars' -export ResponsiveBars from './ResponsiveBars' +export Bar from './Bar' +export Bars from './Bars' +export ResponsiveBar from './ResponsiveBar' +export BarGroup from './BarGroup' diff --git a/src/components/charts/bubble/Bubble.js b/src/components/charts/bubble/Bubble.js index fcf62cdaf..03e3737c2 100644 --- a/src/components/charts/bubble/Bubble.js +++ b/src/components/charts/bubble/Bubble.js @@ -6,18 +6,16 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component } from 'react' -import _ from 'lodash' -import { convertLabel } from '../../../lib/propertiesConverters' +import React, { Component } from 'react' +import _ from 'lodash' +import { convertLabel } from '../../../lib/propertiesConverters' import { bubblePropTypes, bubbleDefaultProps } from './BubbleProps' -import BubblePlaceholders from './BubblePlaceholders' -import { getColorGenerator } from '../../../ColorUtils' - +import BubblePlaceholders from './BubblePlaceholders' +import { getColorGenerator } from '../../../ColorUtils' const createNodes = ({ - borderWidth, borderColor, + borderWidth, + borderColor, enableLabel, label: _label, labelFormat, @@ -25,42 +23,45 @@ const createNodes = ({ labelTextColor, labelTextDY, }) => { - const label = convertLabel(_label, labelFormat) + const label = convertLabel(_label, labelFormat) const borderColorFn = getColorGenerator(borderColor) - const textColorFn = getColorGenerator(labelTextColor) - + const textColorFn = getColorGenerator(labelTextColor) + return nodes => { const renderedNodes = [] - nodes - .filter(node => node.style.r > 0) - .forEach(node => { - renderedNodes.push( - - ) - }) + nodes.filter(node => node.style.r > 0).forEach(node => { + renderedNodes.push( + + ) + }) if (enableLabel === true) { nodes .filter(node => { - return node.data.height === 0 && (labelSkipRadius === 0 || node.data.r >= labelSkipRadius) + return ( + node.data.height === 0 && + (labelSkipRadius === 0 || + node.data.r >= labelSkipRadius) + ) }) .forEach(node => { renderedNodes.push( + {createNodes(this.props)} ) @@ -104,5 +101,4 @@ Bubble.defaultProps = _.omit(bubbleDefaultProps, [ 'transitionEasing', ]) - export default Bubble diff --git a/src/components/charts/bubble/BubbleD3.js b/src/components/charts/bubble/BubbleD3.js index 163c32987..d288b3e55 100644 --- a/src/components/charts/bubble/BubbleD3.js +++ b/src/components/charts/bubble/BubbleD3.js @@ -6,38 +6,39 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component } from 'react'; -import { findDOMNode } from 'react-dom'; -import _ from 'lodash'; -import { bubblePropTypes, bubbleDefaultProps } from './BubbleProps'; -import Nivo from '../../../Nivo'; -import BubbleD3Svg from '../../../lib/charts/bubble/BubbleD3Svg'; -import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren'; - +import React, { Component } from 'react' +import { findDOMNode } from 'react-dom' +import _ from 'lodash' +import { bubblePropTypes, bubbleDefaultProps } from './BubbleProps' +import Nivo from '../../../Nivo' +import BubbleD3Svg from '../../../lib/charts/bubble/BubbleD3Svg' +import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren' class BubbleD3 extends Component { renderChart(props) { - this.bubble.decorate(decoratorsFromReactChildren(props.children, 'decorateBubble')); - this.bubble.draw(_.assign({}, props, { - margin: _.assign({}, Nivo.defaults.margin, props.margin) - })); + this.bubble.decorate( + decoratorsFromReactChildren(props.children, 'decorateBubble') + ) + this.bubble.draw( + _.assign({}, props, { + margin: _.assign({}, Nivo.defaults.margin, props.margin), + }) + ) } shouldComponentUpdate(nextProps) { - this.renderChart(nextProps); + this.renderChart(nextProps) - return false; + return false } componentDidMount() { - this.bubble = BubbleD3Svg(findDOMNode(this.refs.svg)); - this.renderChart(this.props); + this.bubble = BubbleD3Svg(findDOMNode(this.refs.svg)) + this.renderChart(this.props) } render() { - return ; + return } } @@ -46,13 +47,12 @@ BubbleD3.propTypes = _.omit(bubblePropTypes, [ 'namespace', 'motionStiffness', 'motionDamping', -]); +]) BubbleD3.defaultProps = _.omit(bubbleDefaultProps, [ 'namespace', 'motionStiffness', 'motionDamping', -]); - +]) -export default BubbleD3; +export default BubbleD3 diff --git a/src/components/charts/bubble/BubblePlaceholders.js b/src/components/charts/bubble/BubblePlaceholders.js index ef44b8150..e72189744 100644 --- a/src/components/charts/bubble/BubblePlaceholders.js +++ b/src/components/charts/bubble/BubblePlaceholders.js @@ -6,19 +6,16 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component } from 'react' -import { TransitionMotion, spring } from 'react-motion' -import { rgb } from 'd3' -import _ from 'lodash' -import Nivo from '../../../Nivo' -import { getColorRange, extractRGB } from '../../../ColorUtils' -import BubbleHelper from '../../../lib/charts/bubble/BubbleHelper' -import { convertGetter } from '../../../lib/propertiesConverters' +import React, { Component } from 'react' +import { TransitionMotion, spring } from 'react-motion' +import { rgb } from 'd3' +import _ from 'lodash' +import Nivo from '../../../Nivo' +import { getColorRange, extractRGB } from '../../../ColorUtils' +import BubbleHelper from '../../../lib/charts/bubble/BubbleHelper' +import { convertGetter } from '../../../lib/propertiesConverters' import { bubblePropTypes, bubbleDefaultProps } from './BubbleProps' - class BubblePlaceholders extends Component { componentWillMount() { this.bubble = BubbleHelper() @@ -53,25 +50,31 @@ class BubblePlaceholders extends Component { padding, colors, animate, - motionStiffness, motionDamping, + motionStiffness, + motionDamping, children, } = this.props const identity = convertGetter(_identity) - const value = convertGetter(_value) + const value = convertGetter(_value) - const color = getColorRange(colors) + const color = getColorRange(colors) - const margin = Object.assign({}, Nivo.defaults.margin, this.props.margin) - const width = _width - margin.left - margin.right - const height = _height - margin.top - margin.bottom + const margin = Object.assign( + {}, + Nivo.defaults.margin, + this.props.margin + ) + const width = _width - margin.left - margin.right + const height = _height - margin.top - margin.bottom const nodes = this.bubble.compute({ width, height, root, leavesOnly, - identity, value, + identity, + value, padding, color, }) @@ -79,62 +82,70 @@ class BubblePlaceholders extends Component { let wrapperTag let containerTag - const wrapperProps = {} + const wrapperProps = {} const containerProps = {} if (namespace === 'svg') { - wrapperTag = 'svg' + wrapperTag = 'svg' containerTag = 'g' - wrapperProps.width = _width - wrapperProps.height = _height - wrapperProps.xmlns = 'http://www.w3.org/2000/svg' + wrapperProps.width = _width + wrapperProps.height = _height + wrapperProps.xmlns = 'http://www.w3.org/2000/svg' containerProps.transform = `translate(${margin.left},${margin.top})` } else { - wrapperTag = 'div' + wrapperTag = 'div' containerTag = 'div' wrapperProps.style = { position: 'relative', - width: _width, - height: _height, + width: _width, + height: _height, } - containerProps.style = margin + containerProps.style = Object.assign({}, margin, { + position: 'absolute', + }) } if (animate === false) { - return React.createElement(wrapperTag, wrapperProps, + return React.createElement( + wrapperTag, + wrapperProps, React.createElement( containerTag, containerProps, - children(nodes.map(node => { - return { - key: node.data.key, - data: node, - style: _.pick(node, ['r', 'x', 'y', 'color']), - } - })) + children( + nodes.map(node => { + return { + key: node.data.key, + data: node, + style: _.pick(node, ['r', 'x', 'y', 'color']), + } + }) + ) ) ) } const stiffness = motionStiffness - const damping = motionDamping + const damping = motionDamping - return React.createElement(wrapperTag, wrapperProps, ( + return React.createElement( + wrapperTag, + wrapperProps, { return { - key: b.data.key, - data: b, + key: b.data.key, + data: b, style: { r: spring(b.r, { stiffness, damping }), x: spring(b.x, { stiffness, damping }), y: spring(b.y, { stiffness, damping }), ...extractRGB(b.color, { stiffness, damping }), - } + }, } })} > @@ -142,16 +153,24 @@ class BubblePlaceholders extends Component { return React.createElement( containerTag, containerProps, - children(interpolatedStyles.map(interpolatedStyle => { - const { colorR, colorG, colorB } = interpolatedStyle.style - interpolatedStyle.style.color = `rgb(${Math.round(colorR)},${Math.round(colorG)},${Math.round(colorB)})` - - return interpolatedStyle - })) - ); + children( + interpolatedStyles.map(interpolatedStyle => { + const { + colorR, + colorG, + colorB, + } = interpolatedStyle.style + interpolatedStyle.style.color = `rgb(${Math.round( + colorR + )},${Math.round(colorG)},${Math.round(colorB)})` + + return interpolatedStyle + }) + ) + ) }} - )) + ) } } @@ -181,5 +200,4 @@ BubblePlaceholders.defaultProps = _.omit(bubbleDefaultProps, [ 'transitionEasing', ]) - export default BubblePlaceholders diff --git a/src/components/charts/bubble/BubbleProps.js b/src/components/charts/bubble/BubbleProps.js index c3ab1326d..34541e662 100644 --- a/src/components/charts/bubble/BubbleProps.js +++ b/src/components/charts/bubble/BubbleProps.js @@ -6,82 +6,77 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import { PropTypes } from 'react' -import Nivo from '../../../Nivo' -import { margin } from '../../../PropTypes' - +import PropTypes from 'prop-types' +import Nivo from '../../../Nivo' +import { margin } from '../../../PropTypes' const { bool, object, number, string, any, func, oneOf } = PropTypes - /** * Bubble components propTypes. * * @type {object} */ export const bubblePropTypes = { - width: number.isRequired, - height: number.isRequired, + width: number.isRequired, + height: number.isRequired, margin, - root: object.isRequired, - leavesOnly: bool.isRequired, - onBubbleClick: func.isRequired, - identity: string.isRequired, - value: string.isRequired, - padding: number.isRequired, - colors: any.isRequired, + root: object.isRequired, + leavesOnly: bool.isRequired, + onBubbleClick: func.isRequired, + identity: string.isRequired, + value: string.isRequired, + padding: number.isRequired, + colors: any.isRequired, // placeholders - namespace: oneOf(['html', 'svg']), - children: func.isRequired, + namespace: oneOf(['html', 'svg']), + children: func.isRequired, // border - borderWidth: number.isRequired, - borderColor: any.isRequired, + borderWidth: number.isRequired, + borderColor: any.isRequired, // labels - enableLabel: bool.isRequired, - label: string.isRequired, - labelFormat: string, - labelTextColor: any.isRequired, - labelTextDY: number.isRequired, - labelSkipRadius: number.isRequired, + enableLabel: bool.isRequired, + label: string.isRequired, + labelFormat: string, + labelTextColor: any.isRequired, + labelTextDY: number.isRequired, + labelSkipRadius: number.isRequired, // transitions - animate: bool.isRequired, - motionStiffness: number.isRequired, // react-motion - motionDamping: number.isRequired, // react-motion + animate: bool.isRequired, + motionStiffness: number.isRequired, // react-motion + motionDamping: number.isRequired, // react-motion transitionDuration: number.isRequired, // d3 transitions - transitionEasing: string.isRequired, // d3 transitions + transitionEasing: string.isRequired, // d3 transitions } - /** * Bubble components defaultProps. * * @type {object} */ export const bubbleDefaultProps = { - leavesOnly: false, - margin: Nivo.defaults.margin, - onBubbleClick: () => {}, - identity: 'id', - value: 'value', - padding: 1, - colors: Nivo.defaults.colorRange, + leavesOnly: false, + margin: Nivo.defaults.margin, + onBubbleClick: () => {}, + identity: 'id', + value: 'value', + padding: 1, + colors: Nivo.defaults.colorRange, // placeholders - namespace: 'html', + namespace: 'html', // border - borderWidth: 0, - borderColor: 'inherit', + borderWidth: 0, + borderColor: 'inherit', // labels - enableLabel: true, - label: 'id', - labelTextColor: 'inherit:darker(1)', - labelTextDY: 5, - labelSkipRadius: 0, + enableLabel: true, + label: 'id', + labelTextColor: 'inherit:darker(1)', + labelTextDY: 5, + labelSkipRadius: 0, // transitions - animate: true, - motionStiffness: Nivo.defaults.motionStiffness, // react-motion - motionDamping: Nivo.defaults.motionDamping, // react-motion + animate: true, + motionStiffness: Nivo.defaults.motionStiffness, // react-motion + motionDamping: Nivo.defaults.motionDamping, // react-motion transitionDuration: Nivo.defaults.transitionDuration, // d3 transitions - transitionEasing: Nivo.defaults.transitionEasing, // d3 transitions + transitionEasing: Nivo.defaults.transitionEasing, // d3 transitions } diff --git a/src/components/charts/bubble/ResponsiveBubble.js b/src/components/charts/bubble/ResponsiveBubble.js index b35296d4b..c5aa64df9 100644 --- a/src/components/charts/bubble/ResponsiveBubble.js +++ b/src/components/charts/bubble/ResponsiveBubble.js @@ -6,29 +6,43 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component, PropTypes } from 'react' -import Dimensions from 'react-dimensions' -import Bubble from './Bubble' +import React, { Component } from 'react' +import Measure from 'react-measure' +import Bubble from './Bubble' +export default class ResponsiveBubble extends Component { + state = { + dimensions: { + width: -1, + height: -1, + }, + } -class ResponsiveBubble extends Component { render() { - const { - containerWidth, - containerHeight, - } = this.props + const { width, height } = this.state.dimensions + + const shouldRender = width > 0 && height > 0 return ( - + { + this.setState({ dimensions: contentRect.bounds }) + }} + > + {({ measureRef }) => +
+ {shouldRender && + } +
} +
) } } - - -export default Dimensions()(ResponsiveBubble) diff --git a/src/components/charts/bubble/ResponsiveBubbleD3.js b/src/components/charts/bubble/ResponsiveBubbleD3.js index 25f75cf09..1b3b6ac3c 100644 --- a/src/components/charts/bubble/ResponsiveBubbleD3.js +++ b/src/components/charts/bubble/ResponsiveBubbleD3.js @@ -6,16 +6,14 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import Dimensions from 'react-dimensions'; -import BubbleD3 from './BubbleD3'; - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Dimensions from 'react-dimensions' +import BubbleD3 from './BubbleD3' class ResponsiveBubbleD3 extends Component { render() { - const { containerWidth, containerHeight } = this.props; + const { containerWidth, containerHeight } = this.props return ( - ); + ) } } - -export default Dimensions()(ResponsiveBubbleD3); +export default Dimensions()(ResponsiveBubbleD3) diff --git a/src/components/charts/bubble/ResponsiveBubblePlaceholders.js b/src/components/charts/bubble/ResponsiveBubblePlaceholders.js index de4ca8b16..08be5389f 100644 --- a/src/components/charts/bubble/ResponsiveBubblePlaceholders.js +++ b/src/components/charts/bubble/ResponsiveBubblePlaceholders.js @@ -6,26 +6,43 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component, PropTypes } from 'react' -import Dimensions from 'react-dimensions' -import BubblePlaceholders from './BubblePlaceholders' +import React, { Component } from 'react' +import Measure from 'react-measure' +import BubblePlaceholders from './BubblePlaceholders' +export default class ResponsiveBubblePlaceholders extends Component { + state = { + dimensions: { + width: -1, + height: -1, + }, + } -class ResponsiveBubblePlaceholders extends Component { render() { - const { containerWidth, containerHeight } = this.props + const { width, height } = this.state.dimensions + + const shouldRender = width > 0 && height > 0 return ( - + { + this.setState({ dimensions: contentRect.bounds }) + }} + > + {({ measureRef }) => +
+ {shouldRender && + } +
} +
) } } - - -export default Dimensions()(ResponsiveBubblePlaceholders) diff --git a/src/components/charts/bubble/index.js b/src/components/charts/bubble/index.js index b59c7f11f..317e02d9e 100644 --- a/src/components/charts/bubble/index.js +++ b/src/components/charts/bubble/index.js @@ -6,10 +6,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - - -export Bubble from './Bubble' -export ResponsiveBubble from './ResponsiveBubble' -export BubblePlaceholders from './BubblePlaceholders' +export Bubble from './Bubble' +export ResponsiveBubble from './ResponsiveBubble' +export BubblePlaceholders from './BubblePlaceholders' export ResponsiveBubblePlaceholders from './ResponsiveBubblePlaceholders' diff --git a/src/components/charts/calendar/Calendar.js b/src/components/charts/calendar/Calendar.js index c60b4f0cc..ff87f4a8d 100644 --- a/src/components/charts/calendar/Calendar.js +++ b/src/components/charts/calendar/Calendar.js @@ -6,84 +6,109 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import _ from 'lodash' -import React, { Component } from 'react' -import Nivo from '../../../Nivo' -import CalendarLayout from '../../../lib/charts/calendar/CalendarLayout' +import _ from 'lodash' +import React, { Component } from 'react' +import Nivo from '../../../Nivo' +import CalendarLayout from '../../../lib/charts/calendar/CalendarLayout' import { calendarPropTypes, calendarDefaultProps } from './CalendarProps' -import StaticCalendar from './StaticCalendar' -import MotionCalendar from './MotionCalendar' - +import StaticCalendar from './StaticCalendar' +import MotionCalendar from './MotionCalendar' class Calendar extends Component { componentWillMount() { - this.calendarLayout = CalendarLayout(); + this.calendarLayout = CalendarLayout() } render() { const { - from, to, + from, + to, data, onDayClick, direction, colorScale, emptyColor, - yearSpacing, yearLegendOffset, - daySpacing, dayBorderWidth, dayBorderColor, - monthBorderWidth, monthBorderColor, monthLegendOffset, - motion, motionStiffness, motionDamping - } = this.props; + yearSpacing, + yearLegendOffset, + daySpacing, + dayBorderWidth, + dayBorderColor, + monthBorderWidth, + monthBorderColor, + monthLegendOffset, + animate, + motionStiffness, + motionDamping, + } = this.props - const margin = _.assign({}, Nivo.defaults.margin, this.props.margin); - const width = this.props.width - margin.left - margin.right; - const height = this.props.height - margin.top - margin.bottom; + const margin = _.assign({}, Nivo.defaults.margin, this.props.margin) + const width = this.props.width - margin.left - margin.right + const height = this.props.height - margin.top - margin.bottom const { years, months, days } = this.calendarLayout.compute({ - width, height, - from, to, + width, + height, + from, + to, data, direction, colorScale, emptyColor, yearSpacing, - daySpacing - }); + daySpacing, + }) - let calendar; - if (motion === true) { + let calendar + if (animate === true) { calendar = ( - ); + ) } else { calendar = ( - ); + ) } return ( - - + + {calendar} - ); + ) } } @@ -91,13 +116,12 @@ Calendar.propTypes = _.omit(calendarPropTypes, [ 'transitionDuration', 'transitionEasing', 'transitionStaggering', -]); +]) Calendar.defaultProps = _.omit(calendarDefaultProps, [ 'transitionDuration', 'transitionEasing', 'transitionStaggering', -]); - +]) -export default Calendar; +export default Calendar diff --git a/src/components/charts/calendar/CalendarCanvas.js b/src/components/charts/calendar/CalendarCanvas.js index 50c3286c5..ea6645796 100644 --- a/src/components/charts/calendar/CalendarCanvas.js +++ b/src/components/charts/calendar/CalendarCanvas.js @@ -6,63 +6,73 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; +import React, { Component } from 'react' +import { findDOMNode } from 'react-dom' +import d3 from 'd3' +import _ from 'lodash' +import Nivo from '../../../Nivo' +import CalendarLayout from '../../../lib/charts/calendar/CalendarLayout' +import { calendarPropTypes, calendarDefaultProps } from './CalendarProps' -import React, { Component } from 'react'; -import { findDOMNode } from 'react-dom'; -import d3 from 'd3'; -import _ from 'lodash'; -import Nivo from '../../../Nivo'; -import CalendarLayout from '../../../lib/charts/calendar/CalendarLayout'; -import { calendarPropTypes, calendarDefaultProps } from './CalendarProps'; - -const color = d3.scale.category20b(); +const color = d3.scale.category20b() class CalendarCanvas extends Component { constructor(props) { - super(props); + super(props) } renderD3(props) { const { - from, to, + from, + to, direction, yearSpacing, - daySpacing, dayBorderWidth, dayBorderColor, - monthBorderWidth, monthBorderColor, - transitionDuration, transitionEasing, transitionStaggering - } = props; - - const canvas = d3.select(findDOMNode(this)); + daySpacing, + dayBorderWidth, + dayBorderColor, + monthBorderWidth, + monthBorderColor, + transitionDuration, + transitionEasing, + transitionStaggering, + } = props + + const canvas = d3.select(findDOMNode(this)) canvas.attr({ - width: props.width, - height: props.height - }); + width: props.width, + height: props.height, + }) - const margin = _.assign({}, Nivo.defaults.margin, props.margin); - const width = props.width - margin.left - margin.right; - const height = props.height - margin.top - margin.bottom; + const margin = _.assign({}, Nivo.defaults.margin, props.margin) + const width = props.width - margin.left - margin.right + const height = props.height - margin.top - margin.bottom const { days, months } = this.calendarLayout.compute({ - width, height, - from, to, + width, + height, + from, + to, direction, yearSpacing, - daySpacing - }); + daySpacing, + }) - const dayNodes = this.container .selectAll('custom.rect').data(days, d => d.date); + const dayNodes = this.container + .selectAll('custom.rect') + .data(days, d => d.date) - dayNodes.enter() + dayNodes + .enter() .append('custom') .classed('rect', true) .attr('x', 0) .attr('y', 0) - .attr('size', d => d.size) - .attr('fillStyle', d => color(`${d.date.getFullYear()}.${d.date.getMonth()}`)) + .attr('size', d => d.size) + .attr('fillStyle', d => + color(`${d.date.getFullYear()}.${d.date.getMonth()}`) + ) .attr('strokeStyle', dayBorderColor) .attr('lineWidth', dayBorderWidth) - ; dayNodes .transition() @@ -71,77 +81,80 @@ class CalendarCanvas extends Component { .delay(d => d3.time.dayOfYear(d.date) * transitionStaggering) .attr('x', d => d.x) .attr('y', d => d.y) - .attr('size', d => d.size) - .attr('fillStyle', d => color(`${d.date.getFullYear()}.${d.date.getMonth()}`)) + .attr('size', d => d.size) + .attr('fillStyle', d => + color(`${d.date.getFullYear()}.${d.date.getMonth()}`) + ) .attr('strokeStyle', dayBorderColor) .attr('lineWidth', dayBorderWidth) - ; } drawCanvas() { - const ctx = this.context; - - const canvas = d3.select(findDOMNode(this)); - - ctx.fillStyle = '#fff'; - ctx.rect(0, 0, canvas.attr('width'), canvas.attr('height')); - ctx.fill(); - - - const days = this.container.selectAll('custom.rect'); - - days.each(function (d) { - const node = d3.select(this); - - ctx.beginPath(); - ctx.fillStyle = node.attr('fillStyle'); - ctx.strokeStyle = node.attr('strokeStyle'); - ctx.lineWidth = node.attr('lineWidth'); - ctx.rect(node.attr('x'), node.attr('y'), node.attr('size'), node.attr('size')); - ctx.fill(); - ctx.stroke(); - ctx.closePath(); - - }); + const ctx = this.context + + const canvas = d3.select(findDOMNode(this)) + + ctx.fillStyle = '#fff' + ctx.rect(0, 0, canvas.attr('width'), canvas.attr('height')) + ctx.fill() + + const days = this.container.selectAll('custom.rect') + + days.each(function(d) { + const node = d3.select(this) + + ctx.beginPath() + ctx.fillStyle = node.attr('fillStyle') + ctx.strokeStyle = node.attr('strokeStyle') + ctx.lineWidth = node.attr('lineWidth') + ctx.rect( + node.attr('x'), + node.attr('y'), + node.attr('size'), + node.attr('size') + ) + ctx.fill() + ctx.stroke() + ctx.closePath() + }) //console.log(days); } componentWillMount() { - this.calendarLayout = CalendarLayout(); - this.virtualContainer = document.createElement('custom'); - this.container = d3.select(this.virtualContainer); + this.calendarLayout = CalendarLayout() + this.virtualContainer = document.createElement('custom') + this.container = d3.select(this.virtualContainer) - d3.timer(this.drawCanvas.bind(this)); + d3.timer(this.drawCanvas.bind(this)) } shouldComponentUpdate(nextProps, nextState) { - this.renderD3(nextProps, nextState); + this.renderD3(nextProps, nextState) - return false; + return false } componentDidMount() { - this.canvas = findDOMNode(this); - this.context = this.canvas.getContext('2d'); + this.canvas = findDOMNode(this) + this.context = this.canvas.getContext('2d') - this.renderD3(this.props, this.state); + this.renderD3(this.props, this.state) } render() { - return ; + return } } CalendarCanvas.propTypes = _.omit(calendarPropTypes, [ 'motionStiffness', 'motionDamping', -]); +]) CalendarCanvas.defaultProps = _.omit(calendarDefaultProps, [ 'motionStiffness', 'motionDamping', -]); - +]) -export default CalendarCanvas; +export default CalendarCanvas diff --git a/src/components/charts/calendar/CalendarD3.js b/src/components/charts/calendar/CalendarD3.js index 8df6970ef..1fcfddd41 100644 --- a/src/components/charts/calendar/CalendarD3.js +++ b/src/components/charts/calendar/CalendarD3.js @@ -6,121 +6,134 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component } from 'react'; -import { findDOMNode } from 'react-dom'; -import d3 from 'd3'; -import _ from 'lodash'; -import Nivo from '../../../Nivo'; -import CalendarLayout from '../../../lib/charts/calendar/CalendarLayout'; -import { calendarPropTypes, calendarDefaultProps } from './CalendarProps'; -import { DIRECTION_HORIZONTAL } from '../../../constants/directions'; - +import React, { Component } from 'react' +import { findDOMNode } from 'react-dom' +import d3 from 'd3' +import _ from 'lodash' +import Nivo from '../../../Nivo' +import CalendarLayout from '../../../lib/charts/calendar/CalendarLayout' +import { calendarPropTypes, calendarDefaultProps } from './CalendarProps' +import { DIRECTION_HORIZONTAL } from '../../../constants/directions' class CalendarD3 extends Component { constructor(props) { - super(props); + super(props) } renderD3(props) { const { - from, to, + from, + to, data, onDayClick, direction, - colorScale, emptyColor, - yearSpacing, yearLegendOffset, - daySpacing, dayBorderWidth, dayBorderColor, - monthBorderWidth, monthBorderColor, monthLegendOffset, - transitionDuration, transitionEasing, transitionStaggering - } = props; - - const element = d3.select(findDOMNode(this)); - const wrapper = element.select('.nivo_calendar_wrapper'); - - const margin = _.assign({}, Nivo.defaults.margin, props.margin); - const width = props.width - margin.left - margin.right; - const height = props.height - margin.top - margin.bottom; - - element.select('.debug') + colorScale, + emptyColor, + yearSpacing, + yearLegendOffset, + daySpacing, + dayBorderWidth, + dayBorderColor, + monthBorderWidth, + monthBorderColor, + monthLegendOffset, + transitionDuration, + transitionEasing, + transitionStaggering, + } = props + + const element = d3.select(findDOMNode(this)) + const wrapper = element.select('.nivo_calendar_wrapper') + + const margin = _.assign({}, Nivo.defaults.margin, props.margin) + const width = props.width - margin.left - margin.right + const height = props.height - margin.top - margin.bottom + + element + .select('.debug') .attr('transform', `translate(${margin.left},${margin.top})`) .attr({ width, height }) - ; - element.attr({ - width: props.width, - height: props.height - }); - wrapper.attr('transform', `translate(${margin.left},${margin.top})`); + width: props.width, + height: props.height, + }) + wrapper.attr('transform', `translate(${margin.left},${margin.top})`) const { years, months, days } = this.calendarLayout.compute({ - width, height, - from, to, + width, + height, + from, + to, data, direction, colorScale, emptyColor, yearSpacing, - daySpacing - }); + daySpacing, + }) // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— // Days // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const dayNodes = wrapper.selectAll('.nivo_calendar_day').data(days, d => d.date); + const dayNodes = wrapper + .selectAll('.nivo_calendar_day') + .data(days, d => d.date) - dayNodes.enter() + dayNodes + .enter() .append('rect') - .attr('class', d => `nivo_calendar_day nivo_calendar_day-month-${d.date.getMonth()}`) - .attr('width', d => d.size) + .attr( + 'class', + d => + `nivo_calendar_day nivo_calendar_day-month-${d.date.getMonth()}` + ) + .attr('width', d => d.size) .attr('height', d => d.size) .attr('x', 0) .attr('y', 0) .style({ - opacity: 0, - fill: d => d.color, - stroke: dayBorderColor, + opacity: 0, + fill: d => d.color, + stroke: dayBorderColor, 'stroke-width': dayBorderWidth, }) .on('click', d => onDayClick(d)) - ; dayNodes .transition() .duration(transitionDuration) .ease(transitionEasing) .delay(d => d3.time.dayOfYear(d.date) * transitionStaggering) - .attr('width', d => d.size) + .attr('width', d => d.size) .attr('height', d => d.size) .attr('x', d => d.x) .attr('y', d => d.y) .style({ - opacity: 1, - fill: d => d.color, - stroke: dayBorderColor, + opacity: 1, + fill: d => d.color, + stroke: dayBorderColor, 'stroke-width': dayBorderWidth, }) - ; - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— // Months // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const monthPaths = wrapper.selectAll('.nivo_calendar_month').data(months, d => d.date); + const monthPaths = wrapper + .selectAll('.nivo_calendar_month') + .data(months, d => d.date) - monthPaths.enter() + monthPaths + .enter() .append('path') .attr('class', 'nivo_calendar_month') .style({ - opacity: 0, - fill: 'none', - stroke: monthBorderColor, + opacity: 0, + fill: 'none', + stroke: monthBorderColor, 'stroke-width': monthBorderWidth, }) .attr('d', d => d.path) - ; monthPaths .transition() @@ -128,34 +141,36 @@ class CalendarD3 extends Component { .ease(transitionEasing) .delay(d => (d.date.getMonth() + 1) * 30 * transitionStaggering) .style({ - opacity: 1, - stroke: monthBorderColor, + opacity: 1, + stroke: monthBorderColor, 'stroke-width': monthBorderWidth, }) .attr('d', d => d.path) - ; - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— // Month legends // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const monthLegends = wrapper.selectAll('.nivo_calendar_month_legend').data(months, d => d.date); - const monthLegendFormat = d3.time.format('%b'); + const monthLegends = wrapper + .selectAll('.nivo_calendar_month_legend') + .data(months, d => d.date) + const monthLegendFormat = d3.time.format('%b') - monthLegends.enter() + monthLegends + .enter() .append('text') .classed('nivo_calendar_month_legend', true) .text(d => monthLegendFormat(d.date)) .attr('text-anchor', 'middle') .attr('transform', d => { if (direction === DIRECTION_HORIZONTAL) { - return `translate(${d.bbox.x + d.bbox.width / 2},${d.bbox.y - monthLegendOffset})`; + return `translate(${d.bbox.x + d.bbox.width / 2},${d.bbox + .y - monthLegendOffset})` } - return `translate(${d.bbox.x - monthLegendOffset},${d.bbox.y + d.bbox.height / 2}) rotate(-90)`; + return `translate(${d.bbox.x - monthLegendOffset},${d.bbox.y + + d.bbox.height / 2}) rotate(-90)` }) .style('opacity', 0) - ; monthLegends .transition() @@ -164,35 +179,40 @@ class CalendarD3 extends Component { .delay(d => (d.date.getMonth() + 1) * 30 * transitionStaggering) .attr('transform', d => { if (direction === DIRECTION_HORIZONTAL) { - return `translate(${d.bbox.x + d.bbox.width / 2},${d.bbox.y - monthLegendOffset})`; + return `translate(${d.bbox.x + d.bbox.width / 2},${d.bbox + .y - monthLegendOffset})` } - return `translate(${d.bbox.x - monthLegendOffset},${d.bbox.y + d.bbox.height / 2}) rotate(-90)`; + return `translate(${d.bbox.x - monthLegendOffset},${d.bbox.y + + d.bbox.height / 2}) rotate(-90)` }) .style('opacity', 1) - ; - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— // Year legends // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const yearLegends = wrapper.selectAll('.nivo_calendar_year_legend').data(years); + const yearLegends = wrapper + .selectAll('.nivo_calendar_year_legend') + .data(years) - const yearLabelRotation = direction === DIRECTION_HORIZONTAL ? -90 : 0; + const yearLabelRotation = direction === DIRECTION_HORIZONTAL ? -90 : 0 - yearLegends.enter() + yearLegends + .enter() .append('text') .text(d => d.year) .classed('nivo_calendar_year_legend', true) .attr('text-anchor', 'middle') .attr('transform', d => { if (direction === DIRECTION_HORIZONTAL) { - return `translate(${d.bbox.x - yearLegendOffset},${d.bbox.y + d.bbox.height / 2}) rotate(-90)`; + return `translate(${d.bbox.x - yearLegendOffset},${d.bbox + .y + + d.bbox.height / 2}) rotate(-90)` } - return `translate(${d.bbox.x + d.bbox.width / 2},${d.bbox.y - yearLegendOffset})`; + return `translate(${d.bbox.x + d.bbox.width / 2},${d.bbox.y - + yearLegendOffset})` }) - ; yearLegends .transition() @@ -200,26 +220,28 @@ class CalendarD3 extends Component { .ease(transitionEasing) .attr('transform', d => { if (direction === DIRECTION_HORIZONTAL) { - return `translate(${d.bbox.x - yearLegendOffset},${d.bbox.y + d.bbox.height / 2}) rotate(-90)`; + return `translate(${d.bbox.x - yearLegendOffset},${d.bbox + .y + + d.bbox.height / 2}) rotate(-90)` } - return `translate(${d.bbox.x + d.bbox.width / 2},${d.bbox.y - yearLegendOffset})`; + return `translate(${d.bbox.x + d.bbox.width / 2},${d.bbox.y - + yearLegendOffset})` }) - ; } componentWillMount() { - this.calendarLayout = CalendarLayout(); + this.calendarLayout = CalendarLayout() } shouldComponentUpdate(nextProps, nextState) { - this.renderD3(nextProps, nextState); + this.renderD3(nextProps, nextState) - return false; + return false } componentDidMount() { - this.renderD3(this.props, this.state); + this.renderD3(this.props, this.state) } render() { @@ -227,7 +249,7 @@ class CalendarD3 extends Component { - ); + ) } } @@ -235,13 +257,12 @@ CalendarD3.propTypes = _.omit(calendarPropTypes, [ 'enableMotion', 'motionStiffness', 'motionDamping', -]); +]) CalendarD3.defaultProps = _.omit(calendarDefaultProps, [ 'enableMotion', 'motionStiffness', 'motionDamping', -]); - +]) -export default CalendarD3; +export default CalendarD3 diff --git a/src/components/charts/calendar/CalendarDay.js b/src/components/charts/calendar/CalendarDay.js index 9f8d93a53..60999c2a3 100644 --- a/src/components/charts/calendar/CalendarDay.js +++ b/src/components/charts/calendar/CalendarDay.js @@ -6,54 +6,53 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; - +import React, { Component } from 'react' +import PropTypes from 'prop-types' class CalendarDay extends Component { constructor(props) { - super(props); + super(props) - this.handleClick = this.handleClick.bind(this); + this.handleClick = this.handleClick.bind(this) } handleClick() { - const { onClick, data } = this.props; - onClick(data); + const { onClick, data } = this.props + onClick(data) } render() { - const { x, y, size, color, borderWidth, borderColor } = this.props; + const { x, y, size, color, borderWidth, borderColor } = this.props return ( - ); + ) } } -const { number, string, object, func } = PropTypes; +const { number, string, object, func } = PropTypes CalendarDay.propTypes = { - onClick: func.isRequired, - data: object.isRequired, - x: number.isRequired, - y: number.isRequired, - size: number.isRequired, - color: string.isRequired, + onClick: func.isRequired, + data: object.isRequired, + x: number.isRequired, + y: number.isRequired, + size: number.isRequired, + color: string.isRequired, borderWidth: number.isRequired, borderColor: string.isRequired, -}; - +} -export default CalendarDay; +export default CalendarDay diff --git a/src/components/charts/calendar/CalendarMonthPath.js b/src/components/charts/calendar/CalendarMonthPath.js index a2238fcef..21e6cd2aa 100644 --- a/src/components/charts/calendar/CalendarMonthPath.js +++ b/src/components/charts/calendar/CalendarMonthPath.js @@ -6,36 +6,33 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; - +import React, { Component } from 'react' +import PropTypes from 'prop-types' class CalendarMonthPath extends Component { render() { - const { path, borderWidth, borderColor } = this.props; + const { path, borderWidth, borderColor } = this.props return ( - ); + ) } } -const { number, string } = PropTypes; +const { number, string } = PropTypes CalendarMonthPath.propTypes = { - path: string.isRequired, + path: string.isRequired, borderWidth: number.isRequired, borderColor: string.isRequired, -}; - +} -export default CalendarMonthPath; +export default CalendarMonthPath diff --git a/src/components/charts/calendar/CalendarProps.js b/src/components/charts/calendar/CalendarProps.js index 7a829ef4a..bc176853d 100644 --- a/src/components/charts/calendar/CalendarProps.js +++ b/src/components/charts/calendar/CalendarProps.js @@ -6,19 +6,25 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import { PropTypes } from 'react'; -import Nivo from '../../../Nivo'; -import { margin, scale } from '../../../PropTypes'; +import PropTypes from 'prop-types' +import Nivo from '../../../Nivo' +import { margin, scale } from '../../../PropTypes' import { DIRECTION_HORIZONTAL, - DIRECTION_VERTICAL -} from '../../../constants/directions'; - - -const { number, string, bool, func, shape, oneOf, oneOfType, instanceOf, arrayOf } = PropTypes; + DIRECTION_VERTICAL, +} from '../../../constants/directions' +const { + number, + string, + bool, + func, + shape, + oneOf, + oneOfType, + instanceOf, + arrayOf, +} = PropTypes /** * Calendar components propTypes. @@ -26,39 +32,40 @@ const { number, string, bool, func, shape, oneOf, oneOfType, instanceOf, arrayOf * @type {object} */ export const calendarPropTypes = { - width: number.isRequired, - height: number.isRequired, + width: number.isRequired, + height: number.isRequired, margin, - from: oneOfType([string, instanceOf(Date)]).isRequired, - to: oneOfType([string, instanceOf(Date)]).isRequired, - data: arrayOf(shape({ - day: string.isRequired, - value: number.isRequired, - })).isRequired, - onDayClick: func.isRequired, - direction: oneOf([DIRECTION_HORIZONTAL, DIRECTION_VERTICAL]), - colorScale: scale.isRequired, - emptyColor: string.isRequired, + from: oneOfType([string, instanceOf(Date)]).isRequired, + to: oneOfType([string, instanceOf(Date)]).isRequired, + data: arrayOf( + shape({ + day: string.isRequired, + value: number.isRequired, + }) + ).isRequired, + onDayClick: func.isRequired, + direction: oneOf([DIRECTION_HORIZONTAL, DIRECTION_VERTICAL]), + colorScale: scale.isRequired, + emptyColor: string.isRequired, // years - yearSpacing: number.isRequired, - yearLegendOffset: number.isRequired, + yearSpacing: number.isRequired, + yearLegendOffset: number.isRequired, // days - daySpacing: number.isRequired, - dayBorderWidth: number.isRequired, - dayBorderColor: string.isRequired, + daySpacing: number.isRequired, + dayBorderWidth: number.isRequired, + dayBorderColor: string.isRequired, // months - monthBorderWidth: number.isRequired, - monthBorderColor: string.isRequired, - monthLegendOffset: number.isRequired, + monthBorderWidth: number.isRequired, + monthBorderColor: string.isRequired, + monthLegendOffset: number.isRequired, // transitions - motion: bool.isRequired, - motionStiffness: number.isRequired, // react-motion - motionDamping: number.isRequired, // react-motion - transitionDuration: number.isRequired, // d3 transitions - transitionEasing: string.isRequired, // d3 transitions + animate: bool.isRequired, + motionStiffness: number.isRequired, // react-motion + motionDamping: number.isRequired, // react-motion + transitionDuration: number.isRequired, // d3 transitions + transitionEasing: string.isRequired, // d3 transitions transitionStaggering: number.isRequired, // d3 transitions -}; - +} /** * Calendar components defaultProps. @@ -66,26 +73,26 @@ export const calendarPropTypes = { * @type {object} */ export const calendarDefaultProps = { - margin: Nivo.defaults.margin, - direction: DIRECTION_HORIZONTAL, - onDayClick: () => {}, - emptyColor: '#fff', + margin: Nivo.defaults.margin, + direction: DIRECTION_HORIZONTAL, + onDayClick: () => {}, + emptyColor: '#fff', // years - yearSpacing: 30, - yearLegendOffset: 10, + yearSpacing: 30, + yearLegendOffset: 10, // days - daySpacing: 0, - dayBorderWidth: 1, - dayBorderColor: '#000', + daySpacing: 0, + dayBorderWidth: 1, + dayBorderColor: '#000', // months - monthBorderWidth: 2, - monthBorderColor: '#000', - monthLegendOffset: 6, + monthBorderWidth: 2, + monthBorderColor: '#000', + monthLegendOffset: 6, // transitions - motion: false, - motionStiffness: Nivo.defaults.motionStiffness, // react-motion - motionDamping: Nivo.defaults.motionDamping, // react-motion - transitionDuration: Nivo.defaults.transitionDuration, // d3 transitions - transitionEasing: Nivo.defaults.transitionEasing, // d3 transitions - transitionStaggering: 5, // d3 transitions -}; + animate: false, + motionStiffness: Nivo.defaults.motionStiffness, // react-motion + motionDamping: Nivo.defaults.motionDamping, // react-motion + transitionDuration: Nivo.defaults.transitionDuration, // d3 transitions + transitionEasing: Nivo.defaults.transitionEasing, // d3 transitions + transitionStaggering: 5, // d3 transitions +} diff --git a/src/components/charts/calendar/MotionCalendar.js b/src/components/charts/calendar/MotionCalendar.js index 87907de21..08bd8180a 100644 --- a/src/components/charts/calendar/MotionCalendar.js +++ b/src/components/charts/calendar/MotionCalendar.js @@ -6,162 +6,189 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; +import React, { Component } from 'react' +import d3 from 'd3' +import { TransitionMotion, spring } from 'react-motion' +import { DIRECTION_HORIZONTAL } from '../../../constants/directions' +import CalendarDay from './CalendarDay' +import CalendarMonthPath from './CalendarMonthPath' -import React, { Component } from 'react'; -import d3 from 'd3'; -import { TransitionMotion, spring } from 'react-motion'; -import { DIRECTION_HORIZONTAL } from '../../../constants/directions'; -import CalendarDay from './CalendarDay'; -import CalendarMonthPath from './CalendarMonthPath'; - - -const yearLegendStyles = ({ years, direction, yearLegendOffset, stiffness, damping }) => { +const yearLegendStyles = ({ + years, + direction, + yearLegendOffset, + stiffness, + damping, +}) => { return years.map(year => { - let rotation; - let x, y; + let rotation + let x, y if (direction === DIRECTION_HORIZONTAL) { - rotation = -90; - x = year.bbox.x - yearLegendOffset; - y = year.bbox.y + year.bbox.height / 2; + rotation = -90 + x = year.bbox.x - yearLegendOffset + y = year.bbox.y + year.bbox.height / 2 } else { - rotation = 0; - x = year.bbox.x + year.bbox.width / 2; - y = year.bbox.y - yearLegendOffset; + rotation = 0 + x = year.bbox.x + year.bbox.width / 2 + y = year.bbox.y - yearLegendOffset } return { - key: `${year.year}`, - data: year, + key: `${year.year}`, + data: year, style: { rotation: spring(rotation, { stiffness, damping }), - x: spring(x, { stiffness, damping }), - y: spring(y, { stiffness, damping }), - } - }; - }); -}; + x: spring(x, { stiffness, damping }), + y: spring(y, { stiffness, damping }), + }, + } + }) +} -const monthLegendStyles = ({ months, direction, monthLegendOffset, stiffness, damping }) => { +const monthLegendStyles = ({ + months, + direction, + monthLegendOffset, + stiffness, + damping, +}) => { return months.map(month => { - let rotation; - let x, y; + let rotation + let x, y if (direction === DIRECTION_HORIZONTAL) { - rotation = 0; - x = month.bbox.x + month.bbox.width / 2; - y = month.bbox.y - monthLegendOffset; + rotation = 0 + x = month.bbox.x + month.bbox.width / 2 + y = month.bbox.y - monthLegendOffset } else { - rotation = -90; - x = month.bbox.x - monthLegendOffset; - y = month.bbox.y + month.bbox.height / 2; + rotation = -90 + x = month.bbox.x - monthLegendOffset + y = month.bbox.y + month.bbox.height / 2 } return { - key: month.date.toString(), - data: month, + key: month.date.toString(), + data: month, style: { rotation: spring(rotation, { stiffness, damping }), - x: spring(x, { stiffness, damping }), - y: spring(y, { stiffness, damping }), - } - }; - }); -}; + x: spring(x, { stiffness, damping }), + y: spring(y, { stiffness, damping }), + }, + } + }) +} const dayStyles = ({ days, stiffness, damping }) => { return days.map(day => { return { - key: day.date.toString(), - data: day, + key: day.date.toString(), + data: day, style: { - x: spring(day.x, { stiffness, damping }), - y: spring(day.y, { stiffness, damping }), + x: spring(day.x, { stiffness, damping }), + y: spring(day.y, { stiffness, damping }), size: spring(day.size, { stiffness, damping }), - } - }; - }); -}; + }, + } + }) +} class MotionCalendar extends Component { render() { const { onDayClick, - years, months, days, + years, + months, + days, direction, yearLegendOffset, - dayBorderWidth, dayBorderColor, - monthBorderWidth, monthBorderColor, monthLegendOffset, - motionStiffness, motionDamping - } = this.props; + dayBorderWidth, + dayBorderColor, + monthBorderWidth, + monthBorderColor, + monthLegendOffset, + motionStiffness, + motionDamping, + } = this.props - const monthLegendFormat = d3.time.format('%b'); + const monthLegendFormat = d3.time.format('%b') - const stiffness = motionStiffness; - const damping = motionDamping; + const stiffness = motionStiffness + const damping = motionDamping return ( - {interpolatedStyles => ( + {interpolatedStyles => - {interpolatedStyles.map(d => ( + {interpolatedStyles.map(d => - ))} - - )} + )} + } - {interpolatedStyles => ( + {interpolatedStyles => - {interpolatedStyles.map(d => ( + {interpolatedStyles.map(d => {monthLegendFormat(d.data.date)} - ))} - - )} + )} + } - {interpolatedStyles => ( + {interpolatedStyles => - {interpolatedStyles.map(d => ( + {interpolatedStyles.map(d => {d.data.year} - ))} - - )} + )} +
}
- ); + ) } } -MotionCalendar.propTypes = {}; - +MotionCalendar.propTypes = {} -export default MotionCalendar; +export default MotionCalendar diff --git a/src/components/charts/calendar/ResponsiveCalendar.js b/src/components/charts/calendar/ResponsiveCalendar.js index 8b515a1cd..a9a51aa28 100644 --- a/src/components/charts/calendar/ResponsiveCalendar.js +++ b/src/components/charts/calendar/ResponsiveCalendar.js @@ -6,26 +6,43 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import Calendar from './Calendar'; -import Dimensions from 'react-dimensions'; +import React, { Component } from 'react' +import Calendar from './Calendar' +import Measure from 'react-measure' +export default class ResponsiveCalendar extends Component { + state = { + dimensions: { + width: -1, + height: -1, + }, + } -class ResponsiveCalendar extends Component { render() { - const { containerWidth, containerHeight } = this.props; + const { width, height } = this.state.dimensions + + const shouldRender = width > 0 && height > 0 return ( - - ); + { + this.setState({ dimensions: contentRect.bounds }) + }} + > + {({ measureRef }) => +
+ {shouldRender && + } +
} +
+ ) } } - - -export default Dimensions()(ResponsiveCalendar); diff --git a/src/components/charts/calendar/ResponsiveCalendarCanvas.js b/src/components/charts/calendar/ResponsiveCalendarCanvas.js index a0269e8bc..dddbeb113 100644 --- a/src/components/charts/calendar/ResponsiveCalendarCanvas.js +++ b/src/components/charts/calendar/ResponsiveCalendarCanvas.js @@ -6,16 +6,14 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import CalendarCanvas from './CalendarCanvas'; -import Dimensions from 'react-dimensions'; - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import CalendarCanvas from './CalendarCanvas' +import Dimensions from 'react-dimensions' class ResponsiveCalendarCanvas extends Component { render() { - const { containerWidth, containerHeight } = this.props; + const { containerWidth, containerHeight } = this.props return ( - ); + ) } } - -export default Dimensions()(ResponsiveCalendarCanvas); +export default Dimensions()(ResponsiveCalendarCanvas) diff --git a/src/components/charts/calendar/ResponsiveCalendarD3.js b/src/components/charts/calendar/ResponsiveCalendarD3.js index 6b086386f..d3d81fe0e 100644 --- a/src/components/charts/calendar/ResponsiveCalendarD3.js +++ b/src/components/charts/calendar/ResponsiveCalendarD3.js @@ -6,16 +6,14 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import CalendarD3 from './CalendarD3'; -import Dimensions from 'react-dimensions'; - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import CalendarD3 from './CalendarD3' +import Dimensions from 'react-dimensions' class ResponsiveCalendarD3 extends Component { render() { - const { containerWidth, containerHeight } = this.props; + const { containerWidth, containerHeight } = this.props return ( - ); + ) } } - -export default Dimensions()(ResponsiveCalendarD3); +export default Dimensions()(ResponsiveCalendarD3) diff --git a/src/components/charts/calendar/StaticCalendar.js b/src/components/charts/calendar/StaticCalendar.js index ffb1afc05..12abbca3c 100644 --- a/src/components/charts/calendar/StaticCalendar.js +++ b/src/components/charts/calendar/StaticCalendar.js @@ -6,54 +6,63 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component } from 'react'; -import d3 from 'd3'; -import { DIRECTION_HORIZONTAL } from '../../../constants/directions'; -import CalendarDay from './CalendarDay'; -import CalendarMonthPath from './CalendarMonthPath'; - +import React, { Component } from 'react' +import { timeFormat } from 'd3' +import { DIRECTION_HORIZONTAL } from '../../../constants/directions' +import CalendarDay from './CalendarDay' +import CalendarMonthPath from './CalendarMonthPath' class StaticCalendar extends Component { render() { const { onDayClick, - years, months, days, + years, + months, + days, direction, yearLegendOffset, - dayBorderWidth, dayBorderColor, - monthBorderWidth, monthBorderColor, monthLegendOffset - } = this.props; + dayBorderWidth, + dayBorderColor, + monthBorderWidth, + monthBorderColor, + monthLegendOffset, + } = this.props - const monthLegendFormat = d3.time.format('%b'); + const monthLegendFormat = timeFormat('%b') return ( - {days.map(d => ( + {days.map(d => - ))} - {months.map(m => ( + )} + {months.map(m => - ))} + )} {months.map(month => { - let transform; + let transform if (direction === DIRECTION_HORIZONTAL) { - transform = `translate(${month.bbox.x + month.bbox.width / 2},${month.bbox.y - monthLegendOffset})`; + transform = `translate(${month.bbox.x + + month.bbox.width / 2},${month.bbox.y - + monthLegendOffset})` } else { - transform =`translate(${month.bbox.x - monthLegendOffset},${month.bbox.y + month.bbox.height / 2}) rotate(-90)`; + transform = `translate(${month.bbox.x - + monthLegendOffset},${month.bbox.y + + month.bbox.height / 2}) rotate(-90)` } return ( @@ -65,14 +74,18 @@ class StaticCalendar extends Component { > {monthLegendFormat(month.date)} - ); + ) })} {years.map(year => { - let transform; + let transform if (direction === DIRECTION_HORIZONTAL) { - transform = `translate(${year.bbox.x - yearLegendOffset},${year.bbox.y + year.bbox.height / 2}) rotate(-90)`; + transform = `translate(${year.bbox.x - + yearLegendOffset},${year.bbox.y + + year.bbox.height / 2}) rotate(-90)` } else { - transform = `translate(${year.bbox.x + year.bbox.width / 2},${year.bbox.y - yearLegendOffset})`; + transform = `translate(${year.bbox.x + + year.bbox.width / 2},${year.bbox.y - + yearLegendOffset})` } return ( @@ -84,14 +97,13 @@ class StaticCalendar extends Component { > {year.year} - ); + ) })} - ); + ) } } -StaticCalendar.propTypes = {}; - +StaticCalendar.propTypes = {} -export default StaticCalendar; +export default StaticCalendar diff --git a/src/components/charts/calendar/index.js b/src/components/charts/calendar/index.js index edd656e35..7cf3bb2e3 100644 --- a/src/components/charts/calendar/index.js +++ b/src/components/charts/calendar/index.js @@ -6,11 +6,9 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -export Calendar from './Calendar'; -export ResponsiveCalendar from './ResponsiveCalendar'; -export CalendarD3 from './CalendarD3'; -export ResponsiveCalendarD3 from './ResponsiveCalendarD3'; -export CalendarCanvas from './CalendarCanvas'; -export ResponsiveCalendarCanvas from './ResponsiveCalendarCanvas'; +export Calendar from './Calendar' +export ResponsiveCalendar from './ResponsiveCalendar' +//export CalendarD3 from './CalendarD3' +//export ResponsiveCalendarD3 from './ResponsiveCalendarD3' +//export CalendarCanvas from './CalendarCanvas' +//export ResponsiveCalendarCanvas from './ResponsiveCalendarCanvas' diff --git a/src/components/charts/chord/Chord.js b/src/components/charts/chord/Chord.js index de7333d26..8c39f18ee 100644 --- a/src/components/charts/chord/Chord.js +++ b/src/components/charts/chord/Chord.js @@ -6,59 +6,56 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component, PropTypes } from 'react' -import Nivo from '../../../Nivo' -import { margin as marginPropType } from '../../../PropTypes' -import { getColorRange } from '../../../ColorUtils' - -import { - chord as d3Chord, - arc as Arc, - ribbon as Ribbon, - rgb, -} from 'd3' +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Nivo from '../../../Nivo' +import { margin as marginPropType } from '../../../PropTypes' +import { getColorRange } from '../../../ColorUtils' +import { chord as d3Chord, arc as Arc, ribbon as Ribbon, rgb } from 'd3' class Chord extends Component { render() { const { data, margin: _margin, - width: _width, height: _height, + width: _width, + height: _height, padAngle, - innerRadiusRatio, innerRadiusOffset, - ribbonOpacity, ribbonBorderWidth, - arcOpacity, arcBorderWidth, + innerRadiusRatio, + innerRadiusOffset, + ribbonOpacity, + ribbonBorderWidth, + arcOpacity, + arcBorderWidth, colors, } = this.props - const color = getColorRange(colors) + const color = getColorRange(colors) - const margin = Object.assign({}, Nivo.defaults.margin, _margin) - const width = _width - margin.left - margin.right - const height = _height - margin.top - margin.bottom - const radius = Math.min(width, height) / 2 + const margin = Object.assign({}, Nivo.defaults.margin, _margin) + const width = _width - margin.left - margin.right + const height = _height - margin.top - margin.bottom + const radius = Math.min(width, height) / 2 const arcInnerRadius = radius * innerRadiusRatio - const ribbonRadius = radius * (innerRadiusRatio - innerRadiusOffset) + const ribbonRadius = radius * (innerRadiusRatio - innerRadiusOffset) + const chord = d3Chord().padAngle(padAngle) - const chord = d3Chord() - .padAngle(padAngle) + const arc = Arc().innerRadius(arcInnerRadius).outerRadius(radius) - const arc = Arc() - .innerRadius(arcInnerRadius) - .outerRadius(radius) - - const ribbon = Ribbon() - .radius(ribbonRadius) + const ribbon = Ribbon().radius(ribbonRadius) const ribbons = chord(data) - const arcs = ribbons.groups + const arcs = ribbons.groups return ( - + 0 && height > 0 return ( - + { + this.setState({ dimensions: contentRect.bounds }) + }} + > + {({ measureRef }) => +
+ {shouldRender && + } +
} + ) } } - - -export default Dimensions()(ResponsiveChord) diff --git a/src/components/charts/chord/index.js b/src/components/charts/chord/index.js index ddaf8814e..b949086c5 100644 --- a/src/components/charts/chord/index.js +++ b/src/components/charts/chord/index.js @@ -6,8 +6,5 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - - -export Chord from './Chord' +export Chord from './Chord' export ResponsiveChord from './ResponsiveChord' diff --git a/src/components/charts/line/Line.js b/src/components/charts/line/Line.js index 8c93672af..9d6f92043 100644 --- a/src/components/charts/line/Line.js +++ b/src/components/charts/line/Line.js @@ -6,214 +6,60 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component, PropTypes } from 'react' -import _ from 'lodash' -import Nivo from '../../../Nivo' -import { margin as marginPropType } from '../../../PropTypes' -import { getColorRange } from '../../../ColorUtils' -import { convertGetter } from '../../../lib/propertiesConverters' -import Axis from '../../axes/Axis' -import Grid from '../../axes/Grid' +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import _ from 'lodash' import { curvePropMapping, curvePropType } from '../../../properties/curve' -import { - scaleOrdinal, - scaleLinear, - scaleBand, - scaleQuantize, - scaleQuantile, - scaleThreshold, - scalePoint, - stack, - max, - line as LineGenerator, -} from 'd3' +import { line } from 'd3' + +export default class Line extends Component { + static propTypes = { + scales: PropTypes.object.isRequired, + curve: curvePropType.isRequired, + color: PropTypes.string.isRequired, + } + static defaultProps = { + scales: {}, + curve: 'linear', + color: '#000', + } -class Line extends Component { render() { const { data, - keys, - cumulative, - identity: _identity, - margin: _margin, - width: _width, height: _height, + scales, + xScale: _xScale, + yScale: _yScale, + x, + y, curve, - colors, - xAxis, xAxisOrientation, xAxisTickSize, xAxisTickPadding, - yAxis, yAxisOrientation, yAxisTickSize, yAxisTickPadding, - animate, - motionStiffness, motionDamping, + color, } = this.props - const identity = convertGetter(_identity) - - const margin = Object.assign({}, Nivo.defaults.margin, _margin) - const width = _width - margin.left - margin.right - const height = _height - margin.top - margin.bottom - - const color = getColorRange(colors) - - const x = scalePoint() - .range([0, width]) - .domain(data.map(identity)) + const xScale = scales[_xScale] + const yScale = scales[_yScale] - const y = scaleLinear() - .rangeRound([height, 0]) + const getX = _.isFunction(x) ? x : d => d[x] + const getY = _.isFunction(y) ? y : d => d[y] - const lines = [] + const points = data.map(d => ({ + x: xScale(getX(d)), + y: yScale(getY(d)), + })) - if (cumulative) { - const series = stack().keys(keys)(data) - - y.domain([0, max(series[series.length - 1], d => d[1])]) - - series.forEach(serie => { - lines.push({ - key: serie.key, - points: serie.map(d => { - return { - x: x(identity(d.data)), - y: y(d[1]), - } - }) - }) - }) - } else { - y.domain([0, max(data, d => max(_.values(_.pick(d, keys))))]) - - keys.forEach(key => { - lines.push({ - key, - points: data.map(d => { - return { - x: x(identity(d)), - y: y(d[key]), - } - }), - }) - }) - - } - - const lineGenerator = LineGenerator() + const lineGenerator = line() .x(d => d.x) .y(d => d.y) .curve(curvePropMapping[curve]) return ( - - - - {lines.map(line => { - return ( - - ) - })} - {xAxis && ( - - - - )} - {yAxis && ( - - - - )} - - + ) } } - -Line.propTypes = { - // dimensions - width: PropTypes.number.isRequired, - height: PropTypes.number.isRequired, - margin: marginPropType, - - // data - data: PropTypes.arrayOf(PropTypes.object).isRequired, - keys: PropTypes.arrayOf(PropTypes.string).isRequired, - cumulative: PropTypes.bool.isRequired, - identity: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.func, - ]).isRequired, - - colors: PropTypes.any.isRequired, - - curve: curvePropType.isRequired, - - // axes - xAxis: PropTypes.bool.isRequired, - xAxisOrientation: PropTypes.oneOf(['top', 'bottom']).isRequired, - xAxisTickSize: PropTypes.number, - xAxisTickPadding: PropTypes.number, - yAxis: PropTypes.bool.isRequired, - yAxisOrientation: PropTypes.oneOf(['left', 'right']).isRequired, - yAxisTickSize: PropTypes.number, - yAxisTickPadding: PropTypes.number, - - // motion - animate: PropTypes.bool.isRequired, - motionStiffness: PropTypes.number.isRequired, - motionDamping: PropTypes.number.isRequired, -} - -Line.defaultProps = { - margin: Nivo.defaults.margin, - cumulative: true, - colors: Nivo.defaults.colorRange, - - curve: 'linear', - - // axes - xAxis: true, - xAxisOrientation: 'bottom', - yAxis: true, - yAxisOrientation: 'left', - - // motion - animate: true, - motionStiffness: Nivo.defaults.motionStiffness, - motionDamping: Nivo.defaults.motionDamping, -} - - -export default Line diff --git a/src/components/charts/line/ResponsiveLine.js b/src/components/charts/line/ResponsiveLine.js index 220115196..06eb7fe16 100644 --- a/src/components/charts/line/ResponsiveLine.js +++ b/src/components/charts/line/ResponsiveLine.js @@ -6,12 +6,10 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component, PropTypes } from 'react' -import Dimensions from 'react-dimensions' -import Line from './Line' - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Dimensions from 'react-dimensions' +import Line from './Line' class ResponsiveLine extends Component { render() { @@ -27,5 +25,4 @@ class ResponsiveLine extends Component { } } - export default Dimensions()(ResponsiveLine) diff --git a/src/components/charts/line/index.js b/src/components/charts/line/index.js index 84a506de2..d987cd4ce 100644 --- a/src/components/charts/line/index.js +++ b/src/components/charts/line/index.js @@ -6,7 +6,5 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -export Line from './Line' +export Line from './Line' export ResponsiveLine from './ResponsiveLine' diff --git a/src/components/charts/pie/Pie.js b/src/components/charts/pie/Pie.js deleted file mode 100644 index ea28ff058..000000000 --- a/src/components/charts/pie/Pie.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of the nivo project. - * - * (c) Raphaël Benitte - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import { findDOMNode } from 'react-dom'; -import Nivo from '../../../Nivo'; -import PieD3Svg from '../../../lib/charts/pie/PieD3Svg'; -import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren'; - - -class Pie extends Component { - shouldComponentUpdate(nextProps) { - this.pie.decorate(decoratorsFromReactChildren(nextProps.children, 'decoratePie')); - this.pie.draw(nextProps); - - return false; - } - - componentDidMount() { - this.pie = PieD3Svg(findDOMNode(this)); - this.pie.decorate(decoratorsFromReactChildren(this.props.children, 'decoratePie')); - this.pie.draw(this.props); - } - - render() { - return ; - } -} - -const { array, number, string, func, any } = PropTypes; - -Pie.propTypes = { - width: number.isRequired, - height: number.isRequired, - sort: func, - data: array.isRequired, - keyProp: string.isRequired, - valueProp: string.isRequired, - startAngle: number.isRequired, - endAngle: number.isRequired, - padAngle: number.isRequired, - cornerRadius: number.isRequired, - colors: any.isRequired, - transitionDuration: number.isRequired, - transitionEasing: string.isRequired, - innerRadius: number.isRequired -}; - -Pie.defaultProps = { - sort: null, - keyProp: 'label', - valueProp: 'value', - startAngle: 0, - endAngle: 360, - padAngle: 0, - cornerRadius: 0, - transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, - innerRadius: 0, - colors: Nivo.defaults.colorRange -}; - - -export default Pie; diff --git a/src/components/charts/pie/PieColumnLegends.js b/src/components/charts/pie/PieColumnLegends.js index 81e429e59..5d3da7a4d 100644 --- a/src/components/charts/pie/PieColumnLegends.js +++ b/src/components/charts/pie/PieColumnLegends.js @@ -6,56 +6,59 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import invariant from 'invariant'; -import d3 from 'd3'; -import _ from 'lodash'; -import Nivo from '../../../Nivo'; -import { midAngle, findNeighbor } from '../../../ArcUtils'; -import { getColorStyleObject } from '../../../ColorUtils'; - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import invariant from 'invariant' +import d3 from 'd3' +import _ from 'lodash' +import Nivo from '../../../Nivo' +import { midAngle, findNeighbor } from '../../../ArcUtils' +import { getColorStyleObject } from '../../../ColorUtils' class PieColumnLegends extends Component { static decoratePie(element) { - const { props } = element; + const { props } = element - const lineColorStyle = getColorStyleObject(props.lineColor, 'stroke'); - const textColorStyle = getColorStyleObject(props.textColor, 'fill'); - const badgeColorStyle = getColorStyleObject(props.badgeColor, 'fill'); + const lineColorStyle = getColorStyleObject(props.lineColor, 'stroke') + const textColorStyle = getColorStyleObject(props.textColor, 'fill') + const badgeColorStyle = getColorStyleObject(props.badgeColor, 'fill') // Receive context from Parent Pie component return ({ element, - previousData, newData, identity, - arc, pie, radius, - transitionDuration, transitionEasing + previousData, + newData, + identity, + arc, + pie, + radius, + transitionDuration, + transitionEasing, }) => { + const labelFn = props.labelFn || identity - const labelFn = props.labelFn || identity; - - const outerArc = d3.svg.arc() + const outerArc = d3.svg + .arc() .innerRadius(radius + props.radiusOffset) .outerRadius(radius + props.radiusOffset) - ; - let lines = element.selectAll('.line').data(newData, identity); - lines.enter() + let lines = element.selectAll('.line').data(newData, identity) + lines + .enter() .append('polyline') .attr('fill', 'none') .attr('class', 'line') //.style('opacity', 0) - .each(function (d, i) { + .each(function(d, i) { //console.log('LINES ENTER'); - let startingArc = findNeighbor(i, identity, previousData, newData) || d; + let startingArc = + findNeighbor(i, identity, previousData, newData) || d - this._current = startingArc; + this._current = startingArc }) - ; lines - .each(function (d, i) { + .each(function(d, i) { //console.log('LINES UPDATE'); }) .transition() @@ -63,84 +66,89 @@ class PieColumnLegends extends Component { .ease(transitionEasing) .style(lineColorStyle) .style('opacity', 1) - .attrTween('points', function (d) { - const interpolate = d3.interpolate(this._current, d); + .attrTween('points', function(d) { + const interpolate = d3.interpolate(this._current, d) return t => { - const angles = interpolate(t); + const angles = interpolate(t) - const p0 = arc.centroid(angles); - const p1 = outerArc.centroid(angles); - const p2 = [0, p1[1]]; + const p0 = arc.centroid(angles) + const p1 = outerArc.centroid(angles) + const p2 = [0, p1[1]] - p2[0] = (radius + props.horizontalOffset) * (midAngle(angles) < Math.PI ? 1 : -1); + p2[0] = + (radius + props.horizontalOffset) * + (midAngle(angles) < Math.PI ? 1 : -1) - return [p0, p1, p2]; - }; + return [p0, p1, p2] + } }) - ; - lines.exit() - .each(function (d) { - console.log('LINES EXIT', labelFn(d)); + lines + .exit() + .each(function(d) { + console.log('LINES EXIT', labelFn(d)) }) .remove() - ; - return; - let labels = element.selectAll('.column-label').data(newData, identity); - labels.enter() + return + let labels = element + .selectAll('.column-label') + .data(newData, identity) + labels + .enter() .append('g') .attr('class', 'column-label') .attr('transform', d => { - const centroid = outerArc.centroid(d); + const centroid = outerArc.centroid(d) - return `translate(${centroid[0]},${centroid[1]})`; + return `translate(${centroid[0]},${centroid[1]})` }) - .each(function (d, i) { - const el = d3.select(this); + .each(function(d, i) { + const el = d3.select(this) - let labelBackground; + let labelBackground if (props.badgeMode) { - labelBackground = el.append('rect') + labelBackground = el + .append('rect') .style(badgeColorStyle) .attr({ rx: props.badgeBorderRadius, - ry: props.badgeBorderRadius + ry: props.badgeBorderRadius, }) - ; } - const labelText = el.append('text') + const labelText = el + .append('text') .text(labelFn) .style(textColorStyle) - ; - const labelBBox = labelText[0][0].getBBox(); + const labelBBox = labelText[0][0].getBBox() - console.log(labelBBox); + console.log(labelBBox) if (props.badgeMode) { - const badgeWidth = labelBBox.width + props.badgePaddingX * 2; - const badgeHeight = labelBBox.height + props.badgePaddingY * 2; + const badgeWidth = + labelBBox.width + props.badgePaddingX * 2 + const badgeHeight = + labelBBox.height + props.badgePaddingY * 2 labelBackground.attr({ transform: `translate(0,${badgeHeight / 2 * -1})`, - width: badgeWidth, - height: badgeHeight - }); + width: badgeWidth, + height: badgeHeight, + }) - labelText - .attr({ - transform: `translate(${props.badgePaddingX},0)` - }) - ; + labelText.attr({ + transform: `translate(${props.badgePaddingX},0)`, + }) } }) //.style('opacity', 0) - .each(function (d, i) { - this._current = findNeighbor(i, identity, previousData, newData) || _.assign({}, d, { endAngle: d.startAngle }); + .each(function(d, i) { + this._current = + findNeighbor(i, identity, previousData, newData) || + _.assign({}, d, { endAngle: d.startAngle }) }) - ; labels .text(labelFn) @@ -149,74 +157,82 @@ class PieColumnLegends extends Component { .ease(transitionEasing) .style(textColorStyle) .style('opacity', 1) - .attrTween('transform', function (d) { - const interpolate = d3.interpolate({ - startAngle: this._current.startAngle, - endAngle: this._current.endAngle - }, d); + .attrTween('transform', function(d) { + const interpolate = d3.interpolate( + { + startAngle: this._current.startAngle, + endAngle: this._current.endAngle, + }, + d + ) - const el = d3.select(this); + const el = d3.select(this) return t => { - const angles = interpolate(t); + const angles = interpolate(t) - el.attr('text-anchor', midAngle(angles) < Math.PI ? 'start' : 'end'); + el.attr( + 'text-anchor', + midAngle(angles) < Math.PI ? 'start' : 'end' + ) - const centroid = outerArc.centroid(angles); - const position = [0, centroid[1]]; + const centroid = outerArc.centroid(angles) + const position = [0, centroid[1]] - position[0] = (radius + props.horizontalOffset + props.textOffset) * (midAngle(angles) < Math.PI ? 1 : -1); + position[0] = + (radius + + props.horizontalOffset + + props.textOffset) * + (midAngle(angles) < Math.PI ? 1 : -1) - return `translate(${position[0]},${position[1]})`; - }; + return `translate(${position[0]},${position[1]})` + } }) - ; - labels.exit() - .each(function (d) { + labels + .exit() + .each(function(d) { //console.log('EXIT', labelFn(d)); }) .remove() - ; - }; + } } render() { invariant( false, ' element is for Pie configuration only and should not be rendered' - ); + ) } } -const { number, string, bool, func, any } = PropTypes; +const { number, string, bool, func, any } = PropTypes PieColumnLegends.propTypes = { - labelFn: func, - radiusOffset: number.isRequired, - horizontalOffset: number.isRequired, - textOffset: number.isRequired, - lineColor: any.isRequired, - textColor: any.isRequired, - badgeMode: bool.isRequired, - badgeColor: any.isRequired, - badgePaddingX: number.isRequired, - badgePaddingY: number.isRequired, - badgeBorderRadius: number.isRequired -}; + labelFn: func, + radiusOffset: number.isRequired, + horizontalOffset: number.isRequired, + textOffset: number.isRequired, + lineColor: any.isRequired, + textColor: any.isRequired, + badgeMode: bool.isRequired, + badgeColor: any.isRequired, + badgePaddingX: number.isRequired, + badgePaddingY: number.isRequired, + badgeBorderRadius: number.isRequired, +} PieColumnLegends.defaultProps = { - radiusOffset: 16, - horizontalOffset: 30, - textOffset: 10, - lineColor: 'none', - textColor: 'none', - badgeMode: true, - badgeColor: 'none', - badgePaddingX: 7, - badgePaddingY: 3, - badgeBorderRadius: 2 -}; - - -export default PieColumnLegends; + radiusOffset: 16, + horizontalOffset: 30, + textOffset: 10, + lineColor: 'none', + textColor: 'none', + badgeMode: true, + badgeColor: 'none', + badgePaddingX: 7, + badgePaddingY: 3, + badgeBorderRadius: 2, +} + +export default PieColumnLegends diff --git a/src/components/charts/pie/PieD3.js b/src/components/charts/pie/PieD3.js new file mode 100644 index 000000000..3ffe1a68f --- /dev/null +++ b/src/components/charts/pie/PieD3.js @@ -0,0 +1,72 @@ +/* + * This file is part of the nivo project. + * + * (c) Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { findDOMNode } from 'react-dom' +import Nivo from '../../../Nivo' +import PieD3Svg from '../../../lib/charts/pie/PieD3Svg' +import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren' + +class Pie extends Component { + shouldComponentUpdate(nextProps) { + this.pie.decorate( + decoratorsFromReactChildren(nextProps.children, 'decoratePie') + ) + this.pie.draw(nextProps) + + return false + } + + componentDidMount() { + this.pie = PieD3Svg(findDOMNode(this)) + this.pie.decorate( + decoratorsFromReactChildren(this.props.children, 'decoratePie') + ) + this.pie.draw(this.props) + } + + render() { + return + } +} + +const { array, number, string, func, any } = PropTypes + +Pie.propTypes = { + width: number.isRequired, + height: number.isRequired, + sort: func, + data: array.isRequired, + keyProp: string.isRequired, + valueProp: string.isRequired, + startAngle: number.isRequired, + endAngle: number.isRequired, + padAngle: number.isRequired, + cornerRadius: number.isRequired, + colors: any.isRequired, + transitionDuration: number.isRequired, + transitionEasing: string.isRequired, + innerRadius: number.isRequired, +} + +Pie.defaultProps = { + sort: null, + keyProp: 'label', + valueProp: 'value', + startAngle: 0, + endAngle: 360, + padAngle: 0, + cornerRadius: 0, + transitionDuration: Nivo.defaults.transitionDuration, + transitionEasing: Nivo.defaults.transitionEasing, + innerRadius: 0, + colors: Nivo.defaults.colorRange, +} + +export default Pie diff --git a/src/components/charts/pie/PieRadialLegends.js b/src/components/charts/pie/PieRadialLegends.js index 9a973f75d..5a5161dbf 100644 --- a/src/components/charts/pie/PieRadialLegends.js +++ b/src/components/charts/pie/PieRadialLegends.js @@ -6,86 +6,94 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import invariant from 'invariant'; -import d3 from 'd3'; -import Nivo from '../../../Nivo'; -import { midAngle, radiansToDegrees } from '../../../ArcUtils'; -import { getColorGenerator } from '../../../ColorUtils'; - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import invariant from 'invariant' +import d3 from 'd3' +import Nivo from '../../../Nivo' +import { midAngle, radiansToDegrees } from '../../../ArcUtils' +import { getColorGenerator } from '../../../ColorUtils' class PieRadialLegends extends Component { static decoratePie(element) { - const { props } = element; + const { props } = element - const color = getColorGenerator(props.textColor); + const color = getColorGenerator(props.textColor) return ({ element, arc, identity, pie, newData, radius }) => { - const labelFn = props.labelFn || identity; + const labelFn = props.labelFn || identity - const outerArc = d3.svg.arc() + const outerArc = d3.svg + .arc() .innerRadius(radius + props.radiusOffset) .outerRadius(radius + props.radiusOffset) - ; - let labels = element.selectAll('.radial-label').data(newData, identity); - labels.enter().append('g') + let labels = element + .selectAll('.radial-label') + .data(newData, identity) + labels + .enter() + .append('g') .attr('class', 'radial-label') .append('text') .style('opacity', 0) - ; labels - .each(function (d) { - const el = d3.select(this); + .each(function(d) { + const el = d3.select(this) - const angle = midAngle(d); - const angleOffset = angle < Math.PI ? -90 : 90; + const angle = midAngle(d) + const angleOffset = angle < Math.PI ? -90 : 90 - const styles = { opacity: 1 }; + const styles = { opacity: 1 } if (color !== 'none') { - styles.fill = color(d); + styles.fill = color(d) } - el.select('text') + el + .select('text') .text(labelFn) - .attr('text-anchor', d => (midAngle(d) < Math.PI ? 'start' : 'end')) + .attr( + 'text-anchor', + d => (midAngle(d) < Math.PI ? 'start' : 'end') + ) .transition() .duration(props.transitionDuration) .ease(props.transitionEasing) .style(styles) - .attr('transform', `translate(${radius + props.radiusOffset}, 0)`) - ; + .attr( + 'transform', + `translate(${radius + props.radiusOffset}, 0)` + ) }) .transition() .duration(props.transitionDuration) .ease(props.transitionEasing) .attr('transform', d => { - const angle = midAngle(d); + const angle = midAngle(d) - return `rotate(${radiansToDegrees(angle)}, 0, 0)`; + return `rotate(${radiansToDegrees(angle)}, 0, 0)` }) - ; - labels.exit() - .each(function (d) { - const el = d3.select(this); + labels + .exit() + .each(function(d) { + const el = d3.select(this) - el.select('text') + el + .select('text') .transition() .duration(props.transitionDuration) .ease(props.transitionEasing) .style('opacity', 0) - .attr('transform', `translate(${radius + props.radiusOffset + 50}, 0)`) - ; + .attr( + 'transform', + `translate(${radius + props.radiusOffset + 50}, 0)` + ) }) .transition() .duration(0) .delay(props.transitionDuration) .remove() - ; - /* labels.enter() @@ -117,33 +125,32 @@ class PieRadialLegends extends Component { .remove() ; */ - }; + } } render() { invariant( false, ' element is for Pie configuration only and should not be rendered' - ); + ) } } -const { number, string, func, any } = PropTypes; +const { number, string, func, any } = PropTypes PieRadialLegends.propTypes = { - labelFn: func, - radiusOffset: number.isRequired, + labelFn: func, + radiusOffset: number.isRequired, transitionDuration: number.isRequired, - transitionEasing: string.isRequired, - textColor: any.isRequired -}; + transitionEasing: string.isRequired, + textColor: any.isRequired, +} PieRadialLegends.defaultProps = { - radiusOffset: 16, + radiusOffset: 16, transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, - textColor: 'none' -}; - + transitionEasing: Nivo.defaults.transitionEasing, + textColor: 'none', +} -export default PieRadialLegends; +export default PieRadialLegends diff --git a/src/components/charts/pie/PieSliceLegends.js b/src/components/charts/pie/PieSliceLegends.js index 2819f53df..426097d79 100644 --- a/src/components/charts/pie/PieSliceLegends.js +++ b/src/components/charts/pie/PieSliceLegends.js @@ -6,126 +6,126 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import invariant from 'invariant'; -import _ from 'lodash'; -import d3 from 'd3'; -import Nivo from '../../../Nivo'; -import { findNeighbor, midAngle, radiansToDegrees } from '../../../ArcUtils'; -import { getColorStyleObject } from '../../../ColorUtils'; - +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import invariant from 'invariant' +import _ from 'lodash' +import d3 from 'd3' +import Nivo from '../../../Nivo' +import { findNeighbor, midAngle, radiansToDegrees } from '../../../ArcUtils' +import { getColorStyleObject } from '../../../ColorUtils' class PieSliceLegends extends Component { static decoratePie(element) { - const { props } = element; + const { props } = element - const badgeColorStyle = getColorStyleObject(props.badgeColor, 'fill'); - const textColorStyle = getColorStyleObject(props.textColor, 'fill'); + const badgeColorStyle = getColorStyleObject(props.badgeColor, 'fill') + const textColorStyle = getColorStyleObject(props.textColor, 'fill') return ({ element, identity, arc, previousData, newData }) => { - let legends = element.selectAll('.slice-legend').data(newData, identity); + let legends = element + .selectAll('.slice-legend') + .data(newData, identity) - const labelFn = props.labelFn || identity; + const labelFn = props.labelFn || identity - legends.enter() + legends + .enter() .append('g') .attr('class', 'slice-legend') .attr('transform', d => { - const centroid = arc.centroid(d); + const centroid = arc.centroid(d) - return `translate(${centroid[0]}, ${centroid[1]})`; + return `translate(${centroid[0]}, ${centroid[1]})` }) .style('opacity', 0) - .each(function (d, i) { - this._current = findNeighbor(i, identity, previousData, newData) || _.assign({}, d, { endAngle: d.startAngle }); - const el = d3.select(this); + .each(function(d, i) { + this._current = + findNeighbor(i, identity, previousData, newData) || + _.assign({}, d, { endAngle: d.startAngle }) + const el = d3.select(this) - el.append('circle') - .attr('r', props.radius) - ; + el.append('circle').attr('r', props.radius) - el.append('text') - .attr('text-anchor', 'middle') - ; + el.append('text').attr('text-anchor', 'middle') }) - ; legends - .each(function (d) { - d3.select(this).select('circle') - .style(badgeColorStyle) - ; + .each(function(d) { + d3.select(this).select('circle').style(badgeColorStyle) - d3.select(this).select('text') + d3 + .select(this) + .select('text') .style(textColorStyle) .text(labelFn(d)) - ; }) .transition() .duration(props.transitionDuration) .ease(props.transitionEasing) .style('opacity', 1) - .attrTween('transform', function (d) { - const interpolate = d3.interpolate({ - startAngle: this._current.startAngle, - endAngle: this._current.endAngle - }, d); + .attrTween('transform', function(d) { + const interpolate = d3.interpolate( + { + startAngle: this._current.startAngle, + endAngle: this._current.endAngle, + }, + d + ) return t => { - const angles = interpolate(t); - const centroid = arc.centroid(angles); + const angles = interpolate(t) + const centroid = arc.centroid(angles) - let transform = `translate(${centroid[0]}, ${centroid[1]})`; + let transform = `translate(${centroid[0]}, ${centroid[1]})` if (props.orient) { - const angle = midAngle(angles); - transform = `${transform} rotate(${radiansToDegrees(angle)}, 0, 0)`; + const angle = midAngle(angles) + transform = `${transform} rotate(${radiansToDegrees( + angle + )}, 0, 0)` } - return transform; - }; + return transform + } }) - ; - legends.exit() + legends + .exit() .transition() .duration(props.transitionDuration) .ease(props.transitionEasing) .style('opacity', 0) .remove() - ; - }; + } } render() { invariant( false, ' element is for Pie configuration only and should not be rendered' - ); + ) } } -const { number, string, bool, func, any } = PropTypes; +const { number, string, bool, func, any } = PropTypes PieSliceLegends.propTypes = { - labelFn: func, - radius: number.isRequired, - orient: bool.isRequired, + labelFn: func, + radius: number.isRequired, + orient: bool.isRequired, transitionDuration: number.isRequired, - transitionEasing: string.isRequired, - badgeColor: any.isRequired, - textColor: any.isRequired -}; + transitionEasing: string.isRequired, + badgeColor: any.isRequired, + textColor: any.isRequired, +} PieSliceLegends.defaultProps = { - radius: 12, - orient: true, + radius: 12, + orient: true, transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, - badgeColor: 'none', - textColor: 'none' -}; - + transitionEasing: Nivo.defaults.transitionEasing, + badgeColor: 'none', + textColor: 'none', +} -export default PieSliceLegends; +export default PieSliceLegends diff --git a/src/components/charts/pie/ResponsivePie.js b/src/components/charts/pie/ResponsivePie.js deleted file mode 100644 index a94799019..000000000 --- a/src/components/charts/pie/ResponsivePie.js +++ /dev/null @@ -1,185 +0,0 @@ -/* - * This file is part of the nivo project. - * - * (c) Raphaël Benitte - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import { findDOMNode } from 'react-dom'; -import _ from 'lodash'; -import d3 from 'd3'; -import Nivo from '../../../Nivo'; -import { degreesToRadians, findNeighbor } from '../../../ArcUtils'; -import { getColorRange } from '../../../ColorUtils'; - - -class Pie extends Component { - renderD3(nextProps) { - const { - data, - width, height, - sort, - keyProp, valueProp, - startAngle, endAngle, padAngle, - colors, - innerRadius, - transitionDuration, transitionEasing, - } = nextProps; - - const identity = d => d.data[keyProp]; - - const element = d3.select(findDOMNode(this)); - const container = element.select('.nivo_pie_slices'); - - element.attr('transform', `translate(${width / 2}, ${height / 2})`); - - const pie = d3.layout.pie() - .sort(sort) - .value(d => d[valueProp]) - .startAngle(degreesToRadians(startAngle)) - .endAngle(degreesToRadians(endAngle)) - .padAngle(degreesToRadians(padAngle)) - ; - - let radius = Math.min(width / 2, height / 2); - const arc = d3.svg.arc() - .outerRadius(radius) - .innerRadius(radius * innerRadius) - ; - - const outline = element.select('.nivo_pie_outline').attr('d', arc({ - startAngle: degreesToRadians(startAngle), - endAngle: degreesToRadians(endAngle) - })); - - const color = getColorRange(colors); - - let slices = container.selectAll('.nivo_pie_slice'); - const previousData = slices.data(); - const newData = pie(data.map((d, i) => { - if (!d.color) { - d.color = color(i); - } - - return d; - })); - - function arcTween(a) { - const i = d3.interpolate(this._current, a); - this._current = i(0); - - return t => arc(i(t)); - } - - slices = slices.data(newData, identity); - slices.enter().append('path') - .attr('class', 'nivo_pie_slice') - .style('fill', d => d.data.color) - .each(function (d, i) { - this._current = findNeighbor(i, identity, previousData, newData) || _.assign({}, d, { endAngle: d.startAngle }); - }) - ; - slices.exit() - .datum((d, i) => { - return findNeighbor(i, identity, newData, previousData) || d; - }) - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attrTween('d', arcTween) - .remove() - ; - slices - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attrTween('d', arcTween) - .style('fill', d => d.data.color) - ; - - const pieContext = { - element, - pie, - arc, radius, - identity, - previousData, newData - }; - - this.legends.forEach(legend => { - legend(pieContext); - }); - } - - shouldComponentUpdate(nextProps) { - this.renderD3(nextProps); - - return false; - } - - componentDidMount() { - this.renderD3(this.props); - } - - componentWillMount() { - const { children } = this.props; - - const legends = []; - - React.Children.forEach(children, element => { - if (React.isValidElement(element)) { - if (element.type.createLegendsFromReactElement) { - legends.push(element.type.createLegendsFromReactElement(element)); - } - } - }); - - this.legends = legends; - } - - render() { - return ( - - - - - ); - } -} - -const { array, number, string, func, any } = PropTypes; - -Pie.propTypes = { - width: number.isRequired, - height: number.isRequired, - sort: func, - data: array.isRequired, - keyProp: string.isRequired, - valueProp: string.isRequired, - startAngle: number.isRequired, - endAngle: number.isRequired, - padAngle: number.isRequired, - colors: any.isRequired, - transitionDuration: number.isRequired, - transitionEasing: string.isRequired, - innerRadius: number.isRequired -}; - -Pie.defaultProps = { - sort: null, - keyProp: 'label', - valueProp: 'value', - startAngle: 0, - endAngle: 360, - padAngle: 0, - transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, - innerRadius: 0, - colors: Nivo.defaults.colorRange -}; - - -export default Pie; diff --git a/src/components/charts/pie/ResponsivePieD3.js b/src/components/charts/pie/ResponsivePieD3.js new file mode 100644 index 000000000..7331630e3 --- /dev/null +++ b/src/components/charts/pie/ResponsivePieD3.js @@ -0,0 +1,198 @@ +/* + * This file is part of the nivo project. + * + * (c) Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { findDOMNode } from 'react-dom' +import _ from 'lodash' +import d3 from 'd3' +import Nivo from '../../../Nivo' +import { degreesToRadians, findNeighbor } from '../../../ArcUtils' +import { getColorRange } from '../../../ColorUtils' + +class Pie extends Component { + renderD3(nextProps) { + const { + data, + width, + height, + sort, + keyProp, + valueProp, + startAngle, + endAngle, + padAngle, + colors, + innerRadius, + transitionDuration, + transitionEasing, + } = nextProps + + const identity = d => d.data[keyProp] + + const element = d3.select(findDOMNode(this)) + const container = element.select('.nivo_pie_slices') + + element.attr('transform', `translate(${width / 2}, ${height / 2})`) + + const pie = d3.layout + .pie() + .sort(sort) + .value(d => d[valueProp]) + .startAngle(degreesToRadians(startAngle)) + .endAngle(degreesToRadians(endAngle)) + .padAngle(degreesToRadians(padAngle)) + + let radius = Math.min(width / 2, height / 2) + const arc = d3.svg + .arc() + .outerRadius(radius) + .innerRadius(radius * innerRadius) + + const outline = element.select('.nivo_pie_outline').attr( + 'd', + arc({ + startAngle: degreesToRadians(startAngle), + endAngle: degreesToRadians(endAngle), + }) + ) + + const color = getColorRange(colors) + + let slices = container.selectAll('.nivo_pie_slice') + const previousData = slices.data() + const newData = pie( + data.map((d, i) => { + if (!d.color) { + d.color = color(i) + } + + return d + }) + ) + + function arcTween(a) { + const i = d3.interpolate(this._current, a) + this._current = i(0) + + return t => arc(i(t)) + } + + slices = slices.data(newData, identity) + slices + .enter() + .append('path') + .attr('class', 'nivo_pie_slice') + .style('fill', d => d.data.color) + .each(function(d, i) { + this._current = + findNeighbor(i, identity, previousData, newData) || + _.assign({}, d, { endAngle: d.startAngle }) + }) + slices + .exit() + .datum((d, i) => { + return findNeighbor(i, identity, newData, previousData) || d + }) + .transition() + .duration(transitionDuration) + .ease(transitionEasing) + .attrTween('d', arcTween) + .remove() + slices + .transition() + .duration(transitionDuration) + .ease(transitionEasing) + .attrTween('d', arcTween) + .style('fill', d => d.data.color) + + const pieContext = { + element, + pie, + arc, + radius, + identity, + previousData, + newData, + } + + this.legends.forEach(legend => { + legend(pieContext) + }) + } + + shouldComponentUpdate(nextProps) { + this.renderD3(nextProps) + + return false + } + + componentDidMount() { + this.renderD3(this.props) + } + + componentWillMount() { + const { children } = this.props + + const legends = [] + + React.Children.forEach(children, element => { + if (React.isValidElement(element)) { + if (element.type.createLegendsFromReactElement) { + legends.push( + element.type.createLegendsFromReactElement(element) + ) + } + } + }) + + this.legends = legends + } + + render() { + return ( + + + + + ) + } +} + +const { array, number, string, func, any } = PropTypes + +Pie.propTypes = { + width: number.isRequired, + height: number.isRequired, + sort: func, + data: array.isRequired, + keyProp: string.isRequired, + valueProp: string.isRequired, + startAngle: number.isRequired, + endAngle: number.isRequired, + padAngle: number.isRequired, + colors: any.isRequired, + transitionDuration: number.isRequired, + transitionEasing: string.isRequired, + innerRadius: number.isRequired, +} + +Pie.defaultProps = { + sort: null, + keyProp: 'label', + valueProp: 'value', + startAngle: 0, + endAngle: 360, + padAngle: 0, + transitionDuration: Nivo.defaults.transitionDuration, + transitionEasing: Nivo.defaults.transitionEasing, + innerRadius: 0, + colors: Nivo.defaults.colorRange, +} + +export default Pie diff --git a/src/components/charts/pie/index.js b/src/components/charts/pie/index.js index f6c246f0d..de9c32df7 100644 --- a/src/components/charts/pie/index.js +++ b/src/components/charts/pie/index.js @@ -6,9 +6,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -export Pie from './Pie'; -export PieColumnLegends from './PieColumnLegends'; -export PieRadialLegends from './PieRadialLegends'; -export PieSliceLegends from './PieSliceLegends'; +export Pie from './Pie' +export PieColumnLegends from './PieColumnLegends' +export PieRadialLegends from './PieRadialLegends' +export PieSliceLegends from './PieSliceLegends' diff --git a/src/components/charts/radial-stack/RadialStack.js b/src/components/charts/radial-stack/RadialStack.js index 3a4c8ad5d..a6620501d 100644 --- a/src/components/charts/radial-stack/RadialStack.js +++ b/src/components/charts/radial-stack/RadialStack.js @@ -6,71 +6,82 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; -import React, { Component, PropTypes } from 'react'; -import { findDOMNode } from 'react-dom'; -import _ from 'lodash'; -import Nivo from '../../../Nivo'; -import RadialStackD3Svg from '../../../lib/charts/radial-stack/RadialStackD3Svg'; -import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren'; -import { margin as marginPropType } from '../../../PropTypes'; - - -const RADIAL_STACK_DECORATOR = 'decorateRadialStack'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { findDOMNode } from 'react-dom' +import _ from 'lodash' +import Nivo from '../../../Nivo' +import RadialStackD3Svg from '../../../lib/charts/radial-stack/RadialStackD3Svg' +import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren' +import { margin as marginPropType } from '../../../PropTypes' +const RADIAL_STACK_DECORATOR = 'decorateRadialStack' class RadialStack extends Component { shouldComponentUpdate(nextProps) { - this.radialStack.decorate(decoratorsFromReactChildren(nextProps.children, RADIAL_STACK_DECORATOR)); - this.radialStack.draw(_.assign({}, nextProps, { - margin: _.assign({}, Nivo.defaults.margin, nextProps.margin) - })); + this.radialStack.decorate( + decoratorsFromReactChildren( + nextProps.children, + RADIAL_STACK_DECORATOR + ) + ) + this.radialStack.draw( + _.assign({}, nextProps, { + margin: _.assign({}, Nivo.defaults.margin, nextProps.margin), + }) + ) - return false; + return false } componentDidMount() { - this.radialStack = RadialStackD3Svg(findDOMNode(this)); - this.radialStack.decorate(decoratorsFromReactChildren(this.props.children, RADIAL_STACK_DECORATOR)); - this.radialStack.draw(_.assign({}, this.props, { - margin: _.assign({}, Nivo.defaults.margin, this.props.margin) - })); + this.radialStack = RadialStackD3Svg(findDOMNode(this)) + this.radialStack.decorate( + decoratorsFromReactChildren( + this.props.children, + RADIAL_STACK_DECORATOR + ) + ) + this.radialStack.draw( + _.assign({}, this.props, { + margin: _.assign({}, Nivo.defaults.margin, this.props.margin), + }) + ) } - + render() { - return ; + return } } -const { array, number, string, func, any, oneOf } = PropTypes; +const { array, number, string, func, any, oneOf } = PropTypes RadialStack.propTypes = { - width: number.isRequired, - height: number.isRequired, - margin: marginPropType, - innerRadius: number.isRequired, - sort: func, - layers: array.isRequired, - offset: oneOf(['silhouette', 'wiggle', 'expand', 'zero']).isRequired, - keyProp: string.isRequired, - valueProp: string.isRequired, - colors: any.isRequired, + width: number.isRequired, + height: number.isRequired, + margin: marginPropType, + innerRadius: number.isRequired, + sort: func, + layers: array.isRequired, + offset: oneOf(['silhouette', 'wiggle', 'expand', 'zero']).isRequired, + keyProp: string.isRequired, + valueProp: string.isRequired, + colors: any.isRequired, transitionDuration: number.isRequired, - transitionEasing: string.isRequired -}; + transitionEasing: string.isRequired, +} RadialStack.defaultProps = { - margin: Nivo.defaults.margin, - innerRadius: .6, - sort: null, - offset: 'zero', - keyProp: 'label', - valueProp: 'value', + margin: Nivo.defaults.margin, + innerRadius: 0.6, + sort: null, + offset: 'zero', + keyProp: 'label', + valueProp: 'value', transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, - colors: Nivo.defaults.colorRange -}; - + transitionEasing: Nivo.defaults.transitionEasing, + colors: Nivo.defaults.colorRange, +} -export default RadialStack; +export default RadialStack diff --git a/src/components/charts/radial-stack/RadialStackAngleAxis.js b/src/components/charts/radial-stack/RadialStackAngleAxis.js index 00adf44bc..a626061b4 100644 --- a/src/components/charts/radial-stack/RadialStackAngleAxis.js +++ b/src/components/charts/radial-stack/RadialStackAngleAxis.js @@ -6,38 +6,46 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import d3 from 'd3'; -import invariant from 'invariant'; -import { radiansToDegrees } from '../../../ArcUtils'; -import makeLabel, { - LABEL_POSITION_TOP, -} from '../../../lib/charts/labels'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import d3 from 'd3' +import invariant from 'invariant' +import { radiansToDegrees } from '../../../ArcUtils' +import makeLabel, { LABEL_POSITION_TOP } from '../../../lib/charts/labels' class RadialStackAngleAxis extends Component { - static decorateRadialStack({ props: { labelPosition, labelRotation, labelOffset, labelPaddingX, labelPaddingY } }) { - - const radialLine = d3.svg.line.radial().interpolate('cardinal-closed'); + static decorateRadialStack({ + props: { + labelPosition, + labelRotation, + labelOffset, + labelPaddingX, + labelPaddingY, + }, + }) { + const radialLine = d3.svg.line.radial().interpolate('cardinal-closed') /* .radius(radius) .angle(function(d, i) { return angle(i); }); */ return ({ element, - layers, stacked, - angle, radius, - innerRadius, outerRadius, - transitionDuration, transitionEasing + layers, + stacked, + angle, + radius, + innerRadius, + outerRadius, + transitionDuration, + transitionEasing, }) => { - let wrapper = element.select('.nivo_radial-axis'); + let wrapper = element.select('.nivo_radial-axis') if (wrapper.node() === null) { //wrapper = element.append('g') - wrapper = element.insert('g', ':first-child') + wrapper = element + .insert('g', ':first-child') .attr('class', 'nivo_radial-axis') - ; } /* @@ -57,90 +65,99 @@ class RadialStackAngleAxis extends Component { ; */ - const lines = wrapper.selectAll('.nivo_radial-axis_tick').data(stacked[0], d => d.x); + const lines = wrapper + .selectAll('.nivo_radial-axis_tick') + .data(stacked[0], d => d.x) - const newLine = lines.enter().append('g') + const newLine = lines + .enter() + .append('g') .attr('class', 'nivo_radial-axis_tick') .attr('transform', 'rotate(-90)') - ; - newLine.append('line') + newLine + .append('line') .attr('class', 'nivo_radial-axis_tick_grid-line') .attr('x1', innerRadius) .attr('x2', outerRadius) - ; - newLine.append('g') + newLine + .append('g') .attr('transform', `translate(${outerRadius},0)`) - .each(function (d) { - const el = d3.select(this); + .each(function(d) { + const el = d3.select(this) - el.append('g') + el + .append('g') .attr('transform', d => `rotate(${labelRotation})`) - .call(makeLabel({ - text: d.x, - position: labelPosition, - labelOffset, - labelPaddingX, - labelPaddingY - })) - ; + .call( + makeLabel({ + text: d.x, + position: labelPosition, + labelOffset, + labelPaddingX, + labelPaddingY, + }) + ) }) - ; lines .transition() .duration(transitionDuration) .ease(transitionEasing) - .attr('transform', d => `rotate(${radiansToDegrees(angle(d.x)) - 90})`) - .each(function (d) { - const el = d3.select(this); - - d3.transition(el.select('line')) + .attr( + 'transform', + d => `rotate(${radiansToDegrees(angle(d.x)) - 90})` + ) + .each(function(d) { + const el = d3.select(this) + + d3 + .transition(el.select('line')) .attr('x1', innerRadius) .attr('x2', outerRadius) - ; - el.select('g').select('g') + el + .select('g') + .select('g') .attr('transform', d => `rotate(${labelRotation})`) - .call(makeLabel({ - text: d.x, - position: labelPosition, - labelOffset, - labelPaddingX, - labelPaddingY - })) - ; + .call( + makeLabel({ + text: d.x, + position: labelPosition, + labelOffset, + labelPaddingX, + labelPaddingY, + }) + ) }) - ; - }; + } } render() { invariant( false, ' element is for RadialStack components configuration only and should not be rendered' - ); + ) } } -const { number, string } = PropTypes; +const { number, string } = PropTypes RadialStackAngleAxis.propTypes = { labelPosition: string.isRequired, labelRotation: number.isRequired, - labelOffset: number.isRequired, + labelOffset: number.isRequired, labelPaddingX: number.isRequired, - labelPaddingY: number.isRequired -}; + labelPaddingY: number.isRequired, +} RadialStackAngleAxis.defaultProps = { labelPosition: LABEL_POSITION_TOP, labelRotation: 90, - labelOffset: 10, + labelOffset: 10, labelPaddingX: 6, - labelPaddingY: 2 -}; - + labelPaddingY: 2, +} -export default RadialStackAngleAxis; +export default RadialStackAngleAxis diff --git a/src/components/charts/radial-stack/RadialStackRadiusAxis.js b/src/components/charts/radial-stack/RadialStackRadiusAxis.js index f0241b876..9d6e15090 100644 --- a/src/components/charts/radial-stack/RadialStackRadiusAxis.js +++ b/src/components/charts/radial-stack/RadialStackRadiusAxis.js @@ -6,64 +6,67 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import d3 from 'd3'; -import invariant from 'invariant'; -import { radiansToDegrees } from '../../../ArcUtils'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import d3 from 'd3' +import invariant from 'invariant' +import { radiansToDegrees } from '../../../ArcUtils' class RadialStackRadiusAxis extends Component { static decorateRadialStack({ props: { angleData } }) { - - const axis = d3.svg.axis(); + const axis = d3.svg.axis() return ({ element, - angle, radius, - transitionDuration, transitionEasing + angle, + radius, + transitionDuration, + transitionEasing, }) => { - let wrapper = d3.select(`.nivo_radial-stack_radius-axis-${angleData}`); + let wrapper = d3.select( + `.nivo_radial-stack_radius-axis-${angleData}` + ) if (wrapper.node() === null) { - wrapper = element.append('g') - .attr('class', `nivo_radial-stack_radius-axis nivo_radial-stack_radius-axis-${angleData}`) - ; + wrapper = element + .append('g') + .attr( + 'class', + `nivo_radial-stack_radius-axis nivo_radial-stack_radius-axis-${angleData}` + ) } // copy original scale - const scale = radius.copy(); - axis.scale(scale) - .ticks(3) - ; + const scale = radius.copy() + axis.scale(scale).ticks(3) - wrapper.attr('transform', d => `rotate(${radiansToDegrees(angle(angleData))})`); + wrapper.attr( + 'transform', + d => `rotate(${radiansToDegrees(angle(angleData))})` + ) wrapper .transition() .duration(transitionDuration) .ease(transitionEasing) .call(axis) - ; - }; + } } render() { invariant( false, ' element is for Radial components configuration only and should not be rendered' - ); + ) } } -const { any } = PropTypes; +const { any } = PropTypes RadialStackRadiusAxis.propTypes = { - angleData: any.isRequired -}; - -RadialStackRadiusAxis.defaultProps = { -}; + angleData: any.isRequired, +} +RadialStackRadiusAxis.defaultProps = {} -export default RadialStackRadiusAxis; +export default RadialStackRadiusAxis diff --git a/src/components/charts/radial-stack/ResponsiveRadialStack.js b/src/components/charts/radial-stack/ResponsiveRadialStack.js index fb12484a6..f1f777bc9 100644 --- a/src/components/charts/radial-stack/ResponsiveRadialStack.js +++ b/src/components/charts/radial-stack/ResponsiveRadialStack.js @@ -6,16 +6,15 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import RadialStack from './RadialStack'; -import Dimensions from 'react-dimensions'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import RadialStack from './RadialStack' +import Dimensions from 'react-dimensions' class ResponsiveRadialStack extends Component { render() { - const { containerWidth, containerHeight } = this.props; + const { containerWidth, containerHeight } = this.props return ( - ); + ) } } -ResponsiveRadialStack.displayName = 'ResponsiveRadialStack'; - +ResponsiveRadialStack.displayName = 'ResponsiveRadialStack' -export default Dimensions()(ResponsiveRadialStack); +export default Dimensions()(ResponsiveRadialStack) diff --git a/src/components/charts/radial-stack/index.js b/src/components/charts/radial-stack/index.js index e304b8634..074d67cd3 100644 --- a/src/components/charts/radial-stack/index.js +++ b/src/components/charts/radial-stack/index.js @@ -6,9 +6,8 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; -export RadialStack from './RadialStack'; -export ResponsiveRadialStack from './ResponsiveRadialStack'; -export RadialStackRadiusAxis from './RadialStackRadiusAxis'; -export RadialStackAngleAxis from './RadialStackAngleAxis'; +export RadialStack from './RadialStack' +export ResponsiveRadialStack from './ResponsiveRadialStack' +export RadialStackRadiusAxis from './RadialStackRadiusAxis' +export RadialStackAngleAxis from './RadialStackAngleAxis' diff --git a/src/components/charts/stack/ResponsiveStack.js b/src/components/charts/stack/ResponsiveStack.js index 456c21256..1396df933 100644 --- a/src/components/charts/stack/ResponsiveStack.js +++ b/src/components/charts/stack/ResponsiveStack.js @@ -6,16 +6,15 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import Stack from './Stack'; -import Dimensions from 'react-dimensions'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Stack from './Stack' +import Dimensions from 'react-dimensions' class ResponsiveStack extends Component { render() { - const { containerWidth, containerHeight } = this.props; + const { containerWidth, containerHeight } = this.props return ( - ); + ) } } - -export default Dimensions()(ResponsiveStack); +export default Dimensions()(ResponsiveStack) diff --git a/src/components/charts/stack/Stack.js b/src/components/charts/stack/Stack.js index ebad2bff9..e8b5f27cf 100644 --- a/src/components/charts/stack/Stack.js +++ b/src/components/charts/stack/Stack.js @@ -6,44 +6,42 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import { findDOMNode } from 'react-dom'; -import d3 from 'd3'; -import _ from 'lodash'; -import Nivo from '../../../Nivo'; -import { lineInterpolation } from '../../../PropTypes'; -import { getColorRange, getColorGenerator } from '../../../ColorUtils'; -import { margin as marginPropType } from '../../../PropTypes'; -import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { findDOMNode } from 'react-dom' +import d3 from 'd3' +import _ from 'lodash' +import Nivo from '../../../Nivo' +import { lineInterpolation } from '../../../PropTypes' +import { getColorRange, getColorGenerator } from '../../../ColorUtils' +import { margin as marginPropType } from '../../../PropTypes' +import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren' const findPrecedingLayer = (layers, index) => { if (layers === null) { - return null; + return null } for (let i = layers.length - 1; i >= 0; i--) { - const layer = layers[i]; + const layer = layers[i] if (layer.index < index) { - return layer; + return layer } } - return null; -}; - + return null +} class Stack extends Component { constructor(props) { - super(props); + super(props) this.state = { - excludeLayers: [] - }; + excludeLayers: [], + } - this.previousData = null; + this.previousData = null } renderD3(props, state) { @@ -51,193 +49,216 @@ class Stack extends Component { data, offset, interpolation, - colors, overColor, - transitionDuration, transitionEasing - } = props; + colors, + overColor, + transitionDuration, + transitionEasing, + } = props - const { - excludeLayers - } = state; + const { excludeLayers } = state - const overColorFn = getColorGenerator(overColor); + const overColorFn = getColorGenerator(overColor) - const element = d3.select(findDOMNode(this)); - const wrapper = element.select('.nivo_stack_wrapper'); + const element = d3.select(findDOMNode(this)) + const wrapper = element.select('.nivo_stack_wrapper') - const margin = _.assign({}, Nivo.defaults.margin, props.margin); - const width = props.width - margin.left - margin.right; - const height = props.height - margin.top - margin.bottom; + const margin = _.assign({}, Nivo.defaults.margin, props.margin) + const width = props.width - margin.left - margin.right + const height = props.height - margin.top - margin.bottom element.attr({ - width: props.width, - height: props.height - }); - wrapper.attr('transform', `translate(${margin.left},${margin.top})`); + width: props.width, + height: props.height, + }) + wrapper.attr('transform', `translate(${margin.left},${margin.top})`) - const color = getColorRange(colors); + const color = getColorRange(colors) const normData = _.cloneDeep(data).map((values, i) => ({ index: i, color: color(i), values, - })); + })) - let filteredData = []; - let hiddenData = []; + let filteredData = [] + let hiddenData = [] if (excludeLayers.length > 0) { normData.forEach(layer => { if (excludeLayers.indexOf(layer.index) === -1) { - filteredData.push(layer); + filteredData.push(layer) } else { - hiddenData.push(layer); + hiddenData.push(layer) } - }); + }) } else { - filteredData = normData; + filteredData = normData } - const stack = d3.layout.stack() - .offset(offset) - .values(d => d.values) - ; + const stack = d3.layout.stack().offset(offset).values(d => d.values) - const stacked = stack(filteredData); + const stacked = stack(filteredData) - const xScale = d3.scale.linear() + const xScale = d3.scale + .linear() .range([0, width]) .domain([0, stacked[0].values.length - 1]) - ; - const yScale = d3.scale.linear() + const yScale = d3.scale + .linear() .range([height, 0]) - .domain([0, d3.max(stacked, layer => d3.max(layer.values, d => (d.y0 + d.y)))]) - ; + .domain([ + 0, + d3.max(stacked, layer => d3.max(layer.values, d => d.y0 + d.y)), + ]) filteredData = filteredData.map(layer => { return _.assign(layer, { values: layer.values.map(v => ({ - value: v, + value: v, interpolated: { - x: xScale(v.x), + x: xScale(v.x), y0: yScale(v.y0), - y: yScale(v.y0 + v.y) - } - })) - }); - }); + y: yScale(v.y0 + v.y), + }, + })), + }) + }) - const area = d3.svg.area() + const area = d3.svg + .area() .interpolate(interpolation) .x(d => d.x) .y0(d => d.y0) .y1(d => d.y) - ; - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— // Areas // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - let paths = wrapper.select('.nivo_stack_areas').selectAll('.nivo_stack_area').data(stacked, d => d.index); + let paths = wrapper + .select('.nivo_stack_areas') + .selectAll('.nivo_stack_area') + .data(stacked, d => d.index) // ENTER - paths.enter().append('path') + paths + .enter() + .append('path') .attr('class', 'nivo_stack_area') .attr('d', d => { if (this.previousData === null) { - return area(d.values.map(p => ({ - x: p.interpolated.x, - y0: yScale.range()[0], - y: yScale.range()[0], - }))); + return area( + d.values.map(p => ({ + x: p.interpolated.x, + y0: yScale.range()[0], + y: yScale.range()[0], + })) + ) } - const precedingLayer = findPrecedingLayer(this.previousData, d.index); + const precedingLayer = findPrecedingLayer( + this.previousData, + d.index + ) if (precedingLayer !== null) { - return area(precedingLayer.values.map(p => ({ - x: p.interpolated.x, - y0: p.interpolated.y, - y: p.interpolated.y, - }))); + return area( + precedingLayer.values.map(p => ({ + x: p.interpolated.x, + y0: p.interpolated.y, + y: p.interpolated.y, + })) + ) } - return area(d.values.map(p => ({ - x: p.interpolated.x, - y0: p.interpolated.y0, - y: p.interpolated.y0, - }))); + return area( + d.values.map(p => ({ + x: p.interpolated.x, + y0: p.interpolated.y0, + y: p.interpolated.y0, + })) + ) }) .style('fill', d => d.color) - ; // UPDATE paths .on('click', d => { // we cannot have no layer if (filteredData.length > 1) { - this.setState({ excludeLayers: excludeLayers.concat([d.index]) }); + this.setState({ + excludeLayers: excludeLayers.concat([d.index]), + }) } }) - .on('mouseover', function (d) { - d3.select(this).style('fill', overColorFn); + .on('mouseover', function(d) { + d3.select(this).style('fill', overColorFn) }) - .on('mousemove', function (d, i) { - d3.select(this).style('fill', overColorFn); + .on('mousemove', function(d, i) { + d3.select(this).style('fill', overColorFn) }) - .on('mouseout', function (d) { - d3.select(this).style('fill', d.color); + .on('mouseout', function(d) { + d3.select(this).style('fill', d.color) }) .transition() .duration(transitionDuration) .ease(transitionEasing) .attr('d', d => area(d.values.map(v => v.interpolated))) .style('fill', d => d.color) - ; // EXIT - paths.exit() + paths + .exit() .transition() .duration(transitionDuration) .ease(transitionEasing) .attr('d', d => { - const precedingLayer = findPrecedingLayer(filteredData, d.index); + const precedingLayer = findPrecedingLayer(filteredData, d.index) if (precedingLayer !== null) { - return area(precedingLayer.values.map(p => ({ - x: p.interpolated.x, - y0: p.interpolated.y, - y: p.interpolated.y, - }))); + return area( + precedingLayer.values.map(p => ({ + x: p.interpolated.x, + y0: p.interpolated.y, + y: p.interpolated.y, + })) + ) } - return area(d.values.map(p => ({ - x: p.interpolated.x, - y0: p.interpolated.y0, - y: p.interpolated.y0, - }))); + return area( + d.values.map(p => ({ + x: p.interpolated.x, + y0: p.interpolated.y0, + y: p.interpolated.y0, + })) + ) }) .remove() - ; - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— // Hidden layers // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const hiddenControls = wrapper.selectAll('.nivo_stack_hidden_control').data(hiddenData, d => d.index); + const hiddenControls = wrapper + .selectAll('.nivo_stack_hidden_control') + .data(hiddenData, d => d.index) // ENTER - hiddenControls.enter().append('circle') + hiddenControls + .enter() + .append('circle') .attr('class', 'nivo_stack_hidden_control') .attr('r', 8) .attr('transform', (d, i) => `translate(${i * 40},0)`) .style('fill', d => d.color) .style('opacity', 0) .style('cursor', 'pointer') - ; hiddenControls .on('click', d => { - this.setState({ excludeLayers: excludeLayers.filter(index => index !== d.index) }); + this.setState({ + excludeLayers: excludeLayers.filter( + index => index !== d.index + ), + }) }) .transition() .duration(transitionDuration) @@ -245,43 +266,52 @@ class Stack extends Component { .attr('transform', (d, i) => `translate(${i * 40},0)`) .style('fill', d => d.color) .style('opacity', 1) - ; - hiddenControls.exit() + hiddenControls + .exit() .transition() .duration(transitionDuration) .ease(transitionEasing) .style('opacity', 0) .remove() - ; const stackContext = { - element, wrapper, - width, height, + element, + wrapper, + width, + height, stacked, - xScale, yScale, - transitionDuration, transitionEasing - }; + xScale, + yScale, + transitionDuration, + transitionEasing, + } this.decorators.forEach(decorator => { - decorator(stackContext); - }); + decorator(stackContext) + }) - this.previousData = filteredData; + this.previousData = filteredData } shouldComponentUpdate(nextProps, nextState) { - this.decorators = decoratorsFromReactChildren(nextProps.children, 'decorateStack'); + this.decorators = decoratorsFromReactChildren( + nextProps.children, + 'decorateStack' + ) - this.renderD3(nextProps, nextState); + this.renderD3(nextProps, nextState) - return false; + return false } componentDidMount() { - this.decorators = decoratorsFromReactChildren(this.props.children, 'decorateStack'); + this.decorators = decoratorsFromReactChildren( + this.props.children, + 'decorateStack' + ) - this.renderD3(this.props, this.state); + this.renderD3(this.props, this.state) } render() { @@ -291,40 +321,39 @@ class Stack extends Component { - ); + ) } } -const { array, number, string, func, any, oneOf } = PropTypes; +const { array, number, string, func, any, oneOf } = PropTypes Stack.propTypes = { - width: number.isRequired, - height: number.isRequired, - margin: marginPropType, - sort: func, - data: array.isRequired, - offset: oneOf(['silhouette', 'wiggle', 'expand', 'zero']).isRequired, - keyProp: string.isRequired, - valueProp: string.isRequired, - interpolation: lineInterpolation, - colors: any.isRequired, - overColor: any.isRequired, + width: number.isRequired, + height: number.isRequired, + margin: marginPropType, + sort: func, + data: array.isRequired, + offset: oneOf(['silhouette', 'wiggle', 'expand', 'zero']).isRequired, + keyProp: string.isRequired, + valueProp: string.isRequired, + interpolation: lineInterpolation, + colors: any.isRequired, + overColor: any.isRequired, transitionDuration: number.isRequired, - transitionEasing: string.isRequired, -}; + transitionEasing: string.isRequired, +} Stack.defaultProps = { - margin: Nivo.defaults.margin, - sort: null, - offset: 'zero', - keyProp: 'label', - valueProp: 'value', - interpolation: 'monotone', + margin: Nivo.defaults.margin, + sort: null, + offset: 'zero', + keyProp: 'label', + valueProp: 'value', + interpolation: 'monotone', transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, - colors: Nivo.defaults.colorRange, - overColor: 'inherit:brighter(.5)', -}; - + transitionEasing: Nivo.defaults.transitionEasing, + colors: Nivo.defaults.colorRange, + overColor: 'inherit:brighter(.5)', +} -export default Stack; +export default Stack diff --git a/src/components/charts/stack/StackSlicer.js b/src/components/charts/stack/StackSlicer.js index 68be72e2b..5d47ad731 100644 --- a/src/components/charts/stack/StackSlicer.js +++ b/src/components/charts/stack/StackSlicer.js @@ -6,114 +6,120 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; -import React, { Component, PropTypes } from 'react'; -import invariant from 'invariant'; -import _ from 'lodash'; -import d3 from 'd3'; -import { getColorGenerator } from '../../../ColorUtils'; - - -const overTransitionDuration = 200; -const overTransitionEasing = 'linear'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import invariant from 'invariant' +import _ from 'lodash' +import d3 from 'd3' +import { getColorGenerator } from '../../../ColorUtils' +const overTransitionDuration = 200 +const overTransitionEasing = 'linear' class StackSlicer extends Component { static decorateStack(element) { - const { props } = element; + const { props } = element - const colorFn = getColorGenerator(props.color); - const dotBorderColorFn = getColorGenerator(props.dotBorderColor); - const lineColorFn = getColorGenerator(props.lineColor); - const { showOnOver } = props; + const colorFn = getColorGenerator(props.color) + const dotBorderColorFn = getColorGenerator(props.dotBorderColor) + const lineColorFn = getColorGenerator(props.lineColor) + const { showOnOver } = props // Receive context from Parent Stack component return ({ wrapper, stacked, - width, height, - transitionDuration, transitionEasing + width, + height, + transitionDuration, + transitionEasing, }) => { - const slices = []; + const slices = [] stacked.forEach(layer => { layer.values.forEach((datum, i) => { if (!slices[i]) { slices[i] = { - x: datum.interpolated.x, + x: datum.interpolated.x, values: [], - }; + } } - slices[i].values.push(_.assign({}, datum, { - index: layer.index, - color: layer.color, - })); - }); - }); + slices[i].values.push( + _.assign({}, datum, { + index: layer.index, + color: layer.color, + }) + ) + }) + }) - const elements = wrapper.selectAll('.nivo_stack_slices').data(slices); + const elements = wrapper + .selectAll('.nivo_stack_slices') + .data(slices) - const newSlices = elements.enter().append('g') + const newSlices = elements + .enter() + .append('g') .attr('class', 'nivo_stack_slices') .attr('transform', d => `translate(${d.x},0)`) .style('opacity', showOnOver ? 0 : 1) .style('pointer-events', 'all') - ; - newSlices.append('rect') + newSlices + .append('rect') .attr('width', props.radius * 2 + 10) .attr('height', height) .attr('transform', `translate(-${props.radius + 5},0)`) .style('fill', 'none') .style('pointer-events', 'all') - ; elements .style('opacity', showOnOver ? 0 : 1) - .on('mouseover', function () { + .on('mouseover', function() { if (!showOnOver) { - return; + return } - d3.select(this) + d3 + .select(this) .transition() .duration(overTransitionDuration) .ease(overTransitionEasing) .style('opacity', 1) - ; }) - .on('mouseout', function () { + .on('mouseout', function() { if (!showOnOver) { - return; + return } - d3.select(this) + d3 + .select(this) .transition() .duration(overTransitionDuration) .ease(overTransitionEasing) .style('opacity', 0) - ; }) .transition() .duration(transitionDuration) .ease(transitionEasing) .attr('transform', d => `translate(${d.x},0)`) - ; - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // Lines // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - const lines = elements.selectAll('line').data(d => d.values, d => d.index); + const lines = elements + .selectAll('line') + .data(d => d.values, d => d.index) // ENTER - lines.enter().append('line') + lines + .enter() + .append('line') .attr('y1', d => d.interpolated.y) .attr('y2', d => d.interpolated.y0) .style('stroke-width', props.lineWidth) .style('stroke', lineColorFn) - ; // UPDATE lines @@ -124,10 +130,10 @@ class StackSlicer extends Component { .attr('y2', d => d.interpolated.y0) .style('stroke-width', props.lineWidth) .style('stroke', lineColorFn) - ; // EXIT - lines.exit() + lines + .exit() .transition() .duration(transitionDuration) .ease(transitionEasing) @@ -135,41 +141,42 @@ class StackSlicer extends Component { .attr('y2', d => d.interpolated.y0) .style('opacity', 0) .remove() - ; - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // Circles // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - const circles = elements.selectAll('circle').data(d => d.values, d => d.index); + const circles = elements + .selectAll('circle') + .data(d => d.values, d => d.index) // ENTER - circles.enter().append('circle') + circles + .enter() + .append('circle') .attr('r', 0.1) .style('cursor', 'pointer') .attr('transform', d => `translate(0,${d.interpolated.y})`) .style('fill', colorFn) .style('stroke-width', props.dotBorderWidth) .style('stroke', dotBorderColorFn) - ; // UPDATE circles - .on('mouseover', function () { - d3.select(this) + .on('mouseover', function() { + d3 + .select(this) .transition() .duration(overTransitionDuration) .ease(overTransitionEasing) .attr('r', props.radius * 2) - ; }) - .on('mouseout', function () { - d3.select(this) + .on('mouseout', function() { + d3 + .select(this) .transition() .duration(overTransitionDuration) .ease(overTransitionEasing) .attr('r', props.radius) - ; }) .transition() .duration(transitionDuration) @@ -179,48 +186,46 @@ class StackSlicer extends Component { .style('fill', colorFn) .style('stroke-width', props.dotBorderWidth) .style('stroke', dotBorderColorFn) - ; // EXIT - circles.exit() + circles + .exit() .transition() .duration(transitionDuration) .ease(transitionEasing) .attr('r', 0.1) .style('opacity', 0) .remove() - ; - }; + } } render() { invariant( false, ' element is for Stack configuration only and should not be rendered' - ); + ) } } -const { number, bool, any } = PropTypes; +const { number, bool, any } = PropTypes StackSlicer.propTypes = { - showOnOver: bool.isRequired, - radius: number.isRequired, - color: any.isRequired, + showOnOver: bool.isRequired, + radius: number.isRequired, + color: any.isRequired, dotBorderWidth: number.isRequired, dotBorderColor: any.isRequired, - lineWidth: number.isRequired, -}; + lineWidth: number.isRequired, +} StackSlicer.defaultProps = { - showOnOver: false, - radius: 4, - color: 'inherit', + showOnOver: false, + radius: 4, + color: 'inherit', dotBorderWidth: 1, dotBorderColor: 'inherit:darker(.5)', - lineWidth: 1, - lineColor: 'inherit:darker(.3)', -}; - + lineWidth: 1, + lineColor: 'inherit:darker(.3)', +} -export default StackSlicer; +export default StackSlicer diff --git a/src/components/charts/stack/index.js b/src/components/charts/stack/index.js index cd3ae3b31..1bfaa573e 100644 --- a/src/components/charts/stack/index.js +++ b/src/components/charts/stack/index.js @@ -6,8 +6,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; -export Stack from './Stack'; -export ResponsiveStack from './ResponsiveStack'; -export StackSlicer from './StackSlicer'; +export Stack from './Stack' +export ResponsiveStack from './ResponsiveStack' +export StackSlicer from './StackSlicer' diff --git a/src/components/charts/treemap/ResponsiveTreeMap.js b/src/components/charts/treemap/ResponsiveTreeMap.js index 9f492459d..0042840ef 100644 --- a/src/components/charts/treemap/ResponsiveTreeMap.js +++ b/src/components/charts/treemap/ResponsiveTreeMap.js @@ -6,26 +6,44 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; -import React, { Component, PropTypes } from 'react' -import TreeMap from './TreeMap' -import Dimensions from 'react-dimensions' +import React, { Component } from 'react' +import Measure from 'react-measure' +import TreeMap from './TreeMap' +export default class ResponsiveTreeMap extends Component { + state = { + dimensions: { + width: -1, + height: -1, + }, + } -class ResponsiveTreeMap extends Component { render() { - const { containerWidth, containerHeight } = this.props + const { width, height } = this.state.dimensions + + const shouldRender = width > 0 && height > 0 return ( - + { + this.setState({ dimensions: contentRect.bounds }) + }} + > + {({ measureRef }) => +
+ {shouldRender && + } +
} +
) } } - - -export default Dimensions()(ResponsiveTreeMap) diff --git a/src/components/charts/treemap/ResponsiveTreeMapD3.js b/src/components/charts/treemap/ResponsiveTreeMapD3.js index 7861fb797..6e241d4e4 100644 --- a/src/components/charts/treemap/ResponsiveTreeMapD3.js +++ b/src/components/charts/treemap/ResponsiveTreeMapD3.js @@ -6,12 +6,11 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react' -import TreeMapD3 from './TreeMapD3' -import Dimensions from 'react-dimensions' +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import TreeMapD3 from './TreeMapD3' +import Dimensions from 'react-dimensions' class ResponsiveTreeMapD3 extends Component { render() { @@ -27,5 +26,4 @@ class ResponsiveTreeMapD3 extends Component { } } - export default Dimensions()(ResponsiveTreeMapD3) diff --git a/src/components/charts/treemap/ResponsiveTreeMapHTML.js b/src/components/charts/treemap/ResponsiveTreeMapHTML.js index d6efc6397..de45da7fd 100644 --- a/src/components/charts/treemap/ResponsiveTreeMapHTML.js +++ b/src/components/charts/treemap/ResponsiveTreeMapHTML.js @@ -6,26 +6,44 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' -import React, { Component, PropTypes } from 'react' -import TreeMapHTML from './TreeMapHTML' -import Dimensions from 'react-dimensions' +import React, { Component } from 'react' +import TreeMapHTML from './TreeMapHTML' +import Measure from 'react-measure' +export default class ResponsiveTreeMapHTML extends Component { + state = { + dimensions: { + width: -1, + height: -1, + }, + } -class ResponsiveTreeMapHTML extends Component { render() { - const { containerWidth, containerHeight } = this.props + const { width, height } = this.state.dimensions + + const shouldRender = width > 0 && height > 0 return ( - + { + this.setState({ dimensions: contentRect.bounds }) + }} + > + {({ measureRef }) => +
+ {shouldRender && + } +
} +
) } } - - -export default Dimensions()(ResponsiveTreeMapHTML) diff --git a/src/components/charts/treemap/ResponsiveTreeMapPlaceholders.js b/src/components/charts/treemap/ResponsiveTreeMapPlaceholders.js index 787a76a26..f17dc7ecb 100644 --- a/src/components/charts/treemap/ResponsiveTreeMapPlaceholders.js +++ b/src/components/charts/treemap/ResponsiveTreeMapPlaceholders.js @@ -6,26 +6,44 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' -import React, { Component, PropTypes } from 'react' -import TreeMapPlaceholders from './TreeMapPlaceholders' -import Dimensions from 'react-dimensions' +import React, { Component } from 'react' +import TreeMapPlaceholders from './TreeMapPlaceholders' +import Measure from 'react-measure' +export default class ResponsiveTreeMapPlaceholders extends Component { + state = { + dimensions: { + width: -1, + height: -1, + }, + } -class ResponsiveTreeMapPlaceholders extends Component { render() { - const { containerWidth, containerHeight } = this.props + const { width, height } = this.state.dimensions + + const shouldRender = width > 0 && height > 0 return ( - + { + this.setState({ dimensions: contentRect.bounds }) + }} + > + {({ measureRef }) => +
+ {shouldRender && + } +
} +
) } } - - -export default Dimensions()(ResponsiveTreeMapPlaceholders) diff --git a/src/components/charts/treemap/TreeMap.js b/src/components/charts/treemap/TreeMap.js index 64bf0ea14..eb69295e2 100644 --- a/src/components/charts/treemap/TreeMap.js +++ b/src/components/charts/treemap/TreeMap.js @@ -6,16 +6,14 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' -import React, { Component } from 'react' -import { findDOMNode } from 'react-dom' -import _ from 'lodash' -import { convertLabel } from '../../../lib/propertiesConverters' +import React, { Component } from 'react' +import { findDOMNode } from 'react-dom' +import _ from 'lodash' +import { convertLabel } from '../../../lib/propertiesConverters' import { treeMapPropTypes, treeMapDefaultProps } from './TreeMapProps' -import TreeMapPlaceholders from './TreeMapPlaceholders' -import { getColorGenerator } from '../../../ColorUtils' - +import TreeMapPlaceholders from './TreeMapPlaceholders' +import { getColorGenerator } from '../../../ColorUtils' const createNodes = ({ borderWidth, @@ -27,19 +25,23 @@ const createNodes = ({ labelSkipSize, labelTextColor, }) => { - const label = convertLabel(_label, labelFormat) + const label = convertLabel(_label, labelFormat) const borderColorFn = getColorGenerator(borderColor) - const textColorFn = getColorGenerator(labelTextColor) + const textColorFn = getColorGenerator(labelTextColor) return nodes => { const renderedNodes = [] nodes.forEach(node => { - const shouldRenderLabel = enableLabels && + const shouldRenderLabel = + enableLabels && node.data.height === 0 && - (labelSkipSize === 0 || Math.min(node.style.width, node.style.height) > labelSkipSize) + (labelSkipSize === 0 || + Math.min(node.style.width, node.style.height) > + labelSkipSize) - const rotate = shouldRenderLabel && + const rotate = + shouldRenderLabel && orientLabels && node.style.height > node.style.width @@ -56,9 +58,12 @@ const createNodes = ({ stroke={borderColorFn(node.data)} strokeWidth={borderWidth} /> - {shouldRenderLabel && ( + {shouldRenderLabel && {label(node.data.data)} - - )} +
}
) }) @@ -80,27 +84,18 @@ const createNodes = ({ } } - class TreeMap extends Component { render() { return ( - + {createNodes(this.props)} ) } } -TreeMap.propTypes = _.omit(treeMapPropTypes, [ - 'children', - 'namespace', -]) - -TreeMap.defaultProps = _.omit(treeMapDefaultProps, [ -]) +TreeMap.propTypes = _.omit(treeMapPropTypes, ['children', 'namespace']) +TreeMap.defaultProps = _.omit(treeMapDefaultProps, []) export default TreeMap diff --git a/src/components/charts/treemap/TreeMapD3.js b/src/components/charts/treemap/TreeMapD3.js index 3f9343a9e..d84cf8cea 100644 --- a/src/components/charts/treemap/TreeMapD3.js +++ b/src/components/charts/treemap/TreeMapD3.js @@ -6,23 +6,20 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component } from 'react' -import { findDOMNode } from 'react-dom' -import _ from 'lodash' -import d3 from 'd3' -import Nivo from '../../../Nivo' -import { getColorStyleObject, getColorRange } from '../../../ColorUtils' -import { treeMapPropTypes, treeMapDefaultProps } from './TreeMapProps' -import Treemap from '../../../lib/charts/treemap/TreeMapD3' +import React, { Component } from 'react' +import { findDOMNode } from 'react-dom' +import _ from 'lodash' +import d3 from 'd3' +import Nivo from '../../../Nivo' +import { getColorStyleObject, getColorRange } from '../../../ColorUtils' +import { treeMapPropTypes, treeMapDefaultProps } from './TreeMapProps' +import Treemap from '../../../lib/charts/treemap/TreeMapD3' function nodePosition() { - this - .style('left', d => `${d.x0}px`) - .style('top', d => `${d.y0}px`) - .style('width', d => `${Math.max(0, d.x1 - d.x0)}px`) + this.style('left', d => `${d.x0}px`) + .style('top', d => `${d.y0}px`) + .style('width', d => `${Math.max(0, d.x1 - d.x0)}px`) .style('height', d => `${Math.max(0, d.y1 - d.y0)}px`) } @@ -36,57 +33,67 @@ class TreeMapD3 extends Component { root, tile, orientLabels, - innerPadding, outerPadding, + innerPadding, + outerPadding, skipVMin, - identityProperty, valueAccessor, labelFn, + identityProperty, + valueAccessor, + labelFn, colors, - transitionDuration, transitionEasing, + transitionDuration, + transitionEasing, } = this.props - const borderColorStyle = getColorStyleObject(nextProps.borderColor, 'color') + const borderColorStyle = getColorStyleObject( + nextProps.borderColor, + 'color' + ) const margin = _.assign({}, Nivo.defaults.margin, this.props.margin) - const width = nextProps.width - margin.left - margin.right + const width = nextProps.width - margin.left - margin.right const height = nextProps.height - margin.top - margin.bottom const _nodes = this.treemap.compute({ - width, height, + width, + height, root, tile, - innerPadding, outerPadding, - identityProperty, valueAccessor + innerPadding, + outerPadding, + identityProperty, + valueAccessor, }) - const element = d3.select(findDOMNode(this)) - .style({ - width: nextProps.width, - height: nextProps.height - }) + const element = d3.select(findDOMNode(this)).style({ + width: nextProps.width, + height: nextProps.height, + }) - const wrapper = element.select('.nivo_treemap_wrapper') - .style({ - top: `${margin.top}px`, - left: `${margin.left}px`, - width: `${width}px`, - height: `${height}px`, - }) + const wrapper = element.select('.nivo_treemap_wrapper').style({ + top: `${margin.top}px`, + left: `${margin.left}px`, + width: `${width}px`, + height: `${height}px`, + }) const color = getColorRange(colors) const nodes = wrapper.selectAll('.nivo_treemap_node').data(_nodes) - nodes.enter().append('div') + nodes + .enter() + .append('div') .classed('nivo_treemap_node', true) .style('z-index', 10) - .each(function (d) { - + .each(function(d) { let p = d while (p.depth > 1) p = p.parent d.color = color(p.data.name) - const el = d3.select(this) - const label = el.append('span') + const el = d3.select(this) + const label = el + .append('span') .attr('class', 'nivo_treemap_node_label') .text(d.children ? '' : labelFn(d.data)) .style('transform', d => { @@ -94,7 +101,7 @@ class TreeMapD3 extends Component { return 'rotate(-90deg)' } - return 'rotate(0)'; + return 'rotate(0)' }) if (orientLabels) { @@ -105,17 +112,17 @@ class TreeMapD3 extends Component { }) .style(borderColorStyle) .style({ - overflow: 'hidden', - position: 'absolute', - display: 'flex', - 'align-items': 'center', + overflow: 'hidden', + position: 'absolute', + display: 'flex', + 'align-items': 'center', 'justify-content': 'center', }) .call(nodePosition) .style('background', d => d.color) nodes - .each(function (d) { + .each(function(d) { let p = d while (p.depth > 1) p = p.parent d.color = color(p.data.name) @@ -126,16 +133,19 @@ class TreeMapD3 extends Component { .ease(transitionEasing) .style('background', d => d.color) .call(nodePosition) - .each(function (d) { + .each(function(d) { const el = d3.select(this) - const transform = (orientLabels && d.dy > d.dx) ? 'rotate(-90deg)' : 'rotate(0deg)' + const transform = + orientLabels && d.dy > d.dx + ? 'rotate(-90deg)' + : 'rotate(0deg)' - el.select('span') - .style('transform', transform) + el.select('span').style('transform', transform) }) - nodes.exit() + nodes + .exit() .style('z-index', 5) .transition() .duration(transitionDuration) @@ -159,14 +169,20 @@ class TreeMapD3 extends Component { render() { return (
-
+
) } } -TreeMapD3.propTypes = _.omit(treeMapPropTypes, ['children', 'stiffness', 'damping']) +TreeMapD3.propTypes = _.omit(treeMapPropTypes, [ + 'children', + 'stiffness', + 'damping', +]) TreeMapD3.defaultProps = _.omit(treeMapDefaultProps, ['stiffness', 'damping']) - export default TreeMapD3 diff --git a/src/components/charts/treemap/TreeMapHTML.js b/src/components/charts/treemap/TreeMapHTML.js index 80019c987..d34faa928 100644 --- a/src/components/charts/treemap/TreeMapHTML.js +++ b/src/components/charts/treemap/TreeMapHTML.js @@ -6,16 +6,14 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' -import React, { Component } from 'react' -import { findDOMNode } from 'react-dom' -import _ from 'lodash' -import { convertLabel } from '../../../lib/propertiesConverters' +import React, { Component } from 'react' +import { findDOMNode } from 'react-dom' +import _ from 'lodash' +import { convertLabel } from '../../../lib/propertiesConverters' import { treeMapPropTypes, treeMapDefaultProps } from './TreeMapProps' -import TreeMapPlaceholders from './TreeMapPlaceholders' -import { getColorGenerator } from '../../../ColorUtils' - +import TreeMapPlaceholders from './TreeMapPlaceholders' +import { getColorGenerator } from '../../../ColorUtils' const createNodes = ({ borderWidth, @@ -27,19 +25,23 @@ const createNodes = ({ labelSkipSize, labelTextColor, }) => { - const label = convertLabel(_label, labelFormat) + const label = convertLabel(_label, labelFormat) const borderColorFn = getColorGenerator(borderColor) - const textColorFn = getColorGenerator(labelTextColor) + const textColorFn = getColorGenerator(labelTextColor) return nodes => { const renderedNodes = [] nodes.forEach(node => { - const shouldRenderLabel = enableLabels && + const shouldRenderLabel = + enableLabels && node.data.height === 0 && - (labelSkipSize === 0 || Math.min(node.style.width, node.style.height) > labelSkipSize) + (labelSkipSize === 0 || + Math.min(node.style.width, node.style.height) > + labelSkipSize) - const rotate = shouldRenderLabel && + const rotate = + shouldRenderLabel && orientLabels && node.style.height > node.style.width @@ -48,33 +50,32 @@ const createNodes = ({ key={node.key} className="nivo_treemap_node" style={{ - boxSizing: 'border-box', - position: 'absolute', - top: node.style.y, - left: node.style.x, - width: node.style.width, - height: node.style.height, - background: node.style.color, - overflow: 'hidden', - display: 'flex', - alignItems: 'center', + boxSizing: 'border-box', + position: 'absolute', + top: node.style.y, + left: node.style.x, + width: node.style.width, + height: node.style.height, + background: node.style.color, + overflow: 'hidden', + display: 'flex', + alignItems: 'center', justifyContent: 'center', - borderWidth: borderWidth, - borderStyle: 'solid', - borderColor: borderColorFn(node.data), + borderWidth: borderWidth, + borderStyle: 'solid', + borderColor: borderColorFn(node.data), }} > - {shouldRenderLabel && ( + {shouldRenderLabel && {label(node.data.data)} - - )} + }
) }) @@ -83,27 +84,18 @@ const createNodes = ({ } } - class TreeMapHTML extends Component { render() { return ( - + {createNodes(this.props)} ) } } -TreeMapHTML.propTypes = _.omit(treeMapPropTypes, [ - 'children', - 'namespace', -]) - -TreeMapHTML.defaultProps = _.omit(treeMapDefaultProps, [ -]) +TreeMapHTML.propTypes = _.omit(treeMapPropTypes, ['children', 'namespace']) +TreeMapHTML.defaultProps = _.omit(treeMapDefaultProps, []) export default TreeMapHTML diff --git a/src/components/charts/treemap/TreeMapPlaceholders.js b/src/components/charts/treemap/TreeMapPlaceholders.js index a202ccff8..388a9989f 100644 --- a/src/components/charts/treemap/TreeMapPlaceholders.js +++ b/src/components/charts/treemap/TreeMapPlaceholders.js @@ -6,19 +6,17 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - -import React, { Component } from 'react' -import { findDOMNode } from 'react-dom' -import _ from 'lodash' -import { TransitionMotion, spring } from 'react-motion' -import Nivo from '../../../Nivo' -import TreeMapHelper from '../../../lib/charts/treemap/TreeMapHelper' -import { convertGetter } from '../../../lib/propertiesConverters' -import { treeMapPropTypes, treeMapDefaultProps } from './TreeMapProps' -import { getColorRange, extractRGB } from '../../../ColorUtils' -import { rgb } from 'd3' +import React, { Component } from 'react' +import { findDOMNode } from 'react-dom' +import _ from 'lodash' +import { TransitionMotion, spring } from 'react-motion' +import Nivo from '../../../Nivo' +import TreeMapHelper from '../../../lib/charts/treemap/TreeMapHelper' +import { convertGetter } from '../../../lib/propertiesConverters' +import { treeMapPropTypes, treeMapDefaultProps } from './TreeMapProps' +import { getColorRange, extractRGB } from '../../../ColorUtils' +import { rgb } from 'd3' class TreeMapPlaceholders extends Component { componentWillMount() { @@ -26,13 +24,13 @@ class TreeMapPlaceholders extends Component { } willEnter({ data: node }) { - const width = node.x1 - node.x0 + const width = node.x1 - node.x0 const height = node.y1 - node.y0 return { - x: node.x0 + width / 2, - y: node.y0 + height / 2, - width: 0, + x: node.x0 + width / 2, + y: node.y0 + height / 2, + width: 0, height: 0, ...extractRGB(node.color), } @@ -57,112 +55,140 @@ class TreeMapPlaceholders extends Component { } = this.props const identity = convertGetter(_identity) - const value = convertGetter(_value) + const value = convertGetter(_value) - const margin = Object.assign({}, Nivo.defaults.margin, this.props.margin) - const width = _width - margin.left - margin.right - const height = _height - margin.top - margin.bottom + const margin = Object.assign( + {}, + Nivo.defaults.margin, + this.props.margin + ) + const width = _width - margin.left - margin.right + const height = _height - margin.top - margin.bottom - const color = getColorRange(colors) + const color = getColorRange(colors) let wrapperTag let containerTag - const wrapperProps = {} + const wrapperProps = {} const containerProps = {} if (namespace === 'svg') { - wrapperTag = 'svg' + wrapperTag = 'svg' containerTag = 'g' - wrapperProps.width = _width - wrapperProps.height = _height - wrapperProps.xmlns = 'http://www.w3.org/2000/svg' + wrapperProps.width = _width + wrapperProps.height = _height + wrapperProps.xmlns = 'http://www.w3.org/2000/svg' containerProps.transform = `translate(${margin.left},${margin.top})` } else { - wrapperTag = 'div' + wrapperTag = 'div' containerTag = 'div' wrapperProps.style = { position: 'relative', - width: _width, - height: _height, + width: _width, + height: _height, } containerProps.style = { position: 'absolute', - top: margin.top, - left: margin.left + top: margin.top, + left: margin.left, } } const nodes = this.treemap.compute({ - width, height, + width, + height, root, tile, leavesOnly, - innerPadding, outerPadding, - identity, value, + innerPadding, + outerPadding, + identity, + value, color, }) if (animate === false) { - return React.createElement(wrapperTag, wrapperProps, + return React.createElement( + wrapperTag, + wrapperProps, React.createElement( containerTag, containerProps, - this.props.children(nodes.map(node => { - return { - key: node.key, - data: node, - style: { - x: node.x0, - y: node.y0, - width: node.x1 - node.x0, - height: node.y1 - node.y0, - color: node.color, - }, - } - })) + this.props.children( + nodes.map(node => { + return { + key: node.data.key, + data: node.data, + style: { + x: node.x0, + y: node.y0, + width: node.x1 - node.x0, + height: node.y1 - node.y0, + color: node.color, + }, + } + }) + ) ) ) } const springConfig = { stiffness: motionStiffness, - damping: motionDamping, + damping: motionDamping, } - return React.createElement(wrapperTag, wrapperProps, ( - { - return { - key: node.data.key, - data: node, - style: { - x: spring(node.x0, springConfig), - y: spring(node.y0, springConfig), - width: spring(node.x1 - node.x0, springConfig), - height: spring(node.y1 - node.y0, springConfig), - ...extractRGB(node.color, springConfig), - }, - } - })} - > - {interpolatedStyles => ( - React.createElement( - containerTag, - containerProps, - this.props.children(interpolatedStyles.map(interpolatedStyle => { - const { colorR, colorG, colorB } = interpolatedStyle.style - interpolatedStyle.style.color = `rgb(${Math.round(colorR)},${Math.round(colorG)},${Math.round(colorB)})` + return React.createElement( + wrapperTag, + wrapperProps, + { + return { + key: node.data.key, + data: node, + style: { + x: spring(node.x0, springConfig), + y: spring(node.y0, springConfig), + width: spring(node.x1 - node.x0, springConfig), + height: spring(node.y1 - node.y0, springConfig), + ...extractRGB(node.color, springConfig), + }, + } + })} + > + {interpolatedStyles => + React.createElement( + containerTag, + containerProps, + this.props.children( + interpolatedStyles.map(interpolatedStyle => { + const { + colorR, + colorG, + colorB, + } = interpolatedStyle.style + interpolatedStyle.style.color = `rgb(${Math.round( + colorR + )},${Math.round(colorG)},${Math.round(colorB)})` + + interpolatedStyle.style.width = Math.max( + 0, + interpolatedStyle.style.width + ) + interpolatedStyle.style.height = Math.max( + 0, + interpolatedStyle.style.height + ) return interpolatedStyle - })) + }) ) )} - - ) + ) } } @@ -171,15 +197,14 @@ TreeMapPlaceholders.propTypes = _.omit(treeMapPropTypes, [ 'orientLabels', 'skipVMin', 'transitionDuration', - 'transitionEasing' + 'transitionEasing', ]) TreeMapPlaceholders.defaultProps = _.omit(treeMapDefaultProps, [ 'orientLabels', 'skipVMin', 'transitionDuration', - 'transitionEasing' + 'transitionEasing', ]) - export default TreeMapPlaceholders diff --git a/src/components/charts/treemap/TreeMapProps.js b/src/components/charts/treemap/TreeMapProps.js index 65563b89e..754132677 100644 --- a/src/components/charts/treemap/TreeMapProps.js +++ b/src/components/charts/treemap/TreeMapProps.js @@ -6,88 +6,84 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' -import { PropTypes } from 'react' -import Nivo from '../../../Nivo' -import { margin } from '../../../PropTypes' +import PropTypes from 'prop-types' +import Nivo from '../../../Nivo' +import { margin } from '../../../PropTypes' import { tilingMethods } from '../../../lib/charts/treemap/TreeMapD3' - const { object, number, string, bool, func, any, oneOf, oneOfType } = PropTypes - /** * TreeMap components propTypes. * * @type {object} */ export const treeMapPropTypes = { - width: number.isRequired, // for non responsive components - height: number.isRequired, // for non responsive components + width: number.isRequired, // for non responsive components + height: number.isRequired, // for non responsive components margin, - root: object.isRequired, // data - leavesOnly: bool.isRequired, - value: oneOfType([string, func]).isRequired, - identity: oneOfType([string, func]).isRequired, - tile: oneOf(Object.keys(tilingMethods)), + root: object.isRequired, // data + leavesOnly: bool.isRequired, + value: oneOfType([string, func]).isRequired, + identity: oneOfType([string, func]).isRequired, + tile: oneOf(Object.keys(tilingMethods)), // labels - enableLabels: bool.isRequired, - orientLabels: bool.isRequired, - label: oneOfType([string, func]).isRequired, - labelFormat: string, - labelSkipSize: number.isRequired, + enableLabels: bool.isRequired, + orientLabels: bool.isRequired, + label: oneOfType([string, func]).isRequired, + labelFormat: string, + labelSkipSize: number.isRequired, - innerPadding: number.isRequired, - outerPadding: number.isRequired, - colors: any.isRequired, + innerPadding: number.isRequired, + outerPadding: number.isRequired, + colors: any.isRequired, - borderWidth: number.isRequired, - borderColor: any.isRequired, + borderWidth: number.isRequired, + borderColor: any.isRequired, // transitions - animate: bool.isRequired, - motionStiffness: number.isRequired, // react-motion - motionDamping: number.isRequired, // react-motion + animate: bool.isRequired, + motionStiffness: number.isRequired, // react-motion + motionDamping: number.isRequired, // react-motion transitionDuration: number.isRequired, // d3 transitions - transitionEasing: string.isRequired, // d3 transitions + transitionEasing: string.isRequired, // d3 transitions // placeholders - namespace: oneOf(['html', 'svg']).isRequired, - children: func.isRequired, + namespace: oneOf(['html', 'svg']).isRequired, + children: func.isRequired, } - /** * TreeMap components defaultProps. * * @type {object} */ export const treeMapDefaultProps = { - leavesOnly: false, - tile: 'squarify', - value: 'value', - identity: 'name', + leavesOnly: false, + tile: 'squarify', + value: 'value', + identity: 'name', // labels - enableLabels: true, - orientLabels: true, - label: 'id', - labelSkipSize: 0, - labelTextColor: 'inherit:darker(1)', + enableLabels: true, + orientLabels: true, + label: 'id', + labelSkipSize: 0, + labelTextColor: 'inherit:darker(1)', - margin: Nivo.defaults.margin, - innerPadding: 0, - outerPadding: 0, + margin: Nivo.defaults.margin, + innerPadding: 0, + outerPadding: 0, - borderWidth: 0, - borderColor: 'inherit', + borderWidth: 0, + borderColor: 'inherit', // transitions - animate: true, + animate: true, transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, - motionStiffness: 120, - motionDamping: 10, + transitionEasing: Nivo.defaults.transitionEasing, + motionStiffness: 120, + motionDamping: 10, - colors: Nivo.defaults.colorRange, + colors: Nivo.defaults.colorRange, } diff --git a/src/components/charts/treemap/index.js b/src/components/charts/treemap/index.js index ec383e025..7038015a4 100644 --- a/src/components/charts/treemap/index.js +++ b/src/components/charts/treemap/index.js @@ -6,11 +6,10 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' -export TreeMap from './TreeMap' -export ResponsiveTreeMap from './ResponsiveTreeMap' -export TreeMapHTML from './TreeMapHTML' -export ResponsiveTreeMapHTML from './ResponsiveTreeMapHTML' -export TreeMapPlaceholders from './TreeMapPlaceholders' +export TreeMap from './TreeMap' +export ResponsiveTreeMap from './ResponsiveTreeMap' +export TreeMapHTML from './TreeMapHTML' +export ResponsiveTreeMapHTML from './ResponsiveTreeMapHTML' +export TreeMapPlaceholders from './TreeMapPlaceholders' export ResponsiveTreeMapPlaceholders from './ResponsiveTreeMapPlaceholders' diff --git a/src/components/charts/voronoi/ResponsiveVoronoi.js b/src/components/charts/voronoi/ResponsiveVoronoi.js new file mode 100644 index 000000000..a8b8f22ce --- /dev/null +++ b/src/components/charts/voronoi/ResponsiveVoronoi.js @@ -0,0 +1,49 @@ +/* + * This file is part of the nivo project. + * + * (c) Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import React, { Component } from 'react' +import Voronoi from './Voronoi' +import Measure from 'react-measure' + +export default class ResponsiveVoronoi extends Component { + state = { + dimensions: { + width: -1, + height: -1, + }, + } + + render() { + const { width, height } = this.state.dimensions + + const shouldRender = width > 0 && height > 0 + + return ( + { + this.setState({ dimensions: contentRect.bounds }) + }} + > + {({ measureRef }) => +
+ {shouldRender && + } +
} +
+ ) + } +} diff --git a/src/components/charts/voronoi/Voronoi.js b/src/components/charts/voronoi/Voronoi.js new file mode 100644 index 000000000..5c06f40e5 --- /dev/null +++ b/src/components/charts/voronoi/Voronoi.js @@ -0,0 +1,121 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Nivo from '../../../Nivo' +import { voronoi as VoronoiGenerator } from 'd3' + +class Voronoi extends Component { + render() { + const { + data, + width: _width, + height: _height, + margin: _margin, + x, + y, + enableSites, + enableLinks, + enablePolygons, + borderWidth, + borderColor, + linkWidth, + linkColor, + } = this.props + + const margin = Object.assign({}, Nivo.defaults.margin, _margin) + const width = _width - margin.left - margin.right + const height = _height - margin.top - margin.bottom + + const voronoi = VoronoiGenerator() + .x(d => d[x]) + .y(d => d[y]) + .extent([[0, 0], [width, height]]) + + const polygons = voronoi.polygons(data) + const links = voronoi.links(data) + + return ( + + + {enableLinks && + links.map(l => { + return ( + + ) + })} + {enablePolygons && + polygons.map(p => { + return ( + + ) + })} + {enableSites && + data.map(d => { + return ( + + ) + })} + + + ) + } +} + +Voronoi.propTypes = { + enableSites: PropTypes.bool.isRequired, + enableLinks: PropTypes.bool.isRequired, + enablePolygons: PropTypes.bool.isRequired, + x: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, + y: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, + colors: PropTypes.any.isRequired, + borderWidth: PropTypes.number.isRequired, + borderColor: PropTypes.string.isRequired, + linkWidth: PropTypes.number.isRequired, + linkColor: PropTypes.string.isRequired, +} + +Voronoi.defaultProps = { + enableSites: true, + enableLinks: true, + enablePolygons: true, + x: 0, + y: 1, + borderWidth: 1, + borderColor: '#000', + linkWidth: 1, + linkColor: '#bbb', + colors: Nivo.defaults.colorRange, +} + +export default Voronoi diff --git a/src/components/charts/voronoi/index.js b/src/components/charts/voronoi/index.js new file mode 100644 index 000000000..89b0e482e --- /dev/null +++ b/src/components/charts/voronoi/index.js @@ -0,0 +1,11 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +export Voronoi from './Voronoi' +export ResponsiveVoronoi from './ResponsiveVoronoi' diff --git a/src/components/scales/Scale.js b/src/components/scales/Scale.js new file mode 100644 index 000000000..b64483934 --- /dev/null +++ b/src/components/scales/Scale.js @@ -0,0 +1,74 @@ +/* + * This file is part of the nivo project. + * + * (c) Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { scaleLinear, scaleBand, scalePoint } from 'd3' + +export default class Scale extends Component { + static propTypes = { + id: PropTypes.string.isRequired, + type: PropTypes.oneOf(['linear', 'point', 'band']).isRequired, + padding: PropTypes.number, + dataKey: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.func, + ]), + aggregate: PropTypes.array, + maxOf: PropTypes.array, + } + + static create( + { type, axis, dataKey: key, aggregate, maxOf, padding }, + data, + width, + height + ) { + let mapper + if (Array.isArray(aggregate)) { + mapper = d => _.sum(aggregate.map(k => d[k])) + } else if (Array.isArray(maxOf)) { + mapper = d => _.max(maxOf.map(k => d[k])) + } else if (_.isFunction(key)) { + mapper = key + } else { + mapper = d => d[key] + } + + const range = [axis === 'y' ? height : 0, axis === 'x' ? width : 0] + + let scale + switch (type) { + case 'linear': + scale = scaleLinear() + .rangeRound(range) + .domain([0, _.max(data.map(mapper))]) + break + + case 'band': + scale = scaleBand().rangeRound(range).domain(data.map(mapper)) + + if (padding !== undefined) { + scale.padding(padding) + } + break + + case 'point': + scale = scalePoint().range(range).domain(data.map(mapper)) + break + } + + return scale + } + + render() { + return null + } +} diff --git a/src/components/scales/XYScales.js b/src/components/scales/XYScales.js index 475ae6c16..835174518 100644 --- a/src/components/scales/XYScales.js +++ b/src/components/scales/XYScales.js @@ -6,61 +6,67 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import d3 from 'd3'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import d3 from 'd3' class XYScales extends Component { render() { const { data, - identityAccessor, valueAccessor, - width, height, - children - } = this.props; + identityAccessor, + valueAccessor, + width, + height, + children, + } = this.props if (React.Children.count(children) === 0) { - return null; + return null } - const xScale = d3.scale.linear() + const xScale = d3.scale + .linear() .range([0, width]) .domain([0, data.length - 1]) - ; - const yScale = d3.scale.linear() + const yScale = d3.scale + .linear() .range([height, 0]) .domain([0, d3.max(data.map(valueAccessor))]) - ; return ( - {React.Children.map(children, child => ( - React.cloneElement(child, { data: data.slice(), xScale, yScale, width, height }) - ))} + {React.Children.map(children, child => + React.cloneElement(child, { + data: data.slice(), + xScale, + yScale, + width, + height, + }) + )} - ); + ) } } -XYScales.displayName = 'XYScales'; +XYScales.displayName = 'XYScales' -const { array, func, number } = PropTypes; +const { array, func, number } = PropTypes XYScales.propTypes = { - data: array.isRequired, + data: array.isRequired, identityAccessor: func.isRequired, - valueAccessor: func.isRequired, - width: number, - height: number -}; + valueAccessor: func.isRequired, + width: number, + height: number, +} XYScales.defaultProps = { identityAccessor: (d, i) => i, - valueAccessor: d => d -}; - + valueAccessor: d => d, +} -export default XYScales; +export default XYScales diff --git a/src/components/scales/index.js b/src/components/scales/index.js new file mode 100644 index 000000000..8a059bac8 --- /dev/null +++ b/src/components/scales/index.js @@ -0,0 +1,10 @@ +/* + * This file is part of the nivo project. + * + * (c) 2016 Raphaël Benitte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +export Scale from './Scale' diff --git a/src/components/shapes/Area.js b/src/components/shapes/Area.js index f87868370..a84cded75 100644 --- a/src/components/shapes/Area.js +++ b/src/components/shapes/Area.js @@ -6,82 +6,83 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import { findDOMNode } from 'react-dom'; -import d3 from 'd3'; -import Nivo from '../../Nivo'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { findDOMNode } from 'react-dom' +import d3 from 'd3' +import Nivo from '../../Nivo' class Area extends Component { renderD3(props) { const { data, - xScale, yScale, - xAccessor, yAccessor, - width, height, + xScale, + yScale, + xAccessor, + yAccessor, + width, + height, interpolation, transitionDuration, - transitionEasing - } = props; + transitionEasing, + } = props - const element = d3.select(findDOMNode(this)); + const element = d3.select(findDOMNode(this)) - const area = d3.svg.area() + const area = d3.svg + .area() .x((d, i) => xScale(xAccessor(d, i))) .y0(height) .y1((d, i) => yScale(yAccessor(d, i))) .interpolate(interpolation) - ; - element.datum(data) + element + .datum(data) .transition() .duration(transitionDuration) .ease(transitionEasing) .attr('d', area) - ; } componentDidMount() { - this.renderD3(this.props); + this.renderD3(this.props) } shouldComponentUpdate(nextProps) { - this.renderD3(nextProps); + this.renderD3(nextProps) - return false; + return false } render() { - return ; + return } } -Area.displayName = 'Area'; +Area.displayName = 'Area' -const { array, func, string, number } = PropTypes; +const { array, func, string, number } = PropTypes Area.propTypes = { - data: array.isRequired, - xScale: func.isRequired, - yScale: func.isRequired, - xAccessor: func.isRequired, - yAccessor: func.isRequired, - width: number.isRequired, - height: number.isRequired, - interpolation: string.isRequired, + data: array.isRequired, + xScale: func.isRequired, + yScale: func.isRequired, + xAccessor: func.isRequired, + yAccessor: func.isRequired, + width: number.isRequired, + height: number.isRequired, + interpolation: string.isRequired, transitionDuration: number.isRequired, - transitionEasing: string.isRequired -}; + transitionEasing: string.isRequired, +} Area.defaultProps = { - xAccessor: (d, i) => i, - yAccessor: d => d, - interpolation: 'linear', + xAccessor: (d, i) => i, + yAccessor: d => d, + interpolation: 'linear', transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing -}; - + transitionEasing: Nivo.defaults.transitionEasing, +} -export default Area; +export default Area diff --git a/src/components/shapes/Line.js b/src/components/shapes/Line.js index 9e69cd2fe..25738decc 100644 --- a/src/components/shapes/Line.js +++ b/src/components/shapes/Line.js @@ -6,78 +6,78 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import { findDOMNode } from 'react-dom'; -import d3 from 'd3'; -import Nivo from '../../Nivo'; +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { findDOMNode } from 'react-dom' +import d3 from 'd3' +import Nivo from '../../Nivo' class Line extends Component { renderD3(props) { const { data, - xScale, yScale, - xAccessor, yAccessor, + xScale, + yScale, + xAccessor, + yAccessor, interpolation, transitionDuration, - transitionEasing - } = props; + transitionEasing, + } = props - const element = d3.select(findDOMNode(this)); + const element = d3.select(findDOMNode(this)) - const line = d3.svg.line() + const line = d3.svg + .line() .x((d, i) => xScale(xAccessor(d, i))) .y((d, i) => yScale(yAccessor(d, i))) .interpolate(interpolation) - ; - element.datum(data) + element + .datum(data) .transition() .duration(transitionDuration) .ease(transitionEasing) .attr('d', line) - ; } componentDidMount() { - this.renderD3(this.props); + this.renderD3(this.props) } shouldComponentUpdate(nextProps) { - this.renderD3(nextProps); + this.renderD3(nextProps) - return false; + return false } render() { - return ; + return } } -Line.displayName = 'Line'; +Line.displayName = 'Line' -const { array, func, string, number } = PropTypes; +const { array, func, string, number } = PropTypes Line.propTypes = { - data: array.isRequired, - xScale: func.isRequired, - yScale: func.isRequired, - xAccessor: func.isRequired, - yAccessor: func.isRequired, - interpolation: string.isRequired, + data: array.isRequired, + xScale: func.isRequired, + yScale: func.isRequired, + xAccessor: func.isRequired, + yAccessor: func.isRequired, + interpolation: string.isRequired, transitionDuration: number.isRequired, - transitionEasing: string.isRequired -}; + transitionEasing: string.isRequired, +} Line.defaultProps = { - xAccessor: (d, i) => i, - yAccessor: d => d, - interpolation: 'linear', + xAccessor: (d, i) => i, + yAccessor: d => d, + interpolation: 'linear', transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, -}; - + transitionEasing: Nivo.defaults.transitionEasing, +} -export default Line; +export default Line diff --git a/src/constants/directions.js b/src/constants/directions.js index 5516889b4..75b1f6cbe 100644 --- a/src/constants/directions.js +++ b/src/constants/directions.js @@ -6,7 +6,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; -export const DIRECTION_HORIZONTAL = 'horizontal'; -export const DIRECTION_VERTICAL = 'vertical'; +export const DIRECTION_HORIZONTAL = 'horizontal' +export const DIRECTION_VERTICAL = 'vertical' diff --git a/src/index.js b/src/index.js index ff56a2a90..cef148a9a 100644 --- a/src/index.js +++ b/src/index.js @@ -6,14 +6,17 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' - export default from './Nivo' -export * from './components/charts/bars/' -export * from './components/charts/line/' -export * from './components/charts/bubble/' -export * from './components/charts/treemap/' -export * from './components/charts/chord/' -export * from './components/axes/' -export * from './properties/curve' +export * from './components/charts/bars/' +export * from './components/charts/line/' +export * from './components/charts/bubble/' +export * from './components/charts/treemap/' +export * from './components/charts/chord/' +export * from './components/charts/calendar/' +export * from './components/charts/voronoi/' +export * from './components/axes/' +export * from './components/scales/' +export * from './properties/curve' +export Chart from './components/charts/Chart' +export ResponsiveChart from './components/charts/ResponsiveChart' diff --git a/src/lib/charts/bubble/BubbleD3.js b/src/lib/charts/bubble/BubbleD3.js index c7aa4e671..a5d4dfb9a 100644 --- a/src/lib/charts/bubble/BubbleD3.js +++ b/src/lib/charts/bubble/BubbleD3.js @@ -6,14 +6,9 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' import { flatten } from '../../../DataUtils' -import { - hierarchy, - pack, -} from 'd3' - +import { hierarchy, pack } from 'd3' /** * This wrapper is responsible for computing bubble chart positions. @@ -23,7 +18,7 @@ import { * @constructor */ const BubbleD3 = () => { - const layout = pack() + const layout = pack() return { /** @@ -38,11 +33,13 @@ const BubbleD3 = () => { * @returns {array} */ compute({ - width, height, + width, + height, data: _data, - identityProperty, valueAccessor, + identityProperty, + valueAccessor, padding, - color + color, }) { layout //.value(valueAccessor) @@ -53,26 +50,20 @@ const BubbleD3 = () => { const data = hierarchy(_data) layout(data) - console.log(data) - //const flattened = flatten(data, identityProperty) - const nodes = data.descendants() - .filter(d => !d.children) - .map(d => { - if (d.depth > 1) { - d.color = color(d.parentId) - } else { - d.color = color(d[identityProperty]) - } + const nodes = data.descendants().filter(d => !d.children).map(d => { + if (d.depth > 1) { + d.color = color(d.parentId) + } else { + d.color = color(d[identityProperty]) + } - return d - }) - + return d + }) return nodes - } + }, } } - export default BubbleD3 diff --git a/src/lib/charts/bubble/BubbleD3Svg.js b/src/lib/charts/bubble/BubbleD3Svg.js index 44f246019..8c516ed35 100644 --- a/src/lib/charts/bubble/BubbleD3Svg.js +++ b/src/lib/charts/bubble/BubbleD3Svg.js @@ -6,76 +6,89 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import d3 from 'd3'; -import BubbleD3 from './BubbleD3'; -import { getColorRange, getColorGenerator, getColorStyleObject } from '../../../ColorUtils'; -import { convertLabel } from '../../propertiesConverters'; +import d3 from 'd3' +import BubbleD3 from './BubbleD3' +import { + getColorRange, + getColorGenerator, + getColorStyleObject, +} from '../../../ColorUtils' +import { convertLabel } from '../../propertiesConverters' const BubbleD3Svg = domRoot => { - // DOM elements - const element = d3.select(domRoot); - const wrapper = element.append('g').attr('class', 'nivo_bubble_wrapper'); + const element = d3.select(domRoot) + const wrapper = element.append('g').attr('class', 'nivo_bubble_wrapper') - const bubble = BubbleD3(); + const bubble = BubbleD3() // an array to store decorator functions - let decorators = []; + let decorators = [] return { draw(props) { const { data, onBubbleClick, - identityProperty, value, - width, height, margin, + identityProperty, + value, + width, + height, + margin, padding, colors, - borderWidth, borderColor, - label, labelFormat, labelSkipRadius, labelTextColor, labelTextDY, - transitionDuration, transitionEasing - } = props; + borderWidth, + borderColor, + label, + labelFormat, + labelSkipRadius, + labelTextColor, + labelTextDY, + transitionDuration, + transitionEasing, + } = props - const identity = d => d[identityProperty]; - const valueAccessor = d => d[value]; + const identity = d => d[identityProperty] + const valueAccessor = d => d[value] - element.attr({ width, height }); + element.attr({ width, height }) - const useWidth = width - margin.left - margin.right; - const useHeight = height - margin.top - margin.bottom; + const useWidth = width - margin.left - margin.right + const useHeight = height - margin.top - margin.bottom wrapper.attr({ - width: useWidth, - height: useHeight, - transform: `translate(${margin.left},${margin.top})` - }); + width: useWidth, + height: useHeight, + transform: `translate(${margin.left},${margin.top})`, + }) - const color = getColorRange(colors); - const borderColorFn = getColorGenerator(borderColor); + const color = getColorRange(colors) + const borderColorFn = getColorGenerator(borderColor) - const bubbled = bubble.compute({ - width: useWidth, + const bubbled = bubble.compute({ + width: useWidth, height: useHeight, data, - identityProperty, valueAccessor, + identityProperty, + valueAccessor, padding, - color - }); - + color, + }) // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // NODES // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - const nodes = wrapper.selectAll('.nivo_bubble_node').data(bubbled, identity); + const nodes = wrapper + .selectAll('.nivo_bubble_node') + .data(bubbled, identity) // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // ENTER: creates new nodes // ————————————————————————————————————————————————————————————————————————————————————————————————————————— nodes - .enter().append('circle') + .enter() + .append('circle') .attr('class', 'nivo_bubble_node') .attr('r', 2) .style('fill', d => d.color) @@ -83,7 +96,6 @@ const BubbleD3Svg = domRoot => { .style('stroke-width', borderWidth) .attr('transform', d => `translate(${d.x},${d.y})`) .on('click', onBubbleClick) - ; // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // UPDATE: updates existing nodes @@ -97,39 +109,40 @@ const BubbleD3Svg = domRoot => { .style('stroke-width', borderWidth) .attr('r', d => d.r) .attr('transform', d => `translate(${d.x},${d.y})`) - ; // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // EXIT: removes stale nodes // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - nodes.exit() + nodes + .exit() .transition() .duration(transitionDuration) .ease(transitionEasing) .attr('transform', `translate(${width / 2},${height / 2})`) .attr('r', 0) .remove() - ; - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // LABELS // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - const labelFn = convertLabel(label, labelFormat); - const textColorStyle = getColorStyleObject(labelTextColor, 'fill'); - + const labelFn = convertLabel(label, labelFormat) + const textColorStyle = getColorStyleObject(labelTextColor, 'fill') - let legendsData = bubbled; + let legendsData = bubbled if (labelSkipRadius > 0) { - legendsData = bubbled.filter(d => d.r >= labelSkipRadius); + legendsData = bubbled.filter(d => d.r >= labelSkipRadius) } - const legends = wrapper.selectAll('.nivo_bubble_legend').data(legendsData, identity); + const legends = wrapper + .selectAll('.nivo_bubble_legend') + .data(legendsData, identity) // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // ENTER: creates new labels // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - legends.enter().append('text') + legends + .enter() + .append('text') .attr('class', 'nivo_bubble_legend') .style('text-anchor', 'middle') .style(textColorStyle) @@ -138,7 +151,6 @@ const BubbleD3Svg = domRoot => { .attr('transform', d => `translate(${d.x},${d.y})`) .attr('dy', labelTextDY) .on('click', onBubbleClick) - ; // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // UPDATE: updates existing labels @@ -152,41 +164,39 @@ const BubbleD3Svg = domRoot => { .style('opacity', 1) .attr('transform', d => `translate(${d.x},${d.y})`) .attr('dy', labelTextDY) - ; // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // EXIT: removes stale labels // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - legends.exit() + legends + .exit() .transition() .duration(transitionDuration) .ease(transitionEasing) .style('opacity', 0) .remove() - ; const bubbleContext = { - element: wrapper, - width: useWidth, + element: wrapper, + width: useWidth, height: useHeight, - rawData: data, + rawData: data, identity, valueAccessor, - data: bubbled, + data: bubbled, transitionDuration, - transitionEasing - }; + transitionEasing, + } decorators.forEach(decorator => { - decorator(bubbleContext); - }); + decorator(bubbleContext) + }) }, decorate(newDecorators = []) { - decorators = newDecorators; - } - }; -}; - + decorators = newDecorators + }, + } +} -export default BubbleD3Svg; +export default BubbleD3Svg diff --git a/src/lib/charts/bubble/BubbleHelper.js b/src/lib/charts/bubble/BubbleHelper.js index 19efbe78e..90e7a528a 100644 --- a/src/lib/charts/bubble/BubbleHelper.js +++ b/src/lib/charts/bubble/BubbleHelper.js @@ -6,17 +6,10 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' -import { - hierarchy, - pack as Pack, -} from 'd3' +import { hierarchy, pack as Pack } from 'd3' - -const computePath = node => { - -} +const computePath = node => {} /** * This wrapper is responsible for computing bubble chart positions. @@ -26,7 +19,7 @@ const computePath = node => { * @constructor */ const BubbleHelper = () => { - const pack = Pack() + const pack = Pack() return { /** @@ -42,31 +35,26 @@ const BubbleHelper = () => { * @returns {array} */ compute({ - width, height, + width, + height, root: _root, leavesOnly, - identity, value, + identity, + value, padding, - color + color, }) { - pack - .size([width, height]) - .padding(padding) + pack.size([width, height]).padding(padding) const root = hierarchy(_root).sum(value) pack(root) - - const nodes = leavesOnly ? root.leaves() : root.descendants() - - - return nodes - .map(d => { - d.color = color(d.depth) - /* + return nodes.map(d => { + d.color = color(d.depth) + /* if (d.depth > 1) { d.color = color(d.parentId) } else { @@ -74,13 +62,12 @@ const BubbleHelper = () => { } */ - d.data.key = d.ancestors().map(a => identity(a.data)).join('.') + d.data.key = d.ancestors().map(a => identity(a.data)).join('.') - return d - }) - } + return d + }) + }, } } - export default BubbleHelper diff --git a/src/lib/charts/calendar/CalendarLayout.js b/src/lib/charts/calendar/CalendarLayout.js index f6be72f1c..ec2114cfb 100644 --- a/src/lib/charts/calendar/CalendarLayout.js +++ b/src/lib/charts/calendar/CalendarLayout.js @@ -6,13 +6,20 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import d3 from 'd3'; -import _ from 'lodash'; -import scalePropToD3Scale from '../../scalePropToD3Scale'; -import { DIRECTION_HORIZONTAL } from '../../../constants/directions'; +import _ from 'lodash' +import scalePropToD3Scale from '../../scalePropToD3Scale' +import { DIRECTION_HORIZONTAL } from '../../../constants/directions' +import { + timeFormat, + timeDays, + timeWeek, + timeWeeks, + timeMonths, + timeYear, + range, + max, +} from 'd3' /** * Compute day cell size according to current context. @@ -26,20 +33,36 @@ import { DIRECTION_HORIZONTAL } from '../../../constants/directions'; * @param {number} maxWeeks * @returns {number} */ -const computeCellSize = ({ width, height, direction, yearRange, yearSpacing, daySpacing, maxWeeks }) => { - let hCellSize; - let vCellSize; +const computeCellSize = ({ + width, + height, + direction, + yearRange, + yearSpacing, + daySpacing, + maxWeeks, +}) => { + let hCellSize + let vCellSize if (direction === DIRECTION_HORIZONTAL) { - hCellSize = (width - daySpacing * maxWeeks) / maxWeeks; - vCellSize = (height - (yearRange.length - 1) * yearSpacing - yearRange.length * (8 * daySpacing)) / (yearRange.length * 7); + hCellSize = (width - daySpacing * maxWeeks) / maxWeeks + vCellSize = + (height - + (yearRange.length - 1) * yearSpacing - + yearRange.length * (8 * daySpacing)) / + (yearRange.length * 7) } else { - hCellSize = (width - (yearRange.length - 1) * yearSpacing - yearRange.length * (8 * daySpacing)) / (yearRange.length * 7); - vCellSize = (height - daySpacing * maxWeeks) / maxWeeks; + hCellSize = + (width - + (yearRange.length - 1) * yearSpacing - + yearRange.length * (8 * daySpacing)) / + (yearRange.length * 7) + vCellSize = (height - daySpacing * maxWeeks) / maxWeeks } - return Math.min(hCellSize, vCellSize); -}; + return Math.min(hCellSize, vCellSize) +} /** * Computes month path and bounding box. @@ -52,60 +75,76 @@ const computeCellSize = ({ width, height, direction, yearRange, yearSpacing, day * @param {string} direction * @returns { { path: string, bbox: { x: number, y: number, width: number, height: number } } } */ -const monthPathAndBBox = ({ date, cellSize, yearIndex, yearSpacing, daySpacing, direction }) => { - const t1 = new Date(date.getFullYear(), date.getMonth() + 1, 0); // first day of next month - const d0 = date.getDay(); // first day of month - const w0 = d3.time.weekOfYear(date); // first week of month - const d1 = t1.getDay(); // last day of month - const w1 = d3.time.weekOfYear(t1); // last week of month +const monthPathAndBBox = ({ + date, + cellSize, + yearIndex, + yearSpacing, + daySpacing, + direction, +}) => { + const t1 = new Date(date.getFullYear(), date.getMonth() + 1, 0) // first day of next month + const d0 = date.getDay() // first day of month + const w0 = timeWeek.count(timeYear(date), date) // first week of month + const d1 = t1.getDay() // last day of month + const w1 = timeWeek.count(timeYear(t1), t1) // last week of month // offset according to year index - let xO = 0; - let yO = 0; - const yearOffset = yearIndex * (7 * (cellSize + daySpacing) + yearSpacing); + let xO = 0 + let yO = 0 + const yearOffset = yearIndex * (7 * (cellSize + daySpacing) + yearSpacing) if (direction === DIRECTION_HORIZONTAL) { - yO = yearOffset; + yO = yearOffset } else { - xO = yearOffset; + xO = yearOffset } - let path; - let bbox = { x: xO, y: yO, width: 0, height: 0 }; + let path + let bbox = { x: xO, y: yO, width: 0, height: 0 } if (direction === DIRECTION_HORIZONTAL) { path = [ - `M${xO + (w0 + 1) * (cellSize + daySpacing)},${yO + d0 * (cellSize + daySpacing)}`, - `H${xO + w0 * (cellSize + daySpacing)}V${yO + 7 * (cellSize + daySpacing)}`, - `H${xO + w1 * (cellSize + daySpacing)}V${yO + (d1 + 1) * (cellSize + daySpacing)}`, + `M${xO + (w0 + 1) * (cellSize + daySpacing)},${yO + + d0 * (cellSize + daySpacing)}`, + `H${xO + w0 * (cellSize + daySpacing)}V${yO + + 7 * (cellSize + daySpacing)}`, + `H${xO + w1 * (cellSize + daySpacing)}V${yO + + (d1 + 1) * (cellSize + daySpacing)}`, `H${xO + (w1 + 1) * (cellSize + daySpacing)}V${yO}`, - `H${xO + (w0 + 1) * (cellSize + daySpacing)}Z` - ].join(''); + `H${xO + (w0 + 1) * (cellSize + daySpacing)}Z`, + ].join('') - bbox.x = xO + w0 * (cellSize + daySpacing); - bbox.width = (w1 + 1) * (cellSize + daySpacing) - bbox.x; - bbox.height = 7 * (cellSize + daySpacing); + bbox.x = xO + w0 * (cellSize + daySpacing) + bbox.width = (w1 + 1) * (cellSize + daySpacing) - bbox.x + bbox.height = 7 * (cellSize + daySpacing) } else { path = [ - `M${xO + d0 * (cellSize + daySpacing)},${yO + (w0 + 1) * (cellSize + daySpacing)}`, + `M${xO + d0 * (cellSize + daySpacing)},${yO + + (w0 + 1) * (cellSize + daySpacing)}`, `H${xO}V${yO + (w1 + 1) * (cellSize + daySpacing)}`, - `H${xO + (d1 + 1) * (cellSize + daySpacing)}V${yO + w1 * (cellSize + daySpacing)}`, - `H${xO + 7 * (cellSize + daySpacing)}V${yO + w0 * (cellSize + daySpacing)}`, - `H${xO + d0 * (cellSize + daySpacing)}Z` - ].join(''); - - bbox.y = yO + w0 * (cellSize + daySpacing); - bbox.width = 7 * (cellSize + daySpacing); - bbox.height = (w1 + 1) * (cellSize + daySpacing) - bbox.y; + `H${xO + (d1 + 1) * (cellSize + daySpacing)}V${yO + + w1 * (cellSize + daySpacing)}`, + `H${xO + 7 * (cellSize + daySpacing)}V${yO + + w0 * (cellSize + daySpacing)}`, + `H${xO + d0 * (cellSize + daySpacing)}Z`, + ].join('') + + bbox.y = yO + w0 * (cellSize + daySpacing) + bbox.width = 7 * (cellSize + daySpacing) + bbox.height = (w1 + 1) * (cellSize + daySpacing) - bbox.y } - return { path, bbox }; -}; + return { path, bbox } +} /** * Creates a memoized version of monthPathAndBBox function. */ -const memoMonthPathAndBBox = _.memoize(monthPathAndBBox, ({ date, cellSize, yearIndex, yearSpacing, daySpacing, direction }) => { - return `${date.toString()}.${cellSize}.${yearIndex}.${yearSpacing}.${daySpacing}.${direction}`; -}); +const memoMonthPathAndBBox = _.memoize( + monthPathAndBBox, + ({ date, cellSize, yearIndex, yearSpacing, daySpacing, direction }) => { + return `${date.toString()}.${cellSize}.${yearIndex}.${yearSpacing}.${daySpacing}.${direction}` + } +) /** * Returns a function to Compute day cell position for horizontal layout. @@ -116,11 +155,18 @@ const memoMonthPathAndBBox = _.memoize(monthPathAndBBox, ({ date, cellSize, year * @returns { function(): { x: number, y: number } } */ const cellPositionHorizontal = (cellSize, yearSpacing, daySpacing) => { - return (d, yearIndex) => ({ - x: d3.time.weekOfYear(d) * (cellSize + daySpacing) + daySpacing / 2, - y: d.getDay() * (cellSize + daySpacing) + daySpacing / 2 + yearIndex * (yearSpacing + 7 * (cellSize + daySpacing)), - }); -}; + return (d, yearIndex) => { + const weekOfYear = timeWeek.count(timeYear(d), d) + + return { + x: weekOfYear * (cellSize + daySpacing) + daySpacing / 2, + y: + d.getDay() * (cellSize + daySpacing) + + daySpacing / 2 + + yearIndex * (yearSpacing + 7 * (cellSize + daySpacing)), + } + } +} /** * Returns a function to Compute day cell position for vertical layout. @@ -131,16 +177,21 @@ const cellPositionHorizontal = (cellSize, yearSpacing, daySpacing) => { * @returns { function(): { x: number, y: number } } */ const cellPositionVertical = (cellSize, yearSpacing, daySpacing) => { - return (d, yearIndex) => ({ - x: d.getDay() * (cellSize + daySpacing) + daySpacing / 2 + yearIndex * (yearSpacing + 7 * (cellSize + daySpacing)), - y: d3.time.weekOfYear(d) * (cellSize + daySpacing) + daySpacing / 2, - }); -}; - + return (d, yearIndex) => { + const weekOfYear = timeWeek.count(timeYear(d), d) + + return { + x: + d.getDay() * (cellSize + daySpacing) + + daySpacing / 2 + + yearIndex * (yearSpacing + 7 * (cellSize + daySpacing)), + y: weekOfYear * (cellSize + daySpacing) + daySpacing / 2, + } + } +} // used for days range and data matching -const dayFormat = d3.time.format('%Y-%m-%d'); - +const dayFormat = timeFormat('%Y-%m-%d') /** * This layout is responsible for computing Calendar chart data/positions…. @@ -165,97 +216,138 @@ const CalendarLayout = () => { * @returns {object} */ compute({ - width, height, - from, to, + width, + height, + from, + to, data, direction, colorScale, emptyColor, yearSpacing, - daySpacing + daySpacing, }) { // time related data - const fromDate = _.isDate(from) ? from : new Date(from); - const toDate = _.isDate(to) ? to : new Date(to); - let yearRange = d3.range(fromDate.getFullYear(), toDate.getFullYear() + 1); - const maxWeeks = d3.max(yearRange, year => d3.time.weeks(new Date(year, 0, 1), new Date(year + 1, 0, 1)).length) + 1; - + const fromDate = _.isDate(from) ? from : new Date(from) + const toDate = _.isDate(to) ? to : new Date(to) + let yearRange = range( + fromDate.getFullYear(), + toDate.getFullYear() + 1 + ) + const maxWeeks = + max( + yearRange, + year => + timeWeeks( + new Date(year, 0, 1), + new Date(year + 1, 0, 1) + ).length + ) + 1 // —————————————————————————————————————————————————————————————————————————————————————————————————————— // Computes years/months/days // —————————————————————————————————————————————————————————————————————————————————————————————————————— // compute cellSize - const cellSize = computeCellSize({ width, height, direction, yearRange, yearSpacing, daySpacing, maxWeeks }); + const cellSize = computeCellSize({ + width, + height, + direction, + yearRange, + yearSpacing, + daySpacing, + maxWeeks, + }) // determine day cells positioning function according to layout direction - let cellPosition; + let cellPosition if (direction === DIRECTION_HORIZONTAL) { - cellPosition = cellPositionHorizontal(cellSize, yearSpacing, daySpacing); + cellPosition = cellPositionHorizontal( + cellSize, + yearSpacing, + daySpacing + ) } else { - cellPosition = cellPositionVertical(cellSize, yearSpacing, daySpacing); + cellPosition = cellPositionVertical( + cellSize, + yearSpacing, + daySpacing + ) } - let years = []; - let months = []; - let days = []; + let years = [] + let months = [] + let days = [] yearRange.forEach((year, i) => { - const yearStart = new Date(year, 0, 1); - const yearEnd = new Date(year + 1, 0, 1); - - days = days.concat(d3.time.days(yearStart, yearEnd).map(dayDate => _.assign( - { - date: dayDate, - day: dayFormat(dayDate), - size: cellSize - }, - cellPosition(dayDate, i) - ))); - - const yearMonths = d3.time.months(yearStart, yearEnd).map(monthDate => _.assign( - { date: monthDate }, - memoMonthPathAndBBox({ - date: monthDate, - direction, - yearIndex: i, - yearSpacing, - daySpacing, - cellSize, - }) - )); - - months = months.concat(yearMonths); + const yearStart = new Date(year, 0, 1) + const yearEnd = new Date(year + 1, 0, 1) + + days = days.concat( + timeDays(yearStart, yearEnd).map(dayDate => + _.assign( + { + date: dayDate, + day: dayFormat(dayDate), + size: cellSize, + }, + cellPosition(dayDate, i) + ) + ) + ) + + const yearMonths = timeMonths( + yearStart, + yearEnd + ).map(monthDate => + _.assign( + { date: monthDate }, + memoMonthPathAndBBox({ + date: monthDate, + direction, + yearIndex: i, + yearSpacing, + daySpacing, + cellSize, + }) + ) + ) + + months = months.concat(yearMonths) years.push({ year, bbox: { - x: yearMonths[0].bbox.x, - y: yearMonths[0].bbox.y, - width: yearMonths[11].bbox.x - yearMonths[0].bbox.x + yearMonths[11].bbox.width, - height: yearMonths[11].bbox.y - yearMonths[0].bbox.y + yearMonths[11].bbox.height, + x: yearMonths[0].bbox.x, + y: yearMonths[0].bbox.y, + width: + yearMonths[11].bbox.x - + yearMonths[0].bbox.x + + yearMonths[11].bbox.width, + height: + yearMonths[11].bbox.y - + yearMonths[0].bbox.y + + yearMonths[11].bbox.height, }, }) - }); - + }) // —————————————————————————————————————————————————————————————————————————————————————————————————————— // Computes days/data intersection // —————————————————————————————————————————————————————————————————————————————————————————————————————— - const color = scalePropToD3Scale(colorScale); + //const color = scalePropToD3Scale(colorScale) days.forEach(day => { - day.color = emptyColor; + day.color = emptyColor data.forEach(dataDay => { if (dataDay.day === day.day) { - day.color = color(dataDay.value); + //day.color = color(dataDay.value) } - }); - }); + }) + }) - return { years, months, days, cellSize }; - } + return { years, months, days, cellSize } + }, } -}; - +} -export default CalendarLayout; +export default CalendarLayout diff --git a/src/lib/charts/labels.js b/src/lib/charts/labels.js index 2697eb48e..5c107736c 100644 --- a/src/lib/charts/labels.js +++ b/src/lib/charts/labels.js @@ -6,99 +6,99 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; -import d3 from 'd3'; +import d3 from 'd3' // label positioning -export const LABEL_POSITION_CENTER = 'center'; -export const LABEL_POSITION_TOP = 'top'; -export const LABEL_POSITION_RIGHT = 'right'; -export const LABEL_POSITION_BOTTOM = 'bottom'; -export const LABEL_POSITION_LEFT = 'left'; - - -const labelMaker = ({ text, position, labelOffset, labelPaddingX, labelPaddingY }) => { +export const LABEL_POSITION_CENTER = 'center' +export const LABEL_POSITION_TOP = 'top' +export const LABEL_POSITION_RIGHT = 'right' +export const LABEL_POSITION_BOTTOM = 'bottom' +export const LABEL_POSITION_LEFT = 'left' + +const labelMaker = ({ + text, + position, + labelOffset, + labelPaddingX, + labelPaddingY, +}) => { return g => { - let labelBackground = g.select('rect'); - let labelText = g.select('text'); + let labelBackground = g.select('rect') + let labelText = g.select('text') if (labelBackground.empty()) { - labelBackground = g.append('rect'); - labelText = g.append('text'); + labelBackground = g.append('rect') + labelText = g.append('text') } labelText .attr('alignment-baseline', 'text-before-edge') .style('fill', '#fff') .text(text) - ; - const textBBox = labelText.node().getBBox(); + const textBBox = labelText.node().getBBox() - let textX = 0; - let textY = 0; + let textX = 0 + let textY = 0 - let bgX = 0; - let bgY = 0; + let bgX = 0 + let bgY = 0 switch (position) { case 'center': - textX = -textBBox.width / 2; - textY = -textBBox.height / 2; + textX = -textBBox.width / 2 + textY = -textBBox.height / 2 - bgX = -textBBox.width / 2 - labelPaddingX; - bgY = -textBBox.height / 2 - labelPaddingY; - break; + bgX = -textBBox.width / 2 - labelPaddingX + bgY = -textBBox.height / 2 - labelPaddingY + break case 'top': - textX = -textBBox.width / 2; - textY = -textBBox.height - labelOffset - labelPaddingY; + textX = -textBBox.width / 2 + textY = -textBBox.height - labelOffset - labelPaddingY - bgX = -textBBox.width / 2 - labelPaddingX; - bgY = -textBBox.height - labelOffset - labelPaddingY * 2; - break; + bgX = -textBBox.width / 2 - labelPaddingX + bgY = -textBBox.height - labelOffset - labelPaddingY * 2 + break case 'right': - textX = labelOffset + labelPaddingX; - textY = -textBBox.height / 2; + textX = labelOffset + labelPaddingX + textY = -textBBox.height / 2 - bgX = labelOffset; - bgY = -textBBox.height / 2 - labelPaddingY; - break; + bgX = labelOffset + bgY = -textBBox.height / 2 - labelPaddingY + break case 'bottom': - textX = -textBBox.width / 2; - textY = labelOffset + labelPaddingY; + textX = -textBBox.width / 2 + textY = labelOffset + labelPaddingY - bgX = -textBBox.width / 2 - labelPaddingX; - bgY = labelOffset; - break; + bgX = -textBBox.width / 2 - labelPaddingX + bgY = labelOffset + break case 'left': - textX = -textBBox.width - labelOffset - labelPaddingX; - textY = -textBBox.height / 2; + textX = -textBBox.width - labelOffset - labelPaddingX + textY = -textBBox.height / 2 - bgX = -textBBox.width - labelOffset - labelPaddingX * 2; - bgY = -textBBox.height / 2 - labelPaddingY; - break; + bgX = -textBBox.width - labelOffset - labelPaddingX * 2 + bgY = -textBBox.height / 2 - labelPaddingY + break } - d3.transition(labelBackground) - .style('fill', '#e25d47') - .attr({ - width: textBBox.width + labelPaddingX * 2, - height: textBBox.height + labelPaddingY * 2, - rx: 2, - ry: 2, - transform: `translate(${bgX},${bgY})` - }) - ; - - d3.transition(labelText) + d3.transition(labelBackground).style('fill', '#e25d47').attr({ + width: textBBox.width + labelPaddingX * 2, + height: textBBox.height + labelPaddingY * 2, + rx: 2, + ry: 2, + transform: `translate(${bgX},${bgY})`, + }) + + d3 + .transition(labelText) .attr('transform', `translate(${textX},${textY})`) - ; - }; -}; + } +} -export default labelMaker; +export default labelMaker diff --git a/src/lib/charts/pie/PieD3Svg.js b/src/lib/charts/pie/PieD3Svg.js index 102f796f9..973ef0823 100644 --- a/src/lib/charts/pie/PieD3Svg.js +++ b/src/lib/charts/pie/PieD3Svg.js @@ -6,48 +6,50 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import d3 from 'd3'; -import { degreesToRadians, midAngle, findNeighbor } from '../../../ArcUtils'; -import { getColorRange } from '../../../ColorUtils'; +import d3 from 'd3' +import { degreesToRadians, midAngle, findNeighbor } from '../../../ArcUtils' +import { getColorRange } from '../../../ColorUtils' const PieD3Svg = domRoot => { - // DOM elements - const element = d3.select(domRoot); - const outline = element.append('path').attr('class', 'nivo_pie_outline'); - const slices = element.append('g').attr('class', 'nivo_pie_slices'); + const element = d3.select(domRoot) + const outline = element.append('path').attr('class', 'nivo_pie_outline') + const slices = element.append('g').attr('class', 'nivo_pie_slices') // d3 generators - const pie = d3.layout.pie(); - const arc = d3.svg.arc(); + const pie = d3.layout.pie() + const arc = d3.svg.arc() // used to store previous state for smart transitions - let previousData = []; + let previousData = [] // an array to store decorator functions - let decorators = []; + let decorators = [] return { draw(props) { const { data, - width, height, + width, + height, sort, - keyProp, valueProp, - startAngle, endAngle, - padAngle, cornerRadius, + keyProp, + valueProp, + startAngle, + endAngle, + padAngle, + cornerRadius, colors, innerRadius, - transitionDuration, transitionEasing - } = props; + transitionDuration, + transitionEasing, + } = props - const identity = d => d.data[keyProp]; - const color = getColorRange(colors); + const identity = d => d.data[keyProp] + const color = getColorRange(colors) - element.attr('transform', `translate(${width / 2}, ${height / 2})`); + element.attr('transform', `translate(${width / 2}, ${height / 2})`) pie .sort(sort) @@ -55,57 +57,63 @@ const PieD3Svg = domRoot => { .startAngle(degreesToRadians(startAngle)) .endAngle(degreesToRadians(endAngle)) .padAngle(degreesToRadians(padAngle)) - ; - let radius = Math.min(width / 2, height / 2); + let radius = Math.min(width / 2, height / 2) arc .outerRadius(radius) .innerRadius(radius * innerRadius) .cornerRadius(cornerRadius) - ; - outline.attr('d', arc({ - startAngle: degreesToRadians(startAngle), - endAngle: degreesToRadians(endAngle) - })); + outline.attr( + 'd', + arc({ + startAngle: degreesToRadians(startAngle), + endAngle: degreesToRadians(endAngle), + }) + ) - let slice = slices.selectAll('.nivo_pie_slice'); + let slice = slices.selectAll('.nivo_pie_slice') - const newData = pie(data.map((d, i) => { - if (!d.color) { - d.color = color(i); - } + const newData = pie( + data.map((d, i) => { + if (!d.color) { + d.color = color(i) + } - return d; - })); + return d + }) + ) //console.log(_.cloneDeep(newData)); function arcTween(a) { - const i = d3.interpolate(this._current, a); - this._current = i(0); + const i = d3.interpolate(this._current, a) + this._current = i(0) - return t => arc(i(t)); + return t => arc(i(t)) } - slice = slice.data(newData, identity); + slice = slice.data(newData, identity) // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // ENTER: creates new elements // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - slice.enter().append('path') + slice + .enter() + .append('path') .attr('class', 'nivo_pie_slice') .style('fill', d => d.data.color) - .each(function (d, i) { - const angle = midAngle(d); - - this._current = findNeighbor(i, identity, previousData, newData) || _.assign({}, d, { - startAngle: 0, - endAngle: 0 - }); + .each(function(d, i) { + const angle = midAngle(d) + + this._current = + findNeighbor(i, identity, previousData, newData) || + _.assign({}, d, { + startAngle: 0, + endAngle: 0, + }) }) - ; // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // UPDATE: updates existing elements @@ -116,42 +124,45 @@ const PieD3Svg = domRoot => { .ease(transitionEasing) .style('fill', d => d.data.color) .attrTween('d', arcTween) - ; // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // EXIT: removes stale elements // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - slice.exit() + slice + .exit() .attr('class', 'nivo_exit') .datum((d, i) => { - return findNeighbor(i, identity, newData, previousData) || d; + return findNeighbor(i, identity, newData, previousData) || d }) .transition() .duration(transitionDuration) .ease(transitionEasing) .attrTween('d', arcTween) .remove() - ; const pieContext = { element, - pie, arc, radius, - identity, previousData, newData, - transitionDuration, transitionEasing - }; + pie, + arc, + radius, + identity, + previousData, + newData, + transitionDuration, + transitionEasing, + } decorators.forEach(legend => { - legend(pieContext); - }); + legend(pieContext) + }) - previousData = newData; + previousData = newData }, decorate(newDecorators = []) { - decorators = newDecorators; - } - }; -}; - + decorators = newDecorators + }, + } +} -export default PieD3Svg; +export default PieD3Svg diff --git a/src/lib/charts/radial-stack/RadialStackD3Svg.js b/src/lib/charts/radial-stack/RadialStackD3Svg.js index c8a5f58c2..19732eaee 100644 --- a/src/lib/charts/radial-stack/RadialStackD3Svg.js +++ b/src/lib/charts/radial-stack/RadialStackD3Svg.js @@ -6,81 +6,85 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import d3 from 'd3'; -import _ from 'lodash'; -import { getColorRange } from '../../../ColorUtils'; +import d3 from 'd3' +import _ from 'lodash' +import { getColorRange } from '../../../ColorUtils' const RadialStackD3Svg = domRoot => { - // DOM elements - const svg = d3.select(domRoot); - const element = svg.append('g'); + const svg = d3.select(domRoot) + const element = svg.append('g') // d3 scales/layouts - const stack = d3.layout.stack(); - const angle = d3.scale.linear(); - const radius = d3.scale.linear(); - const area = d3.svg.area.radial().interpolate('cardinal-closed'); + const stack = d3.layout.stack() + const angle = d3.scale.linear() + const radius = d3.scale.linear() + const area = d3.svg.area.radial().interpolate('cardinal-closed') // an array to store decorator functions - let decorators = []; + let decorators = [] return { draw(props) { const { margin, layers, - offset, innerRadius, + offset, + innerRadius, colors, - transitionDuration, transitionEasing - } = props; + transitionDuration, + transitionEasing, + } = props - const width = props.width - margin.left - margin.right; - const height = props.height - margin.top - margin.bottom; + const width = props.width - margin.left - margin.right + const height = props.height - margin.top - margin.bottom svg.attr({ - width: props.width, - height: props.height - }); + width: props.width, + height: props.height, + }) - element.attr('transform', `translate(${width / 2 + margin.left}, ${height / 2 + margin.top})`); + element.attr( + 'transform', + `translate(${width / 2 + margin.left}, ${height / 2 + + margin.top})` + ) - stack.offset(offset); + stack.offset(offset) - const stacked = stack(layers); + const stacked = stack(layers) - angle - .range([0, 2 * Math.PI]) - .domain([0, stacked[0].length]) - ; + angle.range([0, 2 * Math.PI]).domain([0, stacked[0].length]) - const outerRadius = Math.min(width, height) / 2; + const outerRadius = Math.min(width, height) / 2 radius .range([outerRadius * innerRadius, outerRadius]) - .domain([0, d3.max(stacked, layer => d3.max(layer, d => (d.y0 + d.y)))]) - ; + .domain([ + 0, + d3.max(stacked, layer => d3.max(layer, d => d.y0 + d.y)), + ]) - const color = getColorRange(colors); + const color = getColorRange(colors) area .angle(d => angle(d.x)) .innerRadius(d => radius(d.y0)) .outerRadius(d => radius(d.y0 + d.y)) - ; - let paths = element.selectAll('.nivo_radial-stack_area').data(stacked); + let paths = element + .selectAll('.nivo_radial-stack_area') + .data(stacked) // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // ENTER: creates new elements // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - paths.enter().append('path') + paths + .enter() + .append('path') .attr('class', 'nivo_radial-stack_area') .attr('d', area) .style('fill', (d, i) => color(i)) - ; // ————————————————————————————————————————————————————————————————————————————————————————————————————————— // UPDATE: updates existing elements @@ -91,27 +95,28 @@ const RadialStackD3Svg = domRoot => { .ease(transitionEasing) .attr('d', area) .style('fill', (d, i) => color(i)) - ; const radialStackContext = { element, outerRadius, innerRadius: outerRadius * innerRadius, - layers, stacked, - radius, angle, - transitionDuration, transitionEasing - }; + layers, + stacked, + radius, + angle, + transitionDuration, + transitionEasing, + } decorators.forEach(decorator => { - decorator(radialStackContext); - }); + decorator(radialStackContext) + }) }, decorate(newDecorators = []) { - decorators = newDecorators; - } - }; -}; - + decorators = newDecorators + }, + } +} -export default RadialStackD3Svg; +export default RadialStackD3Svg diff --git a/src/lib/charts/stack/StackD3.js b/src/lib/charts/stack/StackD3.js index 753ae5a8d..cd54eef65 100644 --- a/src/lib/charts/stack/StackD3.js +++ b/src/lib/charts/stack/StackD3.js @@ -6,10 +6,8 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import { flatten } from '../../../DataUtils'; +import { flatten } from '../../../DataUtils' /** * This wrapper is responsible for computing stack chart positions. @@ -19,7 +17,7 @@ import { flatten } from '../../../DataUtils'; * @constructor */ const StackD3 = () => { - const layout = d3.layout.pack(); + const layout = d3.layout.pack() return { /** @@ -34,33 +32,33 @@ const StackD3 = () => { * @returns {array} */ compute({ - width, height, + width, + height, data, - identityProperty, valueAccessor, + identityProperty, + valueAccessor, padding, - color + color, }) { layout .value(valueAccessor) .sort(null) .size([width, height]) .padding(padding) - ; - const flattened = flatten(data, identityProperty); - const nodes = layout.nodes(flattened) + const flattened = flatten(data, identityProperty) + const nodes = layout + .nodes(flattened) .filter(d => !d.children) .map(d => { - d.color = color(d.parentId); + d.color = color(d.parentId) - return d; + return d }) - ; - return nodes; - } + return nodes + }, } -}; - +} -export default StackD3; +export default StackD3 diff --git a/src/lib/charts/treemap/TreeMapD3.js b/src/lib/charts/treemap/TreeMapD3.js index 08a8e5a98..ec8646fd9 100644 --- a/src/lib/charts/treemap/TreeMapD3.js +++ b/src/lib/charts/treemap/TreeMapD3.js @@ -6,7 +6,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; import { treemap as Treemap, @@ -19,13 +18,12 @@ import { treemapResquarify, } from 'd3-hierarchy' - export const tilingMethods = { - binary: treemapBinary, - dice: treemapDice, - slice: treemapSlice, - sliceDice: treemapSliceDice, - squarify: treemapSquarify, + binary: treemapBinary, + dice: treemapDice, + slice: treemapSlice, + sliceDice: treemapSliceDice, + squarify: treemapSquarify, resquarify: treemapResquarify, } @@ -53,12 +51,15 @@ const TreeMapD3 = () => { * @param {function} color */ compute({ - width, height, + width, + height, root: _root, tile, - innerPadding, outerPadding, - identityProperty, valueAccessor, - color + innerPadding, + outerPadding, + identityProperty, + valueAccessor, + color, }) { treemap .size([width, height]) @@ -67,14 +68,11 @@ const TreeMapD3 = () => { .paddingInner(innerPadding) .paddingOuter(outerPadding) - const root = treemap(hierarchy(_root) - .sum(valueAccessor) - ) + const root = treemap(hierarchy(_root).sum(valueAccessor)) - return root.leaves(); - } + return root.leaves() + }, } } - export default TreeMapD3 diff --git a/src/lib/charts/treemap/TreeMapHelper.js b/src/lib/charts/treemap/TreeMapHelper.js index 9bf0192eb..e356d0e9c 100644 --- a/src/lib/charts/treemap/TreeMapHelper.js +++ b/src/lib/charts/treemap/TreeMapHelper.js @@ -6,7 +6,6 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; import { treemap as Treemap, @@ -19,13 +18,12 @@ import { treemapResquarify, } from 'd3-hierarchy' - export const tilingMethods = { - binary: treemapBinary, - dice: treemapDice, - slice: treemapSlice, - sliceDice: treemapSliceDice, - squarify: treemapSquarify, + binary: treemapBinary, + dice: treemapDice, + slice: treemapSlice, + sliceDice: treemapSliceDice, + squarify: treemapSquarify, resquarify: treemapResquarify, } @@ -54,12 +52,15 @@ const TreeMapHelper = () => { * @param {function} color */ compute({ - width, height, + width, + height, root: _root, leavesOnly, tile, - innerPadding, outerPadding, - identity, value, + innerPadding, + outerPadding, + identity, + value, color, }) { treemap @@ -69,16 +70,13 @@ const TreeMapHelper = () => { .paddingInner(innerPadding) .paddingOuter(outerPadding) - const root = treemap(hierarchy(_root) - .sum(value) - ) + const root = treemap(hierarchy(_root).sum(value)) const nodes = leavesOnly ? root.leaves() : root.descendants() - return nodes - .map(d => { - d.color = color(d.depth) - /* + return nodes.map(d => { + d.color = color(d.depth) + /* if (d.depth > 1) { d.color = color(d.parentId) } else { @@ -86,13 +84,12 @@ const TreeMapHelper = () => { } */ - d.data.key = d.ancestors().map(a => identity(a.data)).join('.') + d.data.key = d.ancestors().map(a => identity(a.data)).join('.') - return d - }) - } + return d + }) + }, } } - export default TreeMapHelper diff --git a/src/lib/decoratorsFromReactChildren.js b/src/lib/decoratorsFromReactChildren.js index 1d1ec9dd8..18ed41b2d 100644 --- a/src/lib/decoratorsFromReactChildren.js +++ b/src/lib/decoratorsFromReactChildren.js @@ -6,24 +6,21 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import React from 'react'; +import React from 'react' const decoratorsFromReactChildren = (children, type) => { - const decorators = []; + const decorators = [] React.Children.forEach(children, element => { if (React.isValidElement(element)) { if (element.type[type]) { - decorators.push(element.type[type](element)); + decorators.push(element.type[type](element)) } } - }); - - return decorators; -}; + }) + return decorators +} -export default decoratorsFromReactChildren; +export default decoratorsFromReactChildren diff --git a/src/lib/hasBrowserContext.js b/src/lib/hasBrowserContext.js index eedc54632..41f7708b5 100644 --- a/src/lib/hasBrowserContext.js +++ b/src/lib/hasBrowserContext.js @@ -6,11 +6,11 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; const hasBrowserContext = !!( - (typeof window !== 'undefined' && window.document && window.document.createElement) -); + typeof window !== 'undefined' && + window.document && + window.document.createElement +) - -export default hasBrowserContext; +export default hasBrowserContext diff --git a/src/lib/propertiesConverters.js b/src/lib/propertiesConverters.js index 437676c67..16313dd4b 100644 --- a/src/lib/propertiesConverters.js +++ b/src/lib/propertiesConverters.js @@ -6,13 +6,9 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' import _ from 'lodash' -import { - format, -} from 'd3' - +import { format } from 'd3' export const convertLabel = (_label, labelFormat) => { if (_.isFunction(_label)) { @@ -44,3 +40,6 @@ export const convertGetter = _property => { return d => _.get(d, _property) } + +export const getAccessorFor = directive => + _.isFunction(directive) ? directive : d => d[directive] diff --git a/src/lib/scale.js b/src/lib/scale.js new file mode 100644 index 000000000..d35b57a0e --- /dev/null +++ b/src/lib/scale.js @@ -0,0 +1,83 @@ +import _ from 'lodash' +import PropTypes from 'prop-types' +import { scaleLinear, scaleBand, scalePoint } from 'd3' + +const SCALE_LINEAR = 'linear' +const SCALE_BAND = 'band' +const SCALE_POINT = 'point' + +export const scaleTypes = [SCALE_LINEAR, SCALE_BAND, SCALE_POINT] + +export const scalePropTypes = { + type: PropTypes.oneOf(scaleTypes).isRequired, + axis: PropTypes.oneOf(['x', 'y']).isRequired, + dataKey: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + PropTypes.func, + ]), + aggregate: PropTypes.array, + maxOf: PropTypes.array, + padding: PropTypes.number, +} + +export const scalesPropType = (props, propName, componentName) => { + const scales = props[propName] + + _.forOwn(scales, (scale, id) => { + PropTypes.checkPropTypes( + scalePropTypes, + scale, + `\`${propName}.${id}\``, + componentName + ) + }) +} + +export const createScale = ( + { type, axis, key, aggregate, maxOf, padding }, + data, + width, + height +) => { + let mapper + if (Array.isArray(aggregate)) { + mapper = d => _.sum(aggregate.map(k => d[k])) + } else if (Array.isArray(maxOf)) { + mapper = d => _.max(maxOf.map(k => d[k])) + } else if (_.isFunction(key)) { + mapper = key + } else { + mapper = d => d[key] + } + + const range = [axis === 'y' ? height : 0, axis === 'x' ? width : 0] + + let scale + switch (type) { + case SCALE_LINEAR: + scale = scaleLinear() + .rangeRound(range) + .domain([0, _.max(data.map(mapper))]) + break + + case SCALE_BAND: + scale = scaleBand().rangeRound(range).domain(data.map(mapper)) + + if (padding !== undefined) { + scale.padding(padding) + } + break + + case SCALE_POINT: + scale = scalePoint().range(range).domain(data.map(mapper)) + break + } + + return scale +} + +export const scalesFromObject = (object, width, height, data) => + _.mapValues(object, (scale, id) => + createScale(Object.assign({}, scale, { id }), data, width, height) + ) diff --git a/src/lib/scalePropToD3Scale.js b/src/lib/scalePropToD3Scale.js index de3cc0c39..6e8ecac09 100644 --- a/src/lib/scalePropToD3Scale.js +++ b/src/lib/scalePropToD3Scale.js @@ -6,15 +6,11 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; -import d3 from 'd3'; +import d3 from 'd3' const scalePropToD3Scale = ({ type, domain, range }) => { - return d3.scale[type]() - .domain(domain) - .range(range) - ; -}; + return d3.scale[type]().domain(domain).range(range) +} -export default scalePropToD3Scale; +export default scalePropToD3Scale diff --git a/src/properties/curve.js b/src/properties/curve.js index 5207affc0..ac373d5c5 100644 --- a/src/properties/curve.js +++ b/src/properties/curve.js @@ -6,9 +6,8 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict' -import { PropTypes } from 'react' +import PropTypes from 'prop-types' import { curveBasis, curveBasisClosed, @@ -30,28 +29,27 @@ import { curveStepBefore, } from 'd3' - export const curvePropMapping = { - basis: curveBasis, - basisClosed: curveBasisClosed, - basisOpen: curveBasisOpen, - bundle: curveBundle, - cardinal: curveCardinal, - cardinalClosed: curveCardinalClosed, - cardinalOpen: curveCardinalOpen, - catmullRom: curveCatmullRom, + basis: curveBasis, + basisClosed: curveBasisClosed, + basisOpen: curveBasisOpen, + bundle: curveBundle, + cardinal: curveCardinal, + cardinalClosed: curveCardinalClosed, + cardinalOpen: curveCardinalOpen, + catmullRom: curveCatmullRom, catmullRomClosed: curveCatmullRomClosed, - catmullRomOpen: curveCatmullRomOpen, - linear: curveLinear, - linearClosed: curveLinearClosed, - monotoneX: curveMonotoneX, - monotoneY: curveMonotoneY, - natural: curveNatural, - step: curveStep, - stepAfter: curveStepAfter, - stepBefore: curveStepBefore, + catmullRomOpen: curveCatmullRomOpen, + linear: curveLinear, + linearClosed: curveLinearClosed, + monotoneX: curveMonotoneX, + monotoneY: curveMonotoneY, + natural: curveNatural, + step: curveStep, + stepAfter: curveStepAfter, + stepBefore: curveStepBefore, } export const curvePropKeys = Object.keys(curvePropMapping) -export const curvePropType = PropTypes.oneOf(curvePropKeys) \ No newline at end of file +export const curvePropType = PropTypes.oneOf(curvePropKeys) diff --git a/test/ArcUtil.test.js b/test/ArcUtil.test.js index c37b98974..f95e61a35 100644 --- a/test/ArcUtil.test.js +++ b/test/ArcUtil.test.js @@ -6,14 +6,11 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import test from 'ava'; -import { - midAngle -} from '../src/ArcUtils'; +'use strict' +import test from 'ava' +import { midAngle } from '../src/ArcUtils' test('midAngle() should compute center of given angles', t => { - t.is(midAngle({ startAngle: 0, endAngle: 90 }), 45); -}); + t.is(midAngle({ startAngle: 0, endAngle: 90 }), 45) +}) diff --git a/test/ColorUtils.test.js b/test/ColorUtils.test.js index 13073a317..ce22afd41 100644 --- a/test/ColorUtils.test.js +++ b/test/ColorUtils.test.js @@ -6,60 +6,62 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -'use strict'; - -import test from 'ava'; -import d3 from 'd3'; -import { getColorGenerator } from '../src/ColorUtils'; +'use strict' +import test from 'ava' +import d3 from 'd3' +import { getColorGenerator } from '../src/ColorUtils' test(`getColorGenerator() should return 'none' if 'none' provided`, t => { - t.is(getColorGenerator('none'), 'none'); -}); + t.is(getColorGenerator('none'), 'none') +}) test(`getColorGenerator() should return a function to use 'data.color' if 'inherit' provided`, t => { - const colorGenerator = getColorGenerator('inherit'); - const color = '#FF0000'; + const colorGenerator = getColorGenerator('inherit') + const color = '#FF0000' - t.is(typeof colorGenerator, 'function'); - t.is(colorGenerator({ data: { color }}), color); -}); + t.is(typeof colorGenerator, 'function') + t.is(colorGenerator({ data: { color } }), color) +}) test(`getColorGenerator() should return a function to use darker 'data.color' if 'inherit:darker(*)' provided`, t => { - const colorGenerator = getColorGenerator('inherit:darker(1)'); - const color = '#FF0000'; + const colorGenerator = getColorGenerator('inherit:darker(1)') + const color = '#FF0000' - t.is(typeof colorGenerator, 'function'); - t.deepEqual(colorGenerator({ data: { color }}), d3.rgb(color).darker(1)); -}); + t.is(typeof colorGenerator, 'function') + t.deepEqual(colorGenerator({ data: { color } }), d3.rgb(color).darker(1)) +}) test(`getColorGenerator() 'inherit:darker(*)' should support floats`, t => { - const colorGenerator = getColorGenerator('inherit:darker(.3)'); - const color = '#FF0000'; + const colorGenerator = getColorGenerator('inherit:darker(.3)') + const color = '#FF0000' - t.is(typeof colorGenerator, 'function'); - t.deepEqual(colorGenerator({ data: { color }}), d3.rgb(color).darker(.3)); -}); + t.is(typeof colorGenerator, 'function') + t.deepEqual(colorGenerator({ data: { color } }), d3.rgb(color).darker(0.3)) +}) test(`getColorGenerator() should return a function to use brighter 'data.color' if 'inherit:brighter(*)' provided`, t => { - const colorGenerator = getColorGenerator('inherit:brighter(1)'); - const color = '#FF0000'; + const colorGenerator = getColorGenerator('inherit:brighter(1)') + const color = '#FF0000' - t.is(typeof colorGenerator, 'function'); - t.deepEqual(colorGenerator({ data: { color }}), d3.rgb(color).brighter(1)); -}); + t.is(typeof colorGenerator, 'function') + t.deepEqual(colorGenerator({ data: { color } }), d3.rgb(color).brighter(1)) +}) test(`getColorGenerator() 'inherit:brighter(*)' should support floats`, t => { - const colorGenerator = getColorGenerator('inherit:brighter(.3)'); - const color = '#FF0000'; + const colorGenerator = getColorGenerator('inherit:brighter(.3)') + const color = '#FF0000' - t.is(typeof colorGenerator, 'function'); - t.deepEqual(colorGenerator({ data: { color }}), d3.rgb(color).brighter(.3)); -}); + t.is(typeof colorGenerator, 'function') + t.deepEqual( + colorGenerator({ data: { color } }), + d3.rgb(color).brighter(0.3) + ) +}) test(`getColorGenerator() should return directive if no match found`, t => { - const color = '#F00'; - const colorGenerator = getColorGenerator(color); + const color = '#F00' + const colorGenerator = getColorGenerator(color) - t.is(colorGenerator, color); -}); \ No newline at end of file + t.is(colorGenerator, color) +}) diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..c00304204 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4516 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +Base64@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/Base64/-/Base64-0.2.1.tgz#ba3a4230708e186705065e66babdd4c35cf60028" + +abbrev@1: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + +accepts@1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" + dependencies: + mime-types "~2.1.11" + negotiator "0.6.1" + +acorn-es7-plugin@^1.0.12: + version "1.1.3" + resolved "https://registry.yarnpkg.com/acorn-es7-plugin/-/acorn-es7-plugin-1.1.3.tgz#6a032a71f1faf396a1a29729c7b150fe480cc17a" + +acorn@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.3.tgz#1a3e850b428e73ba6b09d1cc527f5aaad4d03ef1" + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.0.0.tgz#c5061b6e0ef8a81775e50f5d66151bf6bf371107" + +ansi-styles@^2.1.0, ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + +anymatch@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" + dependencies: + arrify "^1.0.0" + micromatch "^2.1.5" + +aproba@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0" + +are-we-there-yet@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.0 || ^1.1.13" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-exclude@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/arr-exclude/-/arr-exclude-1.0.0.tgz#dfc7c2e552a270723ccda04cf3128c8cbfe5c631" + +arr-flatten@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + +array-slice@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.0, array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arraybuffer.slice@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asap@~2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + dependencies: + util "0.10.3" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async@^0.9.0, async@~0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + +async@^1.3.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@~0.2.6: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +ava-init@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ava-init/-/ava-init-0.1.6.tgz#ef19ed0b24b6bf359dad6fbadf1a05d836395c91" + dependencies: + arr-exclude "^1.0.0" + cross-spawn "^4.0.0" + pinkie-promise "^2.0.0" + read-pkg-up "^1.0.1" + the-argv "^1.0.0" + write-pkg "^1.0.0" + +ava@0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/ava/-/ava-0.14.0.tgz#fbe6001e79a101757141b6948795d64a6935d362" + dependencies: + arr-diff "^2.0.0" + arr-flatten "^1.0.1" + array-union "^1.0.1" + array-uniq "^1.0.2" + arrify "^1.0.0" + ava-init "^0.1.0" + babel-core "^6.3.21" + babel-plugin-detective "^1.0.2" + babel-plugin-espower "^2.1.0" + babel-plugin-transform-runtime "^6.3.13" + babel-preset-es2015 "^6.3.13" + babel-preset-stage-2 "^6.3.13" + babel-runtime "^6.3.19" + bluebird "^3.0.0" + caching-transform "^1.0.0" + chalk "^1.0.0" + clean-yaml-object "^0.1.0" + cli-cursor "^1.0.2" + cli-spinners "^0.1.2" + cli-truncate "^0.2.0" + co-with-promise "^4.6.0" + common-path-prefix "^1.0.0" + convert-source-map "^1.2.0" + core-assert "^0.1.0" + debug "^2.2.0" + empower-core "^0.5.0" + figures "^1.4.0" + find-cache-dir "^0.1.1" + fn-name "^2.0.0" + globby "^4.0.0" + ignore-by-default "^1.0.0" + is-ci "^1.0.7" + is-generator-fn "^1.0.0" + is-obj "^1.0.0" + is-observable "^0.1.0" + is-promise "^2.1.0" + last-line-stream "^1.0.0" + lodash.debounce "^4.0.3" + loud-rejection "^1.2.0" + matcher "^0.1.1" + max-timeout "^1.0.0" + md5-hex "^1.2.0" + meow "^3.7.0" + ms "^0.7.1" + multimatch "^2.1.0" + object-assign "^4.0.1" + observable-to-promise "^0.3.0" + only-shallow "^1.2.0" + option-chain "^0.1.0" + pkg-conf "^1.0.1" + plur "^2.0.0" + power-assert-formatter "^1.3.0" + power-assert-renderers "^0.1.0" + pretty-ms "^2.0.0" + require-precompiled "^0.1.0" + resolve-cwd "^1.0.0" + set-immediate-shim "^1.0.1" + slash "^1.0.0" + source-map-support "^0.4.0" + stack-utils "^0.4.0" + strip-bom "^2.0.0" + time-require "^0.1.2" + unique-temp-dir "^1.0.0" + update-notifier "^0.6.0" + optionalDependencies: + chokidar "^1.4.2" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755" + +babel-cli@6.7.5: + version "6.7.5" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.7.5.tgz#59bb14be719f8b1d6343ddf569e72a0e5890178e" + dependencies: + babel-core "^6.7.5" + babel-polyfill "^6.6.0" + babel-register "^6.6.5" + babel-runtime "^5.0.0" + bin-version-check "^2.1.0" + chalk "1.1.1" + commander "^2.8.1" + convert-source-map "^1.1.0" + fs-readdir-recursive "^0.1.0" + glob "^5.0.5" + lodash "^3.2.0" + log-symbols "^1.0.2" + output-file-sync "^1.1.0" + path-exists "^1.0.0" + path-is-absolute "^1.0.0" + request "^2.65.0" + slash "^1.0.0" + source-map "^0.5.0" + v8flags "^2.0.10" + optionalDependencies: + chokidar "^1.0.0" + +babel-code-frame@^6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.20.0.tgz#b968f839090f9a8bc6d41938fb96cb84f7387b26" + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^2.0.0" + +babel-core@^6.18.0, babel-core@^6.3.21, babel-core@^6.7.5: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.20.0.tgz#ab0d7176d9dea434e66badadaf92237865eab1ec" + dependencies: + babel-code-frame "^6.20.0" + babel-generator "^6.20.0" + babel-helpers "^6.16.0" + babel-messages "^6.8.0" + babel-register "^6.18.0" + babel-runtime "^6.20.0" + babel-template "^6.16.0" + babel-traverse "^6.20.0" + babel-types "^6.20.0" + babylon "^6.11.0" + convert-source-map "^1.1.0" + debug "^2.1.1" + json5 "^0.5.0" + lodash "^4.2.0" + minimatch "^3.0.2" + path-is-absolute "^1.0.0" + private "^0.1.6" + slash "^1.0.0" + source-map "^0.5.0" + +babel-generator@^6.1.0, babel-generator@^6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.20.0.tgz#fee63614e0449390103b3097f3f6a118016c6766" + dependencies: + babel-messages "^6.8.0" + babel-runtime "^6.20.0" + babel-types "^6.20.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.2.0" + source-map "^0.5.0" + +babel-helper-bindify-decorators@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.18.0.tgz#fc00c573676a6e702fffa00019580892ec8780a5" + dependencies: + babel-runtime "^6.0.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + +babel-helper-builder-binary-assignment-operator-visitor@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.18.0.tgz#8ae814989f7a53682152e3401a04fabd0bb333a6" + dependencies: + babel-helper-explode-assignable-expression "^6.18.0" + babel-runtime "^6.0.0" + babel-types "^6.18.0" + +babel-helper-builder-react-jsx@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.18.0.tgz#ab02f19a2eb7ace936dd87fa55896d02be59bf71" + dependencies: + babel-runtime "^6.9.0" + babel-types "^6.18.0" + esutils "^2.0.0" + lodash "^4.2.0" + +babel-helper-call-delegate@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.18.0.tgz#05b14aafa430884b034097ef29e9f067ea4133bd" + dependencies: + babel-helper-hoist-variables "^6.18.0" + babel-runtime "^6.0.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + +babel-helper-define-map@^6.18.0, babel-helper-define-map@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.18.0.tgz#8d6c85dc7fbb4c19be3de40474d18e97c3676ec2" + dependencies: + babel-helper-function-name "^6.18.0" + babel-runtime "^6.9.0" + babel-types "^6.18.0" + lodash "^4.2.0" + +babel-helper-explode-assignable-expression@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.18.0.tgz#14b8e8c2d03ad735d4b20f1840b24cd1f65239fe" + dependencies: + babel-runtime "^6.0.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + +babel-helper-explode-class@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.18.0.tgz#c44f76f4fa23b9c5d607cbac5d4115e7a76f62cb" + dependencies: + babel-helper-bindify-decorators "^6.18.0" + babel-runtime "^6.0.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + +babel-helper-function-name@^6.18.0, babel-helper-function-name@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.18.0.tgz#68ec71aeba1f3e28b2a6f0730190b754a9bf30e6" + dependencies: + babel-helper-get-function-arity "^6.18.0" + babel-runtime "^6.0.0" + babel-template "^6.8.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + +babel-helper-get-function-arity@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.18.0.tgz#a5b19695fd3f9cdfc328398b47dafcd7094f9f24" + dependencies: + babel-runtime "^6.0.0" + babel-types "^6.18.0" + +babel-helper-hoist-variables@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.18.0.tgz#a835b5ab8b46d6de9babefae4d98ea41e866b82a" + dependencies: + babel-runtime "^6.0.0" + babel-types "^6.18.0" + +babel-helper-optimise-call-expression@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.18.0.tgz#9261d0299ee1a4f08a6dd28b7b7c777348fd8f0f" + dependencies: + babel-runtime "^6.0.0" + babel-types "^6.18.0" + +babel-helper-regex@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.18.0.tgz#ae0ebfd77de86cb2f1af258e2cc20b5fe893ecc6" + dependencies: + babel-runtime "^6.9.0" + babel-types "^6.18.0" + lodash "^4.2.0" + +babel-helper-remap-async-to-generator@^6.16.0, babel-helper-remap-async-to-generator@^6.16.2: + version "6.20.3" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.20.3.tgz#9dd3b396f13e35ef63e538098500adc24c63c4e7" + dependencies: + babel-helper-function-name "^6.18.0" + babel-runtime "^6.20.0" + babel-template "^6.16.0" + babel-traverse "^6.20.0" + babel-types "^6.20.0" + +babel-helper-replace-supers@^6.18.0, babel-helper-replace-supers@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.18.0.tgz#28ec69877be4144dbd64f4cc3a337e89f29a924e" + dependencies: + babel-helper-optimise-call-expression "^6.18.0" + babel-messages "^6.8.0" + babel-runtime "^6.0.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + +babel-helpers@^6.16.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.16.0.tgz#1095ec10d99279460553e67eb3eee9973d3867e3" + dependencies: + babel-runtime "^6.0.0" + babel-template "^6.16.0" + +babel-loader@6.2.4: + version "6.2.4" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.2.4.tgz#aa70aff8ddc223a5952e839a43a6c3a4c8bfa1e9" + dependencies: + loader-utils "^0.2.11" + mkdirp "^0.5.1" + object-assign "^4.0.1" + +babel-messages@^6.8.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.8.0.tgz#bf504736ca967e6d65ef0adb5a2a5f947c8e0eb9" + dependencies: + babel-runtime "^6.0.0" + +babel-plugin-check-es2015-constants@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.8.0.tgz#dbf024c32ed37bfda8dee1e76da02386a8d26fe7" + dependencies: + babel-runtime "^6.0.0" + +babel-plugin-detective@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-detective/-/babel-plugin-detective-1.0.2.tgz#b55469c7c792dc4ee89c6f7daa31faedfa16232d" + +babel-plugin-espower@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-espower/-/babel-plugin-espower-2.3.1.tgz#d15e904bc9949b14ac233b7965c2a5dc7a19a6a9" + dependencies: + babel-generator "^6.1.0" + babylon "^6.1.0" + call-matcher "^1.0.0" + core-js "^2.0.0" + espower-location-detector "^0.1.1" + espurify "^1.6.0" + estraverse "^4.1.1" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-async-generators@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + +babel-plugin-syntax-class-constructor-call@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416" + +babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + +babel-plugin-syntax-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + +babel-plugin-syntax-do-expressions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz#5747756139aa26d390d09410b03744ba07e4796d" + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-export-extensions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" + +babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.3.13: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + +babel-plugin-syntax-function-bind@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz#48c495f177bdf31a981e732f55adc0bdd2601f46" + +babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-syntax-trailing-function-commas@^6.3.13: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.20.0.tgz#442835e19179f45b87e92d477d70b9f1f18b5c4f" + +babel-plugin-transform-async-generator-functions@^6.17.0: + version "6.17.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.17.0.tgz#d0b5a2b2f0940f2b245fa20a00519ed7bc6cae54" + dependencies: + babel-helper-remap-async-to-generator "^6.16.2" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-async-to-generator@^6.16.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.16.0.tgz#19ec36cb1486b59f9f468adfa42ce13908ca2999" + dependencies: + babel-helper-remap-async-to-generator "^6.16.0" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-class-constructor-call@^6.3.13: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.18.0.tgz#80855e38a1ab47b8c6c647f8ea1bcd2c00ca3aae" + dependencies: + babel-plugin-syntax-class-constructor-call "^6.18.0" + babel-runtime "^6.0.0" + babel-template "^6.8.0" + +babel-plugin-transform-class-properties@^6.18.0: + version "6.19.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.19.0.tgz#1274b349abaadc835164e2004f4a2444a2788d5f" + dependencies: + babel-helper-function-name "^6.18.0" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.9.1" + babel-template "^6.15.0" + +babel-plugin-transform-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.13.0.tgz#82d65c1470ae83e2d13eebecb0a1c2476d62da9d" + dependencies: + babel-helper-define-map "^6.8.0" + babel-helper-explode-class "^6.8.0" + babel-plugin-syntax-decorators "^6.13.0" + babel-runtime "^6.0.0" + babel-template "^6.8.0" + babel-types "^6.13.0" + +babel-plugin-transform-do-expressions@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.8.0.tgz#fda692af339835cc255bb7544efb8f7c1306c273" + dependencies: + babel-plugin-syntax-do-expressions "^6.8.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-es2015-arrow-functions@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.8.0.tgz#5b63afc3181bdc9a8c4d481b5a4f3f7d7fef3d9d" + dependencies: + babel-runtime "^6.0.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.8.0.tgz#ed95d629c4b5a71ae29682b998f70d9833eb366d" + dependencies: + babel-runtime "^6.0.0" + +babel-plugin-transform-es2015-block-scoping@^6.6.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.20.0.tgz#5d8f3e83b1a1ae1064e64a9e5bb83108d8e73be3" + dependencies: + babel-runtime "^6.20.0" + babel-template "^6.15.0" + babel-traverse "^6.20.0" + babel-types "^6.20.0" + lodash "^4.2.0" + +babel-plugin-transform-es2015-classes@^6.6.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.18.0.tgz#ffe7a17321bf83e494dcda0ae3fc72df48ffd1d9" + dependencies: + babel-helper-define-map "^6.18.0" + babel-helper-function-name "^6.18.0" + babel-helper-optimise-call-expression "^6.18.0" + babel-helper-replace-supers "^6.18.0" + babel-messages "^6.8.0" + babel-runtime "^6.9.0" + babel-template "^6.14.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + +babel-plugin-transform-es2015-computed-properties@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.8.0.tgz#f51010fd61b3bd7b6b60a5fdfd307bb7a5279870" + dependencies: + babel-helper-define-map "^6.8.0" + babel-runtime "^6.0.0" + babel-template "^6.8.0" + +babel-plugin-transform-es2015-destructuring@^6.6.0: + version "6.19.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.19.0.tgz#ff1d911c4b3f4cab621bd66702a869acd1900533" + dependencies: + babel-runtime "^6.9.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.6.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.8.0.tgz#fd8f7f7171fc108cc1c70c3164b9f15a81c25f7d" + dependencies: + babel-runtime "^6.0.0" + babel-types "^6.8.0" + +babel-plugin-transform-es2015-for-of@^6.6.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.18.0.tgz#4c517504db64bf8cfc119a6b8f177211f2028a70" + dependencies: + babel-runtime "^6.0.0" + +babel-plugin-transform-es2015-function-name@^6.3.13: + version "6.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.9.0.tgz#8c135b17dbd064e5bba56ec511baaee2fca82719" + dependencies: + babel-helper-function-name "^6.8.0" + babel-runtime "^6.9.0" + babel-types "^6.9.0" + +babel-plugin-transform-es2015-literals@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.8.0.tgz#50aa2e5c7958fc2ab25d74ec117e0cc98f046468" + dependencies: + babel-runtime "^6.0.0" + +babel-plugin-transform-es2015-modules-commonjs@^6.6.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.18.0.tgz#c15ae5bb11b32a0abdcc98a5837baa4ee8d67bcc" + dependencies: + babel-plugin-transform-strict-mode "^6.18.0" + babel-runtime "^6.0.0" + babel-template "^6.16.0" + babel-types "^6.18.0" + +babel-plugin-transform-es2015-object-super@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.8.0.tgz#1b858740a5a4400887c23dcff6f4d56eea4a24c5" + dependencies: + babel-helper-replace-supers "^6.8.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-es2015-parameters@^6.6.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.18.0.tgz#9b2cfe238c549f1635ba27fc1daa858be70608b1" + dependencies: + babel-helper-call-delegate "^6.18.0" + babel-helper-get-function-arity "^6.18.0" + babel-runtime "^6.9.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + +babel-plugin-transform-es2015-shorthand-properties@^6.3.13: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.18.0.tgz#e2ede3b7df47bf980151926534d1dd0cbea58f43" + dependencies: + babel-runtime "^6.0.0" + babel-types "^6.18.0" + +babel-plugin-transform-es2015-spread@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.8.0.tgz#0217f737e3b821fa5a669f187c6ed59205f05e9c" + dependencies: + babel-runtime "^6.0.0" + +babel-plugin-transform-es2015-sticky-regex@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.8.0.tgz#e73d300a440a35d5c64f5c2a344dc236e3df47be" + dependencies: + babel-helper-regex "^6.8.0" + babel-runtime "^6.0.0" + babel-types "^6.8.0" + +babel-plugin-transform-es2015-template-literals@^6.6.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.8.0.tgz#86eb876d0a2c635da4ec048b4f7de9dfc897e66b" + dependencies: + babel-runtime "^6.0.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.6.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.18.0.tgz#0b14c48629c90ff47a0650077f6aa699bee35798" + dependencies: + babel-runtime "^6.0.0" + +babel-plugin-transform-es2015-unicode-regex@^6.3.13: + version "6.11.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.11.0.tgz#6298ceabaad88d50a3f4f392d8de997260f6ef2c" + dependencies: + babel-helper-regex "^6.8.0" + babel-runtime "^6.0.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.8.0.tgz#db25742e9339eade676ca9acec46f955599a68a4" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.8.0" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-export-extensions@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.8.0.tgz#fa80ff655b636549431bfd38f6b817bd82e47f5b" + dependencies: + babel-plugin-syntax-export-extensions "^6.8.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-flow-strip-types@^6.3.13: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.18.0.tgz#4d3e642158661e9b40db457c004a30817fa32592" + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-function-bind@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.8.0.tgz#e7f334ce69f50d28fe850a822eaaab9fa4f4d821" + dependencies: + babel-plugin-syntax-function-bind "^6.8.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-object-rest-spread@^6.16.0: + version "6.20.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.20.2.tgz#e816c55bba77b14c16365d87e2ae48c8fd18fc2e" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.20.0" + +babel-plugin-transform-react-display-name@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.8.0.tgz#f7a084977383d728bdbdc2835bba0159577f660e" + dependencies: + babel-runtime "^6.0.0" + +babel-plugin-transform-react-jsx-source@^6.3.13: + version "6.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.9.0.tgz#af684a05c2067a86e0957d4f343295ccf5dccf00" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.9.0" + +babel-plugin-transform-react-jsx@^6.3.13: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.8.0.tgz#94759942f70af18c617189aa7f3593f1644a71ab" + dependencies: + babel-helper-builder-react-jsx "^6.8.0" + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.0.0" + +babel-plugin-transform-regenerator@^6.6.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.20.0.tgz#a546cd2aa1c9889929d5c427a31303847847ab75" + dependencies: + regenerator-transform "0.9.8" + +babel-plugin-transform-runtime@^6.3.13: + version "6.15.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.15.0.tgz#3d75b4d949ad81af157570273846fb59aeb0d57c" + dependencies: + babel-runtime "^6.9.0" + +babel-plugin-transform-strict-mode@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.18.0.tgz#df7cf2991fe046f44163dcd110d5ca43bc652b9d" + dependencies: + babel-runtime "^6.0.0" + babel-types "^6.18.0" + +babel-polyfill@^6.6.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.20.0.tgz#de4a371006139e20990aac0be367d398331204e7" + dependencies: + babel-runtime "^6.20.0" + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-preset-es2015@6.6.0, babel-preset-es2015@^6.3.13: + version "6.6.0" + resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.6.0.tgz#88b33e58fec94c6ebde58dc65ece5d14e0ec2568" + dependencies: + babel-plugin-check-es2015-constants "^6.3.13" + babel-plugin-transform-es2015-arrow-functions "^6.3.13" + babel-plugin-transform-es2015-block-scoped-functions "^6.3.13" + babel-plugin-transform-es2015-block-scoping "^6.6.0" + babel-plugin-transform-es2015-classes "^6.6.0" + babel-plugin-transform-es2015-computed-properties "^6.3.13" + babel-plugin-transform-es2015-destructuring "^6.6.0" + babel-plugin-transform-es2015-duplicate-keys "^6.6.0" + babel-plugin-transform-es2015-for-of "^6.6.0" + babel-plugin-transform-es2015-function-name "^6.3.13" + babel-plugin-transform-es2015-literals "^6.3.13" + babel-plugin-transform-es2015-modules-commonjs "^6.6.0" + babel-plugin-transform-es2015-object-super "^6.3.13" + babel-plugin-transform-es2015-parameters "^6.6.0" + babel-plugin-transform-es2015-shorthand-properties "^6.3.13" + babel-plugin-transform-es2015-spread "^6.3.13" + babel-plugin-transform-es2015-sticky-regex "^6.3.13" + babel-plugin-transform-es2015-template-literals "^6.6.0" + babel-plugin-transform-es2015-typeof-symbol "^6.6.0" + babel-plugin-transform-es2015-unicode-regex "^6.3.13" + babel-plugin-transform-regenerator "^6.6.0" + +babel-preset-react@6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.5.0.tgz#d3289aa0e308dbd48b7210f9977101f0f96ebe1f" + dependencies: + babel-plugin-syntax-flow "^6.3.13" + babel-plugin-syntax-jsx "^6.3.13" + babel-plugin-transform-flow-strip-types "^6.3.13" + babel-plugin-transform-react-display-name "^6.3.13" + babel-plugin-transform-react-jsx "^6.3.13" + babel-plugin-transform-react-jsx-source "^6.3.13" + +babel-preset-stage-0@6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/babel-preset-stage-0/-/babel-preset-stage-0-6.5.0.tgz#8b8479b2077482b8f3dc8f8f5f0c9c79788cde22" + dependencies: + babel-plugin-transform-do-expressions "^6.3.13" + babel-plugin-transform-function-bind "^6.3.13" + babel-preset-stage-1 "^6.3.13" + +babel-preset-stage-1@^6.3.13: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.16.0.tgz#9d31fbbdae7b17c549fd3ac93e3cf6902695e479" + dependencies: + babel-plugin-transform-class-constructor-call "^6.3.13" + babel-plugin-transform-export-extensions "^6.3.13" + babel-preset-stage-2 "^6.16.0" + +babel-preset-stage-2@^6.16.0, babel-preset-stage-2@^6.3.13: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.18.0.tgz#9eb7bf9a8e91c68260d5ba7500493caaada4b5b5" + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-transform-class-properties "^6.18.0" + babel-plugin-transform-decorators "^6.13.0" + babel-preset-stage-3 "^6.17.0" + +babel-preset-stage-3@^6.17.0: + version "6.17.0" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.17.0.tgz#b6638e46db6e91e3f889013d8ce143917c685e39" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.3.13" + babel-plugin-transform-async-generator-functions "^6.17.0" + babel-plugin-transform-async-to-generator "^6.16.0" + babel-plugin-transform-exponentiation-operator "^6.3.13" + babel-plugin-transform-object-rest-spread "^6.16.0" + +babel-register@^6.18.0, babel-register@^6.6.5: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.18.0.tgz#892e2e03865078dd90ad2c715111ec4449b32a68" + dependencies: + babel-core "^6.18.0" + babel-runtime "^6.11.6" + core-js "^2.4.0" + home-or-tmp "^2.0.0" + lodash "^4.2.0" + mkdirp "^0.5.1" + source-map-support "^0.4.2" + +babel-runtime@^5.0.0: + version "5.8.38" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-5.8.38.tgz#1c0b02eb63312f5f087ff20450827b425c9d4c19" + dependencies: + core-js "^1.0.0" + +babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.20.0, babel-runtime@^6.3.19, babel-runtime@^6.9.0, babel-runtime@^6.9.1: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.20.0.tgz#87300bdcf4cd770f09bf0048c64204e17806d16f" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-template@^6.14.0, babel-template@^6.15.0, babel-template@^6.16.0, babel-template@^6.8.0: + version "6.16.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.16.0.tgz#e149dd1a9f03a35f817ddbc4d0481988e7ebc8ca" + dependencies: + babel-runtime "^6.9.0" + babel-traverse "^6.16.0" + babel-types "^6.16.0" + babylon "^6.11.0" + lodash "^4.2.0" + +babel-traverse@^6.16.0, babel-traverse@^6.18.0, babel-traverse@^6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.20.0.tgz#5378d1a743e3d856e6a52289994100bbdfd9872a" + dependencies: + babel-code-frame "^6.20.0" + babel-messages "^6.8.0" + babel-runtime "^6.20.0" + babel-types "^6.20.0" + babylon "^6.11.0" + debug "^2.2.0" + globals "^9.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +babel-types@^6.13.0, babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.20.0, babel-types@^6.8.0, babel-types@^6.9.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.20.0.tgz#3869ecb98459533b37df809886b3f7f3b08d2baa" + dependencies: + babel-runtime "^6.20.0" + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^1.0.1" + +babylon@^6.1.0, babylon@^6.11.0: + version "6.14.1" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.14.1.tgz#956275fab72753ad9b3435d7afe58f8bf0a29815" + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + +balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + +base64-js@^1.0.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" + +base64id@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6" + +batch@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.5.3.tgz#3f3414f380321743bfc1042f9a83ff1d5824d464" + +bcrypt-pbkdf@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz#3ca76b85241c7170bf7d9703e7b9aa74630040d4" + dependencies: + tweetnacl "^0.14.3" + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + dependencies: + callsite "1.0.0" + +big.js@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978" + +bin-version-check@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-2.1.0.tgz#e4e5df290b9069f7d111324031efc13fdd11a5b0" + dependencies: + bin-version "^1.0.0" + minimist "^1.1.0" + semver "^4.0.3" + semver-truncate "^1.0.0" + +bin-version@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-1.0.4.tgz#9eb498ee6fd76f7ab9a7c160436f89579435d78e" + dependencies: + find-versions "^1.0.0" + +binary-extensions@^1.0.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" + +blob@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^2.9.27: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" + +bluebird@^3.0.0: + version "3.4.6" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" + +body-parser@^1.12.4: + version "1.15.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.15.2.tgz#d7578cf4f1d11d5f6ea804cef35dc7a7ff6dae67" + dependencies: + bytes "2.4.0" + content-type "~1.0.2" + debug "~2.2.0" + depd "~1.1.0" + http-errors "~1.5.0" + iconv-lite "0.4.13" + on-finished "~2.3.0" + qs "6.2.0" + raw-body "~2.1.7" + type-is "~1.6.13" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +boxen@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-0.3.1.tgz#a7d898243ae622f7abb6bb604d740a76c6a5461b" + dependencies: + chalk "^1.1.1" + filled-array "^1.0.0" + object-assign "^4.0.1" + repeating "^2.0.0" + string-width "^1.0.1" + widest-line "^1.0.0" + +brace-expansion@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +braces@^0.1.2: + version "0.1.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-0.1.5.tgz#c085711085291d8b75fdd74eab0f8597280711e6" + dependencies: + expand-range "^0.1.0" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +browserify-zlib@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" + dependencies: + pako "~0.2.0" + +buf-compare@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +buffer@^4.9.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +bytes@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" + +caching-transform@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" + dependencies: + md5-hex "^1.2.0" + mkdirp "^0.5.1" + write-file-atomic "^1.1.4" + +call-matcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.0.0.tgz#eafa31036dbfaa9c0d1716f12ddacfd9c69ef22f" + dependencies: + core-js "^2.0.0" + deep-equal "^1.0.0" + espurify "^1.6.0" + estraverse "^4.0.0" + +call-signature@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +capture-stack-trace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.1.tgz#509afb67066e7499f7eb3535c77445772ae2d019" + dependencies: + ansi-styles "^2.1.0" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + +chokidar@^1.0.0, chokidar@^1.4.1, chokidar@^1.4.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +ci-info@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534" + +clean-yaml-object@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz#63fb110dc2ce1a84dc21f6d9334876d010ae8b68" + +cli-cursor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-spinners@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" + +cli-truncate@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +clone@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" + +co-with-promise@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co-with-promise/-/co-with-promise-4.6.0.tgz#413e7db6f5893a60b942cf492c4bec93db415ab7" + dependencies: + pinkie-promise "^1.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +colors@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + +commander@2, commander@^2.8.1, commander@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +commander@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" + +common-path-prefix@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-1.0.0.tgz#cd52f6f0712e0baab97d6f9732874f22f47752c0" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + +component-emitter@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3" + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +configstore@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1" + dependencies: + dot-prop "^3.0.0" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + object-assign "^4.0.1" + os-tmpdir "^1.0.0" + osenv "^0.1.0" + uuid "^2.0.1" + write-file-atomic "^1.1.2" + xdg-basedir "^2.0.0" + +connect@^3.3.5: + version "3.5.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.5.0.tgz#b357525a0b4c1f50599cd983e1d9efeea9677198" + dependencies: + debug "~2.2.0" + finalhandler "0.5.0" + parseurl "~1.3.1" + utils-merge "1.0.0" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +constants-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-0.0.1.tgz#92577db527ba6c4cf0a4568d84bc031f441e21f2" + +content-type@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" + +convert-source-map@^1.1.0, convert-source-map@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.3.0.tgz#e9f3e9c6e2728efc2676696a70eb382f73106a67" + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + +core-assert@^0.1.0: + version "0.1.3" + resolved "https://registry.yarnpkg.com/core-assert/-/core-assert-0.1.3.tgz#a339cadfe1898a2299cf7ee0df5c14993a32b3d1" + dependencies: + buf-compare "^1.0.0" + +core-js@^1.0.0, core-js@^1.2.6: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +core-js@^2.0.0, core-js@^2.1.0, core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +create-error-class@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + +cross-env@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.0.1.tgz#ff4e72ea43b47da2486b43a7f2043b2609e44913" + dependencies: + cross-spawn "^5.1.0" + is-windows "^1.0.0" + +cross-spawn@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +crypto-browserify@~3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.2.8.tgz#b9b11dbe6d9651dd882a01e6cc467df718ecf189" + dependencies: + pbkdf2-compat "2.0.1" + ripemd160 "0.2.0" + sha.js "2.2.6" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + +d3-array@1, d3-array@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.0.1.tgz#375c02874fcd96c16ed9f1bcf5b4a7be53f358e7" + +d3-axis@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.3.tgz#ddcbd8a23c2a568d3787de0dee00a36413c5d595" + +d3-brush@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-brush/-/d3-brush-1.0.3.tgz#4fa5374cc3b755d0990bf76b71b7a66417751c74" + dependencies: + d3-dispatch "1" + d3-drag "1" + d3-interpolate "1" + d3-selection "1" + d3-transition "1" + +d3-chord@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d3-chord/-/d3-chord-1.0.2.tgz#9b1ac90efe7de448c0b9188309071de52855a99a" + dependencies: + d3-array "1" + d3-path "1" + +d3-collection@1, d3-collection@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.1.tgz#5b5c5626f731122b600b107d71a08833fec049ad" + +d3-color@1, d3-color@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.0.1.tgz#73cc91f4ee3f12e00ca06b1596a7c83cf104723a" + +d3-dispatch@1, d3-dispatch@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.1.tgz#4bd65a43cecff4318deb9df24552aa8bf281a840" + +d3-drag@1, d3-drag@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-1.0.1.tgz#49ad9f5c91865593fb30c86b15f9322d43fec51f" + dependencies: + d3-dispatch "1" + d3-selection "1" + +d3-dsv@1, d3-dsv@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.0.3.tgz#049fe43c0f5f60c7ff7d376616bc76d6fc9d378f" + dependencies: + commander "2" + iconv-lite "0.4" + rw "1" + +d3-ease@1, d3-ease@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.1.tgz#a18c2d44e218fb8b9ec6d635bcca587f85979a85" + +d3-force@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.0.2.tgz#92dbedeacf9a2d3f6686450c8d6375f3c363af66" + dependencies: + d3-collection "1" + d3-dispatch "1" + d3-quadtree "1" + d3-timer "1" + +d3-format@1, d3-format@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.0.2.tgz#138618320b4bbeb43b5c0ff30519079fbbd7375e" + +d3-geo@1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.2.5.tgz#21f3d15c027e621a6fb505b1d40eee7fc13b8881" + dependencies: + d3-array "1" + +d3-hierarchy@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.0.2.tgz#c8faa11dc49bcc93914c6aa35a46bdee4e01ee72" + +d3-interpolate@1, d3-interpolate@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.1.tgz#f9ad4f9a421b22cad8838cf53d9bd2cbad0b8fd7" + dependencies: + d3-color "1" + +d3-path@1, d3-path@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.2.tgz#9941a472daed62084e5ecf4394987bcadc8c39a7" + +d3-polygon@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d3-polygon/-/d3-polygon-1.0.1.tgz#c1e710cc715b082f18494d102e41bdaaf8c44d03" + +d3-quadtree@1, d3-quadtree@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.1.tgz#13be025624f110405ed43536c506aaec199ed591" + +d3-queue@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/d3-queue/-/d3-queue-3.0.3.tgz#10ee4dd0574a1affaabfb931d0ba4f117926edc6" + +d3-random@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d3-random/-/d3-random-1.0.1.tgz#2c9444cdcba23f8c41f7940d46bf301bf99603eb" + +d3-request@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d3-request/-/d3-request-1.0.2.tgz#98083736d4146fdd28703b5aa8ef7e7328ba3f69" + dependencies: + d3-collection "1" + d3-dispatch "1" + d3-dsv "1" + xmlhttprequest "1" + +d3-scale-chromatic@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.0.2.tgz#19dc284f47415f5d52f4b6a818685fa8e7cff651" + dependencies: + d3-interpolate "1" + +d3-scale@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-1.0.3.tgz#4f9e8f0cc2ea0f3925ff04ac27adc09045fa4c90" + dependencies: + d3-array "1" + d3-collection "1" + d3-color "1" + d3-format "1" + d3-interpolate "1" + d3-time "1" + d3-time-format "2" + +d3-selection@1, d3-selection@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.0.2.tgz#ae662afd4702ac9c5da039b2107a1764fa1c9070" + +d3-shape@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.0.3.tgz#bf685dcfc192ed1d35a39ff69826a409a9385034" + dependencies: + d3-path "1" + +d3-time-format@2, d3-time-format@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.0.2.tgz#1c537e9d4558966a658c51f4ca3dd1b47369c2d5" + dependencies: + d3-time "1" + +d3-time@1, d3-time@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.4.tgz#2ceba09a76b7450c992a1ded4e10fc6195e69649" + +d3-timer@1, d3-timer@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.3.tgz#7a308a10c8524778e6b32d1d6c1c329209ae0ebf" + +d3-transition@1, d3-transition@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.0.2.tgz#987b4e350099ae2f1783fe259a94b45db7209963" + dependencies: + d3-color "1" + d3-dispatch "1" + d3-ease "1" + d3-interpolate "1" + d3-selection "1" + d3-timer "1" + +d3-voronoi@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.0.2.tgz#09b1a3a7891c4ed8376d9ffdb2e770430f3f55c3" + +d3-zoom@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-1.0.3.tgz#b36bfb517e535dff0e179088dbeb3d7899a6050e" + dependencies: + d3-dispatch "1" + d3-drag "1" + d3-interpolate "1" + d3-selection "1" + d3-transition "1" + +d3@4.2.6: + version "4.2.6" + resolved "https://registry.yarnpkg.com/d3/-/d3-4.2.6.tgz#f4ce9fe2aebdbe888e2eff520441857397e2c015" + dependencies: + d3-array "1.0.1" + d3-axis "1.0.3" + d3-brush "1.0.3" + d3-chord "1.0.2" + d3-collection "1.0.1" + d3-color "1.0.1" + d3-dispatch "1.0.1" + d3-drag "1.0.1" + d3-dsv "1.0.3" + d3-ease "1.0.1" + d3-force "1.0.2" + d3-format "1.0.2" + d3-geo "1.2.5" + d3-hierarchy "1.0.2" + d3-interpolate "1.1.1" + d3-path "1.0.2" + d3-polygon "1.0.1" + d3-quadtree "1.0.1" + d3-queue "3.0.3" + d3-random "1.0.1" + d3-request "1.0.2" + d3-scale "1.0.3" + d3-selection "1.0.2" + d3-shape "1.0.3" + d3-time "1.0.4" + d3-time-format "2.0.2" + d3-timer "1.0.3" + d3-transition "1.0.2" + d3-voronoi "1.0.2" + d3-zoom "1.0.3" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + +date-time@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/date-time/-/date-time-0.1.1.tgz#ed2f6d93d9790ce2fd66d5b5ff3edd5bbcbf3b07" + +debug@2.2.0, debug@^2.1.1, debug@^2.2.0, debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +debug@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" + dependencies: + ms "0.7.2" + +decamelize@^1.0.0, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + +deep-extend@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +depd@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + +diff-match-patch@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.0.tgz#1cc3c83a490d67f95d91e39f6ad1f2e086b63048" + +diff@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + +dom-serialize@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +domain-browser@^1.1.1: + version "1.1.7" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" + +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + dependencies: + is-obj "^1.0.0" + +duplexer2@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + dependencies: + readable-stream "^2.0.2" + +eastasianwidth@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.1.1.tgz#44d656de9da415694467335365fb3147b8572b7c" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +element-resize-event@^2.0.4: + version "2.0.7" + resolved "https://registry.yarnpkg.com/element-resize-event/-/element-resize-event-2.0.7.tgz#8b63953715967cd2241620245573e79e684e07b0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + +empower-core@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.5.0.tgz#948d5fc3303fa3c612f7c034191f96d69ee15959" + dependencies: + call-signature "0.0.2" + core-js "^1.2.6" + xtend "^4.0.0" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +engine.io-client@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.2.tgz#c38767547f2a7d184f5752f6f0ad501006703766" + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "2.3.3" + engine.io-parser "1.3.2" + has-cors "1.1.0" + indexof "0.0.1" + parsejson "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + ws "1.1.1" + xmlhttprequest-ssl "1.5.3" + yeast "0.1.2" + +engine.io-parser@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.2.tgz#937b079f0007d0893ec56d46cb220b8cb435220a" + dependencies: + after "0.8.2" + arraybuffer.slice "0.0.6" + base64-arraybuffer "0.1.5" + blob "0.0.4" + has-binary "0.1.7" + wtf-8 "1.0.0" + +engine.io@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.2.tgz#6b59be730b348c0125b0a4589de1c355abcf7a7e" + dependencies: + accepts "1.3.3" + base64id "1.0.0" + cookie "0.3.1" + debug "2.3.3" + engine.io-parser "1.3.2" + ws "1.1.1" + +enhanced-resolve@~0.9.0: + version "0.9.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.2.0" + tapable "^0.1.8" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + +errno@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" + dependencies: + prr "~0.0.0" + +error-ex@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.0.tgz#e67b43f3e82c96ea3a584ffee0b9fc3325d802d9" + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.6.1.tgz#bb8a2064120abcf928a086ea3d9043114285ec99" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.0" + is-callable "^1.1.3" + is-regex "^1.0.3" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@1.0.2, escape-string-regexp@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + +escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +espower-location-detector@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/espower-location-detector/-/espower-location-detector-0.1.2.tgz#d43be738af3e0b18197eeb5c22b95512dee6b83c" + dependencies: + is-url "^1.2.1" + path-is-absolute "^1.0.0" + source-map "^0.5.0" + xtend "^4.0.0" + +espurify@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.6.0.tgz#6cb993582d9422bd6f2d4b258aadb14833f394f0" + dependencies: + core-js "^2.0.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.0, esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +eventemitter3@1.x.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" + +events@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +expand-braces@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea" + dependencies: + array-slice "^0.2.3" + array-unique "^0.2.1" + braces "^0.1.2" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-0.1.1.tgz#4cb8eda0993ca56fa4f41fc42f3cbb4ccadff044" + dependencies: + is-number "^0.1.1" + repeat-string "^0.2.2" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +expect@1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-1.18.0.tgz#3ee9b58d2ef0b04b9584877bdd4fe73fde958fce" + dependencies: + has "^1.0.1" + is-equal "^1.5.1" + is-regex "^1.0.3" + object-inspect "^1.1.0" + object-keys "^1.0.9" + tmatch "^2.0.1" + +extend@^3.0.0, extend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" + +fbjs@^0.8.1, fbjs@^0.8.4, fbjs@^0.8.9: + version "0.8.12" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +figures@^1.4.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +filename-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +filled-array@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filled-array/-/filled-array-1.1.0.tgz#c3c4f6c663b923459a9aa29912d2d031f1507f84" + +finalhandler@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.0.tgz#e9508abece9b6dba871a6942a1d7911b91911ac7" + dependencies: + debug "~2.2.0" + escape-html "~1.0.3" + on-finished "~2.3.0" + statuses "~1.3.0" + unpipe "~1.0.0" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-versions@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-1.2.1.tgz#cbde9f12e38575a0af1be1b9a2c5d5fd8f186b62" + dependencies: + array-uniq "^1.0.0" + get-stdin "^4.0.1" + meow "^3.5.0" + semver-regex "^1.0.0" + +fn-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" + +for-in@^0.1.5: + version "0.1.6" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8" + +for-own@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.4.tgz#0149b41a39088c7515f51ebe1c1386d45f935072" + dependencies: + for-in "^0.1.5" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +fs-access@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a" + dependencies: + null-check "^1.0.0" + +fs-readdir-recursive@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz#315b4fb8c1ca5b8c47defef319d073dad3568059" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0: + version "1.0.15" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.0.15.tgz#fa63f590f3c2ad91275e4972a6cea545fb0aae44" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.29" + +fstream-ignore@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2, function-bind@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" + +gauge@~2.7.1: + version "2.7.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.2.tgz#15cecc31b02d05345a5d6b0e171cdb3ad2307774" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + supports-color "^0.2.0" + wide-align "^1.1.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +get-node-dimensions@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-node-dimensions/-/get-node-dimensions-1.2.2.tgz#7a71e8624cf9e1ab74599bb05b7e5116e995e45b" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + +getpass@^0.1.1: + version "0.1.6" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.3.tgz#e313eeb249c7affaa5c475286b0e115b59839467" + dependencies: + graceful-fs "~2.0.0" + inherits "2" + minimatch "~0.2.11" + +glob@^5.0.5: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^6.0.1: + version "6.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.5: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.0.0: + version "9.14.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.14.0.tgz#8859936af0038741263053b39d0e76ca241e4034" + +globby@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-4.1.0.tgz#080f54549ec1b82a6c60e631fc82e1211dbe95f8" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^6.0.1" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +got@^5.0.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35" + dependencies: + create-error-class "^3.0.1" + duplexer2 "^0.1.4" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + node-status-codes "^1.0.0" + object-assign "^4.0.1" + parse-json "^2.1.0" + pinkie-promise "^2.0.0" + read-all-stream "^3.0.0" + readable-stream "^2.0.5" + timed-out "^3.0.0" + unzip-response "^1.0.2" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.4: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +graceful-fs@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-2.0.3.tgz#7cd2cdb228a4a3f36e95efa6cc142de7d1a136d0" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +growl@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.8.1.tgz#4b2dec8d907e93db336624dcec0183502f8c9428" + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-binary@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.7.tgz#68e61eb16210c9545a0a5cce06a873912fe1e68c" + dependencies: + isarray "0.0.1" + +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + +has-flag@^1.0.0: + version "1.0.0" + resolved "http://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" + +http-browserify@^1.3.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/http-browserify/-/http-browserify-1.7.0.tgz#33795ade72df88acfbfd36773cefeda764735b20" + dependencies: + Base64 "~0.2.0" + inherits "~2.0.1" + +http-errors@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750" + dependencies: + inherits "2.0.3" + setprototypeof "1.0.2" + statuses ">= 1.3.1 < 2" + +http-proxy@^1.13.0: + version "1.16.2" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742" + dependencies: + eventemitter3 "1.x.x" + requires-port "1.x.x" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.0.tgz#b3ffdfe734b2a3d4a9efd58e8654c91fce86eafd" + +iconv-lite@0.4, iconv-lite@~0.4.13: + version "0.4.15" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" + +iconv-lite@0.4.13: + version "0.4.13" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" + +ieee754@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +ignore-by-default@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +interpret@^0.6.4: + version "0.6.6" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-0.6.6.tgz#fecd7a18e7ce5ca6abfb953e1f86213a49f1625b" + +invariant@2.2.1, invariant@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.1.tgz#b097010547668c7e337028ebe816ebe36c8a8d54" + dependencies: + loose-envify "^1.0.0" + +irregular-plurals@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-arrow-function@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-arrow-function/-/is-arrow-function-2.0.3.tgz#29be2c2d8d9450852b8bbafb635ba7b8d8e87ec2" + dependencies: + is-callable "^1.0.4" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-boolean-object@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93" + +is-buffer@^1.0.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.0.4, is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + +is-ci@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" + dependencies: + ci-info "^1.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-dotfile@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-equal@^1.5.1: + version "1.5.3" + resolved "https://registry.yarnpkg.com/is-equal/-/is-equal-1.5.3.tgz#05b7fa3a1122cbc71c1ef41ce0142d5532013b29" + dependencies: + has "^1.0.1" + is-arrow-function "^2.0.3" + is-boolean-object "^1.0.0" + is-callable "^1.1.3" + is-date-object "^1.0.1" + is-generator-function "^1.0.3" + is-number-object "^1.0.3" + is-regex "^1.0.3" + is-string "^1.0.4" + is-symbol "^1.0.1" + object.entries "^1.0.3" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-finite@^1.0.0, is-finite@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + +is-generator-function@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.3.tgz#d374ca57e807444fa2658be3728ed6b174b326b1" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-my-json-valid@^2.12.4: + version "2.15.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + +is-number-object@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799" + +is-number@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806" + +is-number@^2.0.2, is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-observable@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.1.0.tgz#08c59f3ca309eed97134f7240ee36266943e9df8" + dependencies: + symbol-observable "^0.1.0" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + +is-regex@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.3.tgz#0d55182bddf9f2fde278220aec3a75642c908637" + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-stream@^1.0.0, is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-string@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64" + +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-url@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.2.tgz#498905a593bf47cc2d9e7f738372bbf7696c7f26" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-windows@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isbinaryfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.1.tgz#6e99573675372e841a0520c036b41513d783e79e" + +isexe@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +jade@0.26.3: + version "0.26.3" + resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" + dependencies: + commander "0.6.1" + mkdirp "0.3.0" + +jodid25519@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" + dependencies: + jsbn "~0.1.0" + +js-tokens@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5" + +js-tokens@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +jsbn@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonpointer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.0.tgz#6661e161d2fc445f19f98430231343722e1fcbd5" + +jsprim@^1.2.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252" + dependencies: + extsprintf "1.0.2" + json-schema "0.2.3" + verror "1.3.6" + +karma-chrome-launcher@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-0.2.3.tgz#4c6d700d163a9d34c618efd87918be49e7a4a8c9" + dependencies: + fs-access "^1.0.0" + which "^1.2.1" + +karma-mocha-reporter@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/karma-mocha-reporter/-/karma-mocha-reporter-2.0.2.tgz#1381d01cff3632bafdd46d08bab60d8522c59e0c" + dependencies: + chalk "1.1.3" + +karma-mocha@0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-0.2.2.tgz#388ed917da15dcb196d1b915c1934ef803193f8e" + +karma-sourcemap-loader@0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz#91322c77f8f13d46fed062b042e1009d4c4505d8" + dependencies: + graceful-fs "^4.1.2" + +karma-webpack@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-1.7.0.tgz#7e5a4fb2ab68b0cc1c7a4fbfa72bb76eeb18cb2a" + dependencies: + async "~0.9.0" + loader-utils "^0.2.5" + lodash "^3.8.0" + source-map "^0.1.41" + webpack-dev-middleware "^1.0.11" + +karma@0.13.22: + version "0.13.22" + resolved "https://registry.yarnpkg.com/karma/-/karma-0.13.22.tgz#07750b1bd063d7e7e7b91bcd2e6354d8f2aa8744" + dependencies: + batch "^0.5.3" + bluebird "^2.9.27" + body-parser "^1.12.4" + chokidar "^1.4.1" + colors "^1.1.0" + connect "^3.3.5" + core-js "^2.1.0" + di "^0.0.1" + dom-serialize "^2.2.0" + expand-braces "^0.1.1" + glob "^7.0.0" + graceful-fs "^4.1.2" + http-proxy "^1.13.0" + isbinaryfile "^3.0.0" + lodash "^3.8.0" + log4js "^0.6.31" + mime "^1.3.4" + minimatch "^3.0.0" + optimist "^0.6.1" + rimraf "^2.3.3" + socket.io "^1.4.5" + source-map "^0.5.3" + useragent "^2.1.6" + +kind-of@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" + dependencies: + is-buffer "^1.0.2" + +last-line-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/last-line-stream/-/last-line-stream-1.0.0.tgz#d1b64d69f86ff24af2d04883a2ceee14520a5600" + dependencies: + through2 "^2.0.0" + +latest-version@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b" + dependencies: + package-json "^2.0.0" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +load-json-file@^1.0.0, load-json-file@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +loader-utils@^0.2.11, loader-utils@^0.2.5: + version "0.2.16" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.16.tgz#f08632066ed8282835dff88dfb52704765adee6d" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +lodash.debounce@^4.0.3: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + +lodash@4.16.3, lodash@^4.2.0: + version "4.16.3" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.16.3.tgz#0ba761439529127c7a38c439114ca153efa999a2" + +lodash@^3.2.0, lodash@^3.8.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + dependencies: + chalk "^1.0.0" + +log4js@^0.6.31: + version "0.6.38" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-0.6.38.tgz#2c494116695d6fb25480943d3fc872e662a522fd" + dependencies: + readable-stream "~1.0.2" + semver "~4.3.3" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.0.tgz#6b26248c42f6d4fa4b0d8542f78edfcde35642a8" + dependencies: + js-tokens "^2.0.0" + +loose-envify@^1.1.0, loose-envify@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +loud-rejection@^1.0.0, loud-rejection@^1.2.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + +lru-cache@2, lru-cache@2.2.x: + version "2.2.4" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" + +lru-cache@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + +matcher@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-0.1.2.tgz#ef20cbde64c24c50cc61af5b83ee0b1b8ff00101" + dependencies: + escape-string-regexp "^1.0.4" + +max-timeout@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/max-timeout/-/max-timeout-1.0.0.tgz#b68f69a2f99e0b476fd4cb23e2059ca750715e1f" + +md5-hex@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +memory-fs@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290" + +memory-fs@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.3.0.tgz#7bcc6b629e3a43e871d7e29aca6ae8a7f15cbb20" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^3.5.0, meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +micromatch@^2.1.5: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.25.0: + version "1.25.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.25.0.tgz#c18dbd7c73a5dbf6f44a024dc0d165a1e7b1c392" + +mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.7: + version "2.1.13" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.13.tgz#e07aaa9c6c6b9a7ca3012c69003ad25a39e92a88" + dependencies: + mime-db "~1.25.0" + +mime@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +minimatch@~0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimist@0.0.8, minimist@~0.0.1: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +mkdirp@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha@2.4.5: + version "2.4.5" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.4.5.tgz#151768dd2875eb51bc8295e9800026e9f2bb398f" + dependencies: + commander "2.3.0" + debug "2.2.0" + diff "1.4.0" + escape-string-regexp "1.0.2" + glob "3.2.3" + growl "1.8.1" + jade "0.26.3" + mkdirp "0.5.1" + supports-color "1.2.0" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@0.7.2, ms@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + +multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +nan@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.4.0.tgz#fb3c59d45fe4effe215f0b890f8adf6eb32d2232" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +node-fetch@^1.0.1: + version "1.6.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +"node-libs-browser@>= 0.4.0 <=0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-0.6.0.tgz#244806d44d319e048bc8607b5cc4eaf9a29d2e3c" + dependencies: + assert "^1.1.1" + browserify-zlib "~0.1.4" + buffer "^4.9.0" + console-browserify "^1.1.0" + constants-browserify "0.0.1" + crypto-browserify "~3.2.6" + domain-browser "^1.1.1" + events "^1.0.0" + http-browserify "^1.3.2" + https-browserify "0.0.0" + os-browserify "~0.1.2" + path-browserify "0.0.0" + process "^0.11.0" + punycode "^1.2.4" + querystring-es3 "~0.2.0" + readable-stream "^1.1.13" + stream-browserify "^1.0.0" + string_decoder "~0.10.25" + timers-browserify "^1.0.1" + tty-browserify "0.0.0" + url "~0.10.1" + util "~0.10.3" + vm-browserify "0.0.4" + +node-pre-gyp@^0.6.29: + version "0.6.32" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.32.tgz#fc452b376e7319b3d255f5f34853ef6fd8fe1fd5" + dependencies: + mkdirp "~0.5.1" + nopt "~3.0.6" + npmlog "^4.0.1" + rc "~1.1.6" + request "^2.79.0" + rimraf "~2.5.4" + semver "~5.3.0" + tar "~2.2.1" + tar-pack "~3.3.0" + +node-status-codes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" + +nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.5.tgz#8d924f142960e1777e7ffe170543631cc7cb02df" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" + +npmlog@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.1" + set-blocking "~2.0.0" + +null-check@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@4.1.0, object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + +object-inspect@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.2.1.tgz#3b62226eb8f6d441751c7d8f22a20ff80ac9dc3f" + +object-keys@^1.0.8, object-keys@^1.0.9: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object.entries@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.6.1" + function-bind "^1.1.0" + has "^1.0.1" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +observable-to-promise@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/observable-to-promise/-/observable-to-promise-0.3.0.tgz#1676bdb420514e630d0cd2f8256bddf1f5f86092" + dependencies: + is-observable "^0.1.0" + symbol-observable "^0.1.0" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +once@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +only-shallow@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/only-shallow/-/only-shallow-1.2.0.tgz#71cecedba9324bc0518aef10ec080d3249dc2465" + +optimist@^0.6.1, optimist@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +option-chain@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/option-chain/-/option-chain-0.1.1.tgz#e9b811e006f1c0f54802f28295bfc8970f8dcfbd" + dependencies: + object-assign "^4.0.1" + +options@>=0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" + +os-browserify@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.1.2.tgz#49ca0293e0b19590a5f5de10c7f265a617d8fe54" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.0: + version "0.1.4" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +output-file-sync@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + +package-json@^2.0.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-2.4.0.tgz#0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb" + dependencies: + got "^5.0.0" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pako@~0.2.0: + version "0.2.9" + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.1.0, parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-ms@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-0.1.2.tgz#dd3fa25ed6c2efc7bdde12ad9b46c163aa29224e" + +parse-ms@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d" + +parsejson@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/parsejson/-/parsejson-0.0.3.tgz#ab7e3759f209ece99437973f7d0f1f64ae0e64ab" + dependencies: + better-assert "~1.0.0" + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + +path-exists@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-1.0.0.tgz#d5a8998eb71ef37a74c34eb0d9eba6e878eea081" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pbkdf2-compat@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz#b6e0c8fa99494d94e0511575802a59a5c142f288" + +performance-now@^0.2.0, performance-now@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-1.0.0.tgz#d1da67f5482563bb7cf57f286ae2822ecfbf3670" + dependencies: + pinkie "^1.0.0" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-conf@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-1.1.3.tgz#378e56d6fd13e88bfb6f4a25df7a83faabddba5b" + dependencies: + find-up "^1.0.0" + load-json-file "^1.1.0" + object-assign "^4.0.1" + symbol "^0.2.1" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + +plur@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/plur/-/plur-1.0.0.tgz#db85c6814f5e5e5a3b49efc28d604fec62975156" + +plur@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" + dependencies: + irregular-plurals "^1.0.0" + +power-assert-context-formatter@^1.0.7: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-context-formatter/-/power-assert-context-formatter-1.1.1.tgz#edba352d3ed8a603114d667265acce60d689ccdf" + dependencies: + core-js "^2.0.0" + power-assert-context-traversal "^1.1.1" + +power-assert-context-reducer-ast@^1.0.7: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-context-reducer-ast/-/power-assert-context-reducer-ast-1.1.1.tgz#bb419c65ea88c9a4dfc34a9dbcf82e971f6f69bc" + dependencies: + acorn "^4.0.0" + acorn-es7-plugin "^1.0.12" + core-js "^2.0.0" + espurify "^1.6.0" + estraverse "^4.2.0" + +power-assert-context-traversal@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-context-traversal/-/power-assert-context-traversal-1.1.1.tgz#88cabca0d13b6359f07d3d3e8afa699264577ed9" + dependencies: + core-js "^2.0.0" + estraverse "^4.1.0" + +power-assert-formatter@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/power-assert-formatter/-/power-assert-formatter-1.4.1.tgz#5dc125ed50a3dfb1dda26c19347f3bf58ec2884a" + dependencies: + core-js "^2.0.0" + power-assert-context-formatter "^1.0.7" + power-assert-context-reducer-ast "^1.0.7" + power-assert-renderer-assertion "^1.0.7" + power-assert-renderer-comparison "^1.0.7" + power-assert-renderer-diagram "^1.0.7" + power-assert-renderer-file "^1.0.7" + +power-assert-renderer-assertion@^1.0.0, power-assert-renderer-assertion@^1.0.7: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderer-assertion/-/power-assert-renderer-assertion-1.1.1.tgz#cbfc0e77e0086a8f96af3f1d8e67b9ee7e28ce98" + dependencies: + power-assert-renderer-base "^1.1.1" + power-assert-util-string-width "^1.1.1" + +power-assert-renderer-base@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderer-base/-/power-assert-renderer-base-1.1.1.tgz#96a650c6fd05ee1bc1f66b54ad61442c8b3f63eb" + +power-assert-renderer-comparison@^1.0.0, power-assert-renderer-comparison@^1.0.7: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderer-comparison/-/power-assert-renderer-comparison-1.1.1.tgz#d7439d97d85156be4e30a00f2fb5a72514ce3c08" + dependencies: + core-js "^2.0.0" + diff-match-patch "^1.0.0" + power-assert-renderer-base "^1.1.1" + stringifier "^1.3.0" + type-name "^2.0.1" + +power-assert-renderer-diagram@^1.0.0, power-assert-renderer-diagram@^1.0.7, power-assert-renderer-diagram@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderer-diagram/-/power-assert-renderer-diagram-1.1.1.tgz#7e0c82cc08a84b155e51b5ae94f59709778a65fb" + dependencies: + core-js "^2.0.0" + power-assert-renderer-base "^1.1.1" + power-assert-util-string-width "^1.1.1" + stringifier "^1.3.0" + +power-assert-renderer-file@^1.0.0, power-assert-renderer-file@^1.0.7: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderer-file/-/power-assert-renderer-file-1.1.1.tgz#a37e2bbd178ccacd04e78dbb79c92fe34933c5e7" + dependencies: + power-assert-renderer-base "^1.1.1" + +power-assert-renderer-succinct@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderer-succinct/-/power-assert-renderer-succinct-1.1.1.tgz#c2a468b23822abd6f80e2aba5322347b09df476e" + dependencies: + core-js "^2.0.0" + power-assert-renderer-diagram "^1.1.1" + +power-assert-renderers@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderers/-/power-assert-renderers-0.1.1.tgz#6a09e1c01e0ecf8faa6749401a7da2b0e0598107" + dependencies: + power-assert-renderer-assertion "^1.0.0" + power-assert-renderer-comparison "^1.0.0" + power-assert-renderer-diagram "^1.0.0" + power-assert-renderer-file "^1.0.0" + power-assert-renderer-succinct "^1.0.0" + +power-assert-util-string-width@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-util-string-width/-/power-assert-util-string-width-1.1.1.tgz#be659eb7937fdd2e6c9a77268daaf64bd5b7c592" + dependencies: + eastasianwidth "^0.1.1" + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +prettier@^1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.5.3.tgz#59dadc683345ec6b88f88b94ed4ae7e1da394bfe" + +pretty-ms@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-0.2.2.tgz#da879a682ff33a37011046f13d627f67c73b84f6" + dependencies: + parse-ms "^0.1.0" + +pretty-ms@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-2.1.0.tgz#4257c256df3fb0b451d6affaab021884126981dc" + dependencies: + is-finite "^1.0.1" + parse-ms "^1.0.0" + plur "^1.0.0" + +private@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.6.tgz#55c6a976d0f9bafb9924851350fe47b9b5fbb7c1" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +process@^0.11.0, process@~0.11.0: + version "0.11.9" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.9.tgz#7bd5ad21aa6253e7da8682264f1e11d11c0318c1" + +promise@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" + dependencies: + asap "~2.0.3" + +prop-types@^15.5.10, prop-types@^15.5.8: + version "15.5.10" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154" + dependencies: + fbjs "^0.8.9" + loose-envify "^1.3.1" + +prr@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" + +pseudomap@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +qs@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.0.tgz#3b7848c03c2dece69a9522b0fae8c4126d745f3b" + +qs@~6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.0.tgz#f403b264f23bc01228c74131b407f18d5ea5d442" + +querystring-es3@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +raf@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.3.0.tgz#93845eeffc773f8129039f677f80a36044eee2c3" + dependencies: + performance-now "~0.2.0" + +randomatic@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + dependencies: + is-number "^2.0.2" + kind-of "^3.0.2" + +range-parser@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +raw-body@~2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774" + dependencies: + bytes "2.4.0" + iconv-lite "0.4.13" + unpipe "1.0.0" + +rc@^1.0.1, rc@^1.1.6, rc@~1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.6.tgz#43651b76b6ae53b5c802f1151fa3fc3b059969c9" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~1.0.4" + +react-dimensions@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/react-dimensions/-/react-dimensions-1.3.0.tgz#f5dec8e7b84644a605a900cae0f4a6654acf4e9f" + dependencies: + element-resize-event "^2.0.4" + +react-dom@^15.4.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.4.1.tgz#d54c913261aaedb17adc20410d029dcc18a1344a" + dependencies: + fbjs "^0.8.1" + loose-envify "^1.1.0" + object-assign "^4.1.0" + +react-measure@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/react-measure/-/react-measure-2.0.2.tgz#072a9a5fafc01dfbadc1fa5fb09fc351037f636c" + dependencies: + get-node-dimensions "^1.2.0" + prop-types "^15.5.10" + resize-observer-polyfill "^1.4.2" + +react-motion@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.0.tgz#1708fc2aee552900d21c1e6bed28346863e017b6" + dependencies: + performance-now "^0.2.0" + prop-types "^15.5.8" + raf "^3.1.0" + +react@^15.4.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/react/-/react-15.4.1.tgz#498e918602677a3983cd0fd206dfe700389a0dd6" + dependencies: + fbjs "^0.8.4" + loose-envify "^1.1.0" + object-assign "^4.1.0" + +read-all-stream@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" + dependencies: + pinkie-promise "^2.0.0" + readable-stream "^2.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +readable-stream@^1.0.27-1, readable-stream@^1.1.13: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5: + version "2.2.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~1.0.2: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +regenerate@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" + +regenerator-runtime@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.1.tgz#257f41961ce44558b18f7814af48c17559f9faeb" + +regenerator-transform@0.9.8: + version "0.9.8" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.8.tgz#0f88bb2bc03932ddb7b6b7312e68078f01026d6c" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.3" + resolved "http://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" + dependencies: + is-equal-shallow "^0.1.3" + is-primitive "^2.0.0" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +registry-auth-token@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.1.0.tgz#997c08256e0c7999837b90e944db39d8a790276b" + dependencies: + rc "^1.1.6" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + dependencies: + rc "^1.0.1" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request@^2.65.0, request@^2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + +require-precompiled@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" + +requires-port@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + +resize-observer-polyfill@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.4.2.tgz#a37198e6209e888acb1532a9968e06d38b6788e5" + +resolve-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-1.0.0.tgz#4eaeea41ed040d1702457df64a42b2b07d246f9f" + dependencies: + resolve-from "^2.0.0" + +resolve-from@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@^2.3.3, rimraf@~2.5.1, rimraf@~2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + dependencies: + glob "^7.0.5" + +ripemd160@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-0.2.0.tgz#2bf198bde167cacfa51c0a928e84b68bbe171fce" + +rw@1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.2.tgz#14ef5137ff7547c73ecf0e0af1f0aee07e5401ee" + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" + +semver-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-1.0.0.tgz#92a4969065f9c70c694753d55248fc68f8f652c9" + +semver-truncate@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/semver-truncate/-/semver-truncate-1.1.2.tgz#57f41de69707a62709a7e0104ba2117109ea47e8" + dependencies: + semver "^5.3.0" + +"semver@2 || 3 || 4 || 5", semver@^4.0.3, semver@~4.3.3: + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + +semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +setprototypeof@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08" + +sha.js@2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.2.6.tgz#17ddeddc5f722fb66501658895461977867315ba" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +socket.io-adapter@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz#cb6d4bb8bec81e1078b99677f9ced0046066bb8b" + dependencies: + debug "2.3.3" + socket.io-parser "2.3.1" + +socket.io-client@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.2.tgz#39fdb0c3dd450e321b7e40cfd83612ec533dd644" + dependencies: + backo2 "1.0.2" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "2.3.3" + engine.io-client "1.8.2" + has-binary "0.1.7" + indexof "0.0.1" + object-component "0.0.3" + parseuri "0.0.5" + socket.io-parser "2.3.1" + to-array "0.1.4" + +socket.io-parser@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.3.1.tgz#dd532025103ce429697326befd64005fcfe5b4a0" + dependencies: + component-emitter "1.1.2" + debug "2.2.0" + isarray "0.0.1" + json3 "3.3.2" + +socket.io@^1.4.5: + version "1.7.2" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.2.tgz#83bbbdf2e79263b378900da403e7843e05dc3b71" + dependencies: + debug "2.3.3" + engine.io "1.8.2" + has-binary "0.1.7" + object-assign "4.1.0" + socket.io-adapter "0.5.0" + socket.io-client "1.7.2" + socket.io-parser "2.3.1" + +sort-keys@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.7.tgz#d4b5ce2a46535c72c7e8527c71a77d250618172e" + +source-map-support@^0.4.0, source-map-support@^0.4.2: + version "0.4.6" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.6.tgz#32552aa64b458392a85eab3b0b5ee61527167aeb" + dependencies: + source-map "^0.5.3" + +source-map@^0.1.41: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.3, source-map@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +source-map@~0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +sshpk@^1.7.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.10.1.tgz#30e1a5d329244974a1af61511339d595af6638b0" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jodid25519 "^1.0.0" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stack-utils@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-0.4.0.tgz#940cb82fccfa84e8ff2f3fdf293fe78016beccd1" + +"statuses@>= 1.3.1 < 2", statuses@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +stream-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-1.0.0.tgz#bf9b4abfb42b274d751479e44e0ff2656b6f1193" + dependencies: + inherits "~2.0.1" + readable-stream "^1.0.27-1" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string_decoder@~0.10.25, string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +stringifier@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/stringifier/-/stringifier-1.3.0.tgz#def18342f6933db0f2dbfc9aa02175b448c17959" + dependencies: + core-js "^2.0.0" + traverse "^0.6.6" + type-name "^2.0.1" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + +supports-color@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" + +supports-color@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" + +symbol-observable@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.1.0.tgz#299e40228f25e83e42f2f63b68dad84b87ac3bb4" + +symbol@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/symbol/-/symbol-0.2.3.tgz#3b9873b8a901e47c6efe21526a3ac372ef28bbc7" + +tapable@^0.1.8, tapable@~0.1.8: + version "0.1.10" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" + +tar-pack@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.3.0.tgz#30931816418f55afc4d21775afdd6720cee45dae" + dependencies: + debug "~2.2.0" + fstream "~1.0.10" + fstream-ignore "~1.0.5" + once "~1.3.3" + readable-stream "~2.1.4" + rimraf "~2.5.1" + tar "~2.2.1" + uid-number "~0.0.6" + +tar@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +the-argv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/the-argv/-/the-argv-1.0.0.tgz#0084705005730dd84db755253c931ae398db9522" + +through2@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +time-require@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/time-require/-/time-require-0.1.2.tgz#f9e12cb370fc2605e11404582ba54ef5ca2b2d98" + dependencies: + chalk "^0.4.0" + date-time "^0.1.1" + pretty-ms "^0.2.1" + text-table "^0.2.0" + +timed-out@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.0.tgz#43b98b14bb712c9161c28f4dc1f3068d67a04ec2" + +timers-browserify@^1.0.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d" + dependencies: + process "~0.11.0" + +tmatch@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/tmatch/-/tmatch-2.0.1.tgz#0c56246f33f30da1b8d3d72895abaf16660f38cf" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + +to-fast-properties@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +traverse@^0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-is@~1.6.13: + version "1.6.14" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.13" + +type-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/type-name/-/type-name-2.0.2.tgz#efe7d4123d8ac52afff7f40c7e4dec5266008fb4" + +ua-parser-js@^0.7.9: + version "0.7.12" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" + +uglify-js@~2.6.0: + version "2.6.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.6.4.tgz#65ea2fb3059c9394692f15fed87c2b36c16b9adf" + dependencies: + async "~0.2.6" + source-map "~0.5.1" + uglify-to-browserify "~1.0.0" + yargs "~3.10.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +uid-number@~0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +uid2@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + +ultron@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" + +unique-temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz#6dce95b2681ca003eebfb304a415f9cbabcc5385" + dependencies: + mkdirp "^0.5.1" + os-tmpdir "^1.0.1" + uid2 "0.0.3" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +unzip-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" + +update-notifier@^0.6.0: + version "0.6.3" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-0.6.3.tgz#776dec8daa13e962a341e8a1d98354306b67ae08" + dependencies: + boxen "^0.3.1" + chalk "^1.0.0" + configstore "^2.0.0" + is-npm "^1.0.0" + latest-version "^2.0.0" + semver-diff "^2.0.0" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + +url@~0.10.1: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + +useragent@^2.1.6: + version "2.1.9" + resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.1.9.tgz#4dba2bc4dad1875777ab15de3ff8098b475000b7" + dependencies: + lru-cache "2.2.x" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util@0.10.3, util@~0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + +utils-merge@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" + +uuid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + +uuid@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +v8flags@^2.0.10: + version "2.0.11" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.0.11.tgz#bca8f30f0d6d60612cc2c00641e6962d42ae6881" + dependencies: + user-home "^1.1.1" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +verror@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" + dependencies: + extsprintf "1.0.2" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + dependencies: + indexof "0.0.1" + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + +watchpack@^0.2.1: + version "0.2.9" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-0.2.9.tgz#62eaa4ab5e5ba35fdfc018275626e3c0f5e3fb0b" + dependencies: + async "^0.9.0" + chokidar "^1.0.0" + graceful-fs "^4.1.2" + +webpack-core@~0.6.0: + version "0.6.9" + resolved "https://registry.yarnpkg.com/webpack-core/-/webpack-core-0.6.9.tgz#fc571588c8558da77be9efb6debdc5a3b172bdc2" + dependencies: + source-list-map "~0.1.7" + source-map "~0.4.1" + +webpack-dev-middleware@^1.0.11: + version "1.8.4" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.8.4.tgz#e8765c9122887ce9e3abd4cc9c3eb31b61e0948d" + dependencies: + memory-fs "~0.3.0" + mime "^1.3.4" + path-is-absolute "^1.0.0" + range-parser "^1.0.3" + +webpack@1.13.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-1.13.0.tgz#aad3d34f0b7202dd55b17a6a6cebf4dbbe72272a" + dependencies: + acorn "^3.0.0" + async "^1.3.0" + clone "^1.0.2" + enhanced-resolve "~0.9.0" + interpret "^0.6.4" + loader-utils "^0.2.11" + memory-fs "~0.3.0" + mkdirp "~0.5.0" + node-libs-browser ">= 0.4.0 <=0.6.0" + optimist "~0.6.0" + supports-color "^3.1.0" + tapable "~0.1.8" + uglify-js "~2.6.0" + watchpack "^0.2.1" + webpack-core "~0.6.0" + +whatwg-fetch@>=0.10.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.1.tgz#078b9461bbe91cea73cbce8bb122a05f9e92b772" + +which@^1.2.1, which@^1.2.9: + version "1.2.12" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192" + dependencies: + isexe "^1.1.1" + +wide-align@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" + dependencies: + string-width "^1.0.1" + +widest-line@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" + dependencies: + string-width "^1.0.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^1.1.2, write-file-atomic@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.2.0.tgz#14c66d4e4cb3ca0565c28cf3b7a6f3e4d5938fab" + dependencies: + graceful-fs "^4.1.2" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-json-file@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-1.2.0.tgz#2d5dfe96abc3c889057c93971aa4005efb548134" + dependencies: + graceful-fs "^4.1.2" + mkdirp "^0.5.1" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + sort-keys "^1.1.1" + write-file-atomic "^1.1.2" + +write-pkg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-1.0.0.tgz#aeb8aa9d4d788e1d893dfb0854968b543a919f57" + dependencies: + write-json-file "^1.1.0" + +ws@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.1.tgz#082ddb6c641e85d4bb451f03d52f06eabdb1f018" + dependencies: + options ">=0.0.5" + ultron "1.0.x" + +wtf-8@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a" + +xdg-basedir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" + dependencies: + os-homedir "^1.0.0" + +xmlhttprequest-ssl@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d" + +xmlhttprequest@1: + version "1.8.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +yallist@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.0.0.tgz#306c543835f09ee1a4cb23b7bce9ab341c91cdd4" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"