[
  {
    "path": ".editorconfig",
    "content": "# EditorConfig: http://editorconfig.org\n\nroot = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"extends\": [\n    \"eslint:recommended\",\n    \"plugin:react/recommended\",\n    \"plugin:react-hooks/recommended\",\n    \"plugin:jest/recommended\",\n    \"prettier\",\n    \"prettier/react\"\n  ],\n  \"parser\": \"babel-eslint\",\n  \"plugins\": [\n    \"react\",\n    \"react-hooks\",\n    \"prettier\",\n    \"babel\",\n    \"jest\"\n  ],\n  \"ignorePatterns\": [\n    \"node_modules\",\n    \"bundle.js\",\n    \"**/dist/\",\n    \"**/es/\"\n  ],\n  \"settings\":{\n    \"react\":{\n      \"version\": \"detect\"\n    }\n  },\n  \"env\": {\n    \"es6\": true,\n    \"browser\": true,\n    \"jest\": true\n  },\n  \"rules\": {\n    \"consistent-return\": 0,\n    \"max-len\": [1, 110, 4],\n    \"max-params\": [\"error\", 6],\n    \"object-curly-spacing\": 0,\n    \"babel/object-curly-spacing\": 2,\n    \"jest/require-top-level-describe\":\"error\",\n    \"react/prop-types\": \"off\",\n    \"prettier/prettier\": \"warn\"\n  }\n}\n"
  },
  {
    "path": ".gitattributes",
    "content": "yarn.lock -diff\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules/\n.sass-cache/\n.nyc_output/\ncoverage/\ndist/\nes/\n\nnpm-debug.log*\nyarn-error.log*\n.DS_Store\n.idea/\npublic/\n.vscode/\n\nbundle.js\nbundle.css\npackages/showcase/app.css\n\n/index.html\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"singleQuote\": true,\n  \"trailingComma\": \"none\",\n  \"bracketSpacing\": false,\n  \"jsxBracketSameLine\": false,\n  \"semi\": true,\n  \"parser\": \"babel\"\n}\n"
  },
  {
    "path": ".stylelintrc",
    "content": "{\n  \"extends\": \"stylelint-config-standard\",\n  \"rules\": {\n    \"selector-list-comma-newline-after\": \"always\"\n  }\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n  - '10'\nscript:\n  - npm run lint\n  - cd packages/react-vis\n  - npm run cover\nafter_success:\n  - npm install -g coveralls\n  - cat coverage/lcov.info | coveralls\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## v1.12.0\n- Upgraded all d3 dependencies\n- The layout of Sankey and Contour chart are changed due to the d3 upgrade\n- Build fixes\n- Revert #1358 (note that this PR was not included in 1.11.7)\n---\n\n## v1.9.2\n- we removed the check-stylesheets warnings.\n- it's now possible to pass better styling options for radial charts labels. It's also possible to position axis titles along the axis.\n- react-motion and react minimal versions have been updated.\n\n## v1.0.0 Breaking changes\n\nWe recently made a major jump to version v1, which naturally includes some breaking changes. Specifically these include\n\n*Table is deprecated*: There are other substantially better tables in the ecosystem, so we decided to stick to what we do best, charts and plots.\n*Stylesheet has been moved*: the stylesheet for react-vis can now be found within the dist folder, so simply modify your style import to be:\n\n```\n@import './node_modules/react-vis/dist/main';\n```\n\n*Default Opacity*: The default opacity behavior has been modified. Previously, react-vis asserted you had a linear scale with range [0.1, 1] and place your value within that range. Now react-vis presents a literal-scale by default. Check your opacities to make sure they are correct.\n*tickSizeInner & tickSizeOuter have been reversed*: the names of these props on the axes component have been switched. We feel this arrangement offers a more natural way to interact with the plot.\n*ALIGN.TOP_RIGHT was removed from hint.js*: this case did not match the orientation scheme followed by this component so was removed.\n\n### v0.10.1\n\nIn this release we release a new chart type, a large repo refactor, address a variety of bugs, and a host of additional features!\n\n- **New Chart**: Type: Sankey Diagram: this chart type allows users visualize data flows and transfers. We are initially releasing this chart in alpha, so that we can gather feedback, and iterate to make the best chart that we can! Check out the docs here here!\n\n- **Bug Fix**: Fix numerous bugs on the radial plot, including mouse interaction issues, incorrect domains, and props falling out of sync\n\n- **Refactor**: We reorganized the way that we are keeping/organizing our repo, installed yarn, added webpack for the examples. (Pro tip, if you are having trouble running the examples after upgrading rm -rf your dist)\n\n- **Feature**: Allow custom crosshair orientation\n\n- **Feature**: Added interaction listeners for the tree map\n\n### v0.9.0\n\nThis release addresses a couple of bugs and improves our dep tree. The only psuedo-breaking change is to the layout of radial plot. The way that it now works is that the pie is centered within the given width/height and then allowed to grow to an innerWidth/innerHeight that is computed from the margins and the width/height.\n\n- Bug: Modify margin system for radial chart\n- Improvement: Support for classname on legends\n- Chore: Remove duplicated styles\n- Bug: Add default props to classname for axis\n- Chore: Update deps, fix lint errors\n\n### v0.8.0\nThis release adds two new props (and set of illustrative examples) to Hint component: ```align``` and ```getAlignStyle```. ```align``` (replacing ```orientation``` prop) is an object with two props &mdash; ```horizontal``` and ```vertical``` &mdash; and set of values that support existing and new hint placement:\n  a) around a data point in one of four quadrants (imagine the point bisected by two axes &mdash; vertical, horizontal &mdash; creating 4 quadrants around a data point).\n  b) **New**: pin to an edge of chart/plot area and position along that edge using data point's other dimension value.\n\nDevelopers wanting total control can use the ```getAlignStyle(align, x, y)``` function that returns an inline style object with one or more of the following props (```left, right, top, bottom```).\n\nThe ```orientation``` prop is supported for backwards compatibility but will be deprecated in future release.\n\nSee the following figure explaining the two props  (```horizontal, vertical```) for the ```align``` prop object.\n![react-vis-hint](https://cloud.githubusercontent.com/assets/2983206/21572148/f1529198-ce8a-11e6-8dc3-ef5f320ab9a1.png)\n\n### v0.7.0\nThis release adds a new series: rectSeries. Rect series operates similarly to barSeries: they consist of a series of rectangles of various size that be stacked, but with one key difference. Where the bar series operates on the assumption of an ordinal axis, rect series operates on an assumption of a continuous one. This allows users to specify the positions of the edges of their rectangles!\n\n![alt text](https://cloud.githubusercontent.com/assets/6854312/21075697/47f1bbfa-becd-11e6-9f67-9c1ab5ad5e83.png \"example histogram\")\n\nRect series are great for histograms, as they allow you to exactly specify the bounds of buckets. They can be accessed via VerticalRectSeries and HorizontalRectSeries. Check out the examples for more details. This is non breaking change, and can be dropped in immediately.\n\n\n### v0.6.8\n- Feature: Export Abstract series and the rest of the functions in scale utils.\n- Feature: Add specific class names to x and y axes\n\n### v0.6.6\n\n- Improvement: added line smoothing via d3-shape curve functions ([#185](https://github.com/uber/react-vis/pull/185)).\n- Improvement: Expose GridLines, AxisLines, and ScaleUtils to export\n- Improvement: Add className prop to all series\n- Documentation: Expand tree map example\n- Documentation: Add elevated area chart example\n\n### 0.6.4\n\n- Bugfix: Fixed the issue with numeric titles in legends ([#154](https://github.com/uber/react-vis/pull/154)).\n\n### 0.6.3\n\n- Bugfix: fix the broken event listeners for radial charts ([#150](https://github.com/uber/react-vis/issues/150));\n- Bugfix: compatibility fix: do not treat `null` and `undefined` in scale props as existing values ([#149](https://github.com/uber/react-vis/issues/149)).\n\n### 0.6.2\n\n* Feature: added a new `tickLabelAngle` property that rotates the tick label ([see the documentation](docs/xy-plot.md#ticklabelangle-optional) for details).\n* Improvement: added a little bit of examples for the axes.\n* Bugfix: fixed misplaced axis title when orientation is set to `'top'` or `'right'` ([#146](https://github.com/uber/react-vis/issues/146)).\n\n### 0.6.1\n\n* Bugfix: axis is misplaced when `orientation` is set to `'right'`([#143](https://github.com/uber/react-vis/issues/143)).\n\n### 0.6\n\n#### TL;DR\n\nNew legends (sic!), new animations, faster rendering of components, no d3 in actual rendering process, new examples and more.\n\n#### Breaking changes\n\n* `animation` property works differently: duration is removed in favor of stiffness, damping and precision. Please refer to the documentation for the latest changes.\n* `undefined` and `null` values of important scale-related attributes for domains and ranges are now treated as real values (and not ignored anymore).\n\n#### Non-breaking changes\n\n* Feature: added the first version of legends (discrete and continuous color legends, continuous size legend). Please refer to the [docs for legends](docs/legends.md) for more details.\n* Improvement: got rid of assigning properties with d3 after rendering, currently all attributes and event listeners are attached using React (and it is faster).\n* Improvement: eliminated the use of `d3-selection` and `d3-transition` modules and made the source code smaller.\n* Improvement: added some structure into the examples and simplified their source code ([check them out](http://uber.github.com/react-vis)).\n* Bugfix: fixed crashing on animation (#114).\n* Improvement: `onNearestX` event now returns the index of the selected data point as an attribute (more details [here](docs/xy-plot.md#onnearestx-optional))\n* Bugfix: added the donut chart to the list of examples ([#83](https://github.com/uber/react-vis/issues/83)).\n* Bugfix: fixed failing bar charts when the number of segments was changed ([#55](https://github.com/uber/react-vis/issues/55)).\n\n### 0.5\n\n#### TL;DR\n\nUpgraded to modular d3, compiled code became smaller, changed the API for axes and grids, fixed several bugs.\n\n#### Breaking changes\n\n* d3-axis is no longer used, the rendering of axes and grids is made by react (and works faster).\n* The API of axes (`XAxis` and `YAxis`) was significantly changed:\n  * [the API of axes](docs/xy-plot.md#axes) is now (almost) compatible to the API of 'd3-axis'.\n  * `labelFormat` and `labelValues` attributes for the axes are **removed**: similar results can be done achieved when `tickFormat` and `tickValues` attributes are used (see the [the updated documentation for axes](docs/xy-plot.md#axes) for more details).\n  * `tickFormat` function is now gets only **one (value) argument instead of two (value and index)**.\n* The API of grids (`VerticalGridLines` and `HorizontalGridLines`) was significantly changed: it partially replicates the API of the axes.  Please refer to [the updated documentation ](docs/xy-plot.md#grids) for more detail.\n\n#### Non-breaking changes\n\n* Bugfix: `margin` for the radial and ortogonal chart is now able to receive partial objects (e. g.`<XYPlot margin={{left: 20}}>` instead of margins for each side) and numbers (e.g. `<XYPlot margin={20}>`)\n* Bugfix: `makeVisFlexible` doesn't fail anymore (see [#118](https://github.com/uber-common/react-vis/issues/118)).\n* Minor bugfixes and improvements.\n\nPlease find [full change log here](https://github.com/uber/react-vis/releases).\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age,\nbody size, disability, ethnicity, gender identity and expression, level of\nexperience, nationality, personal appearance, race, religion, or sexual\nidentity and orientation.\n\n## Our Standards\nExamples of behavior that contributes to creating a positive environment\ninclude:\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n* The use of sexualized language or imagery and unwelcome sexual attention or\n  advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project email\naddress, posting via an official social media account, or acting as an\nappointed representative at an online or offline event. Representation of a\nproject may be further defined and clarified by project maintainers.\n\n## Enforcement\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at oss-conduct@uber.com. The project\nteam will review and investigate all complaints, and will respond in a way\nthat it deems appropriate to the circumstances. The project team is obligated\nto maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 1.4, available at\n[http://contributor-covenant.org/version/1/4][version].\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Want to contribute?\n\nGreat! That's why this is an open source project. We use this project in our infrastructure at Uber, and we hope that it's useful to others as well.\n\nBefore you get started, here are some suggestions:\n\n - Check open issues for what you want.\n - If there is an open issue, comment on it. Otherwise open an issue describing your bug or feature with use cases.\n - Before undertaking a major change, please discuss this on the issue. We'd hate to see you spend a lot of time working on something that conflicts with other goals or requirements that might not be obvious.\n - Write code to fix the problem, then open a pull request with tests and documentation.\n - The pull requests gets reviewed and then merged assuming there are no problems.\n - A new release version gets cut.\n \n## Hints\n\nWant to make sure your PR gets a speedy review and a quick merge? Here are some tips:\n\n- Add Tests\n- Add documentation about the feature you added\n- Make sure you have a clear description of what your PR is about\n- Include screenshots\n- Add Tests\n\n## Releases\n\nDeclaring formal releases requires peer review.\n\n - A reviewer of a pull request should recommend a new version number (patch, minor or major).\n - Once your change is merged feel free to bump the version as recommended by the reviewer.\n - A new version number should not be cut without peer review unless done by the project maintainer.\n\n### Cutting a new version\n\n - Get your branch merged on master\n - Run `npm version major` or `npm version minor` or `npm version patch`\n - `git push origin master --tags`\n - If you are a project owner, then `npm publish`\n"
  },
  {
    "path": "DEPRECATED.md",
    "content": "# Deprecated\n\nUnfortunately, `react-vis` currently has no active maintainers. As such, we have\ndecided to deprecate the library. This deprecation means that `react-vis` won't\nreceive any patches or new features. If you're interested to take on ownership,\nplease discuss on #1303. Anyone is welcome to fork this library.\n\nWe're working on a new charting library that we'll introduce in 2020. We will\nkeep you folks updated on this repo on the new library!"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2016 Uber Technologies, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"right\">\n  <a href=\"./DEPRECATED.md\">\n    <img src=\"https://img.shields.io/maintenance/no/2020?style=flat-square\" alt=\"deprecated\" />\n  </a>\n  <a href=\"https://npmjs.org/package/react-vis\">\n    <img src=\"https://img.shields.io/npm/v/react-vis.svg?style=flat-square\" alt=\"version\" />\n  </a>\n  <a href=\"https://travis-ci.org/uber/react-vis\">\n    <img src=\"https://img.shields.io/travis/uber/react-vis/master.svg?style=flat-square\" alt=\"build\" />\n  </a>\n  <a href=\"https://coveralls.io/github/uber/react-vis\">\n    <img src=\"https://img.shields.io/coveralls/uber/react-vis.svg?style=flat-square\" alt=\"build\" />\n  </a>\n  <a href=\"https://npmjs.org/package/react-vis\">\n    <img src=\"https://img.shields.io/npm/dm/react-vis.svg?style=flat-square\" alt=\"downloads\" />\n  </a>\n</p>\n\n<h1 align=\"center\">react-vis | <a href=\"http://uber.github.io/react-vis/examples/showcases/axes\">Demos</a> | <a href=\"http://uber.github.io/react-vis/documentation/getting-started/creating-a-new-react-vis-project\">Docs</a></h1>\n\n<h5 align=\"center\">A COMPOSABLE VISUALIZATION SYSTEM</h5>\n\n![demo](docs/assets/react-vis.gif?raw=true)\n\n> **_NOTE:_** This repository is now under new management.  Please reach out to the new administrators if you have any questions.\n\n## Overview\n\nA collection of react components to render common data visualization charts, such as **line/area/bar charts**, **heat maps**, **scatterplots**, **contour plots**, **hexagon heatmaps**, **pie and donut charts**, **sunbursts**, **radar charts**, **parallel coordinates**, and **tree maps**.\n\nSome notable features:\n\n- Simplicity. `react-vis` doesn't require any deep knowledge of data visualization libraries to start building your first visualizations.\n- Flexibility. `react-vis` provides a set of basic building blocks for different charts. For instance, separate X and Y axis components. This provides a high level of control of chart layout for applications that need it.\n- Ease of use. The library provides a set of defaults which can be overridden by the custom user's settings.\n- Integration with React. `react-vis` supports the React's lifecycle and doesn't create unnecessary nodes.\n\n## Usage\n\nInstall react-vis via npm.\n\n    npm install react-vis --save\n\nInclude the built main CSS file in your HTML page or via SASS:\n```scss\n@import \"~react-vis/dist/style\";\n```\n\nYou can also select only the styles you want to use. This helps minimize the size of the outputted CSS. Here's an example of importing only the legends styles:\n```scss\n@import \"~react-vis/dist/styles/legends\";\n```\n\nImport the necessary components from the library...\n\n```jsx\nimport {XYPlot, XAxis, YAxis, HorizontalGridLines, LineSeries} from 'react-vis';\n```\n\n&hellip; and add the following code to your `render` function:\n\n```jsx\n<XYPlot\n  width={300}\n  height={300}>\n  <HorizontalGridLines />\n  <LineSeries\n    data={[\n      {x: 1, y: 10},\n      {x: 2, y: 5},\n      {x: 3, y: 15}\n    ]}/>\n  <XAxis />\n  <YAxis />\n</XYPlot>\n```\n\nIf you're working in a non-node environment, you can also directly include the bundle and compiled style using basic html tags.\n\n```html\n<link rel=\"stylesheet\" href=\"https://unpkg.com/react-vis/dist/style.css\">\n<script type=\"text/javascript\" src=\"https://unpkg.com/react-vis/dist/dist.min.js\"></script>\n```\n\nThe global `reactVis` object will now be available for you to play around.\n\nYou can checkout these example CodePens:\n[#1](https://codepen.io/Apercu/pen/mmLOpY?editors=0010),\n[#2](https://codepen.io/jckr/pen/oWZPJe?editors=0010),\n[#3](https://codepen.io/jckr/pen/BRpReQ?editors=0010) or\n[#4](https://codepen.io/jckr/pen/aWmRGx?editors=0010)\n\n## More information\n\nTake a look at the [folder with examples](docs/examples) or check out some docs:\n\n- Common concepts:\n  * [Scales and Data](docs/scales-and-data.md) about how the attributes can be adjusted.\n  * [Animations](docs/animation.md) about how to tweak animations in the library.\n- Components:\n  * [XYPlot](docs/xy-plot.md) about orthogonal charts.\n  * [RadialChart](docs/radial-chart.md) about radial charts.\n  * [Treemap](docs/treemap.md) about making tree maps.\n  * [Sankey](docs/sankey.md) about making sankey diagrams.\n  * [Radar Chart](docs/radar-chart.md) about making radar charts.\n  * [Parallel Coordinates](docs/parallel-coordinates.md) about making parallel coordinate charts.\n  * [Sunbursts](docs/sunburst.md) about making sunburst diagrams.\n  * [Legends](docs/legends.md) about the legends.\n\n## Development\nMake sure you are using the correct version of `node` and `yarn`. To do so, check `package.json` and find the entry \"volta\", e.g.\n\n```\n\"volta\": {\n  \"node\": \"14.18.0\",\n  \"yarn\": \"1.22.4\"\n}\n```\n\nIt's recommanded to install [volta](https://volta.sh/) to manage node and yarn.\n\nTo develop on react-vis, navigate to `packages/react-vis`, and install the dependencies and then build and watch the static files:\n\n    yarn && yarn start\n\nOnce complete, you can view the component's example in your browser (will open automatically).\nAny changes you make to the example code will run the compiler to build the files again.\n\nTo run the tests, and create code coverage reports:\n\n    yarn cover\n\n## Requirements\n\nreact-vis makes use of ES6 array methods such as [`Array.prototype.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find). If you make use of react-vis, in an environment without these methods, you'll see errors like `TypeError: Server rendering error: Object x,y,radius,angle,color,fill,stroke,opacity,size has no method 'find'`. You can use [`babel-polyfill`](https://babeljs.io/docs/usage/polyfill/) to polyfill these methods.\n"
  },
  {
    "path": "ROADMAP.md",
    "content": "# Roadmap\n\nThis document will be updated with the middle-term ambition for React-vis. \n\n## Current priority\n\nRight now the priority is to get React-Vis healthy and bug free while addressing as many open issues as possible.\n\nThese efforts are essentially focused towards what we consider the core of react-vis: AbstractSeries, ArcSeries, AreaSeries, AxisUtils, ContinuousColorLegend, ContinuousSizeLegend, Crosshair, DiscreteColorLegend, GridLines, Hint, HorizontalBarSeries, HorizontalGridLines, LabelSeries, LineSeries, MarkSeries, RadialChart, ScaleUtils, SearchableDiscreteColorLegend, VerticalBarSeries, VerticalGridLines, XAxis, XYPlot and YAxis.\n\n"
  },
  {
    "path": "babel.config.json",
    "content": "{\n  \"babelrcRoots\": [\n    \".\",\n    \"./packages/*\"\n  ],\n  \"env\": {\n    \"production\": {\n      \"presets\": [\n        \"@babel/preset-env\",\n        \"@babel/preset-react\"\n      ],\n      \"plugins\": [\n        \"@babel/plugin-proposal-class-properties\",\n        \"@babel/plugin-proposal-export-default-from\",\n        \"@babel/plugin-proposal-optional-chaining\",\n        \"@babel/plugin-proposal-nullish-coalescing-operator\"\n      ]\n    },\n    \"development\": {\n      \"presets\": [\n        \"@babel/preset-env\",\n        \"@babel/preset-react\"\n      ],\n      \"plugins\": [\n        \"@babel/plugin-proposal-class-properties\",\n        \"@babel/plugin-proposal-export-default-from\",\n        \"@babel/plugin-proposal-optional-chaining\",\n        \"@babel/plugin-proposal-nullish-coalescing-operator\"\n      ]\n    },\n    \"es\": {\n      \"presets\": [\n        [\n          \"@babel/preset-env\",\n          {\n            \"modules\": false\n          }\n        ],\n        \"@babel/preset-react\"\n      ],\n      \"plugins\": [\n        \"@babel/plugin-proposal-class-properties\",\n        \"@babel/plugin-proposal-export-default-from\",\n        \"@babel/plugin-proposal-optional-chaining\",\n        \"@babel/plugin-proposal-nullish-coalescing-operator\"\n      ]\n    },\n    \"browser\": {\n      \"presets\": [\n        \"@babel/preset-env\",\n        \"@babel/preset-react\"\n      ],\n      \"plugins\": [\n        \"@babel/plugin-proposal-class-properties\",\n        \"@babel/plugin-proposal-export-default-from\",\n        \"@babel/plugin-proposal-optional-chaining\",\n        \"@babel/plugin-proposal-nullish-coalescing-operator\",\n        [\"@babel/plugin-transform-runtime\",\n          {\n            \"regenerator\": true\n          }\n        ]\n      ]\n    }\n  }\n}"
  },
  {
    "path": "docs/animation.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Animation\n\nAnimation makes your charts feel physical, it makes them feel alive, shoot it makes them feel l33t. `react-vis` offers a simple portal into the [react-motion](https://github.com/chenglou/react-motion) animation system by exposing a simple animation prop on most components! This prop accepts three types of values:\n\n*Booleans*: if true is present then `react-vis` will use the `no-wobble` preset (see below)\n\n*Strings*: react-motion offers several different motion presets that cover most use cases. To access them set your animation prop to one of [noWobble, gentle, wobbly, stiff].\n\n<!-- INJECT:\"AnimationExampleWithLink\" -->\n\n*Objects*: react-motion expects an object formatting like `{damping: NUMBER, stiffness: NUMBER}`, and if you want to give us an object like that, we will hand it direct to react-motion. You can also pass an object with `{nonAnimatedProps: ['foo', 'bar']}` to prevent those props from being interpolated by d3-interpolator.\n\n<!-- INJECT:\"TreemapExampleWithLink\" -->\n\nThe above example has `animation: {damping: 9, stiffness: 300}`!\n\n**NOTE** In Jsx the presence of the animation prop is enough to trigger an animation, eg\n\n```javascript\n<MarkSeries\n  data={nodes}\n  animation\n  colorType={'category'}\n  stroke={'#ddd'}\n  strokeWidth={2}\n  colorRange={colors}\n  />\n```\n\nWill be treated as true. If you want to include the animation prop but not have animation be engaged, you need to use animation={null}!\n"
  },
  {
    "path": "docs/arc-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## ArcSeries:\n\n<!-- INJECT:\"ArcSeriesExampleWithLink\" -->\n\nThe arc series allows users to specify arbitrary arcs in the plane! This is useful for making pie charts, sunbursts, and anything else circular.\n\n```javascript\n<XYPlot\n  xDomain={[-5, 5]}\n  yDomain={[-5, 5]}\n  width={300}\n  height={300}>\n  <ArcSeries\n    animation\n    radiusType={'literal'}\n    center={{x: -2, y: 2}}\n    data={myData}\n    colorType={'literal'}/>\n</XYPlot>\n```\n\nA key point: XYPlot infers the necessary x and y domains by converting the angular coordinates to cartesian. If you want to guarantee a centered plot it is advisable to set the x and y domain's yourself, as above.\n\n## Data format Reference\n\nArc series works a little bit different than other series. The most natural language to describe arcs is using polar coordinates, so we allow\nusers to write just that:\n\n```javascript\nconst myData = [\n  {angle0: 0, angle: Math.PI / 4, opacity: 0.2, radius: 2, radius0: 1},\n  {angle0: PI / 4, angle: 2 * PI / 4, radius: 3, radius0: 0},\n  {angle0: 2 * PI / 4, angle: 3 * PI / 4, radius: 2, radius0: 0},\n  {angle0: 3 * PI / 4, angle: 4 * PI / 4, radius: 2, radius0: 0},\n  {angle0: 4 * PI / 4, angle: 5 * PI / 4, radius: 2, radius0: 0},\n  {angle0: 0, angle: 5 * PI / 4, radius: 1.1, radius0: 0.8}\n]\n```\n\nangle0 describes the start of the arc in radians, and angle describes the end of the arc, again in radians. radius0 describes the inner distance from the origin, while radius describes the outer distance to the origin. It is recommended to provide all four of these quantities to format your arcs well.\n\n#### angle0\n\nType: `number`\n\nThe start position of the arc in radians. This quantity is returned literally by default.\n\n#### angle\n\nType: `number`\n\nThe end position of the arc in radians. This quantity is returned literally by default.\n\n#### radius0\n\nType: `number`\n\nThe distance between the origin and the inside of the arc. This values is scaled linearly by default\n\n#### radius\n\nType: `number`\n\nThe distance between the origin and the outside of the arc. This values is scaled linearly by default\n\n#### radiusDomain\n\nType: `array of numbers`\n\nThe domain over which the radius is scaled. This can be an essential element in getting your arcs to look right, the automatic inference for the prop tends to be somewhat inaccurate, so it is highly encourage that you set it for your self as appropriate. For example: [0, 3]. See the code for ArcSeriesExample for more.\n\n#### color (optional)\n\nType: `string|number`\n\nThe color of an arc in the series. By default, the color is interpreted as number to be scaled to a color range. This can be over-ridden by providing the prop colorType=\"literal\" to the series itself. This property can also be defined on the series level. See [colors](colors.md)\n\n#### fill (optional)\n\nType: `string|number`\n\nThe inner color of an arc in the series. If `fill` and `color` are provided, `fill` will override `color`. By default, the color is interpreted as number to be scaled to a color range. This can be over-ridden by providing the prop fillType=\"literal\" to the series itself. This property can also be defined on the series level. See [colors](colors.md)\n\n#### stroke (optional)\n\nType: `string|number`\n\nThe outer color of an arc in the series (i.e. its outline). If `stroke` and `color` are provided, `stroke` will override `color`. By default, the color is interpreted as number to be scaled to a color range. This can be over-ridden by providing the prop strokeType=\"literal\" to the series itself. This property can also be defined on the series level. See [colors](colors.md)\n\n#### opacity (optional)\n\nType: `string|number`\n\nDefault: 1\n\nThe opacity of an arc in the series, from 0 (transparent) to 1 (opaque).\n\n#### padAngle (optional)\n\nType: `number|function`\n\nThe padding to be applied between arcs.\n\n<!-- INJECT:\"ClockExampleWithLink\" -->\n\n## Series API Reference\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### center\n\nType: `Object` of the form `{x, y}`, where x and y are in coordinates\n\nThis allows users to specify the origin of their arcs.\n\n#### color\n\nType: `string|number`\n\nThe color for all elements in the series, this property will be over-ridden by color specified in the data attribute.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. See above data format reference.\n\n#### fill\n\nType: `string|number`\n\nThe inner color for all elements in the series, this property will be over-ridden by color specified in the data attribute.\n\n#### opacity\n\nType: `string|number`\n\nThe opacity for all elements in the series, this property will be over-ridden by color specified in the data attribute.\n\n#### stroke\n\nType: `string|number`\n\nThe outer color for all elements in the series, this property will be over-ridden by color specified in the data attribute.\n\n#### style (optional)\n\nType: `object`\n\nSVG paths (which is what the arc series is made up of) have numerous manipulable properties, so rather than trying to prescribe all of them as props we offer a port to let you style it for yourself.\n\n## Interaction handlers\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onSeriesClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user clicks somewhere on a series, and provides the corresponding event. Unlike onClick, it doesn't pass a specific datapoint.\n\n```jsx\n<ArcSeries\n...\n  onSeriesClick={(event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user's mouse cursor leaves a series, and provides the corresponding event. Unlike onValueMouseOut, it doesn't pass a specific datapoint.\n\n```jsx\n<ArcSeries\n...\n  onSeriesMouseOut={(event)=>{\n    // does something on mouse over\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user mouses over a series, and provides the corresponding event. Unlike onValueMouseOver, it doesn't pass a specific datapoint.\n\n```jsx\n<ArcSeries\n...\n  onSeriesMouseOver={(event)=>{\n    // does something on mouse over\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user right-clicks somewhere on a series, and provides the corresponding event. Unlike onClick, it doesn't pass a specific datapoint.\n\n```jsx\n<ArcSeries\n...\n  onSeriesRightClick={(event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<ArcSeries\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse leaves a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<ArcSeries\n...\n  onValueMouseOut={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse enters a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<ArcSeries\n...\n  onValueMouseOver={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user right-clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<ArcSeries\n...\n  onValueRightClick={(datapoint, event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n```\n"
  },
  {
    "path": "docs/area-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# AreaSeries\n\n<!-- INJECT:\"AreaChartWithLink\" -->\n\nIn addition to the LineSeries, react-vis offers a similar chart type for area charts.\nLike LineSeries, AreaSeries:\n- are styled at the series level, not at the mark level.\n- can have a curve property for a different interpolation between points.\n\nUnlike LineSeries, AreaSeries:\n- have a fill property. By default, the color property affects both the fill color and the outline color of the area charts. However, these two can be set independently,\n- don't have an API to style the stroke beyond color. It's still possible to use the style property, though.\n- can be stacked,\n- do not have a canvas equivalent.\n\nThe stroke property of an AreaChart creates an outline around the whole shape of the chart (including to its left, right and bottom.) To create a chart that has a fill, no distinct lines to the left, right or bottom, but a different line style at the top, you may create an area chart with a line chart on top.\n\n## Data format reference\n\n#### x\n\nType: `number`\n\nLeft-to-right position of marks in the series.\n\n#### y\n\nType: `number`\n\nTop-to-bottom position of the top edge of the series.\n\n#### y0\n\nType: `number`\n\nDefault: `0`\n\nTop-to-bottom position of the bottom edge of the series.\n\n## API Reference\n\n#### color (optional)\n\nType: `string|number`\n\nDefault: see [colors](colors.md)\n\nA color for both the fill and the outline of the area series. Will be overridden by both the fill and the stroke property, if provided.\n\n#### curve (optional)\n\nType: `string|function`\n\nDefault: `null`\n\nApply the provided or named curve function from the D3 shape library to smooth the line series plot, see [the D3 documentation](https://github.com/d3/d3-shape#curves) for function names and instructions. Providing the function, not the name, will require importing the d3-shape package in order to configure it:\n\n```javascript\n// Setting up with only a name\nconst stringCurveProp = <AreaSeries data={data} curve={'curveMonotoneX'} .../>;\n\nconst configuredCurve = d3Shape.curveCatmullRom.alpha(0.5);\nconst funcCurveProp = <AreaSeries data={data} curve={configuredCurve} .../>;\n```\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. See above data format reference.\n\n#### fill (optional)\n\nType: `string|number`\n\nDefault: see [colors](colors.md)\n\nA color for the fill of the area series. Will override the color property if both are provided.\n\n#### getNull (optional)\n\nType: `function`\n\nDefault: `null`\n\nA function that will be invoked for each data element that will return a boolean that specifies if the data point should be drawn or not. For more information see [the D3 documentation](https://github.com/d3/d3-shape#area_defined).\n\n```javascript\n// Only draw datapoints where the y value is not equal to null\n<AreaSeries getNull={(d) => d.y !== null} data={data} />\n```\n\n#### opacity (optional)\n\nType: `number`\n\nDefault: `1`\n\nOpacity of the area chart from 0 (transparent) to 1 (opaque).\n\n#### stroke (optional)\n\nType: `string|number`\n\nDefault: see [colors](colors.md)\n\nA color for the outline of the area series. Will override the color property if both are provided.\n\n#### style (optional)\n\nType: `object`\n\nAn object which holds CSS properties that will be applied to the SVG element(s) rendered by the series. This allows you to style series beyond the other explicitly defined properties and without having to use CSS classnames and stylesheets. See [style](style.md)\n\n```jsx\n<AreaSeries\n  data={data}\n  style={{strokeDasharray: \"2 2\"}}\n/>\n```\n\n### Interaction handlers\n\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n```jsx\n<AreaSeries\n...\n  onNearestX={(datapoint, event)=>{\n  \t// does something on mouseover\n  \t// you can access the value of the event\n  }}\n```\n\n#### onSeriesClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user clicks somewhere on an AreaSeries, and provides the corresponding event. See [interaction](interaction.md)\n\n```jsx\n<AreaSeries\n...\n  onSeriesClick={(event)=>{\n  \t// does something on click\n  \t// you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user's mouse cursor leaves an AreaSeries, and provides the corresponding event. See [interaction](interaction.md)\n\n```jsx\n<AreaSeries\n...\n  onSeriesMouseOut={(event)=>{\n  \t// does something on mouse over\n  \t// you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user mouses over an AreaSeries, and provides the corresponding event. See [interaction](interaction.md)\n\n```jsx\n<AreaSeries\n...\n  onSeriesMouseOver={(event)=>{\n  \t// does something on mouse over\n  \t// you can access the value of the event\n  }}\n```\n"
  },
  {
    "path": "docs/axes.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Axes\n\n<!-- INJECT:\"CustomAxesOrientationWithLink\" -->\n\n`XAxis` and `YAxis` shows are responsible for the axis in the chart. They can be used simply\n\n```javascript\n<XYPlot\n  width={300}\n  height={300}>\n  <XAxis />\n  <YAxis />\n  <MarkSeries data={myData}/>\n</XYPlot>\n```\n\nWhich will automatically interpolate across the relevant domains of the data (ie it will present reasonable values for x and y). It can also be used to create more complex axes\n\n<!-- INJECT:\"CustomAxesWithLink\" -->\n\nWhich is produced via\n\n```javascript\n<XYPlot width={300} height={300}>\n  <XAxis top={0} hideLine tickValues={[0, 1, 3, 4, 5]} title=\"X\"/>\n  <XAxis tickFormat={v => `Value is ${v}`} tickLabelAngle={-90} />\n  <YAxis hideTicks/>\n  <YAxis left={50} tickFormat={v => v * v}/>\n  <YAxis hideLine left={150} tickFormat={v => WORDS[v]}/>\n  <MarkSeries data={[{x: 0, y: 0}, {x: 5, y: 5}]} opacity={0} opacityType=\"linear\"/>\n</XYPlot>\n```\n\nFor greater control over the specific styling and placement of the axis label, please see [ChartLabel](chart-label.md).\n\n## API Reference\n\n#### title (optional)\n\nType: `string`\n\nShows the title for the axis.\n\n#### orientation (optional)\n\nType: `'top'|'left'|'bottom'|'right'`\n\nThe position of the axis inside the chart.\nBy default **it is already set** to `'bottom'` for `XAxis` and to `'left'` for `YAxis`. Similar to how the axis are oriented in d3-axis.\n\n#### position (optional)\n\nType: `'end'|'middle'|'start'`\n\nThe position of the title relative to the axis. This value is set to `'end'` by default (i.e. towards the left of a horizontal axis, towards the top of a vertical axis.)\n\n#### tickTotal (optional)\n\nType: `number`\n\nTotal number of ticks on the axis. Already set by default. Similar to the `tickTotal()` method of d3-axis.\n\n#### tickValues (optional)\n\nType: `Array<*>`\n\nAn array of values (not coordinates!) that where the ticks should be shown. Similar to the `tickValues()` method of d3-axis.\n\n#### tickFormat (optional)\n\nType: `function(value, index, scale, tickTotal)`\n\nFormat function for the tick label. Similar to the `tickFormat()` method of d3-axis. Typically the value that is returned is a string or a number, however this function also supports rendering SVG React elements. To wit, I could have formatting function like\n\n```javascript\nfunction myFormatter(t, i) {\n  return (<tspan>\n    <tspan x=\"0\" dy=\"1em\">MY VALUE</tspan>\n    <tspan x=\"0\" dy=\"1em\">{t}</tspan>\n  </tspan>);\n}\n```\n\nOr you can customize the tick formatting by calling the `tickFormat()` function on the d3-scale by yourself and pass additional formatting parameters (e.g s for SI-prefix).\n```javascript\nfunction mySIPrefixFormatter(value, index, scale, tickTotal) {\n  return `${scale.tickFormat(tickTotal, 's')(value)}Wh`;// -> e.g. 1.2kWh\n}\n```\n\n**Note!** The return value will be wrapped with a `<text>` node if it's a string, `<tspan>`, or `<textPath>`. In all other cases the returned element will replace the `<text>` node. In case it's a custom React element it will also receive two additional props: `containerWidth` and `tickCount`. This way you can e.g. render a `<div>` to truncate long labels:\n\n```javascript\nconst MyLabel = props => (\n  <foreignObject>\n    <div\n      xmlns=\"http://www.w3.org/1999/xhtml\"\n      style={{\n        width: props.containerWidth / props.tickCount, overflow: 'hidden',\n        whiteSpace: 'nowrap'\n      }}\n    >\n      {props.children}\n    </div>\n  </foreignObject>\n);\n\nfunction myFormatter(value) {\n  return <MyLabel>{value}</MyLabel>;\n}\n\n<XAxis tickFormat={myFormatter} />\n```\n\n<!-- INJECT:\"CustomAxisTickElement\" -->\n\n#### tickSize (optional)\n\nType: `number`\n\nDefault: `6`\n\nTick size for the axis. Sets both inner and outer sizes of the tick line. Similar to the `tickSize()` method of d3-axis.\n\n#### tickSizeOuter (optional)\n\nType: `number`\n\nDefault: `null`\n\nTick size for the axis. Sets the outer size of the tick line. Similar to the `tickSizeOuter()` method of d3-axis.\n\nNOTE: 1.0.0 and onwards now properly draws outer tick using this value. Previously, this value affected the drawing of inner tick.\n\n#### tickSizeInner (optional)\n\nType: `number`\n\nDefault: `null`\n\nTick size for the axis. Sets the inner size of the tick line. Similar to the `tickSizeInner()` method of d3-axis.\n\nNOTE: v1.0.0+ properly draws inner tick using this value. Previously, this value affected the drawing of outer tick.\n\n#### tickPadding (optional)\n\nType: `number`\n\nDefault: `2`\n\nDistance between the tick and the text of the tick in pixels. Similar to the `tickPadding()` method of d3-axis.\n\n#### tickLabelAngle (optional)\n\nType: `number`\n\nDefault: `0`\n\nThe angle of the tick label. Can be used to fit the long labels of the axis without truncation.\n\n#### left (optional)\n\nType: `number`\n\nHorizontal position of the axis in pixels. **Already set by default**, but can be overridden by the user.\n\n#### top (optional)\n\nType: `number`\n\nVertical position of the axis in pixels. **Already set by default**, but can be overridden by the user.\n\n#### width (optional)\n\nType: `number`\n\nWidth of the axis in pixels. **Already set by default**, but can be overridden by the user.\n\n#### height (optional)\n\nType: `number`\n\nHeight of the axis in pixels. **Already set by default**, but can be overridden by the user.\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### style (optional)\n\nType: `object`\n\nAn object that contains CSS properties with which the axis component can be entirely re-styled.\nAs the Axis component is composite, it is possible to style its different parts individually. See [style](style.md)\n\nThe various parts of the axis can be styled by passing an object to the `line`, `ticks`, `text` and `title` properties:\n\n```jsx\n<XAxis title=\"X Axis\" style={{\n  line: {stroke: '#ADDDE1'},\n  ticks: {stroke: '#ADDDE1'},\n  text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}\n}}/>\n```\n"
  },
  {
    "path": "docs/bar-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# Bar Series\n\n**TLDR**: use bar series to make bar charts, but not histograms.\n\nBar series allows users to construct charts that contain rectangles that are oriented either left-right or top-bottom. This type: of series is generally used to visualize mappings of categorical data to quantitative data. For instance if you had counts of pigeon sightings by season, that would be a perfect bar series (`[{x: 'winter', y: 10}, {x: 'spring', y: 100}, {x: 'summer', y: 10000}, {x: 'fall', y: 10}]`), while if that data was represented as the individual records of your sightings of pigeons (`[{x: May 1st 2pm}, {x: May 12th 1am}]`) you might either want a mark-series (to make a scatterplot) or a rect-series (to make a histogram).\n\n<!-- INJECT:\"BarChartWithLink\" -->\n\nBar series come in two flavors, `HorizontalBarSeries` and `VerticalBarSeries`. VerticalBarSeries have vertical bars, HorizontalBarSeries have horizontal bars, plain and simple!\n\n<!-- INJECT:\"StackedHorizontalBarChartWithLink\" -->\n\n## Data format Reference\n\nLike other series, it is required that the data be an array of objects, formatted like so:\n\n\n```javascript\nconst myData = [\n  {x: 'A', y: 10},\n  {x: 'B', y: 5},\n  {x: 'C', y: 15}\n]\n```\n\nWhere x and y are required quantities and additional properties may be stapled on.\n\n#### x\nType: (VerticalBarSeries): `string|number`\n\nType: (HorizontalBarSeries): `number`\n\nThe x position in coordinates of the box to be used. This quantity is treated as a category (at least in VerticalBarSeries) and so considers the exact left-right positioning to be not that important (which is something to watch out for if you are providing exact numbers, in such a case it is better to the rect-series).\n\n#### y\nType: (VerticalBarSeries): `number`\n\nType: (HorizontalBarSeries): `string|number`\n\nThe y position in coordinates of the box to be used. For VerticalBarSeries this value is considered a number, and is scaled against it's domain into pixels.\n\n<!-- INJECT:\"DifferenceChartWithLink\" -->\n\n#### y0\n(Optional)\nType: (VerticalBarSeries): `number`\n\nType: (HorizontalBarSeries): `string|number`\n\nThe y0 position in coordinates of the box to be used, this is where the bottom of the bar is placed, defaults to zero. Use is not recommended with stacked bars. For VerticalBarSeries this value is considered a number, and is scaled against it's domain into pixels.\n\n#### color (optional)\n\nType: `string|number`\n\nThe color of a bar in the series. By default the color is interpreted as number to be scaled to a color range. This can be over-ridden by providing the prop colorType=\"literal\" to the series itself. This property can also be defined on the series level.\n\n#### opacity (optional)\n\nType: `number|Object`\n\nOpacity of the individual box to be rendered. By default opacity is scaled by `literal`, so the exact value provided will be used. This property can also be defined on the series level.\n\n#### stroke (optional)\n\nType: `number|Object`\n\nThe color of the outline of the box to be rendered. When this value is not provided the color attribute is used instead. This property can also be defined on the series level.\n\n#### fill (optional)\n\nType: `number|Object`\n\nThe color of the inside of the box to be rendered. When this value is not provided the color attribute is used instead. This property can also be defined on the series level.\n\n## Series API Reference\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### color\n\nType: `string|number`\n\nThe color for all elements in the series, this property will be over-ridden by color specified in the data attribute. See [colors](colors.md)\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### cluster\nSupply a clustering key for this series.\nWhen used with the `stackBy` attribute, creates a clustered stacked bar chart. Returning to our pigeon example from earlier, if you had multiple years of pigeon sightings by season and you wanted to compare the season, clustering would be a great way to do that.\n\n<!-- INJECT:\"ClusteredStackedVerticalBarChartWithLink\" -->\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. See above data format reference.\n\n#### fill\n\nType: `string|number`\n\nThe inner color for all elements in the series, this property will be over-ridden by fill specified in the data attribute. See [colors](colors.md)\n\n#### opacity\n\nType: `string|number`\n\nThe opacity for all elements in the series, this property will be over-ridden by color specified in the data attribute.)\n\n#### stroke\n\nType: `string|number`\n\nThe outer color for all elements in the series, this property will be over-ridden by stroke specified in the data attribute. See [colors](colors.md)\n\n#### style\n\nType: `object`\n\nA list of CSS properties to style the series outside of the explicitly set properties. Note that it will override all other properties (ie fill, stroke, opacity, color). See [style](style.md)\n\n#### barWidth\nType: `Number`\nThe percentage for which each bar fills the designated bucket. 1.0 means that the bar fills the whole bucket (no padding between bars), while a \nsmaller percentage means more whitespace between the bars.\n\n## Interaction handlers\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onSeriesClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user clicks somewhere on a series, and provides the corresponding event. Unlike onClick, it doesn't pass a specific datapoint.\n\n```jsx\n<BarSeries\n...\n  onSeriesClick={(event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user's mouse cursor leaves a series, and provides the corresponding event. Unlike onValueMouseOut, it doesn't pass a specific datapoint.\n\n```jsx\n<BarSeries\n...\n  onSeriesMouseOut={(event)=>{\n    // does something on mouse over\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user mouses over a series, and provides the corresponding event. Unlike onValueMouseOver, it doesn't pass a specific datapoint.\n\n```jsx\n<BarSeries\n...\n  onSeriesMouseOver={(event)=>{\n    // does something on mouse over\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user right-clicks somewhere on a series, and provides the corresponding event. Unlike onClick, it doesn't pass a specific datapoint.\n\n```jsx\n<BarSeries\n...\n  onSeriesRightClick={(event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<BarSeries\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse leaves a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<BarSeries\n...\n  onValueMouseOut={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse enters a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<BarSeries\n...\n  onValueMouseOver={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user right-clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<BarSeries\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n```\n"
  },
  {
    "path": "docs/borders.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Borders\n\nSometimes when modifying the domain of the XYPlot it can be useful to enforce a border, so that some components appear, and others do not. One way to do this is to use the `Borders` component. It is a simple component that creates rectangles the directly correspond to the margins of the plot.\n\n<!-- INJECT:\"GradientExampleWithLink\" -->\n\nFor example, a set up like this:\n\n```jsx\n<XYPlot xDomain={[1.2, 3]} yDomain={[11, 26]} width={300} height={300}>\n  <AreaSeries\n    data={[\n      {x: 1, y: 10, y0: 1},\n      {x: 2, y: 25, y0: 5},\n      {x: 3, y: 15, y0: 3}\n    ]}/>\n  <Borders style={{\n    bottom: {fill: '#fff'},\n    left: {fill: '#fff'},\n    right: {fill: '#fff'},\n    top: {fill: '#fff'}\n  }}/>\n  <XAxis />\n  <YAxis />\n  <AreaSeries\n    data={[\n      {x: 1, y: 5, y0: 6},\n      {x: 2, y: 20, y0: 11},\n      {x: 3, y: 10, y0: 9}\n    ]}/>\n</XYPlot>\n```\n\nwould cause the first area series to be truncated underneath the borders, while the second one would not be! This level of granular border control can be useful if you are using multiple kinds of series, for instance if you have a mark series that you wish to show the entire mark for, and a line series that you are alright with truncating at the border.\n\n## API Reference\n\n#### className (optional)\n\nType: `String`\n\nA class name to apply to each of the borders, as well as the root border container. It will be enumerates on top the borders using suffixes, eg if className={\"my-cool-class\"} the top rectangle will have a class name \"my-cool-class-top\".\n\n#### style (optional)\n\nType: `Object`\n\nYou can pass a style object to your Hint component to apply your own styles. See [style](style.md)\n```jsx\n<Borders style={{\n  bottom: {fill: '#fff'},\n  left: {fill: '#fff'},\n  right: {fill: '#fff'},\n  top: {fill: '#fff'}\n}}/>\n```\n\nBecause border its made up of four individual rectangular components (there being four borders on an XYPlot) it is advisable to specify styles for all four rectangles. This can be done using either the style object or css-classes. Alternatively, if all the borders should be treated the same, this can be achieved by supplying an all object to style. This can be then over-ridden:\n\n```jsx\n<Borders style={{\n  all: {fill: '#fff'}\n  bottom: {fill: '#0f0'}\n}}/>\n```\n"
  },
  {
    "path": "docs/chart-label.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## ChartLabel\n\nWhen you are styling your chart sometimes you just want to take complete control of label placements. Maybe you want to annotate something, or maybe you just want to place your axis labels in a very specific place, ChartLabel allows you to do just that. Let's look at an example:\n\n```jsx\n<XYPlot width={300} height={300}>\n  <HorizontalGridLines />\n  <VerticalGridLines />\n  <XAxis />\n  <YAxis />\n  <ChartLabel\n    text=\"X Axis\"\n    className=\"alt-x-label\"\n    includeMargin={false}\n    xPercent={0.025}\n    yPercent={1.01}\n    />\n\n  <ChartLabel\n    text=\"Y Axis\"\n    className=\"alt-y-label\"\n    includeMargin={false}\n    xPercent={0.06}\n    yPercent={0.06}\n    style={{\n      transform: 'rotate(-90)',\n      textAnchor: 'end'\n    }}\n    />\n  <Line data={[{x: 1, y: 3}, {x: 2, y: 5}, {x: 3, y: 15}, {x: 4, y: 12}]} />\n</XYPlot>\n```\n\nThis usage is the same as using title on the XAxis or YAxis, however it allows us greatly flexibility in terms of styles and placement. It is significantly more verbose than using the basic methods on Axis, but the it allows you to do whatever you want. You could place your axis label in the center! You could make them diagonal or a really big. The world is your oyster.\n\nThis element is different then the [LabelSeries](label-series.md) because the elements that it describes ARE NOT data carrying. This element will not affect the computed domain or range. It'll just go where you place it and it won't affect anything else.\n\n\n## API Reference\n\n\n#### text\n\nType: `string`\n\nThe content of the label\n\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name the label.\n\n\n#### includeMargin (optional)\n\nType: `Boolean`\n\nDefaults to true\n\nWhether or not to use compute the percentage placement with the margins or not.\n\n\n#### xPercent\n\nType: `Number` (between 0 and 1)\n\nWhere to place the label on the charts width, expressed as percentage (of the width). If the includeMargin flag is included, then this percentage is of the total width, if not then it is of just the inner chart area.\n\n\n#### yPercent\n\nType: `Number` (between 0 and 1)\n\nWhere to place the label on the charts height, expressed as percentage (of the height). If the includeMargin flag is included, then this percentage is of the total height, if not then it is of just the inner chart area.\n\n\n#### style\n\nType: `object`\n\nThe specific styles to apply to the text element of the label. These styles are applied directly to the dom object and are interpreted as SVG styles (as opposed to CSS styles).\n"
  },
  {
    "path": "docs/clip.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Clip\n\nDepending on the data and domain, sometimes the series in the plot will extend into the axis. This can either be solved with a [Border](border.md), or the elements can be clipped.\n\nTo have the rendered series, clipped you will need to set up a `clipPath` (see [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath)) and tell the series to use it.\n\nAs seen below, the `clipPath` can be created with the `ContentClipArea` component, and its `id` can be referenced by the components that want to be clipped.\n\n```jsx\n<XYPlot>\n  <ContentClipArea id=\"clip\" />\n  <LineSeries style={{clipPath: 'url(#clip)'}} />\n</XYPlot>\n```\n\n\n\n## API Reference\n\n#### id (optional)\n\nType: `String`\n\nThe id to assign to the `clipArea`. If not provided, this will default to `content-area`\n"
  },
  {
    "path": "docs/colors.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Color\n\nColor can be set and affected in many ways in React-vis.\nThe main principles are:\n* sensible defaults - your chart should look good even if you don't do anything;\n* respect of specificity - you can change things at a high level (ie <XYPlot /> component) but override this at the series level and, when relevant, at the mark level.\n* flexibility - everything down to the humble tick can be colored and recolored.\n\n### Setup\n\nIn this document, let's look at how different color choices affect 3 different mini charts.\nEach chart in the doc is made of 3 series with x going from 0 to 9 and random values of y between 0 and 10. The left-most chart is made of VerticalBarSeries, the middle one is made of 3 LineSeries, and the right-most one is made of MarkSeries.\n\nSo it goes like this:\n\n```jsx\n<XYPlot height={200} width={200}>\n  <VerticalBarSeries data={series1}/>\n  <VerticalBarSeries data={series2}/>\n  <VerticalBarSeries data={series3}/>\n</XYPlot>\n<XYPlot height={200} width={200}>\n  <LineSeries data={series1}/>\n  <LineSeries data={series2}/>\n  <LineSeries data={series3}/>\n</XYPlot>\n<XYPlot height={200} width={200}>\n  <MarkSeries data={series1}/>\n  <MarkSeries data={series2}/>\n  <MarkSeries data={series3}/>\n</XYPlot>\n```\n\n### Cases\n\nWe do nothing:\n\n<!-- INJECT:\"SensibleDefaultsWithLink\" -->\n\nWith no color instruction, colors are automatically set by series according to the default react-vis palette, which is:\n\n<!-- INJECT:\"ReactVis5WithLink\" -->\n\nWe specify color in XYPlot\n\n```jsx\n<XYPlot height={200} width={200} color=\"red\">\n  <VerticalBarSeries data={series1}/>\n  <VerticalBarSeries data={series2}/>\n  <VerticalBarSeries data={series3}/>\n</XYPlot>\n<XYPlot height={200} width={200} stroke=\"red\">\n  <LineSeries data={series1}/>\n  <LineSeries data={series2}/>\n  <LineSeries data={series3}/>\n</XYPlot>\n<XYPlot height={200} width={200} color=\"red\">\n  <MarkSeries data={series1}/>\n  <MarkSeries data={series2}/>\n  <MarkSeries data={series3}/>\n</XYPlot>\n```\n\n<!-- INJECT:\"ColorInXYPlotWithLink\" -->\n\nWithout any further instruction, all the series are red. Note that in the case of LineSeries, we have to use stroke instead of color for this effect to work.\n\nWe specify color by series\n\nThe next step is passing colors to by series. When we do that, we add a color prop to each series component:\n\n```jsx\n<LineSeries data={series1} color=\"1\" />\n<LineSeries data={series2} color=\"red\" />\n```\n\nHow this color information is going to be treated depends on a number of factors.\n\nColor scales\n\nOnce it's passed through series, color works like a [scale](scales-and-data.md); in other words, it transforms data into a visual representation.\nThere are several types of scales.\n\nA linear scale works with a range of numerical values on one hand (\"domain\"), and two colors on the other hand (\"range\"). If given a numerical value in the domain, it transforms it into a color in the range depending on how far into the domain that value was. If given the minimum value of the domain, the scale will return the first color of the range. If given the maximum value of the domain, it will return the second color of the range. And if given a value in between, it will return an interpolation between these two colors - the closer that value is from the minimum, the more it will look like the first color, and the closer it is to the maximum, the more it will look like the second. Else, it's a proportional mix of the two.\n\nFor example, if a domain is [0, 1] and the range is ['black', 'white'], 0 will become 'black', 1 will become 'white', and 0.2 will become '#333333' (20% between black and white)\n\nThe linear scale can be extended to work with multi-point domains and range. If you pass 3 (ordered) values to the domain, and 3 values to the range, when given a data point, the scale will figure out which segment of the domain this data point corresponds to, and will match it with the corresponding segment of the range.\n\nIf our domain is [0, 1, 2] and our range is now ['black', 'white', 'blue'], 0.2 will still be '#333333' (20% between the first 2 values), but 1.5 will become '#8080ff' (halfway between white and blue)\n\nA categorical color scale associates a discrete number of values (also called domain) to a discrete number of colors (also called range). One big difference is that the values can be number or strings.\nFor instance, if a categorical color scale has the domain: ['yes', 'maybe', 'no'] and the range ['blue', 'yellow', 'red'], it will transform 'yes' into 'blue' and 'no' into 'red'. There will be no interpolation. If it finds a value which is not in its domain, it will return undefined (which will be represented in black).\n\nFinally, the literal color scale just returns whatever is provided as is. With a literal color scale, we can have color names in the dataset, and they will be used without transformation.\n\nCategorical colors at series level\n\n<!-- INJECT:\"CategoryColorAtSeriesLevelWithLink\" -->\n\nFor this example, the XYPlot props are:\n\n```jsx\n<XYPlot height={200} width={200}\n  colorType=\"category\"\n  colorDomain={[0, 1, 2]}\n  colorRange={myPalette}\n>\n  <VerticalBarSeries data={series1} color={0} />\n  <VerticalBarSeries data={series2} color={1} />\n  <VerticalBarSeries data={series3} color={2} />\n</XYPlot>\n<XYPlot height={200} width={200}\n  colorType=\"category\"\n  colorDomain={[0, 1, 2]}\n  colorRange={myPalette}\n>\n  <LineSeries data={series1} color={0} />\n  <LineSeries data={series2} color={1} />\n  <LineSeries data={series3} color={2} />\n</XYPlot>\n<XYPlot height={200} width={200}\n  colorType=\"category\"\n  colorDomain={[0, 1, 2]}\n  colorRange={myPalette}\n>\n  <MarkSeries data={series1} color={0} />\n  <MarkSeries data={series2} color={1} />\n  <MarkSeries data={series3} color={2} />\n</XYPlot>\n```\n\nAs you can see, __using categorical color at the series level doesn't work for bar charts or scatterplots__. It does for line charts though.\n\nLinear colors at series level\n\n<!-- INJECT:\"LinearColorAtSeriesLevelWithLink\" -->\n\n```jsx\n<XYPlot height={200} width={200}\n  colorType=\"linear\"\n  colorDomain={[0, 1, 2]}\n  colorRange={myPalette}\n>\n  <VerticalBarSeries data={series1} color={0} />\n  <VerticalBarSeries data={series2} color={1} />\n  <VerticalBarSeries data={series3} color={2} />\n</XYPlot>\n<XYPlot height={200} width={200}\n  colorType=\"linear\"\n  colorDomain={[0, 1, 2]}\n  colorRange={myPalette}\n>\n  <LineSeries data={series1} color={0} />\n  <LineSeries data={series2} color={1} />\n  <LineSeries data={series3} color={2} />\n</XYPlot>\n<XYPlot height={200} width={200}\n  colorType=\"linear\"\n  colorDomain={[0, 1, 2]}\n  colorRange={myPalette}\n>\n  <MarkSeries data={series1} color={0} />\n  <MarkSeries data={series2} color={1} />\n  <MarkSeries data={series3} color={2} />\n</XYPlot>\n```\n\nLikewise, __using linear color at the series level only works for line charts__.\n\nLiteral colors at series level\n\n<!-- INJECT:\"LiteralColorAtSeriesLevelWithLink\" -->\n\n```jsx\n<XYPlot height={200} width={200}>\n  <VerticalBarSeries data={series1} color=\"#cd3b54\" />\n  <VerticalBarSeries data={series2} color=\"#59b953\" />\n  <VerticalBarSeries data={series3} color=\"#ba4fb9\" />\n</XYPlot>\n<XYPlot height={200} width={200}>\n  <LineSeries data={series1} color=\"#cd3b54\" />\n  <LineSeries data={series2} color=\"#59b953\" />\n  <LineSeries data={series3} color=\"#ba4fb9\" />\n</XYPlot>\n<XYPlot height={200} width={200}>\n  <LineSeries data={series1} color=\"#cd3b54\" />\n  <LineSeries data={series2} color=\"#59b953\" />\n  <LineSeries data={series3} color=\"#ba4fb9\" />\n</XYPlot>\n```\n\nHowever, setting color at the series level works for all kinds of charts. It's not even necessary to specify a color type, a domain or a range.\n\nWe specify color information at mark level\n\nFor this second series of charts, we are going to specify color information inside of our dataset (ie the series which will be passed to the props \"data\").\nPreviously, our datasets only included x and y information:\n```js\nconst series1 = [\n  {x: 0, y: 2},\n  {x: 1, y: 6},\n  ...\n];\n```\nNow, they will have a color information as well.\n* For our categorical examples, that color value will be a random integer between 0 and 10.\n* For our linear examples, that color value will be a random number between 0 and 10 (not necessarily an integer).\n* Finally, for our literal example, the color information will be the name of a color in hex format.\n\n\nCategorical colors at mark level\n<!-- INJECT:\"CategoryColorAtMarkLevelWithLink\" -->\n\n```jsx\n<XYPlot height={200} width={200} colorType=\"category\">\n  <VerticalBarSeries data={seriesWithColor1} />\n  <VerticalBarSeries data={seriesWithColor2} />\n  <VerticalBarSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200} colorType=\"category\">\n  <LineSeries data={seriesWithColor1} />\n  <LineSeries data={seriesWithColor2} />\n  <LineSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200} colorType=\"category\">\n  <MarkSeries data={seriesWithColor1} />\n  <MarkSeries data={seriesWithColor2} />\n  <MarkSeries data={seriesWithColor3} />\n</XYPlot>\n```\n\nSo what happens here?\n\nFor line charts, __nothing!__ They ignore colors at mark level. So they behave just like the default case (as if we passed no color information at all)\n\nFor the 2 other charts, marks are colored according to the default extended palette:\n\n<!-- INJECT:\"ReactVis20WithLink\" -->\n\nHere, I have specified the colorType prop at the XYPlot level. I could have done so at the series level, inside of each series component (it cascades down). However, I haven't specified a colorRange or a colorDomain.\n\nIt's going to use the default extended palette as the color range. We'll override this in the next example. As for domain, it's going to associate the first color value it finds in the dataset with the first color of the palette, the second distinct color it finds with the second color of the palette, and so on and so forth.\nWith this syntax, we'll render marks which have different color information in different colors, but we don't control which color. If we want to control which color a specific value is going to be associated with, we have to pass a colorDomain.\n\nCategorical colors at mark level, custom palette\n<!-- INJECT:\"CategoryColorAtMarkLevelCustomPaletteWithLink\" -->\n\n```jsx\n<XYPlot height={200} width={200} colorType=\"category\" colorRange={myPalette}>\n  <VerticalBarSeries data={seriesWithColor1} />\n  <VerticalBarSeries data={seriesWithColor2} />\n  <VerticalBarSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200} colorType=\"category\" colorRange={myPalette}>\n  <LineSeries data={seriesWithColor1} />\n  <LineSeries data={seriesWithColor2} />\n  <LineSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200} colorType=\"category\" colorRange={myPalette}>\n  <MarkSeries data={seriesWithColor1} />\n  <MarkSeries data={seriesWithColor2} />\n  <MarkSeries data={seriesWithColor3} />\n</XYPlot>\n```\n\nThis time, I'm passing a custom palette:\n\n<!-- INJECT:\"CustomPaletteWithLink\" -->\n\nBehavior for line chart is still identical, but the colors are different for our bar charts and scatterplots. As I'm not passing a color domain, I still don't control which value will be associated with which color - not super important since my color values are random numbers. But if order matters, a colorDomain is required.\n\nLinear colors at mark level, default palette\n\n<!-- INJECT:\"LinearColorAtMarkLevelNoPaletteWithLink\" -->\n\n```jsx\n<XYPlot height={200} width={200}>\n  <VerticalBarSeries data={seriesWithColor1} />\n  <VerticalBarSeries data={seriesWithColor2} />\n  <VerticalBarSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200}>\n  <LineSeries data={seriesWithColor1} />\n  <LineSeries data={seriesWithColor2} />\n  <LineSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200}>\n  <MarkSeries data={seriesWithColor1} />\n  <MarkSeries data={seriesWithColor2} />\n  <MarkSeries data={seriesWithColor3} />\n</XYPlot>\n```\n\nThe linear color scale is the default color scale. So, to get that behavior, we don't need to specify this colorType in XYPlot. Its associated color range was conceived by someone who really likes orange:\n\n<!-- INJECT:\"ContinuousWithLink\" -->\n\nI haven't specified the color range either. React-Vis will compute it by looking at the minimum and maximum value associated with color in all the series of a given XYPlot, and use that as the domain.\n\nThe line charts are still unaffected.\n\nLinear colors at mark level, custom palette\n\n<!-- INJECT:\"LinearColorAtMarkLevelWithLink\" -->\n\n```jsx\n<XYPlot height={200} width={200} colorRange={['#c7e9c0', '#00441b']}>\n  <VerticalBarSeries data={seriesWithColor1} />\n  <VerticalBarSeries data={seriesWithColor2} />\n  <VerticalBarSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200} colorRange={['#c7e9c0', '#00441b']}>\n  <LineSeries data={seriesWithColor1} />\n  <LineSeries data={seriesWithColor2} />\n  <LineSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200} colorRange={['#c7e9c0', '#00441b']}>\n  <MarkSeries data={seriesWithColor1} />\n  <MarkSeries data={seriesWithColor2} />\n  <MarkSeries data={seriesWithColor3} />\n</XYPlot>\n```\n\nHere's the same code, but we define the color range. This green palette comes from ColorBrewer.\n\nLiteral colors at mark level, default palette\n\n<!-- INJECT:\"LiteralColorAtMarkLevelWithLink\" -->\n\n```jsx\n<XYPlot height={200} width={200} colorType=\"literal\"}>\n  <VerticalBarSeries data={seriesWithColor1} />\n  <VerticalBarSeries data={seriesWithColor2} />\n  <VerticalBarSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200} colorType=\"literal\"}>\n  <LineSeries data={seriesWithColor1} />\n  <LineSeries data={seriesWithColor2} />\n  <LineSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200} colorType=\"literal\"}>\n  <MarkSeries data={seriesWithColor1} />\n  <MarkSeries data={seriesWithColor2} />\n  <MarkSeries data={seriesWithColor3} />\n</XYPlot>\n```\n\nFinally, we can pass literal color names in our dataset from our custom palette. The line charts are still not affected.\n\n### Going beyond\n\nIndependently control fill and stroke\n\nThe line chart series (LineSeries) is only a line, but most other series (AreaSeries, ArcSeries, BarSeries, HeatmapSeries, HexbinSeries, MarkSeries, RectSeries and their derivatives, including LineMarkSeries) involve 2D shapes that have both a fill color and a stroke color.\n\nIn SVG, those correspond to the fill and the stroke css properties (fillStyle and strokeStyle in canvas).\n\nWhen we pass color information, we set both the fill and stroke. However, we can set them independently by using \"fill\" or \"stroke\" instead of color.\n\nAs of this writing, ContourSeries and PolygonSeries don't follow this model and their color can only be controlled by \"color\".\n\n<!-- INJECT:\"CategoryColorAtMarkLevelFixedStrokeWithLink\" -->\n\n```jsx\n<XYPlot height={200} width={200} colorType=\"category\" stroke=\"#f70\">\n  <VerticalBarSeries data={seriesWithColor1} />\n  <VerticalBarSeries data={seriesWithColor2} />\n  <VerticalBarSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200} colorType=\"category\" stroke=\"#f70\">\n  <LineSeries data={seriesWithColor1} />\n  <LineSeries data={seriesWithColor2} />\n  <LineSeries data={seriesWithColor3} />\n</XYPlot>\n<XYPlot height={200} width={200} colorType=\"category\" stroke=\"#f70\">\n  <LineSeries data={seriesWithColor1} />\n  <LineSeries data={seriesWithColor2} />\n  <LineSeries data={seriesWithColor3} />\n</XYPlot>\n```\n\nHere, we set a stroke value at the XYPlot level for all of our charts. What happens?\n\nThe bar chart outerbox is now of that color,\n\nThe line series are now represented in that color - this takes over the default behavior,\n\nThe scatterplot dots are also now surrounded with that color.\n\nNote that in the case of a LineMarkSeries (a combination of a LineSeries and a MarkSeries) the stroke property will control both the color of the line and the stroke of the marks. If you want a different color, you can just instead create a LineSeries and a MarkSeries with the same data:\n\n<!-- INJECT:\"LineSeriesMarkSeriesWithLink\" -->\n\n```jsx\n<XYPlot height={200} width={600}>\n  <LineSeries data={series1} color={myPalette[0]} />\n  <MarkSeries data={series1} color={myPalette[0]} stroke=\"white\" />\n  <LineSeries data={series2} color={myPalette[1]} />\n  <MarkSeries data={series2} color={myPalette[1]} stroke=\"white\" />\n  <LineSeries data={series3} color={myPalette[2]} />\n  <MarkSeries data={series3} color={myPalette[2]} stroke=\"white\" />\n</XYPlot>\n```\n\nHere, I want my dots to have a white outline.\nWhy did I specify the color of each of my series? You might have to scroll all the way to the top for the answer! If I had done nothing all the colors of my series would have been taken from the default palette for each new series. So the first line series would have had the first color, then the first mark series would have had the _second_ color... and so on and so forth. By specifying a color, we are guaranteeing that the dots and the lines have the same color.\n\nUsing styles\n\nWe can pass style information to anything - XYPlot, series, mark - and override the look and feel of that element. Styles don't have to be static objects - they can be computed at run time. Styles are a different way to control colors. While using the color prop, or a color property in a dataset, can be much more concise, everything can be affected by styles - including non-mark elements such as ticks or gridlines. See [style](style.md) for more info.\n\nUsing specificity\n\nWe've seen that we can set color information at the plot level, at the series level and at the mark level. But what happens when we do it at several levels at the same time? The most specific wins.\n\nIf you need to color one element (say, one mark) differently from all the others, you can specify color at a higher level (say, the series or the plot) and only pass color information to the exception, rather than pass color information to all elements.\n\n<!-- INJECT:\"ColorSpecificityWithLink\" -->\n\n```jsx\n  <XYPlot {...defaultXYPlotProps} color=\"#12939A\" colorType=\"literal\">\n    <VerticalBarSeries data={seriesWithOneElementColored} />\n  </XYPlot>\n  <XYPlot {...defaultXYPlotProps} stroke=\"#e5e5e5\" strokeType=\"literal\">\n    <LineSeries data={series1} />\n    <LineSeries data={series2} />\n    <LineSeries data={series3} stroke=\"#FF9833\"/>\n  </XYPlot>\n  <XYPlot {...defaultXYPlotProps} color=\"#12939A\" colorType=\"literal\" stroke=\"white\" >\n    <MarkSeries data={series1} />\n    <MarkSeries data={series2} />\n    <MarkSeries data={seriesWithOneElementColored} color=\"#4fb79b\"/>\n  </XYPlot>\n\n```\n\nNotes:\n\n* For the line series, which behave differently than other series, you must use stroke instead of color for this to work.\n* For the scatterplot series, I'm using specificity twice: there's a color at the plot level, overridden by a color at the first series level, overridden by a color on the 7th mark of the series.\n\nUsing gradients\n\nWhy use a boring solid color when you can use gradients? We're not sure either! Once you define gradients (see [gradients](gradients.md)) you can use them instead of color (or fill, or stroke) at the series level.\n\n<!-- INJECT:\"GradientChartsWithLink\" -->\n\n```jsx\n  const gradient = (<GradientDefs>\n    <linearGradient\n        id=\"myGradient\"\n        gradientUnits=\"userSpaceOnUse\"\n        x1=\"0\" y1=\"0\" x2=\"200\" y2=\"200\">\n        <stop offset=\"10%\" stopColor=\"#c6e48b\" />\n        <stop offset=\"33%\" stopColor=\"#7bc96f\" />\n        <stop offset=\"66%\" stopColor=\"#239a3b\" />\n        <stop offset=\"90%\" stopColor=\"#196127\" />\n    </linearGradient>\n  </GradientDefs>);\n  return (<div style={{display: 'flex'}}>\n    <XYPlot height={200} width={200}>\n      {gradient}\n      <VerticalBarSeries data={series1} color={'url(#myGradient)'} />\n    </XYPlot>\n    <XYPlot height={200} width={200}>\n      {gradient}\n      <LineSeries data={series1} color={'url(#myGradient)'} />\n    </XYPlot>\n    <XYPlot height={200} width={200}>\n      {gradient}\n      <MarkSeries data={series1} color={'url(#myGradient)'} />\n    </XYPlot>\n  </div>)\n```\n\nNote that I'm using the userSpaceOnUse gradient unit, so the colors are set independently of the size of the object. I'm borrowing the colors of the gradient from the ones used on the activity sparklines in GitHub.\n"
  },
  {
    "path": "docs/contour-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## ContourSeries\n\nThe contour series allows for the easy creation of contour density plots. These can be more effective for visualizing heat map data than a rectangular heat map! Given a number of points in a space the relative contour lines are computed, so as to simplify the output into a more legible format!\n\n<!-- INJECT:\"ContourSeriesExampleWithLink\" -->\n\nThe ContourSeries expects a similar data input as would be fed to either the MarkSeries or the HeatmapSeries. It can be as easy as just providing a well formatted data prop (an array of object containing numerically valued x and y keys), or more complex such as below:\n\n```javascript\n<XYPlot\n  xDomain={[40, 100]}\n  yDomain={[1.5, 8]}\n  width={600}\n  height={300}>\n  <ContourSeries\n    animation\n    className=\"contour-series-example\"\n    style={{\n      stroke: '#125C77',\n      strokeLinejoin: 'round'\n    }}\n    colorRange={[\n      '#79C7E3',\n      '#FF9833'\n    ]}\n    data={data}/>\n</XYPlot>\n```\n\n## API reference\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### bandwidth (optional)\nA parameter that directly maps into d3-contour's bandwidth parameter. See the [docs for more](https://github.com/d3/d3-contour#density_bandwidth)\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. Follows the usual pattern of an array of objects formatted with x and y coordinates, [{x: 0, y: 0}, ...].\n\n#### style\n\nType: `object`\n\nA list of CSS properties to style the series outside of the explicitly set properties. Note that it will override all other properties (ie fill, stroke, opacity, color). See [style](style.md)\n\n## Interaction handlers\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n"
  },
  {
    "path": "docs/crosshair.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Crosshair\n\n<!-- INJECT:\"DynamicCrosshairWithLink\" -->\n\n`Crosshair` is a tooltip for multiple values at the same time. Its purpose is to combine several values with the similar X coordinate in one tooltip. Crosshair is automatically aligned by the x coordinate depending on what values are passed.\nIn case if custom representation of crosshair is needed, the component is able to wrap the user's JSX. In this case no CSS is applied to that. Here's a short example:\n\n```jsx\n<Crosshair values={myValues}>\n  <div style={{background: 'black'}}>\n    <h3>Values of crosshair:</h3>\n    <p>Series 1: {myValues[0].x}</p>\n    <p>Series 2: {myValues[1].x}</p>\n  </div>\n</Crosshair>\n```\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### itemsFormat (optional)\n\nType: `function`\n\nThe function that formats the list of items for the crosshair. Receives the list of data points, should return an array of objects containing `title` and `value` properties.\n_Note: please pass custom contents in case if you need different look for the crosshair._\n\n#### style (optional)\n\nType: `object`\n\nAn object that contains objects of CSS properties with which the component can be entirely re-styled.\nAs the Crosshair is composed of several elements, it is possible to provide style objects for any and all parts of the tree. See [style](style.md)\nMost generally, there are three top level keys: `line`, `title`, and `box`. These in turn lead to their corresponding style objects.\n\n#### titleFormat (optional)\n\nType: `function`\n\nThe function that formats the title for the crosshair. Receives the list of data points, should return an object containing `title` and `value` properties.\n_Note: please pass custom contents in case if you need different look for the crosshair._\n\n#### values\n\nType: `Array<Object>`\n\nThe array of data points to show the crosshair at. Crosshair will automatically align to the horizontal position of the points passed there.\n"
  },
  {
    "path": "docs/custom-svg-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## CustomSVGSeries\n\nWhen creating visualizations, it is sometimes necessary to get your hands dirty and completely take control over what SVG components will be shown. This could be necessary in situations where you have predefined SVG code that you just want to appear the way you drew it in Sketch (but positioned using coordinates), or maybe you have multiline text annotations that you want to formatted in a particular way, or you just want to use an alternative type of mark instead of the usual scatterplot mark to differentiate series in a set. To serve these and many other tasks, we use the CustomSVGSeries.\n\n<!-- INJECT:\"CustomSVGExampleWithLink\" -->\n\nThe premise of the series is that it simply puts a `<g>` element at a desired x,y location, and the offers you a variety of ways to fill in the contents of that `<g>` element. Here's an example of the data format:\n\n```javascript\nconst myData = [\n  {x: 1, y: 10, customComponent: 'circle', size: 10},\n  {x: 1.7, y: 12, size: 20, style: {stroke: 'red', fill: 'orange'}},\n  {x: 2, y: 5},\n  {x: 3, y: 15},\n  {x: 2.5, y: 7, customComponent: (row, positionInPixels) => {\n    return (\n      <g className=\"inner-inner-component\">\n        <circle cx=\"0\" cy=\"0\" r={10} fill=\"green\"/>\n        <text x={0} y={0}>\n          <tspan x=\"0\" y=\"0\">{`x: ${positionInPixels.x}`}</tspan>\n          <tspan x=\"0\" y=\"1em\">{`y: ${positionInPixels.y}`}</tspan>\n        </text>\n      </g>\n    );\n  }}\n]\n```\n\nJust like other series, x and y are used to position the group. The customComponent key word is used to determine how to fill in the svg (see below), and then size is used modify the size of the contents when using a string. Used in context of the series:\n\n```javascript\n<XYPlot width={300} height={300}>\n  <CustomSVGSeries customComponent=\"square\" data={myData} />\n</XYPlot>\n```\n\n### Defining your marks\n\nThe type of custom svg marks can be determined in one of several ways:\n\n- As a string on a series level\n- As a function on a series level\n- As a string on row level\n- As a function on a row level\n\nThere are currently four types of string accessible custom marks: **star**, **square**, **circle**, and **diamond**. If using a string, it can be useful to specify a size for the mark. This is done on a row level (see above data api example), with the size prop. Size is expressed in pixels, and is NOT scaled with the normal react-vis size keyword. They look like this:\n\n<!-- INJECT:\"CustomSVGAllTheMarksWithLink\" -->\n\nIf using a function to defined your mark, it is important to note that the function receives three arguments (customComponent, positionInPixels, globalStyle), where customComponent is the row of data as you have defined it. Thus if you are defining a function for the series as a whole you can make modifications based on the individual row as you go!\n\n## API reference\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### customComponent (optional)\n\nType: `string|function`\n\nProvides the mark type for the entire series. Defaults to a 'circle'. See `Defining You Marks` above.\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. See above data format reference.\n\n#### style\n\nType: `object`\n\nA list of CSS properties to style the series outside of the explicitly set properties. Note that it will override all other properties (ie fill, stroke, opacity, color). See [style](style.md)\n\n## Interaction handlers\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onValueMouseOver (optional)\nType: `function(d, {event})`\n`mouseover` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onValueMouseOut (optional)\nType: `function(d, {event})`\n`mouseout` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n"
  },
  {
    "path": "docs/decorative-axis.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## DecorativeAxis\n\n<!-- INJECT:\"ParallelCoordinatesExampleWithLink\" -->\n\nIn react-vis we try to express all of our components in terms of x and y coordinates. This is splendid and allows to separate a lot of our rendering logic from components! However, sometimes it is necessary to create labels that don't necessarily correspond to the underlying coordinates. For instance in cases of parallel coordinates (above) we want to mark up space in a series of discrete channels to show change across many different variables. To fill this need we use the ```DecorativeAxis``` component!\n\n```javascript\n<XYPlot\n  xDomain={[0, 1]}\n  yDomain={[0, 1]}\n  width={300}\n  height={300}>\n  <DecorativeAxis\n    axisStart={{x: 0, y: 0}}\n    axisEnd={{x: 1, y: 1}}\n    axisDomain={[-10, 100]}\n    />\n</XYPlot>\n```\n\nIn the above example we start be setting our domain on the XYPlot (though this would be accomplished automatically if any of it's children had a data prop), and then specified where in the XY space we want our Axis to be (axisStart/axisEnd). Finally we specify the domain that we wish to show across that axis.\n\n<!-- INJECT:\"DecorativeAxisCrissCrossWithLink\" -->\n\n**WHAT IS THIS FOR** Labeling sections of XY space when we wish the viewer to interpret space in a different way. This could be as part of a Radar chart or radial chart! Or even, the inherently bad Dual Y Axis chart.\n\n**WHAT IS NOT THIS FOR** Using in place of XAxis or YAxis, which should cover most of use cases in which space is being used normally. This type of axis allows for a lot of freedom in it's usage, however that can be dangerous. Most of the time, if you can't get XAxis and YAxis to do what you want, you maybe don't need axes. Be careful!\n\n## API Reference\n\n#### axisStart\n\nType: `Object`\n\nSpecify a start point for the decorativeAxis. It should be expressed in terms of coordinates (not pixels!) as a object like ```{x: 10, y: 1}```\n\n#### axisEnd\n\nType: `Object`\n\nSpecify a start point for the decorativeAxis. It should be expressed in terms of coordinates (not pixels!) as a object like ```{x: 10, y: 1}```\n\n#### axisDomain\n\nType: `Array`\n\nThis array of numbers allows the user to specify the values that will be interpolated across on the axis.\n\n#### tickTotal (optional)\n\nType: `number`\n\nTotal number of ticks on the axis. Already set by default. Similar to the `tickTotal()` method of d3-axis.\n\n#### tickSize (optional)\n\nType: `number`\n\nDefault: `5`\n\nTick size for the axis. Sets both inner and outer sizes of the tick line. Similar to the `tickSize()` method of d3-axis.\n\n#### tickValue (optional)\n\nType: `function(*)`\n\nFormat function for the tick label. Similar to the `tickFormat()` method of d3-axis.\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### style (optional)\n\nType: `object`\n\nAn object that contains CSS properties with which the axis component can be entirely re-styled.\nAs the Axis component is composite, it is possible to style its different parts individually. See [style](style.md)\n\nThe various parts of the axis can be styled by passing an object to the `line`, `ticks`, `text` and `title` properties:\n\n```jsx\n<DecorativeAxis style={{\n  line: {stroke: '#ADDDE1'},\n  ticks: {stroke: '#ADDDE1'},\n  text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}\n}}/>\n```\n"
  },
  {
    "path": "docs/examples/building-things-other-than-charts.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"ForceDirectedGraph\" -->\n\n[Source code](https://github.com/uber/react-vis/blob/master/packages/showcase/examples/force-directed-graph/force-directed-graph.js)\n"
  },
  {
    "path": "docs/examples/extensibility.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"Candlestick\" -->\n\n\n## Extensibility\n\nreact-vis is easily extensible! If we don't have what you want it's easy to make! For instance, the above chart\nwas made by simply extending abstract series and adding a little sugar.\n\n[Source code](https://github.com/uber/react-vis/blob/master/packages/showcase/examples/candlestick/candlestick.js)\n"
  },
  {
    "path": "docs/examples/iris-dashboard.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- STYLETYPE:\"example-page\" -->\n<!-- INJECT:\"IrisDashboard\" -->\n\nClick and drag on the charts!\n\nThe iris data set is a well beloved data set for getting to know various technical topics.\nHere we use it to show how to make a small multiples dashboard with react vis.\nYou can find out more about it at it's [wikipedia page](https://en.wikipedia.org/wiki/Iris_flower_data_set)\n\n[Source code](https://github.com/uber/react-vis/blob/master/packages/showcase/examples/iris-dashboard/iris-dashboard.js)\n"
  },
  {
    "path": "docs/examples/responsive-vis.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- STYLETYPE:\"example-page\" -->\n<!-- INJECT:\"ResponsiveVis\" -->\n\nThis demo explores the concept of \"Responsive Data Visualization\" (As coined by Nick Rabinowitz). The basic notion is lifted from responsive design: some features work for some screen resolutions, while others do not. Responsive design determines whether or not to use a given feature by consulting an aspect ratio (width by height). Through this notation we are able to create beautiful web experiences that work seamlessly between phones, tablets, and computers. Taking this idea on step farther we introduce a third element into the fray: data size.\n\nIn data visualization, we often need to create applications that work with enormous ranges of sizes of data. Sometimes the data might be small (10 - 100 rows), or it might be gigantic (100k-1M+ row): throughout the entire range it just needs to work. Again, following our cues from responsive design, we note that maybe labels on scatterplots look great when you have under 50 data points, but bad when you have 2000. Checkout Nicks [original demo](http://nrabinowitz.github.io/rdv/) for more details on the theory, as well to see his rad implementation in raw d3.\n\n[Scatterplot source code](https://github.com/uber/react-vis/blob/master/packages/showcase/examples/responsive-vis/responsive-scatterplot.js)\n\n[Barchart source code](https://github.com/uber/react-vis/blob/master/packages/showcase/examples/responsive-vis/responsive-bar-chart.js)\n"
  },
  {
    "path": "docs/examples/showcases/axes-showcase.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"AxesShowcase\" -->\n"
  },
  {
    "path": "docs/examples/showcases/legends-showcase.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"LegendsShowcase\" -->\n"
  },
  {
    "path": "docs/examples/showcases/misc-showcase.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"MiscShowcase\" -->\n"
  },
  {
    "path": "docs/examples/showcases/plots-showcase.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"PlotsShowcase\" -->\n"
  },
  {
    "path": "docs/examples/showcases/radar-chart-showcase.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"RadarShowcase\" -->\n"
  },
  {
    "path": "docs/examples/showcases/radial-showcase.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"RadialShowcase\" -->\n"
  },
  {
    "path": "docs/examples/showcases/sankeys-showcase.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"SankeysShowcase\" -->\n"
  },
  {
    "path": "docs/examples/showcases/sunburst-showcase.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"SunburstSection\" -->\n"
  },
  {
    "path": "docs/examples/showcases/treemaps-showcase.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- INJECT:\"TreemapShowcase\" -->\n"
  },
  {
    "path": "docs/examples/stream-graph.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n<!-- STYLETYPE:\"example-page\" -->\n<!-- INJECT:\"StreamgraphExample\" -->\n\n[Source code](https://github.com/uber/react-vis/blob/master/packages/showcase/examples/streamgraph/streamgraph-example.js)\n"
  },
  {
    "path": "docs/flexible-plots.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Flexible plots\n\nBy default, XYPlot requires a width and a height. There are times, however, when you'd like your chart to take all the space it can.\nFor these cases, React-vis provides three different types of `XYPlot` with different flexible dimensions:\n\n  - FlexibleWidthXYPlot\n  - FlexibleHeightXYPlot\n  - FlexibleXYPlot\n\nand the associated helper functions that have been used to create these flexible components.\n\n<!-- INJECT:\"FlexibleChartsWithLink\" -->\n\n```jsx\nimport {\n  FlexibleXYPlot,\n  FlexibleWidthXYPlot,\n  FlexibleHeightXYPlot\n} from 'react-vis';\n```\n\n`FlexibleWidthXYPlot` modifies `XYPlot` so that it no longer requires a width, since it will take all the with in its container div.\nLikewise, `FlexibleHeightXYPlot` modifies `XYPlot` so that is no longer requires a height, and its height will be that of its container div.\nFinally, `FlexibleXYPlot` modifies `XYPlot` so that it no longer requires either a width and a height, its dimensions will be that of its container.\n\nThese components can be used exactly as `XYPlot`:\n\n```jsx\n<FlexibleWidthXYPlot height={100}>\n  <VerticalBarSeries data={data} />\n</FlexibleWidthXYPlot>\n\n<FlexibleHeightXYPlot width={100}>\n  <VerticalBarSeries data={data} />\n</FlexibleHeightXYPlot>\n\n<FlexibleXYPlot>\n  <VerticalBarSeries data={data} />\n</FlexibleXYPlot>\n```\n\n### No worries about resizing\n\nA flexible plot is useful when you don't know for sure the size of the container where the chart will go.\nOn top of that, flexible plots resize themselves when the window size changes. You can try that by changing the size of this window.\n\n### Size of parent container is not the same as \"all the available space\"\n\nFlexible plots will inherit dimensions from their container. This is not the same thing as taking all the available space; if there are other elements in that container, a flexible plot won't deduce their dimensions from its own.\nFor best results, a flexible plot should be the only child of its container.\n\n### Responsive visualizations\n\nWe can go one step beyond and not simply adjust the dimensions of the chart of the available space, but change how a dataset is being represented.\nSee the example [responsive visualizations](#/examples/charts/responsive-vis)\n\n### Custom flexible components\n\nBy using the provided flexible helpers, you can use them to make your own components flexible, like we did to create `XYPlot` flexible alternatives:\n\n```jsx\nimport {\n  XYPlot,\n  makeVisFlexible,\n  makeWidthFlexible,\n  makeHeightFlexible,\n} from 'react-vis';\n\nconst FlexibleXYPlot = makeVisFlexible(XYPlot);\nconst FlexibleWidthXYPlot = makeWidthFlexible(XYPlot);\nconst FlexibleHeightXYPlot = makeHeightFlexible(XYPlot);\n```\n"
  },
  {
    "path": "docs/getting-started/getting-started.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n### Getting started\n\n#### Jump right in on codepen!\n\nYou can use react-vis directly on [codepen](https://codepen.io/ubervisualization/pen/BZOeZB) (or equivalent).  \nEach published version of react-vis is accessible via [unpkg.com](https://unpkg.com).\n\nAdd react files, and a link to the latest react-vis version - such as https://unpkg.com/react-vis@1.6.7/dist/dist.min.js.\n\nBut you can simply just use that [pen](https://codepen.io/ubervisualization/pen/BZOeZB) and take it from there.\n\n#### Install the react-vis module\n\nIf you want to use react-vis in your project, add it from the command line: \n\n```\nnpm install react-vis\n```\n\n(or yarn add react-vis - the following will assume that you use npm for concision's sake but you can substitute yarn if installed)\n\n#### Create a new project with react-vis\n\nLet's create a new vis app from scratch.\nTo do this, let's use [create-react-app](https://github.com/facebookincubator/create-react-app), the popular Facebook scaffold. \n\nIf you haven't installed yet, do so: \n\n```\nnpm install -g create-react-app\n```\n\nAnd now:\n```\ncreate-react-app my-awesome-vis-app\ncd my-awesome-vis-app\nnpm install react-vis\n```\n\nThat's it! you are now ready to create amazing charts. \n\nLet's edit create-react-app's default App.js: \n\n```jsx\nimport React, { Component } from 'react';\nimport './App.css';\nimport '../node_modules/react-vis/dist/style.css';\nimport {XYPlot, LineSeries} from 'react-vis';\n\nclass App extends Component {\n  render() {\n    const data = [\n      {x: 0, y: 8},\n      {x: 1, y: 5},\n      {x: 2, y: 4},\n      {x: 3, y: 9},\n      {x: 4, y: 1},\n      {x: 5, y: 7},\n      {x: 6, y: 6},\n      {x: 7, y: 3},\n      {x: 8, y: 2},\n      {x: 9, y: 0}\n    ];\n    return (\n      <div className=\"App\">\n        <XYPlot height={300} width={300}>\n          <LineSeries data={data} />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n\nexport default App;\n```\n\nand then on the command line interface:\n\n```\nnpm run start\n```\n\nand your chart is in the browser. \n\nNote that on line 3, I have imported the react-vis stylesheet. There are many ways to do that, and it is actually optional. But apps made with create-react-app will let you import stylesheets directly, so that's a simple way to do so.\n\n#### Your first chart\n\nWe tried to make react-vis syntax as close to the traditional react syntax. You have components which have props and possibly children. \n\nEvery react-vis chart is inside a component called XYPlot, for which a height and a width must be specified:\n\n```jsx\n<XYPlot height={300} width = {300} />\n```\n\nAnd all the elements of a chart - series, axes, gridlines, etc. are other components, which will be children of XYPlot.\n\n```jsx\n<XYPlot height={300} width= {300}>\n  <VerticalGridLines />\n  <HorizontalGridLines />\n  <XAxis />\n  <YAxis />\n  <LineSeries data={data} />\n</XYPlot>\n```\n\nAnd like in traditional react, order matters as components are drawn in order. In the previous example, the gridlines are drawn below the line series, but in this next example, they will be drawn above it.\n\n```jsx\n<XYPlot height={300} width= {300}>\n  <LineSeries data={data} />\n  <VerticalGridLines />\n  <HorizontalGridLines />\n  <XAxis />\n  <YAxis />\n</XYPlot>\n```\n\n"
  },
  {
    "path": "docs/getting-started/installing-react-vis.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n### Install the react-vis module\n\nIf you want to use react-vis in your project, add it from the command line: \n\n```\nnpm install react-vis\n```\n\n(or yarn add react-vis - the following will assume that you use npm for concision's sake but you can substitute yarn if installed)\n"
  },
  {
    "path": "docs/getting-started/new-react-vis-project.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n### Create a new project with react-vis\n\nLet's create a new vis app from scratch.\nTo do this, let's use [create-react-app](https://github.com/facebookincubator/create-react-app), the popular Facebook scaffold. \n\nIf you haven't installed yet, do so: \n\n```\nnpm install -g create-react-app\n```\n\nAnd now:\n```\ncreate-react-app my-awesome-vis-app\ncd my-awesome-vis-app\nnpm install react-vis\n```\n\nThat's it! you are now ready to create amazing charts. \n\nLet's edit create-react-app's default App.js: \n\n```jsx\nimport React, { Component } from 'react';\nimport './App.css';\nimport '../node_modules/react-vis/dist/style.css';\nimport {XYPlot, LineSeries} from 'react-vis';\n\nclass App extends Component {\n  render() {\n    const data = [\n      {x: 0, y: 8},\n      {x: 1, y: 5},\n      {x: 2, y: 4},\n      {x: 3, y: 9},\n      {x: 4, y: 1},\n      {x: 5, y: 7},\n      {x: 6, y: 6},\n      {x: 7, y: 3},\n      {x: 8, y: 2},\n      {x: 9, y: 0}\n    ];\n    return (\n      <div className=\"App\">\n        <XYPlot height={300} width={300}>\n          <LineSeries data={data} />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n\nexport default App;\n```\n\nand then on the command line interface:\n\n```\nnpm run start\n```\n\nand your chart is in the browser. \n\nNote that on line 3, I have imported the react-vis stylesheet. There are many ways to do that, and it is actually optional. But apps made with create-react-app will let you import stylesheets directly, so that's a simple way to do so.\n"
  },
  {
    "path": "docs/getting-started/react-vis-in-codepen.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n### Jump right in on codepen!\n\nYou can use react-vis directly on [codepen](https://codepen.io/ubervisualization/pen/BZOeZB) (or equivalent).  \nEach published version of react-vis is accessible via [unpkg.com](https://unpkg.com).\n\nAdd react files, and a link to the latest react-vis version - such as https://unpkg.com/react-vis@1.6.7/dist/dist.min.js.\n\nBut you can simply just use that [pen](https://codepen.io/ubervisualization/pen/BZOeZB) and take it from there.\n"
  },
  {
    "path": "docs/getting-started/your-first-chart.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n### Your first chart\n\nWe tried to make react-vis syntax as close to the traditional react syntax. You have components which have props and possibly children. \n\nEvery react-vis chart is inside a component called XYPlot, for which a height and a width must be specified:\n\n```js\n<XYPlot height={300} width = {300} />\n```\n\nAnd all the elements of a chart - series, axes, gridlines, etc. are other components, which will be children of XYPlot.\n\n```js\nconst data = [\n  {x: 0, y: 8},\n  {x: 1, y: 5},\n  {x: 2, y: 4},\n  {x: 3, y: 9},\n  {x: 4, y: 1},\n  {x: 5, y: 7},\n  {x: 6, y: 6},\n  {x: 7, y: 3},\n  {x: 8, y: 2},\n  {x: 9, y: 0}\n];\n<XYPlot height={300} width= {300}>\n  <VerticalGridLines />\n  <HorizontalGridLines />\n  <XAxis />\n  <YAxis />\n  <LineSeries data={data} />\n</XYPlot>\n```\n\nAnd like in traditional react, order matters as components are drawn in order. In the previous example, the gridlines are drawn below the line series, but in this next example, they will be drawn above it.\n\n```js\n<XYPlot height={300} width= {300}>\n  <LineSeries data={data} />\n  <VerticalGridLines />\n  <HorizontalGridLines />\n  <XAxis />\n  <YAxis />\n</XYPlot>\n```\n\n"
  },
  {
    "path": "docs/gradients.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Gradient\n\nSometimes it is useful to style our svg components using gradients. The way that this is done in React-vis is by making use of the GradientDefs component, which is a simple wrapper on the svg <defs> tag.\n\n\n<!-- INJECT:\"GradientExampleWithLink\" -->\n<!-- INJECT:\"GradientPieWithLink\" -->\n\nSimply write gradient commands as you would normally as children of the GradientDefs component, and reference them from your series!\n\n```javascript\n<XYPlot width={300} height={300}>\n  <GradientDefs>\n    <linearGradient id=\"CoolGradient\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n      <stop offset=\"0%\" stopColor=\"red\" stopOpacity={0.4}/>\n      <stop offset=\"100%\" stopColor=\"blue\" stopOpacity={0.3} />\n    </linearGradient>\n  </GradientDefs>\n  <AreaSeries\n    color={'url(#CoolGradient)'}\n    data={[\n      {x: 1, y: 10, y0: 1},\n      {x: 2, y: 25, y0: 5},\n      {x: 3, y: 15, y0: 3}\n    ]}/>\n</XYPlot>\n```\n\nThis approach works with both types of gradients (Linear and circular gradients)! The biggest gotcha is that react doesn't play nice the style prop that is normally specified on the gradientTags, so it is best to specify each property directly on the component as above.\n\n\n<!-- INJECT:\"TriangleExampleWithLink\" -->\n\n## Component API Reference\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n"
  },
  {
    "path": "docs/grids.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Cartesian Grids\n\n<!-- INJECT:\"CustomAxisChartWithLink\" -->\n\n`VerticalGridLines` and `HorizontalGridLines` show a grid inside the chart. Here is a short example:\n\n```jsx\n<XYPlot\n  width={300}\n  height={300}>\n  <VerticalGridLines />\n  <HorizontalGridLines />\n</XYPlot>\n```\n\nCurrently both components have following properties:\n\n#### tickTotal (optional)\n\nType: `number`\n\nTotal number of lines on the grid. Already set by default, depends on the size of the grid. Similar to the `tickTotal()` method of d3-axis.\n\n#### tickValues (optional)\n\nType: `Array<*>`\n\nAn array of values (not coordinates!) that where the lines should be shown. Similar to the `tickValues()` method of d3-axis.\n\n#### left (optional)\n\nType: `number`\n\nHorizontal position of the grid lines in pixels. **Already set by default**, but can be overridden by the user.\n\n#### top (optional)\n\nType: `number`\n\nVertical position of the grid lines in pixels. **Already set by default**, but can be overridden by the user.\n\n#### width (optional)\n\nType: `number`\n\nWidth of the grid lines in pixels. **Already set by default**, but can be overridden by the user.\n\n#### height (optional)\n\nType: `number`\n\nHeight of the grid lines in pixels. **Already set by default**, but can be overridden by the user.\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### className (optional)\n\nType: `String`\n\nA class name to apply to the gridlines.\n\n#### style (optional)\n\nType: `object`\n\nAn CSS object that will style these gridlines.\n\n## Polar Grids\n\n<!-- INJECT:\"FauxScatterplotChartWithLink\" -->\n\n`CircularGridLines` allows you to draw circular grid lines. This might be useful for a polar scatterplot, as shown above, or a radar chart or any of a wide host of additional contexts. Usage example\n\n```\n<XYPlot\n  margin={margin}\n  xDomain={[-3, 3]}\n  yDomain={[-3, 3]}\n  width={WIDTH}\n  height={HEIGHT}>\n  <CircularGridLines />\n  <XAxis top={(HEIGHT - margin.top) / 2}/>\n  <YAxis left={(WIDTH - margin.left - margin.right) / 2}/>\n  <MarkSeries\n    strokeWidth={2}\n    sizeRange={[5, 15]}\n    data={data.map(row => ({\n      ...row,\n      x: Math.cos(row.theta) * row.r,\n      y: Math.sin(row.theta) * row.r\n    }))}/>\n</XYPlot>\n```\n\nIt can often be useful to specify the x and y domains on the surrounding XYPLot. CircularGridLines accepts all of the same props as the cartesian grids, but also accepts two more:\n\n#### centerX (optional)\n\nType: `number`\n\nThe left-right value in coordinates of where the circles should be centered.\n\n#### centerY (optional)\n\nType: `number`\n\nThe top-bottom value in coordinates of where the circles should be centered.\n\n#### rRange (optional)\nType:[`number`, `number`]\nThis allows users to specify the exact pixel range over which they wish their rings to appear.\n\n#### style (optional)\n\nType: `object`\n\nAn CSS object that will style these gridlines. See [style](style.md)\n\n"
  },
  {
    "path": "docs/heatmap-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## HeatmapSeries:\n\n<!-- INJECT:\"HeatmapChartWithLink\" -->\n\nThe heatmap series enables users to create a 2d binning of the plane. These series often come in useful in situations when you might be using a scatterplot, but have too many rows of data for the reader to easily understand what is going on. So arises HeatmapSeries!\n\n```javascript\n<XYPlot\n  width={300}\n  height={300}>\n  <XAxis />\n  <YAxis />\n  <HeatmapSeries\n    className=\"heatmap-series-example\"\n    data={myData}/>\n</XYPlot>\n```\n\nAnother way to think of the heatmap, is as a 2D histogram, where each cell is colored by it's value rather than height-ed or width-ed.\n\n#### Color in heatmaps\n\n<!-- INJECT:\"LabeledHeatmap\" -->\n\nThe Heatmap's color can be manipulated in two data driven ways, first by setting the setting colorRange on the series\n\n```javascript\n<HeatmapSeries\n  className=\"heatmap-series-example\"\n  colorRange={[\"red\", \"blue\"]}\n  data={myData}/>\n```\n\nWhich assumes that each row of data has a number specifying it's color attribute. Alternatively you can change the scale type of color to allow yourself to specify color of the cell directly:\n\n```javascript\n<HeatmapSeries\n  colorType=\"literal\"\n  data={[\n    {x: 1, y: 0, color: \"#f00\"},\n    {x: 1, y: 5, color: \"#f00\"},\n    {x: 1, y: 10, color: \"#0f0\"}\n  ]}/>\n```\n\nThe color can also usefully be set using a color accessor,\n```javascript\n<HeatmapSeries\n  colorType=\"literal\"\n  getColor={d => d.color === 'bad' ? '#f00' : '#0f0'}\n  data={[\n    {x: 1, y: 0, color: 'bad'},\n    {x: 1, y: 5, color: 'bad'},\n    {x: 1, y: 10, color: 'good'}\n  ]}/>\n```\n\nFinally, the color could also be specified on the series itself, however that would probably not be the best use of a heatmap as it would color every cell in the series the same color.\n\n## Data format Reference\n\nLike other series, it is required that the data be an array of objects, formatted like so:\n\n\n```javascript\nconst myData = [\n  {x: 1, y: 0, color: 10},\n  {x: 1, y: 5, color: 10},\n  {x: 1, y: 10, color: 6},\n  {x: 1, y: 15, color: 7},\n  {x: 2, y: 0, color: 12},\n  {x: 2, y: 5, color: 2},\n  {x: 2, y: 10, color: 1},\n  {x: 2, y: 15, color: 12},\n  {x: 3, y: 0, color: 9},\n  {x: 3, y: 5, color: 2},\n  {x: 3, y: 10, color: 6},\n  {x: 3, y: 15, color: 12}\n]\n```\n\nWhere x and y are required quantities and additional properties may be stapled on.\n\n#### x\n\nType: `number`\n\nThe x position in coordinates of the box to be used.\n\n#### y\n\nType: `number`\n\nThe y position in coordinates of the box to be used.\n\n#### color (optional)\n\nType: `string|number`\n\nThe color of a box in the series. By default the color is interpreted as number to be scaled to a color range. This can be over-ridden by providing the prop colorType=\"literal\" to the series itself. This property can also be defined on the series level.\n\n\n## Series API Reference\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### color\n\nType: `string|number`\n\nThe color for all elements in the series, this property will be over-ridden by color specified in the data attribute. See [colors](colors.md)\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. See above data format reference.\n\n#### fill\n\nType: `string|number`\n\nThe inner color for all elements in the series, this property will be over-ridden by color specified in the data attribute. See [colors](colors.md)\n\n#### opacity\n\nType: `string|number`\n\nThe opacity for all elements in the series, this property will be over-ridden by color specified in the data attribute.\n\n#### stroke\n\nType: `string|number`\n\nThe outer color for all elements in the series, this property will be over-ridden by color specified in the data attribute. See [colors](colors.md)\n\n#### style\n\nType: `object`\n\nA list of CSS properties to style the series outside of the explicitly set properties. Note that it will override all other properties (ie fill, stroke, opacity, color). See [style](style.md)\n\n## Interaction handlers\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onValueClick (optional)\n\nType: `function(d, {event})`\n\n`click` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onValueMouseOver (optional)\n\nType: `function(d, {event})`\n\n`mouseover` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onValueMouseOut (optional)\n\nType: `function(d, {event})`\n\n`mouseout` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onValueRightClick (optional)\n\nType: `function(d, {event})`\n\n`right-click` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n"
  },
  {
    "path": "docs/hexbin-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## HexbinSeries\n\nThe hexbin series enables the easy creation of aggregated and binned data. This can be useful if you have a lot of overlapping data or if you simply want to provide a courser representation of data to your user. Unlike many other series this one performs the aggregation computation, simply provide a scatterplot like collection of data (points in linear x and y space) and your off!\n\n\n<!-- INJECT:\"HexbinSizeExampleWithLink\" -->\n\n\nPoints are binned into hexagonal containers, which are then rendered as svg paths. These svg hexes can encode their counts through color and size! It can be particularly effective to pair this series with a [border](borders.md) element.\n\n```javascript\n<XYPlot\n  xDomain={[40, 100]}\n  yDomain={[1.5, 8]}\n  width={300}\n  getX={d => d.waiting}\n  getY={d => d.eruptions}\n  onMouseLeave={() => this.setState({hoveredNode: null})}\n  height={300}>\n  <HexbinSeries\n    animation\n    className=\"hexbin-example\"\n    style={{\n      stroke: '#125C77',\n      strokeLinejoin: 'round'\n    }}\n    onValueMouseOver={d => this.setState({hoveredNode: d})}\n    colorRange={['white', 'black']}\n    radius={radius}\n    data={data}/>\n</XYPlot>\n```\n\n<!-- INJECT:\"HexHeatmapWithLink\" -->\n\n## API reference\n\n#### animation (optional)\n\nType: `Boolean`\n\nSee the [Animation](animation.md)'s `animation` section for more information.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### countDomain (optional)\n\nType: `Array of two numbers`\n\nProvide the specific counts to the hexagon binning between. If not provided defaults to [0, <max number of cells in a binning>].\n\n#### colorRange (optional)\n\nType: `Array of two strings`\n\nProvide the colors for hexagons to interpolate between.\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. Follows the usual pattern of an array of objects formatted with x and y coordinates, [{x: 0, y: 0}, ...].\n\n#### radius\n\nType: `Number`\n\nThe maximum size of the hexagon, specified in pixels.\n\n#### style\n\nType: `object`\n\nA list of CSS properties to style the series outside of the explicitly set properties. These style elements are applied directly to each individual hexagon. Note that it will override all other properties (ie fill, stroke, opacity, color). See [style](style.md) for more information.\n\n#### sizeHexagonsWithCount\n\nType: `Boolean`\n\nSize the hexagons based on the number of values in side of the hexagon. Ranges between [0, <radius prop>].\n\n#### xOffset (optional)\n\nType: `Number`\n\nDefault: `0`\n\nSize of aggregation offset form base value, this enables fine tuning along the x axis.\n\n#### yOffset (optional)\n\nType: `Number`\n\nDefault: `0`\n\nSize of aggregation offset form base value, this enables fine tuning along the y axis.\n\n## Interaction handlers\n#### onValueClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<HexbinSeries\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\nIt is very important to note that data point is specified in pixels NOT in data coordinates. This can have serious consequences for how interactivity works. See the HexHeatmap example above for a worked example.\n\n#### onValueMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse leaves a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<HexbinSeries\n...\n  onValueMouseOut={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\nIt is very important to note that data point is specified in pixels NOT in data coordinates. This can have serious consequences for how interactivity works. See the HexHeatmap example above for a worked example.\n\n#### onValueMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse enters a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<HexbinSeries\n...\n  onValueMouseOver={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\nIt is very important to note that data point is specified in pixels NOT in data coordinates. This can have serious consequences for how interactivity works. See the HexHeatmap example above for a worked example.\n\n#### onValueRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user right-clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<HexbinSeries\n...\n  onValueRightClick={(datapoint, event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n```\nIt is very important to note that data point is specified in pixels NOT in data coordinates. This can have serious consequences for how interactivity works. See the HexHeatmap example above for a worked example.\n"
  },
  {
    "path": "docs/highlight.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Highlight\n\nThe highlight component enables use interaction via direct manipulation of chart through dragging and brushing. This component is stateful and can maintain a notion of a dragged box. It can be applied either in two directions or in one!\n\n<!-- INJECT:\"ZoomableChartExampleWithLink\" -->\n\nIt is quite easy to drop this functionality into an existing chart, for example:\n\n```jsx\n<XYPlot\n  width={300}\n  height={300}>\n  <VerticalGridLines />\n  <HorizontalGridLines />\n  <XAxis />\n  <YAxis />\n\n  <MarkSeries\n    className=\"mark-series-example\"\n    strokeWidth={2}\n    opacity=\"0.8\"\n    sizeRange={[5, 15]}\n    colorType=\"literal\"\n    getColor={d => highlightPoint(d) ? '#EF5D28' : '#12939A'}\n    data={data}/>\n  <Highlight\n    drag\n    enableX={false}\n    onBrush={area => this.setState({filter: area})}\n    onDrag={area => this.setState({filter: area})}/>\n</XYPlot>\n```\n\nAn important point to notice here is that direction responsiveness (the thing that makes calling on brush and on drag return meaningful values) is OPT OUT. VERY IMPORTANT! See examples for more details.\n\n\n<!-- INJECT:\"DragableChartExampleWithLink\" -->\n\nIn drag mode (activated by including the prop drag) you are able to drag a selection box around in the chart space. When putting this shape you first execute a drag action to define the size of the box and then are able to move it around. See above and below for examples.\n\n<!-- INJECT:\"BidirectionDragChartWithLink\" -->\n\nWhen designing your listeners it is important to be mindful the lifecycle of this component as there are a lot of edge cases. To wit, if you NOT using drag mode then the life cycle will always be brushStart > brush > brushEnd. While if you are in drag mode it will be brushStart > brush > brushEnd when you are making the box and then dragStart > drag > dragEnd while dragging the box.\n\nThe biggest gotchas revolve around click to clear type events. In order to implement this, make sure to include an on End listener to set update your state. In click events there isn't a middle state between start and end because your user does not move the mouse. Be aware! See the code for the examples for more details.\n\nIt is important to note that brushing over non-continuous scales is not supported! Specifically this means that you can not brush over category or ordinal scales.\n\n\n\n## API Reference\n\n<!-- INJECT:\"SelectionPlotExampleWithLink\" -->\n\n\n#### className (optional)\n\nType: `String`\n\nAdd css class to Voronoi container\n\n#### drag (optional)\n\nType: `Boolean`\n\nEnable dragging interactions\n\n#### enableX (optional)\n\nType: `Boolean`\n\nDefaults to `true`\nEnable brushing and dragging in the x direction\n\n#### enableY (optional)\n\nType: `Boolean`\n\nDefaults to `true`\nEnable brushing and dragging in the y direction\n\n#### highlightX (optional)\n\nType: `String or Number`\n\nDefaults to left edge\nPosition in x coordinate space to place the left edge of the highlight bar.\n\n#### highlightY (optional)\n\nType: `String or Number`\n\nDefaults to top edge\nPosition in y coordinate space to place the top edge of the highlight bar.\n\n#### highlightHeight (optional)\n\nType: `Number`\n\nDefaults to full height\nThe height of highlight bar in pixels.\n\n#### highlightWidth (optional)\n\nType: `Number`\n\nDefaults to full width\nThe width of highlight bar in pixels.\n\n#### onBrushStart (optional)\n\nType: `Function`\n\nFunction called on the start of brushing.\n\n#### onBrush (optional)\n\nType: `Function`\n\nFunction called on the start of brushing.\n\n#### onBrushEnd (optional)\n\nType: `Function`\n\nFunction called on the start of brushing.\n\n#### onDragStart (optional)\n\nType: `Function`\n\nFunction called on the start of dragging.\n\n#### onDrag (optional)\n\nType: `Function`\n\nFunction called on the start of dragging.\n\n#### onDragEnd (optional)\n\nType: `Function`\n\nFunction called on the start of dragging.\n"
  },
  {
    "path": "docs/hint.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Hint\n\n<!-- INJECT:\"DynamicComplexEdgeHintsWithLink\" -->\n\n`Hint` is a simple component that shows tooltips inside the chart. `Hint` places itself to the place which is set by your data. In case a custom representation is needed, the component is also able to wrap custom JSX. Here is a short example:\n\n```jsx\n<Hint value={myValue}>\n  <div style={{background: 'black'}}>\n    <h3>Value of hint</h3>\n    <p>{myValue.x}</p>\n  </div>\n</Hint>\n```\n\n\n<!-- INJECT:\"DynamicHintsWithLink\" -->\n<!-- INJECT:\"DynamicSimpleEdgeHintsWithLink\" -->\n\nHints can be placed in two ways\na) around a data point in one of four quadrants (imagine the point bisected\n   by two axes -vertical, horizontal- creating 4 quadrants around a data\n   point).\nb) Pin to an edge of chart/plot area and position along that edge\n   using data point's other dimension value.\n\n<!-- INJECT:\"StaticHintsWithLink\" -->\n\n#### value\n\nType: `Object`\n\nThe data point to show the value at. Hint component will automatically find the place where the data point is and put the hint there.\n\n#### format (optional)\n\nType: `function`\n\nFormat function for a tooltip. Receives the data point, should return an array of objects containing `title` and `value` properties. Each item of an array is shown on a separate line by default.\n_Note: please pass custom contents in case if you need different look for the hint._\n\n#### align (optional)\n\nType: `Object`\n\nDefault: `{horizontal: 'auto', vertical: 'auto'}`\n\nThe way to align the hint inside the chart. Within the object, specify the horizontal alignment `(auto|left|right)` and the vertical alignment `(auto|top|bottom)`. For example, to see a \"conventional\" hint alignment: `{vertical: 'top', horizontal: 'left'}`.\n\n<!-- INJECT:\"DynamicSimpleTopEdgeHintsWithLink\" -->\n\n#### className (optional)\n\nType: `String`\n\nA class name to apply to the hint container.\n\n#### style (optional)\n\nType: `Object`\n\nYou can pass a style object to your Hint component to apply your own styles. See [style](style.md)\n```jsx\n<Hint value={value} style={{fontSize: 14}}/>\n```\n\nStyle is a composite component, and individual parts of it can receive different parts.\nThe different parts are: content, row, title, value. To style a specific part, you can pass an object to the property with that name.\n```jsx\n<Hint value={value} style={{\n  fontSize: 14,\n  text: {\n    display: 'none'\n  },\n  value: {\n    color: 'red'\n  }\n}}/>\n```\n\n<!-- INJECT:\"DynamicProgrammaticRightEdgeHintsWithLink\" -->\n"
  },
  {
    "path": "docs/interaction.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Interaction\n\nInteraction in react-vis happens through _event handlers_ which are triggered by certain interactive events, such as mouse movement or clicks.\n\nThese events can be implemented either at the XYPlot level or at the plot level:\n* At the plot level: this is for events that affect the whole chart. The mouse events that can be captured are: down, enter, leave, move. For instance, you can use `onMouseLeave` to reset the visualization when the user's mouse cursor is no longer on it.\n\n* At the series level, there are three kind of handlers.\n\t* Some series (arc, bar, heatmap, label, mark, rect) support interaction at the individual mark level. These series have onValueClick, onValueMouseOut and onValueMouseOver, which, in addition to passing the event, also pass the datapoint corresponding to the mark with which the user interacted.\n    * The above series, and some others (area, line, polygon) support interaction at the series level. These series have handlers like onSeriesClick, onSeriesMouseOut, onSeriesMouseOver. Those handlers only pass the mouseevent that triggered them.\n    * Finally, all series support onNearestX and onNearestXY. These two special handlers are triggered when the user moves their mouse on the plot area, and can access the datapoint of the nearest mark, in addition to the mouse event.\n\n* You can also interact with your plot through specialized components, such as the [highlight](highlight.md) for brushing and dragging or the [voronoi](voronoi.md) for mouse overs.\n\n### What handlers are implemented by series type\n\n| Series                                | Proximity handlers (onNearestX, onNearestY) | series level handlers (onSeriesClick, onSeriesRightClick, onSeriesMouseOver, onSeriesMouseOut) | mark-level handlers (onValueClick, onValueRightClick, onValueMouseOver, onValueMouseOut) |\n|---------------------------------------|---------------------------------------------|------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|\n| [ArcSeries](arc-series.md)            |                      ✔︎                      |                                                ✔︎                                               |                                             ✔︎                                            |\n| [AreaSeries](area-series.md)          |                      ✔︎                      |                                                ✔︎                                               |                                                                                          |\n| [BarSeries](bar-series.md)            |                      ✔︎                      |                                                ✔︎                                               |                                             ✔︎                                            |\n| [ContourSeries](contour-series.md)    |                      ✔︎                      |                                                                                                |                                                                                          |\n| [HeatmapSeries](heatmap-series.md)    |                      ✔︎                      |                                                ✔︎                                               |                                             ✔︎                                            |\n| [HexbinSeries](hexbin-series.md)    |                      ✔︎                      |                                                ✔︎                                               |                                             ✔︎                                            |\n| [LabelSeries](label-series.md)        |                      ✔︎                      |                                                ✔︎                                               |                                             ✔︎                                            |\n| [LineSeries](line-series.md)          |                      ✔︎                      |                                                ✔︎                                               |                                                                                          |\n| [LineMarkSeries](line-mark-series.md) |                      ✔︎                      |                                                ✔︎                                               |                                             ✔︎                                            |\n| [MarkSeries](mark-series.md)          |                      ✔︎                      |                                                ✔︎                                               |                                             ✔︎                                            |\n| [PolygonSeries](polygon-series.md)    |                      ✔︎                      |                                                ✔︎                                               |                                                                                          |\n| [RectSeries](rect-series.md)          |                      ✔︎                      |                                                ✔︎                                               |                                             ✔︎                                            |\n| [WhiskerSeries](whisker-series.md)    |                      ✔︎                      |                                                ✔︎                                               |                                             ✔︎                                            |\n\nHow to read this table:\nFor some series types (Arc, Bar, Rect, Label, Mark) - onValueClick, onValueMouseOut and onValueMouseOver handlers will work at the mark type. When the user clicks on the series, or moves their mouse on our out of it, an event handler will be fired and will pass the datapoint corresponding to the mark that the user interacted with.\n\nThe other series types (area, line, polygon) have an onSeriesClick, onSeriesMouseOut and onSeriesMouseOver respectively. These event handler will work at the series level and will not pass a specific datapoint.\n\nIn all cases, onNearestX and onNearestXY can be implemented at the series level, but when fired, they will also pass a specific datapoint.\n\n### Note\n- the contour series doesn't support interaction other than onNearestX or onNearestXY\n- whenever the datapoint-level handlers are supported, they can also catch all the events happening at the series level.\n\n## API\n\n### XYPlot event handlers\n\n#### onMouseDown\n\nType: `function`\n\nDefault: none\n\nThis event handler is triggered whenever the mousebutton of the user is down while their mouse cursor is in the plot area. It passes a mouse event.\n\n#### onMouseUp\n\nType: `function`\n\nDefault: none\n\nThis event handler is triggered whenever the user release the mouse button while their mouse cursor is in the plot area. It passes a mouse event.\n\n#### onMouseEnter\n\nType: `function`\n\nDefault: none\n\nThis event handler is triggered whenever the mouse of the user enters the plot area. It passes a mouse event.\n\n#### onMouseLeave\n\nType: `function`\n\nDefault: none\n\nThis event handler is triggered whenever the mouse of the user exits the plot area. It passes a mouse event.\n\n#### onMouseMove\n\nType: `function`\n\nDefault: none\n\nThis event handler is triggered whenever the mouse of the user moves while in the plot area. It passes a mouse event.\n\n#### onTouchStart\n\nType: `function`\n\nThe event handler is triggered whenever the finger of the user first touches the plot area. It passes a touch event.\n\n#### onTouchMove\n\nType: `function`\n\nThis event handler is triggered whenever the finger of the user moves while in the plot area. It passes a touch event.\n\n#### onTouchEnd\n\nType: `function`\n\nThis event handler is triggered when a touch point of the user lifts off the plot area. It passes a touch event.\n\n#### onTouchCancel\n\nType: `function`\n\nThis event handler is triggered when a touch point of the user has been disrupted in an implementation-specific manner\n\n### Series event handlers\n\n#### onNearestX\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user moves their mouse somewhere on the plot. The handler fires a function that takes two argument: the datapoint with the x value closest to the cursor or touch point, and a second object containing: the `innerX` value (x coordinates of the cursor relative to the left of the plot), `index` (position of this datapoint in the dataset, where 0 is the first datapoint, 1 is the second, etc) plus the actual event as `event`.\n\nonNearestX is at the series level, not at the plot level. If you attach onNearestX to several series, each time the user moves their mouse or touch point, each onNearestX handler will be triggered once with the closest mark of each series.\n\n```jsx\n<LineSeries\n...\n  onNearestX={(datapoint, event)=>{\n  \t// does something on mouseover\n  \t// you can access the value of the event\n  }}\n```\n\n#### onNearestXY\n\nType: `function`\n\nDefault: none\n\nThis handler is nearly identical to `onNearestX`. The difference is that it will return datapoint corresponding to the mark closest to the cursor or touch point, not just the one with the closest x coordinate.\n\nonNearestXY will supersede onNearestX, so if both exist for the same series, only onNearestXY will be fired.\n\nThis handler fires when the user moves their mouse or touch point somewhere on the plot. The handler fires a function that takes two argument: the datapoint which is closest to the cursor or touch point, and a second object containing: the `innerX` and `innerY` value (x, y coordinates of the cursor or touch point relative to the top left of the plot), `index` (position of this datapoint in the dataset, where 0 is the first datapoint, 1 is the second, etc) plus the actual event as `event`.\n\nonNearestXY is at the series level, not at the plot level. If you attach onNearestX to several series, each time the user moves their mouse or touch point, each onNearestX handler will be triggered once with the closest mark of each series.\n\n```jsx\n<LineSeries\n...\n  onNearestX={(datapoint, event)=>{\n  \t// does something on mouseover\n  \t// you can access the value of the event\n  }}\n```\n\n#### onSeriesClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user clicks somewhere on a series, and provides the corresponding event. Unlike onValueClick, it doesn't pass a specific datapoint.\n\n```jsx\n<AreaSeries\n...\n  onSeriesClick={(event)=>{\n  \t// does something on click\n  \t// you can access the value of the event\n  }}\n```\n\n#### onSeriesRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user right-clicks somewhere on a series, and provides the corresponding event. Unlike onValueRightClick, it doesn't pass a specific datapoint.\n\n```jsx\n<AreaSeries\n...\n  onSeriesRightClick={(event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n```\n\n\n#### onSeriesMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user's mouse cursor leaves a series, and provides the corresponding event. Unlike onValueMouseOut, it doesn't pass a specific datapoint.\n\n```jsx\n<AreaSeries\n...\n  onSeriesMouseOut={(event)=>{\n  \t// does something on mouse over\n  \t// you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user mouses over a series, and provides the corresponding event. Unlike onMouseOver, it doesn't pass a specific datapoint.\n\n```jsx\n<AreaSeries\n...\n  onSeriesMouseOver={(event)=>{\n  \t// does something on mouse over\n  \t// you can access the value of the event\n  }}\n```\n\n#### onValueClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<MarkSeries\n...\n  onValueClick={(datapoint, event)=>{\n  \t// does something on click\n  \t// you can access the value of the event\n  }}\n```\n\n#### onValueRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user right-clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<MarkSeries\n...\n  onValueRightClick={(datapoint, event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse leaves a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<MarkSeries\n...\n  onValueMouseOut={(datapoint, event)=>{\n  \t// does something on click\n  \t// you can access the value of the event\n  }}\n```\n\n#### onValueMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse enters a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<MarkSeries\n...\n  onValueMouseOver={(datapoint, event)=>{\n  \t// does something on click\n  \t// you can access the value of the event\n  }}\n```\n\n\n## Interaction strategies and examples\n\n### Interaction and hints or crosshairs\n\nThis was the first use case we built for interaction. We have one line chart on a plot, we want to show the value of the nearest mark to the cursor, without requiring the user to actually be over the plot proper.\n\n<!-- INJECT:\"DynamicCrosshairWithLink\" -->\n\n```jsx\nconst DATA = [\n  [\n    {x: 1, y: 10},\n    {x: 2, y: 7},\n    {x: 3, y: 15}\n  ],\n  [\n    {x: 1, y: 20},\n    {x: 2, y: 5},\n    {x: 3, y: 15}\n  ]\n];\n\nexport default class DynamicCrosshair extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      crosshairValues: []\n    };\n  }\n\n  render() {\n    return (\n      <XYPlot\n        onMouseLeave={() => this.setState({crosshairValues: []})}\n        width={300}\n        height={300}>\n        <VerticalGridLines />\n        <HorizontalGridLines />\n        <XAxis />\n        <YAxis />\n        <LineSeries\n          onNearestX={(value, {index}) =>\n          \tthis.setState({crosshairValues: DATA.map(d => d[index])})}\n          data={DATA[0]}/>\n        <LineSeries\n          data={DATA[1]}/>\n        <Crosshair values={this.state.crosshairValues}/>\n      </XYPlot>\n    );\n  }\n}\n```\n\nA few notes:\n- here, we are using the state to record the position of the crosshair. So, we're using the class syntax vs the React functional API.\n- We use onMouseLeave, at the plot level, to reset the visualization if the user's mouse cursor leaves the plot area.\n- There are 2 LineSeries components, but we only outfit one of them with a onNearestX handler.\n- In that handler, we get the datapoint value as first argument, and the index part of the object as 2nd argument. Actually, we only care about that index value. We're using it to generate values for the crosshair.\n- Having the handler on the 2nd LineSeries would have the exact same effect. We would change the state twice, to the same value. This is why it's not useful to call it several times.\n\n### Mousing over near scatterplot marks\n<!-- INJECT:\"ScatterPlotOnNearestXYWithLink\" -->\n\n```jsx\nclass ScatterPlotOnNearestXY extends Component {\n  constructor() {\n    super();\n    this.state = {index: null};\n  }\n  render() {\n    const {index} = this.state;\n    const data = scatterPlotData.map((d, i) => ({...d, color: i === index ? 1 : 0}));\n    return <XYPlot\n      colorDomain={[0, 1]}\n      onMouseLeave={() => this.setState({index: null})}\n    >\n      <MarkSeries\n        data={data}\n        stroke=\"white\"\n        onNearestXY={(datapoint, {index}) => this.setState({index})}\n      />\n    </XYPlot>\n  }\n}\n```\n\nNotes:\n- Here, we could have used the onMouseOver prop but that would require the user to move their mouse on each dot. But those dots are small! it would be more comfortable to select whichever dot is the nearest from the cursor.\n- Again, we're going to use the state for interaction, so we use the class syntax.\n- Each time we're rendering this component, we're going to regenerate a dataset that takes the state into account. The selected datapoint will have its color property set to 1, for others it will be 0.\n- the colorDomain of XYPlot will be set to [0, 1]. This is because else, when no point is selected, the colorDomain would be [0, 0] and all dots would have the color of the higher bound (light orange).\n- As above, when the mouse leaves the plot, the state of the visualization is reset.\n- As above, in the onNearestXY handler, we're actually only interested in the index part of the second argument.\n\n### Mousing over series - the 2nd series group option\n<!-- INJECT:\"LineChartMouseOverSeriesWithLink\" -->\n```jsx\nclass LineChartMouseOverSeries extends Component {\n  constructor() {\n    super();\n    this.state = {index: null};\n  }\n  render() {\n    const {index} = this.state;\n    return <XYPlot {...defaultProps}\n        onMouseLeave={() => this.setState({index: null})}\n      >\n      {lineData.map((d, i) => (<LineSeries\n        data={d} key={`${i}`} stroke={i === index ? \"orange\" : undefined}\n      />))}\n      {lineData.map((d, i) => (<LineSeries\n        data={d} key={`${i}-mouseover`}\n        onSeriesMouseOut={() => this.setState({index: null})}\n        onSeriesMouseOver={() => this.setState({index: i})}\n        strokeWidth={10} stroke=\"transparent\"}\n      />))}\n    </XYPlot>\n  }\n}\n```\nHere, we are going to explore 2 strategies to handle highlighting one line series among several on screen.\nWe could do that with a simple onSeriesMouseOver but, again, that would require mousing over exactly on a line series, which are notoriously narrow.\nInstead, we create a second set of LineSeries whose only purpose is to handle interaction. That second set of LineSeries is thicker (here, the stroke width is set at a generous 10px) and is also transparent. In the embedded example, I'm highlighting each lineSeries as it is moused over, but I'm not reflecting this on the snippet of code.\n\nHere, lineData is an array of arrays. The LineSeries are created by mapping over that array, which is quite common.\nWhen creating the LineSeries for mouseover, I write:\n\n```jsx\n{lineData.map((d, i) => (<LineSeries\n  ...\n  onSeriesMouseOver={() => this.setState({index: i})}\n```\n\nIn the onSeriesMouseOver handler, I don't pass any argument in the handler proper, but I'm using the index of the array from the mapping method. So, for the first LineSeries, that value is 0, then 1, then 2.\n\n### Mousing over series - the extra scatterplot option\n<!-- INJECT:\"LineChartMouseOverXYWithLink\" -->\n```jsx\nconst allData = lineData.reduce((prev, curr, i) => {\n  return [...prev, ...curr.map((d) => ({...d, index: i}))]\n}, []);\n\nclass LineChartMouseOverXY extends Component {\n  constructor() {\n    super();\n    this.state = {index: null};\n  }\n  render() {\n    const {index} = this.state;\n\n    return <XYPlot {...defaultProps}\n        onMouseLeave={() => this.setState({\n          highlightedSeries: null,\n          pointUsed: null\n        })}\n      >\n      {lineData.map((d, i) => (<LineSeries\n        data={d} key={`${i}`} stroke={i === index ? \"orange\" : undefined}\n      />))}\n      <MarkSeries\n        data={allData}\n        color=\"transparent\"\n        size={10}\n        onNearestXY={({index}) => this.setState({index})}\n      />\n    </XYPlot>\n  }\n}\n```\nHere's a slightly different strategy to obtain a similar effect.\nPrior to rendering this component, I've created an \"allData\" dataset which is a flat array of all the datapoints in the 3 lineSeries' datasets, only we've added to each of these datapoints an extra property, index, which will be 0, 1 or 2 depending from which of the 3 dataset each datapoint comes.\n\nSo allData will be an array of objects of the form: {x: ..., y: ..., index: ...}. Index, the last property, will be ignored by scales and won't affect the rendering in any way.\n\nThen, on top of our 3 lineSeries, we're adding a MarkSeries with an onNearestXY handler, just as 2 examples above.\n\nThe first argument of the onNearestXY handler is the datapoint proper. So again: an object of the form: {x:... ,y:..., index:...}. While the index property was not taken into account for rendering, it is definitely part of the first argument. Actually, it's the only part that we care about, so we just write ({index}) =>.\n\nIn the embedded version of this example, I'm highlighting the mark that triggers onNearestXY, however I haven't added this in the snippet of code above.\n\n### Linked Charts\n<!-- INJECT:\"LinkedChartsWithLink\" -->\n\n```jsx\nclass LinkedCharts extends Component {\n  constructor() {\n    super();\n    this.state = {index: null};\n    this.handleMouseOver = this.handleMouseOver.bind(this);\n  }\n  handleMouseOver(index) {\n    this.setState({index});\n  }\n  render() {\n    const {index} = this.state;\n    return (<div style={{display: 'flex'}}>\n      {lineData.map((d, i) => (<div key={i}>\n        <LineChart\n          data={d}\n          index={index}\n          handleMouseOver={this.handleMouseOver} />\n        </div>))}\n    </div>);\n  }\n}\n\nfunction LineChart({data, index, handleMouseOver}) {\n  return (<XYPlot\n    yDomain={[0, 10]}\n    onMouseLeave={() => handleMouseOver(null)}\n    >\n      <LineSeries\n        data={data}\n        onNearestX={(datapoint, {index}) => handleMouseOver(index)} />\n      {index === null ? null : <LineSeries\n        data={[{x: index, y: 0}, {x: index, y: 10}]}\n        opacity={0.5} />\n      }\n      {index === null ? null : <MarkSeries\n        data={[data[index]}]}\n        stroke=\"white\" />\n      }\n    </XYPlot>);\n}\n```\n\nMore often than not, you want to be able to handle an action that happened in one of the charts and reflect it in different parts of your app, i.e. outside the chart.\n\nThis is a common React problem, and we're going to deal with it in a proven React way - with a container that has a state, and which will pass this state and actions to presentation components.\n\nThese presentation components will be represented according to the state of that container, and will be able to fire actions that will impact it.\n\nOur container is a simple class. We create this method, handleMouseOver, that we'll have to bind to the container because we're going to pass it down. When we're doing that, we'll want that method to affect the state of the container.\n\nOur container will create three \"LineChart\" components, to which it will pass the dataset of a line (i.e. an array of {x, y} objects, the contents of the state - which is simply an index value, if there has been a mouseOver action, or null if there hasn't been - and our handleMouseOver method.\n\nInside the LineChart components, we'll use onMouseLeave and onNearestX to trigger the handler, as in the examples above. So, if the user mouses over any of these line charts, this changes the state of the container above, which will trickle down to all 3 components again.\n\nFinally, we create a dynamic line and dot gizmo to represent where the user is mousing over. We can easily generate a dataset for that, since index is the x value of where both the line and the dot should be.\n"
  },
  {
    "path": "docs/label-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## LabelSeries:\n\n<!-- INJECT:\"LabelSeriesExampleWithLink\" -->\n\nSometimes you just need to write on your data, and labelSeries has your back. This simple series has a similar API as the markSeries except it adds a label property to each of the rows. This label is then rendered as part of the svg tree.\n\n```javascript\n<XYPlot width={300} height={300}>\n  <LabelSeries\n    animation\n    allowOffsetToBeReversed\n    data={data} />\n</XYPlot>\n```\nThis can be useful for annotating points, as above, or in labeling wedges as (as in the radial chart).\n\n## Data format Reference\n\nLike other series the `labelSeries` requires the data be formatted as an array of objects with several required keys and several options ones. Here's an example\n\n\n```javascript\nconst myData = [\n  {x: 0, y: 0, label: 'woah!', style: {fontSize: 10}},\n  {x: 1, y: 0, label: 'dope city', yOffset: 5},\n  {x: 0, y: 1, label: 'cool Dog friend', xOffset: 5, rotation: 34}\n]\n```\n\nThe above would render three points with labels as suggested!\n\n#### x\n\nType: `number`\n\nThe x position in coordinates of the label.\n\n#### y\n\nType: `number`\n\nThe y position in coordinates of the label.\n\n#### label\n\nType: `string`\n\nThe actual text to be offered.\n\n#### xOffset\n\nType: `number`\n\nA number in pixels for the label to be offset from the x position specified on the row.\n\n#### yOffset\n\nType: `number`\n\nA number in pixels for the label to be offset from the y position specified on the row.\n\n#### rotation\n\nType: `number`\n\nNumber in degrees for the text to be rotated about its xy point.\n\n\n## Series API Reference\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### allowOffsetToBeReversed (optional)\nThe allows the offset specified on the data rows to flipped if the label is too close to an edge. This allows you to make sure your labels never get randomly clipped by going offscreen.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. See above data format reference.\n\n#### style\n\nType: `object`\n\nSVG text objects (which is what the labelSeries is made up of) accept a ton of different styles, so rather than prescribe every single one we just accept a general grab bag pf the styles. check out the [mozilla](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/text) page for more details.\n\n#### labelAnchorX\n\nType: `string`\n\nThis attribute is used to align (start-, middle- or end-alignment) the label text horizontally relative to the data point. (Sets the text-anchor attribute for the element https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-anchor)\n\n#### labelAnchorY\n\nType: `string`\n\nThis attribute is used to align the label text vertically relative to the datapoint. (Sets the dominant-baseline attribute for the element https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline)\n\n## Interaction handlers\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onValueClick (optional)\n\nType: `function(d, {event})`\n\n`click` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onValueMouseOver (optional)\n\nType: `function(d, {event})`\n\n`mouseover` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onValueMouseOut (optional)\n\nType: `function(d, {event})`\n\n`mouseout` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onValueRightClick (optional)\n\nType: `function(d, {event})`\n\n`right-click` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n"
  },
  {
    "path": "docs/legends.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Legends\n\n<!-- INJECT:\"HorizontalDiscreteColorLegendExampleWithLink\" -->\n\nCurrently following types of legends are supported:\n\n- for colors:\n  * DiscreteColorLegend (for a fixed number of colors, good for series);\n  * SearchableDiscreteColorLegend) (same as DiscreteColorLegend, but with search on top);\n  * ContinuousColorLegend (for gradually changing colors);\n- for sizes:\n  * ContinuousSizeLegend (for gradually changing size).\n\n## Color legends\n\n### DiscreteColorLegend\n\n<!-- INJECT:\"VerticalDiscreteColorLegendExampleWithLink\" -->\n\n#### items (required)\n\nType: `Array<string|{title: string|react element, color: String, strokeDasharray: string, strokeStyle: string, strokeWidth: number, disabled: boolean}|react element>`\n\nArray of items that should be shown on the legend. The array should consist from either objects (`title`, optional `color`, optional `strokeDasharray`, optional `strokeStyle`, optional `strokeWidth`, and optional `disabled` flag) or strings (treated as titles). The stroke properties should match those in your series (see [line series](line-mark-series.md))\n\n\n\n#### orientation (optional)\n\nType: `(vertical|horizontal)`\n\nDefault: `'vertical'`\n\nString either `horizontal` or `vertical` representing which direction the legend elements are rendered.\n\n#### onItemClick\n\nType: `function(Object, number): void`\n\nDefault: noop\n\nClick callback for the item in the list. Gets the clicked item and its index as parameters.\n\n#### onItemMouseEnter\n\nType: `function`\n\nDefault: noop\n\nThis handler is triggered either when the user's mouse enters a legend item.\nThe handler passes three arguments, the corresponding item, legend index and the actual event.\n```jsx\n<DiscreteColorLegend\n...\n  onItemMouseEnter={(item, index, event) => {\n    // does something on mouse enter\n    // you can access the value of the event\n  }}\n```\n\n#### onItemMouseLeave\n\nType: `function`\n\nDefault: noop\n\nThis handler is triggered either when the user's mouse leaves a legend item.\nThe handler passes three arguments, the corresponding item, legend index and the actual event.\n```jsx\n<DiscreteColorLegend\n...\n  onItemMouseLeave={(item, index, event) => {\n    // does something on mouse leave\n    // you can access the value of the event\n  }}\n```\n\n#### width\n\nType: `number`\n\nOuter width of the component. Default width is not set.\n\n#### height\n\nType: `number`\n\nOuter height of the component. Default is not set, the component stretches with the items added into it.\n\n### SearchableDiscreteColorLegend\n\n`SearchableDiscreteColorLegend` allows the user to perform search among the items.\n\n<!-- INJECT:\"SearchableDiscreteColorLegendExampleWithLink\" -->\n\nIts API includes the API of `DiscreteColorLegend`, but adds several search-related items:\n\n#### searchText (optional)\n\nType: `string`\n\nDefault: `''`\n\n\n#### searchFn (optional)\n\nType: `function(Array, string):Array`\n\nFunction that is should filter out the unnecessary items by the given initial array of items and the search string. By default the function returns an array of items which titles contain a string.\n\n#### searchPlaceholder (optional)\n\nType: `string`\n\nDefault: `''`\n\nPlaceholder for an search input field.\n\n#### onSearchChange (optional)\n\nType: `function(string):void`\n\nEvent handler for the change of the input field. The handler is triggered with the search field value as a parameter.\n\n#### onItemMouseEnter\n\nType: `function`\n\nDefault: noop\n\nThis handler is triggered either when the user's mouse enters a legend item.\nThe handler passes three arguments, the corresponding item, legend index and the actual event.\n```jsx\n<SearchableDiscreteColorLegend\n...\n  onItemMouseEnter={(item, index, event) => {\n    // does something on mouse enter\n    // you can access the value of the event\n  }}\n```\n\n#### onItemMouseLeave\n\nType: `function`\n\nDefault: noop\n\nThis handler is triggered either when the user's mouse leaves a legend item.\nThe handler passes three arguments, the corresponding item, legend index and the actual event.\n```jsx\n<SearchableDiscreteColorLegend\n...\n  onItemMouseLeave={(item, index, event) => {\n    // does something on mouse leave\n    // you can access the value of the event\n  }}\n```\n\n### ContinuousColorLegend\n\n<!-- INJECT:\"ContinuousColorLegendExampleWithLink\" -->\n\n#### startTitle\n\nType: `string|number`\n\nThe title that is shown in the beginning of the legend.\n\n#### midTitle\n\nType: `string|number`\n\nThe title that is show in the middle of the legend.\n\n#### endTitle\n\nType: `string|number`\n\nThe title that is show in the end of the legend.\n\n#### startColor (optional)\n\nType: `string`\n\nThe initial color of the bar\n\n#### endColor (optional)\n\nType: `string`\n\nThe end color of the bar.\n\n#### midColor (optional)\n\nType: `string`\n\nThe middle color of the bar.\n\n#### width (optional)\n\nType: `number`\n\nOuter width of the component.\n\n#### height (optional)\n\nType: `number`\n\nOuter height of the component.\n\n## Size Legends\n\n### ContinuousSizeLegend\n\n<!-- INJECT:\"ContinuousSizeLegendExampleWithLink\" -->\n\n#### startTitle\n\nType: `string|number`\n\nThe title that is shown in the beginning of the legend.\n\n#### endTitle\n\nType: `string|number`\n\nThe title that is show in the end of the legend.\n\n#### startSize (optional)\n\nType: `number`\n\nDefault: `2`\n\nThe initial size of the circles in the legend.\n\n#### endSize (optional)\n\nType: `number`\n\nDefault: `20`\n\nThe end size of the circles in the legend.\n\n#### circlesTotal (optional)\n\nType: `number`\n\nDefault: `10`\n\nTotal amount of circles displayed in the legend\n\n#### width (optional)\n\nType: `number`\n\nOuter width of the component.\n\n#### height (optional)\n\nType: `number`\n\nOuter height of the component.\n"
  },
  {
    "path": "docs/line-mark-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# LineMarkSeries\n\nThe Line Mark series is a combination of a LineSeries and a MarkSeries: under the hood, it creates both a LineSeries and a MarkSeries and passes them all of its properties.\n\n<!-- INJECT:\"LineMarkChartWithLink\" -->\n\n## Data format reference\n\n#### x\n\nType: `string|number|date`\n\nx will be used to determine the x position of each point on the line. The format of x depends on what scale is being used - see [Scales and Data](scales-and-data.md)\n\n#### y\n\nType: `string|number|date`\n\ny will be used to determine the y position of each point on the line. The format of y depends on what scale is being used - see [Scales and Data](scales-and-data.md)\n\n#### color (optional)\n\nType: `string|number`\n\nThe color of the line and that of the marks. By default the color is interpreted as number to be scaled to a color range. This can be over-ridden by providing the prop colorType=\"literal\" to the series itself. This property can also be defined on the series level.\n\n#### opacity (optional)\n\nType: `string|number`\n\nOpacity of the individual box to be rendered. By default opacity is scaled by `literal`, so the exact value provided will be used. This property can also be defined on the series level.\n\n#### stroke (optional)\n\nType: `string|number`\n\nStroke affects both the color of the line, and the outline of the marks. When this value is not provided, the color attribute is used instead. This property can also be defined on the series level.\n\n#### fill (optional)\n\nType: `string|number`\n\nThe color of the inside of the marks. When this value is not provided the color attribute is used instead. This property can also be defined on the series level.\n\n#### size (optional)\n\nType: `string|number`\n\nDefault: `5`\n\nThe size of each of the marks.\n\n## API Reference\n\n#### curve (optional)\n\nType: `string|function`\n\nDefault: `null`\n\nApply the provided or named curve function from the D3 shape library to smooth the line series plot, see [the D3 documentation](https://github.com/d3/d3-shape#curves) for function names and instructions. Providing the function, not the name, will require importing the d3-shape package in order to configure it:\n\n```javascript\n// Setting up with only a name\nconst stringCurveProp = <LineMarkSeries data={data} curve={'curveMonotoneX'} .../>;\n\nconst configuredCurve = d3Shape.curveCatmullRom.alpha(0.5);\nconst funcCurveProp = <LineMarkSeries data={data} curve={configuredCurve} .../>;\n```\n\nSome, but not all line interpolations have the resulting curve going through the original coordinates of its data points. If not, the LineSeries part of the LineMarkSeries will be detached from the MarkSeries part.\n\n#### fill (optional)\n\nType: `string|number`\n\nThe inner color for all the marks in the series, this property will be over-ridden by fill specified in the data attribute. See [colors](colors.md)\n\n#### getNull (optional)\n\nType: `function`\n\nDefault: `null`\n\nA function that will be invoked for each data element that will return a boolean that specifies if the data point should be drawn or not. For more information see [the D3 documentation](https://github.com/d3/d3-shape#line_defined).\n\n```javascript\n// Only draw datapoints where the y value is not equal to null\n<LineMarkSeries getNull={(d) => d.y !== null} data={data} />\n```\n\n#### stroke (optional)\n\nType: `string|number`\n\nDefault: see [colors](colors.md)\n\nA color for the series. Will override color if both are provided.\n\n##### strokeDasharray (optional)\n\nType: `string`\n\nSpecify a custom `stroke-dasharray` attribute which controls the pattern of dashes and gaps used to stroke paths. This will only affect the LineSeries part of the LineMarkSeries.\n\n##### strokeStyle (optional)\n\nType: `string`\n\nIf set to `dashed`, your series will use dashed lines. If set to `solid` or unspecified, your series will use solid lines. See `strokeDasharray` for specifying a custom stroke dash-array value. This will only affect the LineSeries part of the LineMarkSeries.\n\n##### strokeWidth (optional)\n\nType: `string|number`\n\nSpecifies the width of the line for the series. By default, this is determined by react-vis css (2px). This will affect both the thickness of the Line and the Marks.\n\n#### style (optional)\n\nType: `object`\n\nAn object which holds CSS properties that will be applied to the SVG element(s) rendered by the series. See [style](style.md)This allows you to style series beyond the other explicitly defined properties and without having to use CSS classnames and stylesheets.\n\n```jsx\n<LineMarkSeries\n  data={data}\n  style={{strokeLinejoin: \"round\"}}\n/>\n```\n\n`LineMarkSeries` being a composite component (a mix of [LineSeries](line-series.md) and [MarkSeries](mark-series.md)), there are two additional property in the `style` object: `line` and `mark`, which allow you to specify a style for the line or the mark part of the line mark series, respectively.\n\n```jsx\n<LineMarkSeries\n  data={data}\n  lineStyle={{stroke:\"red\"}}\n  markStyle={{stroke:\"blue\"}}\n/>\n```\n\n## Interaction handlers\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n\n#### onSeriesClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user clicks somewhere on a series, and provides the corresponding event. Unlike onClick, it doesn't pass a specific datapoint.\n\n```jsx\n<LineMarkSeries\n...\n  onSeriesClick={(event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user's mouse cursor leaves a series, and provides the corresponding event. Unlike onValueMouseOut, it doesn't pass a specific datapoint.\n\n```jsx\n<LineMarkSeries\n...\n  onSeriesMouseOut={(event)=>{\n    // does something on mouse over\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user mouses over a series, and provides the corresponding event. Unlike onValueMouseOver, it doesn't pass a specific datapoint.\n\n```jsx\n<LineMarkSeries\n...\n  onSeriesMouseOver={(event)=>{\n    // does something on mouse over\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user right-clicks somewhere on a series, and provides the corresponding event. Unlike onClick, it doesn't pass a specific datapoint.\n\n```jsx\n<LineMarkSeries\n...\n  onSeriesRightClick={(event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<LineMarkSeries\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse leaves a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<LineMarkSeries\n...\n  onValueMouseOut={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse enters a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<LineMarkSeries\n...\n  onValueMouseOver={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user right-clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<LineMarkSeries\n...\n  onValueRightClick={(datapoint, event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n"
  },
  {
    "path": "docs/line-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# LineSeries/LineMarkSeries\n\n<!-- INJECT:\"LineChartWithLink\" -->\n\nreact-vis offers two different types of LineSeries, one that renders SVG and one that renders Canvas.\nThe SVG mode is accessed by using the normal `LineSeries`, just as above, while the Canvas mode is used by simply calling `LineSeriesCanvas` instead of `LineSeries`.\n\n<!-- INJECT:\"LineChartCanvasWithLink\" -->\n-**NOTE**: using the Canvas version of this layer disables animation\n\n## Data format reference\n\n#### x\n\nType: `number`\n\nLeft-to-right position of marks in the series.\n\n#### y\n\nType: `number`\n\nTop-to-bottom position of the top edge of the series.\n\n## API Reference\n\n#### color (optional)\n\nType: `string|number`\n\nDefault: see [colors](colors.md)\n\nColor of the line series.\nBy default, you can pass a literal color to the series (i.e. \"red\" or \"#f70\"). You can also define a color scale at the top level, and pass a number which will be interpolated by the scale. If nothing is provided, lineSeries will be colored according to react-vis default scale.\n\n#### curve (optional)\n\nType: `string|function`\n\nDefault: `null`\n\nApply the provided or named curve function from the D3 shape library to smooth the line series plot, see [the D3 documentation](https://github.com/d3/d3-shape#curves) for function names and instructions. Providing the function, not the name, will require importing the d3-shape package in order to configure it:\n\n```javascript\n// Setting up with only a name\nconst stringCurveProp = <LineSeries data={data} curve={'curveMonotoneX'} .../>;\n\nconst configuredCurve = d3Shape.curveCatmullRom.alpha(0.5);\nconst funcCurveProp = <LineSeries data={data} curve={configuredCurve} .../>;\n```\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. See above data format reference.\n\n#### getNull (optional)\n\nType: `function`\n\nDefault: `null`\n\nA function that will be invoked for each data element that will return a boolean that specifies if the data point should be drawn or not. For more information see [the D3 documentation](https://github.com/d3/d3-shape#line_defined).\n\n```javascript\n// Only draw datapoints where the y value is not equal to null\n<LineSeries getNull={(d) => d.y !== null} data={data} />\n```\n\n#### opacity (optional)\n\nType: `number`\n\nDefault: `1`\n\nOpacity of the area chart from 0 (transparent) to 1 (opaque).\n\n#### stroke (optional)\n\nType: `string|number`\n\nDefault: see [colors](colors.md)\n\nA color for the series. Will override color if both are provided.\n\n##### strokeDasharray (optional)\n\nType: `string`\n\nSpecify a custom `stroke-dasharray` attribute which controls the pattern of dashes and gaps used to stroke paths. For the canvas version of this series, this should be an array of values, ala [7, 5].\n\n##### strokeStyle (optional)\n\nType: `string`\n\nIf set to `dashed`, your series will use dashed lines. If set to `solid` or unspecified, your series will use solid lines. See `strokeDasharray` for specifying a custom stroke dash-array value.\n\n##### strokeWidth (optional)\n\nType: `string|number`\n\nSpecifies the width of the line for the series. By default, this is determined by react-vis css (2px).\n\n#### style (optional)\n\nType: `object`\n\nAn object which holds CSS properties that will be applied to the SVG element(s) rendered by the series. This allows you to style series beyond the other explicitly defined properties and without having to use CSS classnames and stylesheets. See [style](style.md)\n\n```jsx\n<LineSeries\n  data={data}\n  style={{strokeLinejoin: \"round\"}}\n/>\n```\n\n### Interaction handlers\n\nNote - interacting with a line may be difficult especially with the standard width. To address that, consider:\n- the proximity handlers - onNearestX, onNearestXY;\n- increasing the width of your line to make it easier to reach with the mouse,\n- creating a near-transparent line series with extra width to catch mouse events.\n\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onSeriesClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user clicks somewhere on a LineSeries, and provides the corresponding event. See [interaction](interaction.md)\n\n```jsx\n<LineSeries\n...\n  onSeriesClick={(event)=>{\n  \t// does something on click\n  \t// you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user's mouse cursor leaves a LineSeries, and provides the corresponding event. See [interaction](interaction.md)\n\n```jsx\nLineSeries\n...\n  onSeriesMouseOut={(event)=>{\n  \t// does something on mouse over\n  \t// you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user mouses over a LineSeries, and provides the corresponding event. See [interaction](interaction.md)\n\n```jsx\n<LineSeries\n...\n  onSeriesMouseOver={(event)=>{\n  \t// does something on mouse over\n  \t// you can access the value of the event\n  }}\n```\n\n#### onSeriesRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user right-clicks somewhere on a LineSeries, and provides the corresponding event. See [interaction](interaction.md)\n\n```jsx\n<LineSeries\n...\n  onSeriesRightClick={(event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n"
  },
  {
    "path": "docs/mark-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## MarkSeries & MarkSeriesCanvas\n\n<!-- INJECT:\"ScatterplotChartWithLink\" -->\n\nThe MarkSeries allows users to embed discrete information in pairs of continuous variables,\nthat is make scatterplots. Deploying a MarkSeries is super easy:\n\n```javascript\nrender() {\n  return (\n    <XYPlot\n      width={300}\n      height={300}>\n      <MarkSeries\n        className=\"mark-series-example\"\n        sizeRange={[5, 15]}\n        data={myData}/>\n    </XYPlot>\n  );\n```\n\nJust like other series, MarkSeries expects its data to be formatted as an array of objects, like so:\n\n```javascript\nconst myData = [\n  {x: 1, y: 10, size: 30},\n  {x: 1.7, y: 12, size: 10},\n  {x: 2, y: 5, size: 1},\n  {x: 3, y: 15, size: 12},\n  {x: 2.5, y: 7, size: 4}\n]\n```\n\nreact-vis offers two different types of MarkSeries, one that renders SVG and one that renders Canvas.\nThe SVG mode is accessed by using the normal `MarkSeries`, just as above, while the Canvas mode is used by simply calling `MarkSeriesCanvas` instead of `MarkSeries`.\n\n<!-- INJECT:\"ScatterplotCanvasWithLink\" -->\n\n-**NOTE**: using the Canvas version of this layer disables animation\n\nMark series can usefully be deployed with voronois for fast and accurate mouse overs!\n\n<!-- INJECT:\"DynamicCrosshairScatterplotWithLink\" -->\n\n## Data format reference\n\n#### x\n\nType: `string|number|date`\n\nx will be used to determine the x position of each mark. The format of x depends on what scale is being used - see [Scales and Data](scales-and-data.md)\n\n#### y\n\nType: `string|number|date`\n\ny will be used to determine the y position of each mark. The format of y depends on what scale is being used - see [Scales and Data](scales-and-data.md)\n\n#### color (optional)\n\nType: `string|number`\n\nThe color of the marks. By default the color is interpreted as number to be scaled to a color range. This can be over-ridden by providing the prop colorType=\"literal\" to the series itself. This property can also be defined on the series level.\n\n#### opacity (optional)\n\nType: `string|number`\n\nDefault: `1`\n\nOpacity of the individual marks, from 0 (transparent) to 1 (opaque). By default opacity is scaled by `literal`, so the exact value provided will be used. This property can also be defined on the series level.\n\n#### stroke (optional)\n\nType: `string|number`\n\nThe color of the outline of the marks. When this value is not provided, the color attribute is used instead. This property can also be defined on the series level.\n\n#### fill (optional)\n\nType: `string|number`\n\nThe color of the inside of the marks. When this value is not provided the color attribute is used instead. This property can also be defined on the series level.\n\n#### size (optional)\n\nType: `string|number`\n\nDefault: `5`\n\nThe size of each of the marks.\n\n## API Reference\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### color (optional)\n\nType: `string|number`\n\nExact color for all series points or a series object.\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series.\n\n#### fill (optional)\n\nType: `string|number`\n\nThe inner color for all the marks in the series, this property will be over-ridden by fill specified in the data attribute. See [colors](colors.md)\n\n#### opacity (optional)\n\nType: `string|number`\n\nExact opacity for all series points in pixels or a series object, from 0 (transparent) to 1 (opaque)\n\n#### size (optional)\n\nType: `string|number`\n\nExact size for all series points in pixels or a series object.\n\n#### stroke (optional)\n\nType: `string|number`\n\nDefault: see [colors](colors.md)\n\nA color for the outline of the marks. Will override color if both are provided.\n\n#### strokeWidth (optional)\n\nType: `string|number`\n\nDefault: `1`\n\nThe width of the outline of the marks.\n\n## Interaction handlers\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onSeriesClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user clicks somewhere on a series, and provides the corresponding event. Unlike onClick, it doesn't pass a specific datapoint.\n\n```jsx\n<MarkSeries\n...\n  onSeriesClick={(event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user's mouse cursor leaves a series, and provides the corresponding event. Unlike onValueMouseOut, it doesn't pass a specific datapoint.\n\n```jsx\n<MarkSeries\n...\n  onSeriesMouseOut={(event)=>{\n    // does something on mouse over\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user mouses over a series, and provides the corresponding event. Unlike onValueMouseOver, it doesn't pass a specific datapoint.\n\n```jsx\n<MarkSeries\n...\n  onSeriesMouseOver={(event)=>{\n    // does something on mouse over\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user right-clicks somewhere on a series, and provides the corresponding event. Unlike onClick, it doesn't pass a specific datapoint.\n\n```jsx\n<MarkSeries\n...\n  onSeriesRightClick={(event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<MarkSeries\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse leaves a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<MarkSeries\n...\n  onValueMouseOut={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse enters a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<MarkSeries\n...\n  onValueMouseOver={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user right-clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<MarkSeries\n...\n  onValueRightClick={(datapoint, event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n```\n"
  },
  {
    "path": "docs/parallel-coordinates.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# Parallel Coordinates\n\nParallel Coordinates provide a robust method for displaying many variables simultaneously. It allows for rapid at-a-glance comparisons across a bunch of dimensions. These graphics can effectively be used either with several data rows on a single chart (as below) or as a small multiple. For more information, check out the [Wiki](https://en.wikipedia.org/wiki/Parallel_coordinates), it's got some really neat examples.\n\n<!-- INJECT:\"BasicParallelCoordinatesWithLink\" -->\n\nImagine you have a trio of models of cars that you are trying to compare. You're being data driven so you've collected a number of measurements based on a variety of values. You know basic facts about your variables, eg the interior rating a car can have is 7 and the minimum 1. You can use all this information to produce the above chart! Viola! Informed consumer.\n\n<!-- INJECT:\"AnimatedParallelCoordinatesWithLink\" -->\n\nJust like every other chart and series ParallelCoordinates expects an array of data, each row or object corresponds to a line or polygon (depending on how you have your chart styled). A key caveat for this chart type is that react-vis can not simply infer the variables from each data object that you wish to plot, so we need you to tell us! So enters the domains prop, an array of object specifying the order and behavior of each of the variables. So you have to tell react-vis a little more to get started, but you get a lot more expressiveness. Let's consider some code. You might provide the following object as props to the parallel coordinates chart:\n\n```javascript\nconst PARALLEL_COORDINATES_PROPS = {\n  data: [{\n    neatExplosions: 7,\n    wow: 10,\n    dog: 8,\n    sickMoves: 9,\n    nice: 7\n  }],\n  domains: [\n    {name: 'nice', domain: [0, 100]},\n    {name: 'explosions', domain: [6.9, 7.1], getValue: d => d.neatExplosions},\n    {name: 'wow', domain: [0, 11]},\n    {name: 'sickMoves', domain: [0, 20]}\n  ],\n  height: 300,\n  width: 400\n};\n```\n\nIn such a case, there would be ONE polygon rendered for four variables (nice/explosions/wow/sickMoves), because those values are listed in the domains prop.\n\nThe ParallelCoordinates also features a stateful brushing mode in which your user can brush and drag on the the chart to selected and unselected lines. See the [highlight](highlight.md) component for more details.\n\n<!-- INJECT:\"BrushedParallelCoordinatesWithLink\" -->\n\n## API Reference\n#### data\n\nType: `arrayOf(Objects)`\n\nEach object must have keys for each of the intended display domains (eg in the above example any input row should have at neatExplosions/wow/dog/sickMoves/nice). Additional a style prop can be provided on the row of the data itself to style the line series that it corresponds to, for instance here's one of the rows from the car example:\n\n```javascript\n{\n  name: 'Honda',\n  mileage: 8,\n  price: 6,\n  safety: 9,\n  performance: 6,\n  interior: 3,\n  warranty: 9,\n  style: {\n    strokeWidth: 3,\n    strokeDasharray: '2, 2'\n  }\n}\n```\n\nIt is not necessary to provide style, but it can be helpful!\n\n\n#### domains\n\nType: `arrayOf(Objects)`\n\nThe domains allow the user to specify the nature of the variables being plotted. This information is captured in an object formatted like:\n\n```javascript\nPropTypes.shape({\n  name: PropTypes.string.isRequired,\n  getValue: PropTypes.func,\n  domain: PropTypes.arrayOf([PropTypes.number]).isRequired,\n  tickFormat: PropTypes.func\n})\n```\n\nLet's looks at each member of the object\n\n- name: generates a member of a labelSeries that shows at the end of the corresponding axis\n- getValue: an accessor function that grabs a value from the row being accessed, if this is not provided a default one that uses the name property is used.\n- domain: a pair of numbers that are interpolated between. Setting these values correctly is essential for making your graphic legible! Because it is often the case that there will only be one or two data rows in a parallel coordinates, react-vis requires the user to specify the exact domain for each variable. Without which we would be unable to plot the variables well.\n- tickFormat: allows the user to provide a formatting function for prettifying the way that axis interpolates between the domain values.\n\n#### width\n\nType: `number`\n\nWidth of the component.\n\n#### height\n\nType: `number`\n\nHeight of the component.\n\n#### margin (optional)\n\nType: `Object`\n\nDefault: `{left: 40, right: 10, top: 10, bottom: 40}`\n\nMargin around the chart.\n\n#### brushing\n\nType: `Boolean`\n\nDefault: false\n\nEnable stateful brushing on parallel coordinates\n\n#### style (optional)\n\nType: `object`\n\nAn object that contains CSS properties with which the axis component can be entirely re-styled.\nAs the ParallelCoordinates is composite of several composite elements, it is possible to provide style objects for any and all parts of the tree. See [style](style.md)\nMost generally, there are three top level components `axes`, `labels`, and `lines`. These in turn lead to their corresponding to style objects. As an example, here is the default style object for the ParallelCoordinates:\n\n```jsx\n<ParallelCoordinates data={mydata} style={{\n  axes: {\n    line: {},\n    ticks: {},\n    text: {}\n  },\n  labels: {\n    fontSize: 10\n  },\n  line: {\n    strokeOpacity: 1\n  },\n  deselectedLineStyle: {\n    strokeOpacity: 0.1\n  }\n}}/>\n```\n\nIf you are using the stateful brushing mode and have filtered out a line then, in addition to the previous styles that were applied to a particular line, deselectedLineStyle will also be applied.\n\n#### animation (optional)\n\nType: `boolean|Object`\n\nPlease refer to [Animation](animation.md) doc for more information.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### colorType (optional)\n\nType: `string`\n\nSpecify the type of color scale to be used on the parallel coordinates chart, please refer to [Scales and data](scales-and-data.md) for more information.\n\n#### showMarks (optional)\n\nType: 'boolean'\n\nSpecific whether or not to show the marks on the vertices of the lines\n\n#### tickFormat (optional)\n\nType: 'function'\n\nSpecify the tick format for all axes. Will be over-ridden by tickFormats specified on single domains.\n"
  },
  {
    "path": "docs/polygon-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## PolygonSeries:\n\n<!-- INJECT:\"TriangleExampleWithLink\" -->\n\nThe polygon series allows users to specify arbitrary polygons in coordinates. This may seem un-useful, but it allows for\neasy creation of radar charts, fancy mark series dots, and any variety of additional things you might need polygons for!\n\n```javascript\n<XYPlot\n  width={300}\n  height={300}>\n  <XAxis />\n  <YAxis />\n  <PolygonSeries\n    className=\"polygon-series-example\"\n    data={myData}/>\n</XYPlot>\n```\n\nEach series corresponds to exactly **one** svg path. It is perfectly okay to many series to express many polygons!\n\n## Data format Reference\n\nLike other series, it is required that the data be an array of objects, formatted like so:\n\n\n```javascript\nconst myData = [\n  {x: 0, y: 0},\n  {x: 1, y: 0},\n  {x: 0, y: 1}\n]\n```\n\nWhich would render a triangle.\n\n#### x\n\nType: `number`\n\nThe x position in coordinates of the box to be used.\n\n#### y\n\nType: `number`\n\nThe y position in coordinates of the box to be used.\n\n\n## Series API Reference\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### color\n\nType: `string`\n\nThe color for all elements in the series, this property will be over-ridden by color specified in the data attribute. See [colors](colors.md)\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. See above data format reference.\n\n#### style\n\nType: `object`\n\nPaths accept a ton of different styles, so rather than prescribe every single one we just accept a general grab bag pf the styles. check out the [w3](https://www.w3schools.com/graphics/svg_path.asp) page for more details and the [style] documentation (style.md).\n\n## Interaction handlers\n\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onSeriesClick (optional)\n\nType: `function(d, {event})`\n\n`click` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property. See [interaction](interaction.md)\n\n#### onSeriesMouseOut (optional)\n\nType: `function(d, {event})`\n\n`mouseout` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an\n\n#### onSeriesMouseOver (optional)\n\nType: `function(d, {event})`\n\n`mouseover` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property. See [interaction](interaction.md)\nobject with the only `event` property. See [interaction](interaction.md)\n\n#### onSeriesRightClick (optional)\n\nType: `function(d, {event})`\n\n`right-click` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property. See [interaction](interaction.md)\n"
  },
  {
    "path": "docs/presentation.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# React-vis\n\n__React-vis__ is a React visualization library. It's been designed with the following principles in mind:\n\n## React-friendly:\nReact-vis components are designed to work just like other React components. They have properties, children and callbacks. They can be composed. If you can work with React components, you can work with React-Vis.\n\n## High-level and customizable:\nYou can create complex charts with a minimum amount of code and sensible defaults, however, you can also customize every aspect of your chart.\n\n## Expressive:\nReact-vis handles a great number of charts, from area charts to treemaps;\n\n## Industry-strong:\nReact-vis was built to support the many internal tools at Uber.\n"
  },
  {
    "path": "docs/radar-chart.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# Radar Charts\n\nRadar charts provide a cute method for displaying many variables simultaneously. It allows for rapid at-a-glance comparisons across a bunch of dimensions. These graphics can effectively be used either with several data rows on a single chart (as below) or as a small multiple. For more information, check out the [Wiki](https://en.wikipedia.org/wiki/Radar_chart), it's got some really neat examples.\n\n<!-- INJECT:\"BasicRadarChartWithLink\" -->\n\nImagine you have a trio of models of cars that you are trying to compare. You're being data driven so you've collected a number of measurements based on a variety of values. You know basic facts about your variables, eg the interior rating a car can have is 7 and the minimum 1. You can use all this information to produce the above chart! Viola! Informed consumer.\n\n<!-- INJECT:\"AnimatedRadarChartWithLink\" -->\n\nJust like every other chart and series RadarChart expects an array of data, each row or object corresponds to a line or polygon (depending on how you have your chart styled). A key caveat for this chart type is that react-vis can not simply infer the variables from each data object that you wish to plot, so we need you to tell us! So enters the domains prop, an array of object specifying the order and behavior of each of the variables. So you have to tell react-vis a little more to get started, but you get a lot more expressiveness. Let's consider some code. You might provide the following object as props to the radar chart:\n\n```javascript\nconst RADAR_PROPS = {\n  data: [{\n    neatExplosions: 7,\n    wow: 10,\n    dog: 8,\n    sickMoves: 9,\n    nice: 7\n  }],\n  domains: [\n    {name: 'nice', domain: [0, 100]},\n    {name: 'explosions', domain: [6.9, 7.1], getValue: d => d.neatExplosions},\n    {name: 'wow', domain: [0, 11]},\n    {name: 'sickMoves', domain: [0, 20]}\n  ],\n  height: 300,\n  width: 400\n};\n```\n\nIn such a case, there would be ONE polygon rendered for four variables (nice/explosions/wow/sickMoves), because those values are listed in the domains prop. The radar chart accepts children if you wish to provide additional components, such as CircularGridLines.\n\n\n## API Reference\n\n\n#### data\n\nType: `arrayOf(Objects)`\n\n\n#### domains\n\nType: `arrayOf(Objects)`\n\nThe domains allow the user to specify the nature of the variables being plotted. This information is captured in an object formatted like:\n\n```javascript\nPropTypes.shape({\n  name: PropTypes.string.isRequired,\n  getValue: PropTypes.func,\n  domain: PropTypes.arrayOf([PropTypes.number]).isRequired,\n  tickFormat: PropTypes.func\n})\n```\n\nLet's looks at each member of the object\n\n- name: generates a member of a labelSeries that shows at the end of the corresponding axis\n- getValue: an accessor function that grabs a value from the row being accessed, if this is not provided a default one that uses the name property is used.\n- domain: a pair of numbers that are interpolated between. Setting these values correctly is essential for making your graphic legible! Because it is often the case that there will only be one or two data rows in a radar chart, react-vis requires the user to specify the exact domain for each variable. Without which we would be unable to plot the variables well.\n- tickFormat: allows the user to provide a formatting function for prettifying the way that axis interpolates between the domain values.\n\n#### width\n\nType: `number`\n\nWidth of the component.\n\n#### height\n\nType: `number`\n\nHeight of the component.\n\n#### margin (optional)\n\nType: `Object`\n\nDefault: `{left: 40, right: 10, top: 10, bottom: 40}`\n\nMargin around the chart.\n\n#### style (optional)\n\nType: `object`\n\nAn object that contains CSS properties with which the axis component can be entirely re-styled.\nAs the RadarChart is composite of several composite elements, it is possible to provide style objects for any and all parts of the tree. See [style](style.md)\nMost generally, there are three top level components `axes`, `labels`, and `polygons`. These in turn lead to their corresponding to style objects. As an example, here is the default style object for the RadarChart:\n\n```jsx\n<RadarChart data={mydata} style={{\n  axes: {\n    line: {},\n    ticks: {},\n    text: {}\n  },\n  labels: {\n    fontSize: 10\n  },\n  polygons: {\n    strokeWidth: 0.5,\n    strokeOpacity: 1,\n    fillOpacity: 0.1\n  }\n}}/>\n```\n\n#### animation (optional)\n\nType: `boolean|Object`\n\nPlease refer to [Animation](animation.md) doc for more information.\n\n#### hideInnerMostValues (optional)\n\nType: `boolean`\n\ndefaults to true\nWhether or not to hide the inner most tick values of the radar chart. This attempts to ensure that the ticks do not run over each other.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### colorType (optional)\n\nType: `string`\n\nSpecify the type of color scale to be used on the radar chart, please refer to [Scales and data](scales-and-data.md) for more information.\n\n#### tickFormat (optional)\n\nType: 'function'\n\nSpecify the tick format for all axes. Will be over-ridden by tickFormats specified on single domains.\n\n#### startingAngle (optional)\n\nType: `number`\n\nThe angle of the first axis in radians. Defaults to PI / 2.\n\n#### renderAxesOverPolygons (optional)\nType: `boolean`\nBy default, the axes are rendered beneath the data (polygons) on the radar chart. Setting this to true will reverse the rendering, drawing the axes on top. This can be useful if you have a lot of data or your polygons have high opacity.\n\n#### onValueMouseOver (optional)\nType: `function(d, {event})`\n`mouseover` event handler for the elements corresponding separate data points, where each data point is a point on the radar chart. First argument received, `d`, is the relevant data point, including the `domain`, `name`, and `value` of the data point. The second argument is the `event` property.\n\n#### onValueMouseOut (optional)\nType: `function(d, {event})`\n`mouseout` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.  \n\n#### onSeriesMouseOver (optional)\nType: `function(d, {event})`\n`mouseover` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onSeriesMouseOut (optional)\nType: `function(d, {event})`\n`mouseout` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n"
  },
  {
    "path": "docs/radial-chart.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# Radial chart\n\n`RadialChart` is responsible for creating pie and donut charts. While this kind of chart is easy to overlook as insignificant, intentionally confusing, or almost always replaceable with a treemap; they can be useful for quickly showing small groups. People don't understand angles very well [(such is our biology)](https://www.interaction-design.org/literature/book/the-encyclopedia-of-human-computer-interaction-2nd-ed/data-visualization-for-human-perception), but over the last hundred years we have seen a lot of pie charts! This has caused us to become intimately familiar with them.\n\n<!-- INJECT:\"CustomRadiusRadialChartWithLink\" -->\n\nWe can leverage this familiarity to quickly transmit information to our reader. The best type of information to display in this way (in our opinion) is groups of less 6 or so. More than that becomes pretty hard to compare and the reader just sees visual noise. The radial chart is easy to deploy:\n\n```jsx\n\n<RadialChart\n  data={myData}\n  width={300}\n  height={300} />\n```\n\nThe radial chart accepts children if you wish to give it them. This can be useful for adding tooltips, for example:\n\n<!-- INJECT:\"DonutChartExampleWithLink\" -->\n\n\n## Data format Reference\n\n\nRadial chart has a very similar API to the arc series, but with even fewer requirements. To wit the data can be as simple as\n\n\n```javascript\nconst myData = [{angle: 1}, {angle: 5}, {angle: 2}]\n```\n\nOr as complex as\n\n[\n  {angle: 1, radius: 10},\n  {angle: 2, label: 'Super Custom label', subLabel: 'With annotation', radius: 20},\n  {angle: 5, radius: 5, label: 'Alt Label'},\n  {angle: 3, radius: 14},\n  {angle: 5, radius: 12, subLabel: 'Sub Label only', className: 'custom-class'}\n];\n\n#### angle\n\nType: `number`\n\nThe only required property for the data, this determines the angular size of each wedge.\n\n#### radius\n\nType: `number`\n\nThe distance between the origin and the outside of the arc. This values is scaled linearly by default\n\n#### label\n\nType: `string`\n\nThe label to show next to the wedge.\n\n#### subLabel\n\nType: `string`\n\nThe subLabel to show next to the wedge. This can be used for annotations to the top label.\n\n#### color (optional)\n\nType: `string|number`\n\nThe color of a box in the series. By default the color is interpreted as number to be scaled to a color range. This can be over-ridden by providing the prop colorType=\"literal\" to the series itself. This property can also be defined on the series level.\n\n#### style (optional)\n\nType: `object`\n\nSVG paths (which is what the arc series is made up of) have numerous manipulable properties, so rather than trying to prescribe all of them as props we offer a port to let you style it for yourself. This overrides the series level version of this property.\n\n#### className (optional)\n\nType: `string`\n\nThe className to be added to an individual arc in the series.\n\n#### padAngle (optional)\n\nType: `number|function`\n\nThe padding to be applied between arcs. See above donut chart for an example of a padded angle.\n\n## Api\n\n##### angleDomain, angleRange, angleType\n\nScale properties for the `angle` scale. The `angle` property _should be_ passed in the data, otherwise the chart won't be shown.\nPlease refer to [Scales and Data](scales-and-data.md) for more information about scales.\n\n##### animation (optional)\n\nType: `boolean|Object`\n\nPlease refer to [Animation](animation.md) doc for more information.\n\n##### className (optional)\n\n\nType: `string`\n\nDOM classNames to be added to the wrapper component.\n\n##### colorDomain, colorRange, colorType\n\nScale properties for the `color` scale. If `color` property is not passed in the data object, each new section of the chart gets the next color (e. g. the `'category'` scale is applied).\nPlease refer to [Scales and Data](scales-and-data.md) for more information about scales.\n\n##### data\n\n\nType: `Array<Object>`\n\nArray of data for the series. See above data format reference.\n\n##### fillDomain, fillRange, fillType\n\nScale properties for the `fill` scale. If `fill` property is not passed in the data object, color scale is used instead.\nPlease refer to [Scales and Data](scales-and-data.md) for more information about scales.\n\n##### height (required, pixels)\n\n#### innerRadius\n\nType: `number` in pixels\n\nIf radius is not set on the data then this can be used to set the innerRadius for all of the rows. This can be useful for building donut charts.\n\n##### width (required, pixels)\n\n##### labelsAboveChildren\n\nType: `boolean`\n\nWhether or not to position the labels on top of the children. This can be useful if you have circular gridline and you want your labels to be legible on top of your grids.\n\n##### labelsRadiusMultiplier\n\nType: `number`\n\nHow far the labels should be from the center of the chart as a function of the radius of the chart. If not specified, the default value of 1.1 is used (slightly outside of the chart).\nNote that the property is labelsRadiusMultiplier (labels plural, not labelRadiusMultiplier)\n\n##### labelsStyle\n\nType: 'Object'\n\nA style object specifically for the labels.\nNote that the property is labelsStyle (labels plural, not labelStyle)\n\n##### margin (optional, pixels)\n\nType: `Object`\n\nDefault: `{left: 40, right: 40, top: 10, bottom: 10}`\n\n#### radius\n\nType: `number` in pixels\n\nIf radius is not set on the data then this can be used to set the radius for all of the rows.\n\n##### showLabels (optional)\n\nType: `boolean`\n\nWhether or not to show the labels specified in the data\n\n##### strokeDomain, strokeRange, strokeType\n\nScale properties for the `stroke` scale. If `stroke` property is not passed in the data object, stroke is _not_ visualized.\nPlease refer to [Scales and Data](scales-and-data.md) for more information about scales.\n"
  },
  {
    "path": "docs/rect-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# Rect Series\n\nRectSeries is a generalization of [BarSeries](bar-series.md) which allows users to build a series of rectangles of arbitrary dimensions. Whereas in barSeries, one dimension of the bars is fixed (width for vertical bar series, height for horizontal bar series), in RectSeries, both dimensions can be controlled.\n\nRectSeries can be used to build histograms, icicle charts, or anything really where both height and width matter.\n\n<!-- INJECT:\"HistogramWithLink\" -->\n\n<!-- INJECT:\"StackedHistogramWithLink\" -->\n\nLike BarSeries, RectSeries has two wrappers: HorizontalRectSeries and VerticalRectSeries. It also has a canvas version, RectSeriesCanvas (along with HorizontalRectSeriesCanvas and VerticalRectSeriesCanvas).\n\nRectSeries isn't meant to be used directly, however, it's provided as it's being used under the hood by HorizontalRectSeries and VerticalRectSeries.\n\n## Data format Reference\n\nLike other series, it is required that the data be an array of objects, formatted like so:\n\n```javascript\nconst myData = [\n  {x: 1, x0: 0, y: 10, y0: 0},\n  {x: 2, x0: 1, y: 5, y0: 0},\n  {x: 4, x0: 2, y: 15, y0: 0}\n]\n```\n\nThe main difference with bar series is that it has x0 and y0 properties.\n\n### For HorizontalRectSeries:\n\n#### x (optional)\n\nType: `string|number|date`\n\nDefault: `0`\n\nThe value used to compute the x position of _the right_ side of the rectangle.\n\n#### x0 (optional)\n\nType: `string|number|date`\n\nDefault: `0`\n\nThe value used to compute the x position of _the left_ side of the rectangle.\n\n#### y (optional)\n\nType: `string|number|date`\n\nDefault: `0`\n\nThe value used to compute the y position of _the bottom_ of the rectangle.\n\n#### y0 (optional)\n\nType: `string|number|date`\n\nDefault: `0`\n\nThe value used to compute the y position of _the top_ of the rectangle.\n\n### For VerticalRectSeries:\n\n#### x (optional)\n\nType: `string|number|date`\n\nDefault: `0`\n\nThe value used to compute the x position of _the left_ side of the rectangle.\n\n#### x0 (optional)\n\nType: `string|number|date`\n\nDefault: `0`\n\nThe value used to compute the x position of _the right_ side of the rectangle.\n\n#### y (optional)\n\nType: `string|number|date`\n\nDefault: `0`\n\nThe value used to compute the y position of _either_ side of the rectangle.\n\n#### y0 (optional)\n\nType: `string|number|date`\n\nDefault: `0`\n\nThe value used to compute the y position of the other side of the rectangle.\n\n#### color (optional)\n\nType: `string|number`\n\nThe color of a bar in the series. By default the color is interpreted as number to be scaled to a color range. This can be over-ridden by providing the prop colorType=\"literal\" to the series itself. This property can also be defined on the series level. See [colors](colors.md).\n\n#### opacity (optional)\n\nType: `number|Object`\n\nOpacity of the individual box to be rendered. By default opacity is scaled by `literal`, so the exact value provided will be used. This property can also be defined on the series level.\n\n#### stroke (optional)\n\nType: `number|Object`\n\nThe color of the outline of the box to be rendered. When this value is not provided the color attribute is used instead. This property can also be defined on the series level. See [colors](colors.md).\n\n#### fill (optional)\n\nType: `number|Object`\n\nThe color of the inside of the box to be rendered. When this value is not provided the color attribute is used instead. This property can also be defined on the series level. See [colors](colors.md).\n\n## Series API Reference\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### color\n\nType: `string|number`\n\nThe color for all elements in the series, this property will be over-ridden by color specified in the data attribute. See [colors](colors.md).\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series. See above data format reference.\n\n#### fill\n\nType: `string|number`\n\nThe inner color for all elements in the series, this property will be over-ridden by color specified in the data attribute.\n\n#### opacity\n\nType: `string|number`\n\nThe opacity for all elements in the series, this property will be over-ridden by color specified in the data attribute.\n\n#### stroke\n\nType: `string|number`\n\nThe outer color for all elements in the series, this property will be over-ridden by color specified in the data attribute.\n\n#### style\n\nType: `object`\n\nA list of CSS properties to style the series outside of the explicitly set properties. Note that it will override all other properties (ie fill, stroke, opacity, color). See [style](style.md)\n\n## Interaction handlers\n\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onValueClick (optional)\n\nType: `function(d, {event})`\n\n`click` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onValueMouseOut (optional)\n\nType: `function(d, {event})`\n\n`mouseout` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onValueMouseOver (optional)\n\nType: `function(d, {event})`\n\n`mouseover` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onValueRightClick (optional)\n\nType: `function(d, {event})`\n\n`right-click` event handler for the elements corresponding separate data points. First argument received is, `d`, the relevant data point, and second an object with the only `event` property.\n\n#### onSeriesClick (optional)\n\nType: `function({event})`\n\n`click` event handler for the entire series. Receives an object as argument with the `event` property.\n\n#### onSeriesMouseOut (optional)\n\nType: `function({event})`\n\n`mouseout` event handler for the entire series. Receives an object as argument with the `event` property.\n\n#### onSeriesMouseOver (optional)\n\nType: `function({event})`\n\n`mouseover` event handler for the entire series. Receives an object as argument with the `event` property.\n\n#### onSeriesRightClick (optional)\n\nType: `function({event})`\n\n`right-click` event handler for the entire series. Receives an object as argument with the `event` property.\n"
  },
  {
    "path": "docs/sankey.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# Sankey\n\nSankey diagrams are a form of graph that allows for the easy communication of flows and other transferal processes.\n\n<!-- INJECT:\"EnergySankeyWithLink\" -->\n\n### Usage\n\n```jsx\nimport {Sankey} from 'react-vis';\n\nconst nodes = [{name: 'a'}, {name: 'b'}, {name: 'c'}];\nconst links = [\n  {source: 0, target: 1, value: 10},\n  {source: 0, target: 2, value: 20},\n  {source: 1, target: 2, value: 20}\n];\n\n<Sankey\n  nodes={nodes}\n  links={links}\n  width={200}\n  height={200}\n/>\n```\n\n### Api\n\n##### width (required, pixels)\n##### height (required, pixels)\n\n<!-- INJECT:\"BasicSankeyWithLink\" -->\n\n##### nodes (required)\n\nType: `Object`\n\nAn array of objects matching the following shape:\n\n```\n{\n  name: String,\n  color: String,\n  opacity: Number,\n  key: String\n}\n```\n\nThe name will be displayed as a label next to its node.\n\nAll these fields are optional.\n\n##### links (required)\n\nType: `Object`\n\nAn array of objects matching the following shape, where both `source` and `target`\nare the indexes of the nodes they intent to represent, and `value` that would\nmatch the height of the path link.\n\n```\n{\n  // required\n  source: Number,\n  target: Number,\n  value: Number,\n  // optional\n  color: String,\n  opacity: Number,\n  key: String\n}\n```\n\n##### margin (pixels)\n\nType: either number or {top: Number, left: Number, right: Number, bottom: Number}\n\nThe margin that will applied around the edge of the diagram.\n\n##### nodeWidth (optional)\n\nType: `Number`(pixels)\n\nDefaults: `10`.\n\nWidth of the nodes.\n\n##### nodePadding (optional)\n\nType: `Number`(pixels)\n\nDefaults: `10`.\n\nPadding between each node.\n\n##### align (optional)\n\nType: `String`, one of  `justify`, `center`, `left`, `right`\n\nDefaults: `justify`.\n\nThe alignment used for the sankey, see above for an example.\n\n##### layout (optional)\n\nType: `Number`\n\nDefaults: `50`.\n\nThe number of passes the sankey algorithm will do in order to arrange positioning.\n\n##### hasVoronoi (optional)\n\nType: `Boolean`\n\nDefaults: `false`\n\nDetermine if the node selection will be done using a voronoi or not. Although less\nprecise, it can help providing a better interactive experience to the user.\n\n<!-- INJECT:\"VornoiSankeyWithLink\" -->\n\n##### hideLabels (optional)\n\nType: `Boolean`\n\nDefaults: `false`.\n\nHide the display of the node names if specified to true.\n\n\n#### labelRotation (optional)\n\nType: `Number`\n\nDefault: `0`\nRotate the angle of the labels in the sankey\n\n##### onValueClick (optional)\n\nType: `function`\n\nDefault: noop\nThis handler is triggered either when the user clicks on a node. Callback when clicking a node, or the voronoi assigned to this node, pass the node.\n```jsx\n<Sankey\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n\n##### onValueMouseOver (optional)\n\nType: `function`\n\nDefault: noop\nThis handler is triggered either when the user hovers over a node. Callback when clicking a node, or the voronoi assigned to this node, pass the node.\n```jsx\n<Sankey\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n##### onValueMouseOut (optional)\n\nType: `function`\n\nDefault: noop\nThis handler is triggered either when the users mouse leaves a node. Callback when clicking a node, or the voronoi assigned to this node, pass the node.\n```jsx\n<Sankey\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n\n#### onLinkClick (optional)\n\nType: `function`\n\nDefault noop\nThis handler is triggered when the user clicks on a link. Callback accepts the data point associated with this link as well as the click event.\n```jsx\n<Sankey\n  onLinkClick={(linkdata, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n/>\n```\n\n#### onLinkMouseOver (optional)\n\nType: `function`\n\nDefault noop\nThis handler is triggered when the user's mouse hovers over a link. Callback accepts the data point associated with this link as well as the click event.\n```jsx\n<Sankey\n  onLinkMouseOver={(linkdata, event)=>{\n    // does something on mouseover\n    // you can access the value of the event\n  }}\n/>\n```\n\n#### onLinkMouseOut (optional)\n\nType: `function`\n\nDefault noop\nThis handler is triggered when the user's exits a link. Callback accepts the data point associated with this link as well as the click event.\n```jsx\n<Sankey\n  onLinkMouseOut={(linkdata, event)=>{\n    // does something on mouseout\n    // you can access the value of the event\n  }}\n/>\n```\n\n#### style (optional)\n\nType: `object`\n\nAn object that contains CSS properties with which the axis component can be entirely re-styled.\nAs the Sankey is composite of several composite elements, it is possible to provide style objects for any and all parts of the tree. See [style](style.md)\nMost generally, there are three top level components `labels`, `links`, and `rects`. These in turn lead to their corresponding to style objects. As an example, here is the default style object for the Sankey:\n\n```jsx\n<Sankey data={mydata} style={{\n  labels: {},\n  links: {},\n  rects: {}\n}}/>\n```\n\n##### children (optional)\nType: `Node` (Based on React.PropTypes.node: Anything that can be rendered: numbers, strings, elements or an array (or fragment) containing these types.)\n\n\nAllows to render additional children at the inner XYPlot used by the Sankey. See the [XYPlot](xy-plot.md)'s for more general information on children.\nThis is especially useful for rendering of Hints within a Sankey (since the must be rendered inside the XYPlot).\n```jsx\n<Sankey\n  nodes={nodes}\n  links={links}\n  width={200}\n  height={200}\n  >\n  <Hint x={x} y={y} value={myValue}/>\n</Sankey>\n```\n(See sample [Sankey - With hint (for links)](examples/showcases/sankeys-showcase.md) at showcase for more details.)\n"
  },
  {
    "path": "docs/scales-and-data.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Scales and data\n\n### Data\n\nReact-Vis charts are made of Series components - LineSeries, BarSeries and so on and so forth.\nEach of these Series components requires a `data` property, through which we pass an array of objects.\n\nThese properties correspond to various visual characteristics of the corresponding marks. For example, x and y, which are required for most series types, affect the position of each mark. Each series type takes more properties, though, which are described in the series section.\n\nHere is how a simple dataset is transformed in some simple charts:\n\n<!-- INJECT:\"MiniChartsWithLink\" -->\n\n```jsx\nconst data = [\n  {x: 0, y: 8},\n  {x: 1, y: 5},\n  {x: 2, y: 4},\n  {x: 3, y: 9},\n  {x: 4, y: 1},\n  {x: 5, y: 7},\n  {x: 6, y: 6},\n  {x: 7, y: 3},\n  {x: 8, y: 2},\n  {x: 9, y: 0}\n];\n\n...\n\n<XYPlot height={200} width={200}>\n  <VerticalBarSeries data={data} />\n</XYPlot>\n<XYPlot height={200} width={200}>\n  <LineSeries data={data} />\n</XYPlot>\n<XYPlot height={200} width={200}>\n  <MarkSeries data={data} />\n</XYPlot>\n\n```\n\nBy the way: can you guess what this dataset is? Answer at the end of the document.\n\n### Scales\n\nScales are what actually transform the values of the properties in the data objects into visual attributes. In the example above, for instance, the third object is {x: 2, y: 4}. But the corresponding rectangle is 39.45px from the left and 105.56px from the top of the top left corner of the chart. How? Scales.\n\nReact-vis scales are designed so that as often as possible, you shouldn't have to do anything; yet they give you control to override anything they do.  \n\nThe notion of scales and the corresponding vocabulary are directly taken from d3js.\nScales have a type, a range and a domain. For a given chart, there are multiple scales: there's one scale per attribute. Attributes include x position, y position, color, size, angle etc. Again, not all attributes are applicable in all series.\n\nWe are following the definition of scales which was given by Mike Bostock: _scales are functions that map from an input domain to an output range_.\n\nUnder the hood, scales have a default type; a default domain can be inferred automatically from the data and, depending on the attribute, there's either a default range, or it is being generated depending on context.\n\nFor example, for x and y:\n- the default type is a linear scale (the relationship between the value in the data object and the actual position of the mark is of the form: y = ax + b ),\n- the domain is defined by the smallest and highest values for found in the dataset - in the above example, both x and y vary from 0 to 9, so the domains are [0, 9] for both the x- and the y- scale,\n- and the range is the total width of the XYPlot minus the margin.\n\nAll of this is sensible most of the time.\n\nScales transform each datapoint into visual characteristics for a mark, so, for a given attribute, they only work if the corresponding data property exists. The property in the datapoint MUST have the same name as the attribute. You can have all the properties you want in your datapoint object, but to position the mark from left to right, you NEED a x property.\n\n### Available scales by series type:\n\nHere is what attribute is available as a scale per series type, and what is the default scale type:\n\n| Series              | angle  | angle0 | color      | fill       | opacity    | radius | radius0 | size   | stroke     | x      | x0     | y      | y0     |\n|---------------------|--------|--------|------------|------------|------------|--------|---------|--------|------------|--------|--------|--------|--------|\n| [ArcSeries](arc-series.md)           | linear | linear | linear     | linear     | literal    | linear | linear  |        | linear     | linear |        | linear |        |\n| [AreaSeries](area-series.md)          |        |        | / series | / series | / series |        |         |        | / series | linear |        | linear | linear |\n| [ContourSeries](contour-series.md)       |        |        | linear*    |            |            |        |         |        |            | linear |        | linear |        |\n| [HeatmapSeries](heatmap-series.md)       |        |        | linear     |            | literal    |        |         |        | linear     | linear |        | linear |        |\n| [HorizontalBarSeries](bar-series.md) |        |        | linear     | linear     | literal    |        |         |        | linear     | linear | linear | linear |        |\n| [LabelSeries](label-series.md)         |        |        |            |            |            |        |         |        |            | linear |        | linear |        |\n| [LineSeries](line-series.md)          |        |        | / series |            | / series |        |         |        | / series | linear |        | linear |        |\n| [MarkSeries](mark-series.md)          |        |        | linear     | linear     | literal    |        |         | linear | linear     | linear |        | linear |        |\n| [PolygonSeries](polygon-series.md)       |        |        | / series |            |            |        |         |        |            | linear |        | linear |        |\n| [RectSeries](rect-series.md)          |        |        | linear     | linear     | literal    |        |         |        | linear     | linear | linear | linear | linear |\n| [VerticalBarSeries](bar-series.md)   |        |        | linear     | linear     | literal    |        |         |        | linear     | linear |        | linear | linear |\n\nFor the Heatmap and Hexbin series, while you can pass a colorDomain and a colorRange, you cannot override the type of scale for colors.\n\n\"Per series\" means that it's possible to pass a value to the series as a whole, but not per data point.\n\nIf an attribute is not available as a scale for a given series, all values passed in the corresponding property will be ignored. For instance, if you use a dataset that has fill properties, it will be ignored for LineSeries.\n\nThis table is also meant to be used for derived series. Canvas series have the same interface as SVG series. HorizontalRectSeries and VerticalRectSeries take the same attribute as RectSeries. And LineMarkSeries take the same attribute as Line and Mark series.\n\n### Scale properties\n\nTo redefine a scale, you must pass a prop to the series that uses that scale. The prop names are based on the name of the attribute: name + Domain, name + Range, name + Type, name + Padding (for instance: yDomain, colorType, xRange).\n\n* `get[name]` (optional)  \n  Type: `function`  \n  An accessor function that gets the value to be compute from the data. For instance if you were keeping your data as rows like {a: 1, b: 2, c: 3}, you could define an x accessor like `getX: d => d.a`.\n* `[name]Domain` (optional)  \n  Type: `Array`  \n  Array of values to visualize from. If domain is not passed, it will be calculated from the values which are passed to component.\n* `[name]Padding` (optional)  \n  Type: `Number`  \n  A percentage that will pad your `[name]Domain`. If the padding not passed `[name]Domain` will not be padded. Note: if you pass `[name]Domain` and it is not calculated from the values, padding will not be used.\n* `[name]Range` (optional)\n  Type: `Array`  \n  Array of real-world values to visualize to. If range is not passed, the defaults (depend on visualization type) will be applied.\n* `[name]Type` (optional)  \n  Type: `('linear'|'ordinal'|'category'|'time'|'time-utc'|'log'|'literal')`  \n  Default: `'linear'`  \n  Type of the scale. Each scale type can be one of following values:\n    * `'linear'`  \n    Continuous scale, that works with numbers. Similar to [d3.scaleLinear](https://github.com/d3/d3-scale/blob/master/README.md#scaleLinear).\n    * `'ordinal'`  \n    Ordinal scale, works with numbers and strings. Similar to [d3.scaleOrdinal](https://github.com/d3/d3-scale/blob/master/README.md#ordinal-scales).\n    * `'category'`  \n    Categorical scale, each new value gets the next value from the range. Similar to d3.scale.category\\[Number\\], but works with other values besides colors.\n    * `'time'`  \n    Time scale. Similar to [d3.scaleTime](https://github.com/d3/d3-scale/blob/master/README.md#time-scales).\n    * `'time-utc'`  \n    Time UTC scale. Similar to [d3.scaleUtc](https://github.com/d3/d3-scale/blob/master/README.md#scaleUtc)\n    * `'log'`  \n    Log scale. Similar to [d3.scaleLog](https://github.com/d3/d3-scale/blob/master/README.md#log-scales).\n    * `'literal'`  \n    Returns exactly the value that was given to it. Similar to [d3.scaleIdentity](https://github.com/d3/d3-scale#scaleIdentity), except that it does NOT coerce data into numbers. This is useful for precisely specifying properties in the data, eg color can be specified directly on the data.\n\n### Overriding scales\n\nScales can be defined either at the XYPlot level, in which case they apply to the whole chart, or at the series level. Scales defined at the series level override those defined at the XYPlot level.\n\nThe scales provided to each individual series don't have to have the same parameters. For instance, if you wanted to do a dual-axis chart, you could provide a different yDomain and yRange to two data series (use at your own risk).\n\n### A brief example\n\nLet's apply these ideas to a reasonably common use case: reversing the domain of a chart. Imagine we wanted to reverse the x display order of our mark series above. To do this we would make use of the xDomain and our prior knowledge of the domain of the x variable.\n\n```javascript\n<XYPlot height={200} width={200} xDomain={[9, 0]}>\n  <MarkSeries data={data} />\n</XYPlot>\n```\n\nThis of course applies for all types of series.\n\n### Other uses of scales\n\nScales can also be used in [Axes](axes.md) and in [Gridlines](grids.md). You can pass an x-scale (so xDomain, xRange, xPadding, xType) to an XAxis or a VerticalGridLines component, and a y-scale (so yDomain, yRange, yPadding, yType) to a YAxis or HorizontalGridLines component. These scale parameters don't have to be the same as the ones passed to your series.\n\nDid you guess that this data set was the digits sorted alphabetically? eight, five, four...\n\n### Time scale localization\n\nThe locale used by d3 to format the time series tick labels is `en-US` by default. You can override it by providing a locale object to the `timeFormatDefaultLocale` function of [d3-time-format](https://github.com/d3/d3-time-format#timeFormatDefaultLocale) which you need to have as a dependency. [Various locale files](https://github.com/d3/d3-time-format/tree/master/locale) are available in the [d3-time-format git repository](https://github.com/d3/d3-time-format#timeFormatDefaultLocale).\n\neg for including the french locale :\n```javascript\nimport {timeFormatDefaultLocale} from 'd3-time-format';\ntimeFormatDefaultLocale({\n    dateTime    : '%a %b %e %X %Y',\n    date        : '%d/%m/%Y',\n    time        : '%H : %M : %S',\n    periods     : ['AM', 'PM'],\n    days        : ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],\n    shortDays   : ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'],\n    months      : ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Decembre'],\n    shortMonths : ['Jan', 'Fev', 'Mar', 'Avr', 'Mai', 'Jui', 'Juil', 'Aou', 'Sep', 'Oct', 'Nov', 'Dec']\n});\n```\nIf you do not want to add d3-time-format as a dependency, you can still use the `tickFormat` prop that can be passed to [Axes](axes.md) to handle the localization yourself, although you will lose the benefits of d3-scale formatting.\n"
  },
  {
    "path": "docs/series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Series\n\nThe library supports several types of series:\n\n* [ArcSeries](arc-series.md) for radial arcs such as might be found in pie charts.\n* [AreaSeries](area-series.md) for area charts;\n* [BarSeries](bar-series.md) for discrete bar charts, covers (covers HorizontalBarSeries and VerticalBarSeries);\n* [ContourSeries](contour-series.md) for making contour density plots;\n* [HeatmapSeries](heatmap-series.md) for heat maps.\n* [HexbinSeries](hexbin-series.md) for aggregate hexagonal binning heatmaps.\n* [LabelSeries](label-series.md) for adding annotations to charts\n* [LineMarkSeries](line-mark-series.md) is a shorthand to place marks (e.g. circles) on lines;\n* [LineSeries](line-series.md) for lines;\n* [MarkSeries](mark-series.md) for scatterplots;\n* [PolygonSeries](polygon-series.md) for arbitrary SVG shapes\n* [RectSeries](rect-series.md) for arbitrary histograms and other continuous variable boxes. (covers HorizontalRectSeries and VerticalRectSeries)\n\nEach series provides following API:\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series.\n\n#### x\n\nType: `number|Object`\n\nExact X position of all series points in pixels or a series object.\n\n#### y (optional)\n\nType: `number|Object`\n\nExact Y position of all series points in pixels or a series object.\n\n#### color (optional)\n\nType: `string|Object`\n\nExact color for all series points or a series object.\n\n#### size (optional)\n\nType: `number|Object`\n\nExact size for all series points in pixels or a series object.\n\n#### opacity (optional)\n\nType: `number|Object`\n\nExact opacity for all series points in pixels or a series object.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### onNearestX (optional)\n\nType: `function(value, info)`\n\nA callback function which is triggered each time when the mouse pointer gets close to some X value.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the value;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\n\n#### onValueMouseOver (optional)\n\nType: `function(d, info)`\n\n`mouseover` event handler for the elements corresponding separate data points `d` is a data point, `info` is an object with the only `event` property.\n**NOTE**: This event handler is *not* triggered for AreaSeries and LineSeries.\n\n#### onValueMouseOut (optional)\n\nType: `function(d, info)`\n\n`mouseout` event handler for the elements corresponding separate data points. `d` is a data point, `info` is an object with the only `event` property.\n**NOTE**: This event handler is *not* triggered for AreaSeries and LineSeries.\n\n#### onValueClick (optional)\n\nType: `function(d, info)`\n\n`click` event handler for the elements corresponding separate data points. `d` is a data point, `info` is an object with the only `event` property.\n**NOTE**: This event handler is *not* triggered for AreaSeries and LineSeries.\n\n#### onSeriesMouseOver (optional)\n\nType: `function(info)`\n\n`mouseover` event handler for the entire series. Received `info` object as argument with the only `event` property.\n\n#### onSeriesMouseOut (optional)\n\nType: `function(info)`\n\n`mouseout` event handler for the entire series. Received `info` object as argument with the only `event` property.\n\n#### onSeriesClick (optional)\n\nType: `function(info)`\n\n`click` event handler for the entire series. Received `info` object as argument with the only `event` property.\n\n#### style (optional)\n\nType: `object`\n\nAn object which holds CSS properties that will be applied to the SVG element(s) rendered by the series. This allows you to style series beyond the other explicitly defined properties and without having to use CSS classnames and stylesheets. For instance, you can set the stroke-linejoin style of a line series to \"round\":\n```jsx\n<LineSeries\n  data={data}\n  style={{strokeLinejoin: \"round\"}}\n/>\n```\nLineMark series is a composite series, and as such, it's possible to separate style instructions for the line and the mark part by putting them under a \"line\" and a \"mark\" property respectively:\n\n```jsx\n<LineMarkSeries\n  data={data}\n  style={{\n  \t// affect both the line and the mark part\n  \tstroke: \"red\",\n  \tline: {\n  \t  // affects just the line series\n  \t  strokeWidth: 2\n  \t},\n  \tmark: {\n  \t  // affects just the mark series\n  \t  strokeWidth: 4\n  \t}\n  }}\n/>\n```\n\nNote that style information passed through the style property will override those passed through props.\n```jsx\n<MarkSeries\n  data={data}\n  /// all the points are red\n  style={{fill: \"red\"}}\n/>\n```\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### stack (optional)\n\nType: `Boolean`\n\nDefault: `false`\n\nOpt-in for stacking series and mix stacked and non-stacked series in a single chart. If all series have the `stack` prop set to `false` (which is default behaviour), they will all be considered stackable. Otherwise if at least two of the series have the `stack` prop set to `true`, they will be stacked together and the other series will be considered non stackable.\nSee the [XYPlot](xy-plot.md)'s `stackBy` section for more information.\n"
  },
  {
    "path": "docs/style.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Style\n\nIn order to control the look and feel of your React-Vis components, you have four strategies.\n\n### the React-Vis style sheet\nReact-Vis comes with a default style sheet. You need to import it or otherwise link it to your app (as shown in the [getting started](tutorial/getting-started.md) page), or you may overwrite it.\n\n### Class names\nYou may also use the class names of the React-Vis component to style them through your own stylesheets, or your own style strategies.\nFurthermore, all series components accept a `className` property, which adds a class of your own choosing to the element.\n\n### Component-specific properties\nVirtually every component accept several properties that affects its appearance. For instance, [line series](line-series.md) take a `color` property to control the stroke color of the line, but others as well such as strokeWidth that controls its thickness. Each of these is described in detail for each component.\n\n#### style property\nFinally, components can also accept a special property called `style`. This let you pass an object to the component. The keys of that object are CSS properties, camel-cased (ie `stroke-width` would be written `strokeWidth`) and values are what you'd want to set those properties to. These are the same conventions than when [passing style](https://facebook.github.io/react/docs/dom-elements.html) to a standard DOM element with React.\n\n```javascript\n<LineSeries\n  data={data}\n  style={{strokeWidth: 2}}\n/>\n```\n\nSome React-Vis components are composite in the sense that they group several elements that you may want to style distinctly. For instance, the [line-mark series](line-mark-series.md) combines a [line series](line-series.md) and a [mark series](mark-series.md). While you could pass the same style object to both, you can also use special properties (in this case, `line` and `mark`) to send a specific style object to either or both sub-components.\n\n```javascript\n<LineMarkSeries\n  data={data}\n  color=\"red\"\n  style={{mark:{stroke: 'white'}}}\n/>\n```\nIn that example, without the style property, both lines and marks would be red. Without specifying `mark` in the style property, the stroke color of both lines and marks would be white. Here, the line remains red, and the marks are going to be red (their fill color) but with a white outline.\n"
  },
  {
    "path": "docs/sunburst.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# Sunbursts\n\nSunbursts are a powerful way to demonstrate part to whole relationships. While they certainly have the many of easily criticized problems of pie charts, they allow for\nat a glance understanding of deeply nested systems. This could be useful for understanding for funnels problems or distributions of nested groups (eg how does my cities performance compare to other cities in my country?).\n\n<!-- INJECT:\"BasicSunburstWithLink\" -->\n\nThe `Sunburst` is a thin data processing wrapper on an XYPlotted [ArcSeries](arc-series.md), it generates highly re-stylable SVG! Any props that are available in the arc series are also available here. Additionally it copies the data format of the treemap, so if you have data prepped to drop into the tree map, you can use that same data to get a sunburst.\n\n## Usage\n\nImport the `Sunburst` component:\n```jsx\nimport {Sunburst} from 'react-vis';\n```\n\nAdd the following code to your render function:\n```jsx\n<Sunburst\n  hideRootNode\n  colorType=\"literal\"\n  data={data}\n  height={300}\n  width={350}/>\n```\n\nLike other systems that make use of d3's hierarchy layout system we ask that our data be presented to us in a tree like structure.\nHere's a slice of the famous d3-flare dataset:\n\n\n```javascript\nconst myData = {\n \"title\": \"analytics\",\n \"color\": \"#12939A\",\n \"children\": [\n  {\n   \"title\": \"cluster\",\n   \"children\": [\n    {\"title\": \"AgglomerativeCluster\", \"color\": \"#12939A\", \"size\": 3938},\n    {\"title\": \"CommunityStructure\", \"color\": \"#12939A\", \"size\": 3812},\n    {\"title\": \"HierarchicalCluster\", \"color\": \"#12939A\", \"size\": 6714},\n    {\"title\": \"MergeEdge\", \"color\": \"#12939A\", \"size\": 743}\n   ]\n  },\n  {\n   \"title\": \"graph\",\n   \"children\": [\n    {\"title\": \"BetweennessCentrality\", \"color\": \"#12939A\", \"size\": 3534},\n    {\"title\": \"LinkDistance\", \"color\": \"#12939A\", \"size\": 5731},\n    {\"title\": \"MaxFlowMinCut\", \"color\": \"#12939A\", \"size\": 7840},\n    {\"title\": \"ShortestPaths\", \"color\": \"#12939A\", \"size\": 5914},\n    {\"title\": \"SpanningTree\", \"color\": \"#12939A\", \"size\": 3416}\n   ]\n  },\n  {\n   \"title\": \"optimization\",\n   \"children\": [\n    {\"title\": \"AspectRatioBanker\", \"color\": \"#12939A\", \"size\": 7074}\n   ]\n  }\n ]\n}\n```\n\nFirst, note the recursive tree relationship: each node has a title, and an array of children.\nThis pattern continues until we reach the leaves, where we declare the size of the leaves. This value is rolled up, so that\nthe \"cluster\" node has  3938 + 3812 + 6714 + 743 = 15207 size units.\n\n### Adding annotations\n\nTooltips and other helpful annotations can be added to the sunburst diagram by providing those elements as children. For instance, if we wanted to add a tooltip to the above Sunburst, this could be done by adding a [Hint](hint.md) component as a child.\n\n```jsx\n<Sunburst\n  hideRootNode\n  colorType=\"literal\"\n  data={data}\n  height={300} \n  width={350}>\n  <Hint value={hoveredValue} />\n</Sunburst>\n```\n\nWhere `hoveredValue` is an appropriately curated coordinate value. See the [sunburst-with-tooltips](https://github.com/uber/react-vis/blob/master/packages/showcase/sunbursts/sunburst-with-tooltips.js) code for more details.\n\n## API Reference\n\n#### width\n\nType: `number`\n\nWidth of the component.\n\n#### height\n\nType: `number`\n\nHeight of the component.\n\n#### data\n\nType: `Object`\n\nThe data for the component. The `data` property is a tree-like structure.\nEach point consists of following properties:\n\n* `title`\n\n  Type: `string`\n\n  The title to show inside the cell. Might be a string or a React component.\n* `size`\n\n  Type: `number`\n\n  The relative size of the cell.\n* `color` (optional)\n\n  Type: `number` or `string`\n\n  The value to visualize the color with.\n* `label` (optional)\n\n  Type: `string`\n\n  The label to be attached for the current node.\n* `labelStyle` (optional)\n\n  Type: `object`\n\n  The style of the attached label. Example `{labelStyle: {fontSize: 15}, ...}`\n* `dontRotateLabel` (optional)\n\n  Type: `boolean`\n\n  Don't rotate this label\n* `children` (optional)\n\n  Type: `Array`\n\n  The children for the leaf.\n\n<!-- INJECT:\"SunburstWithTooltipsWithLink\" -->\n\n#### hideRootNode (optional)\n\nType: `boolean`\n\nSimple boolean on whether or not to show the root node of the tree.\n\n#### children (optional)\n\nType: `react components`\n\nSunburst can accept react components as children if you wish to annotate your diagram.\n\n#### animation (optional)\n\nType: `boolean|Object`\n\nPlease refer to [Animation](animation.md) doc for more information.\n\n<!-- INJECT:\"AnimatedSunburstWithLink\" -->\n\n#### onValueClick (optional)\n\nType: `function`\n\n- Should accept arguments (arc node, domEvent)\n\nPass in a function that will be called on click on a given arc.\n\n#### onValueRightClick (optional)\n\nType: `function`\n\n- Should accept arguments (arc node, domEvent)\n\nPass in a function that will be called on right click on a given arc.\n\n#### onValueMouseOver (optional)\n\nType: `function`\n\n- Should accept arguments (arc node, domEvent)\n\nPass in a function that will be called on mouseEnter on a given arc.\n\n#### onValueMouseOut (optional)\n\nType: `function`\n\n- Should accept arguments (arc node, domEvent)\n\nPass in a function that will be called on mouseOut on a given arc.\n\n#### padAngle (optional)\n\nType: `number|function`\n\nThe padding to be applied between arcs.\n"
  },
  {
    "path": "docs/treemap.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# Treemap\n\nTreemaps are a splendid way to represent data that has a nested aspect to it. They allow for the easy display of complicated\nrelative information, such as nested-part-to-whole relationships in a easy to grok fashion. Checkout [the wikipedia page](https://en.wikipedia.org/wiki/Treemapping) or Ben Shneiderman's excellent [History of treemaps](http://www.cs.umd.edu/hcil/treemap-history/index.shtml) for more information.\n\n<!-- INJECT:\"SimpleTreemapWithLink\" -->\n\nThe `treemap` in react-vis builds a series of nested divs (allow for easy and highly restyleable trees). We offer ten different layout\nstrategies, enabling the construction of standard treemaps, circle packed treemaps, and partition trees (also called icicle diagrams).\n\nOur treemap can target SVG or pure dom (via the renderMode prop)! You can play with the representation above.\n\n## Usage\n\nImport the `treemap` component:\n```jsx\nimport {Treemap} from 'react-vis';\n```\n\nAdd the following code to your render function:\n```jsx\n<Treemap\n  title={'My New Treemap'}\n  width={300}\n  height={300}\n  data={myData}\n  />\n```\n\nLike other systems that make use of d3's hierarchy layout system we ask that our data be presented to us in a tree like structure.\nHere's a slice of the famous d3-flare dataset:\n\n\n```javascript\nconst myData = {\n \"title\": \"analytics\",\n \"color\": \"#12939A\",\n \"children\": [\n  {\n   \"title\": \"cluster\",\n   \"children\": [\n    {\"title\": \"AgglomerativeCluster\", \"color\": \"#12939A\", \"size\": 3938},\n    {\"title\": \"CommunityStructure\", \"color\": \"#12939A\", \"size\": 3812},\n    {\"title\": \"HierarchicalCluster\", \"color\": \"#12939A\", \"size\": 6714},\n    {\"title\": \"MergeEdge\", \"color\": \"#12939A\", \"size\": 743}\n   ]\n  },\n  {\n   \"title\": \"graph\",\n   \"children\": [\n    {\"title\": \"BetweennessCentrality\", \"color\": \"#12939A\", \"size\": 3534},\n    {\"title\": \"LinkDistance\", \"color\": \"#12939A\", \"size\": 5731},\n    {\"title\": \"MaxFlowMinCut\", \"color\": \"#12939A\", \"size\": 7840},\n    {\"title\": \"ShortestPaths\", \"color\": \"#12939A\", \"size\": 5914},\n    {\"title\": \"SpanningTree\", \"color\": \"#12939A\", \"size\": 3416}\n   ]\n  },\n  {\n   \"title\": \"optimization\",\n   \"children\": [\n    {\"title\": \"AspectRatioBanker\", \"color\": \"#12939A\", \"size\": 7074}\n   ]\n  }\n ]\n}\n```\n\nFirst, note the recursive tree relationship: each node has a title, and an array of children.\nThis pattern continues until we reach the leaves, where we declare the size of the leaves. This value is rolled up, so that\nthe \"cluster\" node has  3938 + 3812 + 6714 + 743 = 15207 size units.\n\n#### Hints\n\n- It is often quite effective to use the literal scale type for Treemap's color attribute, as this allows highly granular control\nover all of the nodes.\n\n- It can useful to encode opacity to indicate tree depth, however because each tree leaf is a nested div this gets a little\ntricky. One technique is to compute the effective RGBA to hex value, check out [this link](viget.com/articles/equating-color-and-transparency)\nfor more details.\n\n- If your not sure when to use a treemap, remember they provide an easy drop in relationship for pie charts.\n\n## API Reference\n\n#### width\n\nType: `number`\n\nWidth of the component.\n\n#### height\n\nType: `number`\n\nHeight of the component.\n\n#### padding\n\nType: `number`\n\nThe padding between cells the cells of the heatmap in pixels.\n\n#### data\n\nType: `Object`\n\nThe data for the component. The `data` property is a tree-like structure.\nEach point consists of following properties:\n\n* `title`\n\n  Type: `string`\n\n  The title to show inside the cell. Might be a string or a React component.\n* `size`\n\n  Type: `number`\n\n  The relative size of the cell.\n* `opacity` (optional)\n\n  Type: `number`\n\n  The value to visualize the opacity with.\n* `color` (optional)\n\n  Type: `number` or `string`\n\n  The value to visualize the color with.\n* `style` (optional)\n\n  Type: `object`\n\n  style object to be added to the inline styles of the array\n* `children` (optional)\n\n  Type: `Array`\n\n  The children for the leaf.\n\n#### animation (optional)\n\nType: `boolean|Object`\n\nPlease refer to [Animation](animation.md) doc for more information.\n\n#### hideRootNode (optional)\n\nType: `boolean`\n\nSimple boolean on whether or not to show the root node of the tree.\n\n#### onLeafClick (optional)\n\nType: `function`\n\n- Should accept arguments (leafNode, domEvent)\n\nPass in a function that will be called on click on a given leaf.\n\n#### onLeafMouseOver (optional)\n\nType: `function`\n\n- Should accept arguments (leafNode, domEvent)\n\nPass in a function that will be called on mouseEnter on a given leaf.\n\n#### onLeafMouseOut (optional)\n\nType: `function`\n\n- Should accept arguments (leafNode, domEvent)\n\nPass in a function that will be called on mouseOut on a given leaf.\n\n#### mode (options)\n\nType: `string`\n\n- One of squarify, resquarify, slice, dice, slicedice, binary, circlePack, partition, partition-pivot\n\nThis modifies the tiling strategy for the treemap, for more information see the [d3 hierarchy docs](https://github.com/d3/d3-hierarchy).\n\n#### renderMode\n\nType: `string`\n\n- One of 'SVG', or 'DOM'\n\nDetermines which type of rendering to use for the treemap.\n\n#### sortFunction (optional)\n\nType: `function`\n\n- Should accept arguments (a, b)\n\nPass in a function that will be used to sort the nodes, for more information see the [d3 hierarchy docs on sorting](https://github.com/d3/d3-hierarchy#node_sort).\n\n##### colorDomain, colorRange, colorType\n\nScale properties for the `color` scale. If `color` property is not passed in the data object, each new section of the chart gets the next color (e. g. the `'category'` scale is applied).\nPlease refer to [Scales and Data](scales-and-data.md) for more information about scales.\n"
  },
  {
    "path": "docs/voronoi.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## Voronoi\n\nVoronoi diagrams are useful for making a chart interactive by creating target areas for events like hover and click.\n\n<!-- INJECT:\"VoronoiLineChartWithLink\" -->\n\n```jsx\n<Voronoi\n    extent={[[0, 0], [200, 200]]}\n    nodes={[{x: 0, y: 10}, {x: 1, y: 5}, {x: 3, y: 3}, {x: 4, y: 1}, {x: 5, y: 6}]}\n    x={d => x(d.x)}\n    y={d => y(d.y)}\n/>\n```\n\n## API Reference\n\n\n<!-- INJECT:\"DynamicCrosshairScatterplotWithLink\" -->\n\n#### extent\n\nType: `Array`\n\nSets the clip extent of the Voronoi layout to the specified bounds. The extent bounds are specified as an array [[x0, y0], [x1, y1]], where x0 is the left side of the extent, y0 is the top, x1 is the right and y1 is the bottom.\nExtent should take the dimensions of the accompanying XYPlot into account, so using the plot's width, height and margins: `[[marginLeft, marginTop], [width, height]]`, which coincidentally is the default extent.\n\n#### nodes (required)\n\nType: `Array`\n\nThe array must consist of `{x, y}` objects. These are often identical to the data passed to a series in the accompanying plot.\n\nEach item in the array will create a polygon cell in the resulting Voronoi diagram. Optional properties are:\n - style `Object`\n - className `String`\n\nExample:\n```js\n[\n  { x: 0, y: 10 },\n  { x: 1, y: 5, style: { stroke: 'blue' } }\n];\n```\n\n#### x (optional)\n\nType: `Function`\n\nSets the x-coordinate accessor. Often you want to convert the coordinate-values to pixel values like\n`x={d => x(d.x)}`. If not provided defaults to wrapping XYPlot's xScale.\n\n#### y (optional)\n\nType: `Function`\n\nSets the y-coordinate accessor. Often you want to convert the coordinate-values to pixel values like\n`y={d => y(d.y)}`. If not provided defaults to wrapping XYPlot's yScale.\n\n#### onBlur (optional)\n\nType: `Function`\n\nAdd `blur`-event to Voronoi cells\n\n#### onClick (optional)\n\nType: `Function`\n\nAdd `click`-event to Voronoi cells\n\n#### onMouseUp (optional)\n\nType: `Function`\n\nAdd `mouseUp`-event to Voronoi cells\n\n#### onMouseDown (optional)\n\nType: `Function`\n\nAdd `mouseDown`-event to Voronoi cells\n\n#### onHover (optional)\n\nType: `Function`\n\nAdd `hover`-event to Voronoi cells\n\n#### className (optional)\n\nType: `String`\n\nAdd css class to Voronoi container\n\n##### style (optional)\n\nType: `Object`\n\nAdd css styles to Voronoi container\n\n#### polygonStyle (optional)\n\nType: `Object`\n\nAdd css styles to Voronoi cells.\n\nFor example:\n`polygonStyle={{stroke: 'red'}}`\nThis will add a red border around cell which is very useful for debugging the Voronoi diagram.\n"
  },
  {
    "path": "docs/whisker-series.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n## WhiskerSeries\n\n<!-- INJECT:\"WhiskerChartWithLink\" -->\n\nWhiskerSeries plots variance \"whiskers\" for each data point. Often this is used in combination with another series (e.g. a MarkSeries or LineSeries) to represent the variance (or alternately standard deviation) associated with each value. Variance lines can be in the Y dimension, X dimension, or both.\n\nDeploy a WhiskerSeries like this:\n\n```javascript\nrender() {\n  return (\n    <XYPlot\n      width={300}\n      height={300}>\n      <WhiskerSeries\n        className=\"whisker-series-example\"\n        data={myData}/>\n    </XYPlot>\n  );\n```\n\nJust like other series, WhiskerSeries expects its data to be formatted as an array of\nobjects. These data points may include an `xVariance` property, a `yVariance` property,\nor both:\n\n```javascript\nconst myData = [\n  {x: 1, y: 10, xVariance: 4, yVariance: 4},\n  {x: 1.7, y: 12, xVariance: 7, yVariance: 7},\n  {x: 2, y: 5, xVariance: 3, yVariance: 3},\n  {x: 3, y: 15, xVariance: 10, yVariance: 10},\n  {x: 2.5, y: 7, xVariance: 4, yVariance: 4}\n];\n```\n\nWhiskerSeries also accepts a `size` value that specifies an empty \"buffer\" region.\nThis is especially useful if you are combining the whiskers with another series, and\nthe marks of that series include transparent regions. The buffer region prevents\nwhisker lines from being drawn behind that other mark.\n\n```javascript\nconst myData = [\n  {x: 1, y: 10, size: 30, yVariance: 4},\n  {x: 1.7, y: 12, size: 10, yVariance: 7},\n  {x: 2, y: 5, size: 1, yVariance: 3},\n  {x: 3, y: 15, size: 12, yVariance: 10},\n  {x: 2.5, y: 7, size: 4, yVariance: 4}\n];\n```\n\n\n## Data format reference\n\n#### x\n\nType: `string|number|date`\n\nx will be used to determine the x position of each mark. The format of x depends on what scale is being used - see [Scales and Data](scales-and-data.md)\n\n#### y\n\nType: `string|number|date`\n\ny will be used to determine the y position of each mark. The format of y depends on what scale is being used - see [Scales and Data](scales-and-data.md)\n\n#### color (optional)\n\nType: `string|number`\n\nThe color of the marks. By default the color is interpreted as number to be scaled to a color range. This can be over-ridden by providing the prop colorType=\"literal\" to the series itself. This property can also be defined on the series level.\n\n#### opacity (optional)\n\nType: `string|number`\n\nDefault: `1`\n\nOpacity of the individual marks, from 0 (transparent) to 1 (opaque). By default opacity is scaled by `literal`, so the exact value provided will be used. This property can also be defined on the series level.\n\n#### stroke (optional)\n\nType: `string|number`\n\nThe color of the outline of the marks. When this value is not provided, the color attribute is used instead. This property can also be defined on the series level.\n\n#### size (optional)\n\nType: `string|number`\n\nDefault: `0`\n\nThe size of an empty \"buffer\" region at the center of each mark.\n\n#### xVariance (optional)\n\nType: `string|number`\n\nThe size of each of the lines in the X dimension. Either xVariance, yVariance, or both should be specified.\n\n#### yVariance (optional)\n\nType: `string|number`\n\nThe size of each of the lines in the Y dimension. Either xVariance, yVariance, or both should be specified.\n\n\n## API Reference\n\n#### animation (optional)\nSee the [XYPlot](xy-plot.md)'s `animation` section for more information.\n\n#### className (optional)\n\nType: `string`\n\nProvide an additional class name for the series.\n\n#### color (optional)\n\nType: `string|number`\n\nExact color for all series points or a series object.\n\n#### data\n\nType: `Array<Object>`\n\nArray of data for the series.\n\n#### opacity (optional)\n\nType: `string|number`\n\nExact opacity for all series points in pixels or a series object, from 0 (transparent) to 1 (opaque)\n\n#### size (optional)\n\nType: `string|number`\n\nExact size of an empty \"buffer\" region for all series points in pixels or a series object.\n\n#### stroke (optional)\n\nType: `string|number`\n\nDefault: see [colors](colors.md)\n\nA color for the outline of the marks. Will override color if both are provided.\n\n#### strokeWidth (optional)\n\nType: `string|number`\n\nDefault: `1`\n\nThe width of the outline of the marks.\n\n\n## Interaction handlers\n\n#### onNearestX (optional)\n\nType: `function(value, {event, innerX, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose x position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onNearestXY (optional)\n\nType: `function(value, {event, innerX, innerY, index})`\n\nA callback function which is triggered each time the mouse pointer moves. It can access the datapoint of the mark whose position is the closest to that of the cursor.\nCallback is triggered with two arguments. `value` is the data point, `info` object has following properties:\n- `innerX` is the left position of the mark;\n- `innerY` is the top position of the mark;\n- `index` is the index of the data point in the array of data;\n- `event` is the event object.\nSee [interaction](interaction.md)\n\n#### onSeriesClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user clicks somewhere on a series, and provides the corresponding event. Unlike onValueClick, it doesn't pass a specific datapoint.\n\n```jsx\n<WhiskerSeries\n...\n  onSeriesClick={(event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user's mouse cursor leaves a series, and provides the corresponding event. Unlike onValueMouseOut, it doesn't pass a specific datapoint.\n\n```jsx\n<WhiskerSeries\n...\n  onSeriesMouseOut={(event)=>{\n    // does something on mouse over\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user mouses over a series, and provides the corresponding event. Unlike onValueMouseOver, it doesn't pass a specific datapoint.\n\n```jsx\n<WhiskerSeries\n...\n  onSeriesMouseOver={(event)=>{\n    // does something on mouse over\n    // you can access the value of the event\n  }}\n```\n\n#### onSeriesRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler fires when the user right-clicks somewhere on a series, and provides the corresponding event. Unlike onValueRightClick, it doesn't pass a specific datapoint.\n\n```jsx\n<WhiskerSeries\n...\n  onSeriesRightClick={(event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<WhiskerSeries\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOut\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse leaves a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<WhiskerSeries\n...\n  onValueMouseOut={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueMouseOver\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user's mouse enters a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<WhiskerSeries\n...\n  onValueMouseOver={(datapoint, event)=>{\n    // does something on click\n    // you can access the value of the event\n  }}\n```\n\n#### onValueRightClick\n\nType: `function`\n\nDefault: none\n\nThis handler is triggered either when the user right-clicks on a mark.\nThe handler passes two arguments, the corresponding datapoint and the actual event.\n```jsx\n<WhiskerSeries\n...\n  onValueClick={(datapoint, event)=>{\n    // does something on right click\n    // you can access the value of the event\n  }}\n```\n"
  },
  {
    "path": "docs/xy-plot.md",
    "content": "> This library is deprecated. Please see `DEPRECATED.md`.\n\n# XYPlot\n\nXYPlot allows you to make line charts, area charts, scatterplots, heat maps, etc with animations and different interactions between them.\n\nCurrently following components are used for this purpose:\n\n* XYPlot to wrap all the items.\n* [Grids](grids.md) to show vertical and horizontal grids.\n* [Axes](axes.md) to show X and Y axis.\n* [Different kinds of series](series.md) for line/area/bar charts, scatterplots, heat maps, etc.\n* [Hint](hint.md) to show the selected hint.\n* [Crosshair](crosshair.md) for crosshairs.\n\n## Usage\n\nImport the necessary components from the library&hellip;\n\n```jsx\nimport {XYPlot, XAxis, YAxis, HorizontalGridLines, LineSeries} from 'react-vis';\n```\n\n&hellip; and add the following code to your `render` function:\n\n```jsx\n<XYPlot\n  width={300}\n  height={300}>\n  <HorizontalGridLines />\n  <LineSeries\n    color=\"red\"\n    data={[\n      {x: 1, y: 10},\n      {x: 2, y: 5},\n      {x: 3, y: 15}\n    ]}/>\n  <XAxis title=\"X\" />\n  <YAxis />\n</XYPlot>\n```\n\n## Common concepts\n\nXYPlot is a wrapper for series, hints, axes and other components. Most of these components do not require any properties by default, however it is expected that the user will pass the `data` property into each series.\n\n`data` is an array of objects. Each item is some point on the chart. Object may contain following properties:\n\n* `x`\n* `y`\n* `opacity` (optional)\n* `fill` (optional)\n* `stroke` (optional)\n* `strokeWidth` (optional), `strokeStyle` (optional) - to control the width of the line series and whether they are dashed or solid.\n* `color` (optional, used instead of `fill` and `stroke` if none of them is passed)\n* `size` (optional)\n* `style` (optional) - css properties as an object.\n\nAccessors can also be used to retreieve the properties above from the `data` object. For instance, the `getX` and `getY` accessors can be passed to the XYPlot object to access the `x` and `y` properties from `data` for each series.\n\n```jsx\n<XYPlot\n  width={300}\n  height={300}\n  getX={d => d[0]}\n  getY={d => d[1]}>\n  <LineSeries\n    color=\"red\"\n    data={[\n      [1, 0],\n      [2, 1],\n      [3, 2]\n    ]}/>\n</XYPlot>\n```\n\nIf the property is not passed in any of the objects, the property is not visualized. The user can override the way how properties are visualized by passing custom range, domain or type of scales to the series or the entire chart (please see [Series](series.md) for more info).\n\nNot all properties can be visualized in each series. Here's a short comparison of them:\n\n|                      | `x` | `y` | `color` | `opacity` | `size` |\n|----------------------|-----|-----|---------|-----------|--------|\n| [LineSeries](line-series.md)  | + | + | + |  |  |\n| [AreaSeries](area-series.md)         | + | + | + |  |  |\n| [LineMarkSeries](line-mark-series.md)     | + | + | + | + | + |\n| [MarkSeries](mark-series.md)         | + | + | + | + | + |\n| [VerticalBarSeries](bar-series.md)  | + | + | + | + |  |\n| [HorizontalBarSeries](bar-series.md)| + | + | + | + |  |\n| [VerticalRectSeries](rect-series.md)  | + | + | + | + |  |\n| [HorizontalRectSeries](rect-series.md)| + | + | + | + |  |\n| [HeatmapSeries](heatmap-series.md)      | + | + | + | + |  |\n| [HexbinSeries](hexbin-series.md)      | + | + | + | + |  |\n\n\n### A note on ordering\n\nXYPlot is pretty flexible, and can accept most kinds of things DOM, SVG, really whatever react can build. As far as XYPlot is concerned there are two types of components in the world: those that can be rendered as part of an SVG tree and those that can't. It separates it's children into these two groups, and clusters the SVG elements under a root svg tag in order and then presents each of the remaining children in order. With a react configuration like:\n\n```javascript\n<XYPlot>\n  <XAxis />\n  <YAxis />\n  <RectSeries {...props}/>\n  <Hint className=\"first-hint\"/>\n  <Hint className=\"second-hint\"/>\n</XYPlot>\n```\nWould generate HTML something like:\n\n```javascript\n<div class=\"rv-xy-plot\">\n  <svg>\n    <svg for XAxis />\n    <svg for YAxis />\n    <svg for RectSeries />\n  </svg>\n  <div class=\"rv-hint first-hint\">...</div>\n  <div class=\"rv-hint second-hint\">...</div>\n</div>\n```\n\nThe TLDR here is that *ORDER MATTERS*! If you want the elements to appear in a different order, reorder them!\n\n## API Reference\n\n### XYPlot\n\n`XYPlot` is a component that wraps series, axis and grids, hints, etc and seamlessly provides necessary dimensions, sizes and scales into its children.\n`XYPlot` may or may not contain axes, grids, hints, crosshairs or series.\n\n#### width\n\nType: `number`\n\nWidth of the chart. The width should be passed.\n\n#### height\n\nType: `number`\n\nHeight of the component. The height should be passed.\n\n#### className (optional)\n\nType: `string`\n\nDOM classNames to be added to the wrapper component.\n\n#### hasTreeStructure (optional)\n\nType: `Boolean`\n\nFlag declaring whether or not react-vis should try to remove potential cyclic deps from tree structures created by d3. Specifically references to \"parent\" are removed. This is generally used as an internal prop, checkout the treemap or sunburst if you are curious.\n\n#### margin (optional)\n\nType: `Object`\n\nDefault: `{left: 40, right: 10, top: 10, bottom: 40}`\n\nMargin around the chart.\n\n#### stackBy (optional)\n\nType: `string`\n\nStack the chart by the given attribute. If the attribute is `y`, the chart is stacked vertically; if the attribute is `x` then it's stacked horizontally. See the [Series](series.md) API reference for series level stack opt-in.\n\n#### style (optional)\n\nType: `object`\n\nCSS properties that will affect this wrapper component. Those will be applied to the SVG element in which other react-vis components will be created.\n\n```jsx\n<XYPlot\n  stackBy=\"y\"\n  width={300}\n  height={300}>\n  <LineSeries\n    data={[\n      {x: 1, y: 10},\n      {x: 2, y: 5},\n      {x: 3, y: 15}\n    ]}/>\n  <LineSeries\n    data={[\n      {x: 1, y: 12},\n      {x: 2, y: 21},\n      {x: 3, y: 2}\n    ]}/>\n</XYPlot>\n```\n\n*NOTE* in order to stack properly react-vis expects each x value in each series to be present (assuming stackBy: 'x', the same applies to stackBy 'y', just transposed). If our data looks like\n```\nconst seriesOne = [\n  {x: 1, y: 10},\n  {x: 3, y: 15}\n];\n\nconst seriesTwo = [\n  {x: 1, y: 10},\n  {x: 2, y: 5},\n  {x: 3, y: 15}\n];\n\nconst seriesThree = [\n  {x: 3, y: 15}\n];\n\n```\n\nwould render weirdly (eg boxes would not lump together at the bottom of the chart). To avoid this, simply provide zeroes for empty cells\n\n```\nconst seriesOne = [\n  {x: 1, y: 10},\n  {x: 2, y: 0},\n  {x: 3, y: 15}\n];\n\nconst seriesTwo = [\n  {x: 1, y: 10},\n  {x: 2, y: 5},\n  {x: 3, y: 15}\n];\n\nconst seriesThree = [\n  {x: 1, y: 0},\n  {x: 2, y: 0},\n  {x: 3, y: 15}\n];\n\n```\n\nWill render beautifully!\n\n#### onClick (optional)\n\nType: `function()`\n\nThe function that is triggered each time the mouse clicks the component.\n\n#### onDoubleClick (optional)\n\nType: `function()`\n\nThe function that is triggered each time the mouse double-clicks the component.\n\n#### onMouseLeave (optional)\n\nType: `function()`\n\nThe function that is triggered each time the mouse leaves the component.\n\n#### onMouseMove (optional)\n\nType: `function()`\n\nThe function that is triggered each time mouse moves over at the component.\n\n#### onMouseEnter (optional)\n\nType: `function()`\n\nThe function that is triggered each time the mouse enters the component.\n\n#### onMouseDown (optional)\n\nType: `function()`\n\nThe function that is triggered each time the mouse button is pressed over the component.\n\n#### onMouseUp (optional)\n\nType: `function()`\n\nThe function that is triggered each time the mouse button is released over the component.\n\n#### onTouchStart (optional)\n\nType: `function()`\n\nThe function that is triggered each time the touch starts.\n\n#### onTouchMove (optional)\n\nType: `function()`\n\nThe function that is triggered each time the touch moves.\n\n#### onTouchEnd (optional)\n\nType: `function()`\n\nThe function that is triggered each time the touch ends.\n\n#### onTouchCancel (optional)\n\nType: `function()`\n\nThe function that is triggered each time the touch cancels.\n\n#### onWheel (optional)\n\nType: `function()`\n\nThe function that is triggered each time a wheel button is rotated on the component.\n\n#### animation (optional)\n\nType: `{duration: number}|boolean`\n\nDefault: `false`\n\nAnimation config, which is automatically passed to all children, but can be overridden for the each child.\nIf `false` is passed, then the child components *will not be* animated.\nIf `true` is passed then the child components *will be* animated with the default settings.\nIf an object is passed, then the child components *will be* animated with the given settings.\n\n#### dontCheckIfEmpty (optional)\n\nType: `Boolean`\n\nDefault: `false`\n\nIf this prop is provided then the XYPlot with not check if the plot is empty before rendering. This can be useful if you have a variable amount of data, especially when that variable can be zero.\n\n<!-- INJECT:\"EmptyChartWithLink\" -->\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-vis-master\",\n  \"version\": \"1.12.0\",\n  \"license\": \"MIT\",\n  \"author\": \"Visualization Team <visualization@uber.com>\",\n  \"description\": \"Data visualization library based on React and d3.\",\n  \"private\": true,\n  \"workspaces\": [\n    \"packages/showcase\",\n    \"packages/react-vis\",\n    \"packages/website\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/uber-common/react-vis.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/uber-common/react-vis/issues/new\",\n    \"email\": \"visualization@uber.com\"\n  },\n  \"keywords\": [\n    \"d3\",\n    \"react\",\n    \"visualization\",\n    \"chart\",\n    \"es6\",\n    \"babel\"\n  ],\n  \"scripts\": {\n    \"lint\": \"eslint .\",\n    \"remove-unpm-rfs\": \"./remove-refs-to-unpm.pl\"\n  },\n  \"devDependencies\": {\n    \"babel-eslint\": \"^10.1.0\",\n    \"eslint\": \"6.8.0\",\n    \"eslint-config-prettier\": \"^6.11.0\",\n    \"eslint-plugin-babel\": \"^5.3.0\",\n    \"eslint-plugin-prettier\": \"^3.1.3\",\n    \"eslint-plugin-react\": \"^7.20.0\",\n    \"eslint-plugin-react-hooks\": \"^4.0.4\",\n    \"husky\": \"^1.1.2\"\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"npm run remove-unpm-rfs && git add yarn.lock\"\n    }\n  },\n  \"volta\": {\n    \"node\": \"14.18.0\",\n    \"yarn\": \"1.22.4\"\n  },\n  \"resolutions\": {\n    \"js-beautify\": \"1.10.3\",\n    \"d3-color\": \"3.1.0\"\n  }\n}\n"
  },
  {
    "path": "packages/react-vis/.babelrc.json",
    "content": "{\n  \"plugins\": [\n    [\"module-resolver\", {\n      \"root\": [\"src\"]\n    }]\n  ]\n}"
  },
  {
    "path": "packages/react-vis/build-browser.sh",
    "content": "#!/bin/bash\n# Browserify doesn't seem to support defining custom entry point for modules in node_modules\n# This build script replaces the entry point (the main field of package.json) of d3 libraries to the files\n# defined in the unpkg field when building browser bundles.\n# The replacement are reverted after the build finishes.\nD3_LIB_PATHS=$(ls -d ../../node_modules/d3-*)\n\nget_key_from_d3_path() {\n  local KEY=$(echo $1 | sed 's/..\\/..\\/node_modules\\/d3-//')\n  local KEY=$(echo $KEY | sed 's/-/_/')\n  echo $KEY\n}\n\nfor D3_LIB_PATH in $D3_LIB_PATHS\ndo\n  PACKAGE_JSON=$D3_LIB_PATH/package.json\n  UNPKG=$(jq -r '.unpkg' $PACKAGE_JSON)\n  if ! [ -z $UNPKG ] && [ $UNPKG != null ]\n  then\n    # save the main field\n    MAIN=$(jq -r '.main' $PACKAGE_JSON)\n    KEY=$(get_key_from_d3_path $D3_LIB_PATH)\n    declare var_$KEY=$MAIN\n\n    # modify the main field\n    MOD=$(jq --arg unpkg $UNPKG '.main = $unpkg' $PACKAGE_JSON)\n    cat <<< $MOD | jq . > $PACKAGE_JSON\n  fi\ndone\n\nBABEL_ENV=browser browserify src/index.js -t [ babelify --rootMode upward --global ] --standalone reactVis | uglifyjs > dist/dist.min.js\n\n# set the main fields of package.json back to original\nfor D3_LIB_PATH in $D3_LIB_PATHS\ndo\n  PACKAGE_JSON=$D3_LIB_PATH/package.json\n  KEY=$(get_key_from_d3_path $D3_LIB_PATH)\n  MAIN=\"var_$KEY\"\n  if ! [ -z  \"${!MAIN}\" ]\n  then\n    MOD=$(jq --arg var \"${!MAIN}\" '.main = $var' $PACKAGE_JSON)\n    cat <<< $MOD | jq . > $PACKAGE_JSON\n  fi\ndone\n\n"
  },
  {
    "path": "packages/react-vis/jest.config.js",
    "content": "/*eslint-env node*/\nconst path = require('path');\n\nmodule.exports = {\n  transform: {\n    '^.+\\\\.js$': path.resolve(__dirname, './jestBabelTransform.js')\n  },\n  setupFilesAfterEnv: ['./jest.setup.js'],\n  snapshotSerializers: ['enzyme-to-json/serializer'],\n  transformIgnorePatterns: [\n    '/node_modules/(?!(d3-color|d3-scale|d3-interpolate|d3-hierarchy|d3-format|d3-shape|d3-array|d3-contour|d3-path|internmap|d3-time|d3-geo))'\n  ]\n};\n"
  },
  {
    "path": "packages/react-vis/jest.setup.js",
    "content": "/*eslint-env node*/\nimport 'regenerator-runtime/runtime';\nimport jsdom from 'jsdom';\nimport Enzyme from 'enzyme';\nimport Adapter from 'enzyme-adapter-react-16';\n\nEnzyme.configure({adapter: new Adapter()});\n\nglobal.document = jsdom.jsdom('<body></body>');\nglobal.window = document.defaultView;\nObject.keys(document.defaultView).forEach(function mapProperties(property) {\n  if (typeof global[property] === 'undefined') {\n    global[property] = document.defaultView[property];\n  }\n});\n\nglobal.navigator = {\n  userAgent: 'node.js'\n};\n\n/*\n * Canvas mocks\n */\nHTMLCanvasElement.prototype.getContext = () => {};\n"
  },
  {
    "path": "packages/react-vis/jestBabelTransform.js",
    "content": "/*eslint-env node*/\nconst babelJest = require('babel-jest');\n\n// see https://github.com/facebook/jest/issues/7359#issuecomment-471509996\nmodule.exports = babelJest.createTransformer({\n  rootMode: 'upward'\n});\n"
  },
  {
    "path": "packages/react-vis/package.json",
    "content": "{\n  \"name\": \"react-vis\",\n  \"version\": \"1.12.1\",\n  \"license\": \"MIT\",\n  \"author\": \"Visualization Team <visualization@uber.com>\",\n  \"description\": \"Data visualization library based on React and d3.\",\n  \"main\": \"dist/dist.min.js\",\n  \"module\": \"es\",\n  \"jsnext:main\": \"es\",\n  \"files\": [\n    \"dist\",\n    \"es\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/uber-common/react-vis.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/uber-common/react-vis/issues/new\",\n    \"email\": \"visualization@uber.com\"\n  },\n  \"scripts\": {\n    \"docs\": \"./publish-docs.sh\",\n    \"clean\": \"rm -rf dist es bundle.* index.html && mkdir dist es\",\n    \"start\": \"(cd ../showcase && command -v yarn >/dev/null && yarn start)\",\n    \"build:browser\": \"./build-browser.sh\",\n    \"build\": \"yarn run clean && babel --root-mode upward src -d dist --copy-files && BABEL_ENV=es babel --root-mode upward src -d es --copy-files && node-sass src/main.scss dist/style.css --output-style compressed && yarn run build:browser\",\n    \"lint-styles\": \"stylelint src/styles/*.scss --syntax scss\",\n    \"test:windows\": \"babel-node --inspect ./tests/index.js\",\n    \"test\": \"NODE_ENV=development jest\",\n    \"full-test\": \"npm run lint && npm run cover\",\n    \"cover\": \"NODE_ENV=development jest --coverage\",\n    \"prettier\": \"prettier --write $(git ls-files | grep '.js$')\"\n  },\n  \"dependencies\": {\n    \"d3-array\": \"^3.2.1\",\n    \"d3-collection\": \"^1.0.7\",\n    \"d3-color\": \"^3.1.0\",\n    \"d3-contour\": \"^4.0.0\",\n    \"d3-format\": \"^3.1.0\",\n    \"d3-geo\": \"^3.1.0\",\n    \"d3-hexbin\": \"^0.2.2\",\n    \"d3-hierarchy\": \"^3.1.2\",\n    \"d3-interpolate\": \"^3.0.1\",\n    \"d3-sankey\": \"^0.12.3\",\n    \"d3-scale\": \"^4.0.2\",\n    \"d3-shape\": \"^3.2.0\",\n    \"d3-voronoi\": \"^1.1.4\",\n    \"deep-equal\": \"^1.0.1\",\n    \"global\": \"^4.3.1\",\n    \"prop-types\": \"^15.5.8\",\n    \"react-motion\": \"^0.5.2\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.0.0\",\n    \"@babel/core\": \"^7.0.0\",\n    \"@babel/node\": \"^7.0.0\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.0.0\",\n    \"@babel/plugin-proposal-export-default-from\": \"^7.0.0\",\n    \"@babel/plugin-proposal-nullish-coalescing-operator\": \"^7.0.0\",\n    \"@babel/plugin-proposal-optional-chaining\": \"^7.0.0\",\n    \"@babel/plugin-transform-runtime\": \"^7.0.0\",\n    \"@babel/preset-env\": \"^7.0.0\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"@babel/register\": \"^7.0.0\",\n    \"babel-eslint\": \"^10.1.0\",\n    \"babel-jest\": \"^25.5.1\",\n    \"babel-plugin-module-resolver\": \"^4.0.0\",\n    \"babelify\": \"^10.0.0\",\n    \"browserify\": \"^14.3.0\",\n    \"canvas\": \"^2.11.0\",\n    \"enzyme\": \"^3.11.0\",\n    \"enzyme-adapter-react-16\": \"^1.15.2\",\n    \"enzyme-to-json\": \"^3.5.0\",\n    \"eslint-plugin-jest\": \"^23.13.2\",\n    \"jest\": \"^25.5.4\",\n    \"jsdom\": \"^9.9.1\",\n    \"node-sass\": \"^4.9.3\",\n    \"prettier\": \"^1.14.2\",\n    \"react\": \"^17.0.2\",\n    \"react-addons-test-utils\": \">=15.4.2\",\n    \"react-dom\": \"^17.0.2\",\n    \"react-test-renderer\": \"^16.13.1\",\n    \"react-vis-showcase\": \"^0.1.0\",\n    \"regenerator-runtime\": \"^0.13.11\",\n    \"stylelint\": \"^7.7.1\",\n    \"stylelint-config-standard\": \"^15.0.1\",\n    \"uglify-js\": \"^2.8.22\"\n  },\n  \"peerDependencies\": {\n    \"react\": \"^17.0.2\",\n    \"react-dom\": \"^17.0.2\"\n  },\n  \"keywords\": [\n    \"d3\",\n    \"react\",\n    \"visualization\",\n    \"chart\",\n    \"es6\",\n    \"babel\"\n  ],\n  \"nyc\": {\n    \"exclude\": [\n      \"tests/**/*.js\",\n      \"./utils/react-utils.js\"\n    ]\n  },\n  \"engines\": {\n    \"node\": \">=14.18.0\",\n    \"npm\": \">=6.13.0\"\n  },\n  \"volta\": {\n    \"node\": \"14.18.0\",\n    \"yarn\": \"1.22.4\"\n  }\n}\n"
  },
  {
    "path": "packages/react-vis/src/animation.js",
    "content": "import React, {PureComponent} from 'react';\nimport PropTypes from 'prop-types';\nimport {interpolate} from 'd3-interpolate';\nimport {spring, Motion, presets} from 'react-motion';\n\nconst ANIMATION_PROPTYPES = PropTypes.oneOfType([\n  PropTypes.string,\n  PropTypes.shape({\n    stiffness: PropTypes.number,\n    nonAnimatedProps: PropTypes.arrayOf(PropTypes.string),\n    damping: PropTypes.number\n  }),\n  PropTypes.bool\n]);\n\nconst propTypes = {\n  animatedProps: PropTypes.arrayOf(PropTypes.string).isRequired,\n  animation: ANIMATION_PROPTYPES,\n  onStart: PropTypes.func,\n  onEnd: PropTypes.func\n};\n\n/**\n * Format the animation style object\n * @param {Object|String} animationStyle - The animation style property, either the name of a\n * presets are one of noWobble, gentle, wobbly, stiff\n */\nfunction getAnimationStyle(animationStyle = presets.noWobble) {\n  if (typeof animationStyle === 'string') {\n    return presets[animationStyle] || presets.noWobble;\n  }\n  const {damping, stiffness} = animationStyle;\n  return {\n    ...animationStyle,\n    damping: damping || presets.noWobble.damping,\n    stiffness: stiffness || presets.noWobble.stiffness\n  };\n}\n\n/**\n * Extract the animated props from the entire props object.\n * @param {Object} props Props.\n * @returns {Object} Object of animated props.\n */\nexport function extractAnimatedPropValues(props) {\n  const {animatedProps, ...otherProps} = props;\n\n  return animatedProps.reduce((result, animatedPropName) => {\n    if (Object.prototype.hasOwnProperty.call(otherProps, animatedPropName)) {\n      result[animatedPropName] = otherProps[animatedPropName];\n    }\n    return result;\n  }, {});\n}\n\nclass Animation extends PureComponent {\n  constructor(props) {\n    super(props);\n    this._updateInterpolator(props);\n  }\n\n  componentDidUpdate(props) {\n    this._updateInterpolator(this.props, props);\n    if (props.onStart) {\n      props.onStart();\n    }\n  }\n\n  _motionEndHandler = () => {\n    if (this.props.onEnd) {\n      this.props.onEnd();\n    }\n  };\n\n  /**\n   * Render the child into the parent.\n   * @param {Number} i Number generated by the spring.\n   * @returns {React.Component} Rendered react element.\n   * @private\n   */\n  _renderChildren = ({i}) => {\n    const {children} = this.props;\n    const interpolator = this._interpolator;\n    const child = React.Children.only(children);\n    const interpolatedProps = interpolator ? interpolator(i) : interpolator;\n\n    // interpolator doesnt play nice with deeply nested objected\n    // so we expose an additional prop for situations like these, soit _data,\n    // which stores the full tree and can be recombined with the sanitized version\n    // after interpolation\n    let data = (interpolatedProps && interpolatedProps.data) || null;\n    if (data && child.props._data) {\n      data = data.map((row, index) => {\n        const correspondingCell = child.props._data[index];\n        return {\n          ...row,\n          parent: correspondingCell.parent,\n          children: correspondingCell.children\n        };\n      });\n    }\n\n    return React.cloneElement(child, {\n      ...child.props,\n      ...interpolatedProps,\n      data: data || child.props.data || null,\n      // enforce re-rendering\n      _animation: Math.random()\n    });\n  };\n\n  /**\n   * Update the interpolator function and assign it to this._interpolator.\n   * @param {Object} oldProps Old props.\n   * @param {Object} newProps New props.\n   * @private\n   */\n  _updateInterpolator(oldProps, newProps) {\n    this._interpolator = interpolate(\n      extractAnimatedPropValues(oldProps),\n      newProps ? extractAnimatedPropValues(newProps) : null\n    );\n  }\n\n  render() {\n    const animationStyle = getAnimationStyle(this.props.animation);\n    const defaultStyle = {i: 0};\n    const style = {i: spring(1, animationStyle)};\n    // In order to make Motion re-run animations each time, the random key is\n    // always passed.\n    // TODO: find a better solution for the spring.\n    const key = Math.random();\n    return (\n      <Motion {...{defaultStyle, style, key}} onRest={this._motionEndHandler}>\n        {this._renderChildren}\n      </Motion>\n    );\n  }\n}\n\nAnimation.propTypes = propTypes;\nAnimation.displayName = 'Animation';\n\nexport default Animation;\n\nexport const AnimationPropType = ANIMATION_PROPTYPES;\n"
  },
  {
    "path": "packages/react-vis/src/index.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nexport AbstractSeries from 'plot/series/abstract-series';\nexport ArcSeries from 'plot/series/arc-series';\nexport AreaSeries from 'plot/series/area-series';\nexport Borders from 'plot/borders';\nexport ChartLabel from 'plot/chart-label';\nexport CircularGridLines from 'plot/circular-grid-lines';\nexport ContourSeries from 'plot/series/contour-series';\nexport Crosshair from 'plot/crosshair';\nexport CustomSVGSeries from 'plot/series/custom-svg-series';\nexport DecorativeAxis from 'plot/axis/decorative-axis';\nexport GradientDefs from 'plot/gradient-defs';\nexport GridLines from 'plot/grid-lines';\nexport HeatmapSeries from 'plot/series/heatmap-series';\nexport HexbinSeries from 'plot/series/hexbin-series';\nexport Highlight from 'plot/highlight';\nexport Hint from 'plot/hint';\nexport HorizontalBarSeries from 'plot/series/horizontal-bar-series';\nexport HorizontalBarSeriesCanvas from 'plot/series/horizontal-bar-series-canvas';\nexport HorizontalGridLines from 'plot/horizontal-grid-lines';\nexport HorizontalRectSeries from 'plot/series/horizontal-rect-series';\nexport HorizontalRectSeriesCanvas from 'plot/series/horizontal-rect-series-canvas';\nexport LabelSeries from 'plot/series/label-series';\nexport LineMarkSeries from 'plot/series/line-mark-series';\nexport LineMarkSeriesCanvas from 'plot/series/line-mark-series-canvas';\nexport LineSeries from 'plot/series/line-series';\nexport LineSeriesCanvas from 'plot/series/line-series-canvas';\nexport MarkSeries from 'plot/series/mark-series';\nexport MarkSeriesCanvas from 'plot/series/mark-series-canvas';\nexport PolygonSeries from 'plot/series/polygon-series';\nexport VerticalBarSeries from 'plot/series/vertical-bar-series';\nexport VerticalBarSeriesCanvas from 'plot/series/vertical-bar-series-canvas';\nexport VerticalGridLines from 'plot/vertical-grid-lines';\nexport VerticalRectSeries from 'plot/series/vertical-rect-series';\nexport VerticalRectSeriesCanvas from 'plot/series/vertical-rect-series-canvas';\nexport Voronoi from 'plot/voronoi';\nexport RectSeries from 'plot/series/rect-series';\nexport RectSeriesCanvas from 'plot/series/rect-series-canvas';\nexport WhiskerSeries from 'plot/series/whisker-series';\nexport XYPlot from 'plot/xy-plot';\nexport XAxis from 'plot/axis/x-axis';\nexport YAxis from 'plot/axis/y-axis';\n\nexport ContinuousColorLegend from 'legends/continuous-color-legend';\nexport ContinuousSizeLegend from 'legends/continuous-size-legend';\nexport DiscreteColorLegend from 'legends/discrete-color-legend';\nexport SearchableDiscreteColorLegend from 'legends/searchable-discrete-color-legend';\n\nexport ParallelCoordinates from 'parallel-coordinates';\nexport RadarChart from 'radar-chart';\nexport RadialChart from 'radial-chart';\nexport Sankey from 'sankey';\nexport Sunburst from 'sunburst';\nexport Treemap from 'treemap';\n\nexport ContentClipPath from './plot/content-clip-path';\n\nexport {\n  makeHeightFlexible,\n  makeVisFlexible,\n  makeWidthFlexible,\n  FlexibleXYPlot,\n  FlexibleWidthXYPlot,\n  FlexibleHeightXYPlot\n} from './make-vis-flexible';\n\nexport AxisUtils from 'utils/axis-utils';\nexport ScaleUtils from 'utils/scales-utils';\n"
  },
  {
    "path": "packages/react-vis/src/legends/continuous-color-legend.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport {CONTINUOUS_COLOR_RANGE} from 'theme';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst propTypes = {\n  className: PropTypes.string,\n  height: PropTypes.number,\n  endColor: PropTypes.string,\n  endTitle: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n    .isRequired,\n  midColor: PropTypes.string,\n  midTitle: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n  startColor: PropTypes.string,\n  startTitle: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n    .isRequired,\n  width: PropTypes.number\n};\n\nconst defaultProps = {\n  className: '',\n  startColor: CONTINUOUS_COLOR_RANGE[0],\n  endColor: CONTINUOUS_COLOR_RANGE[1]\n};\n\nfunction ContinuousColorLegend({\n  startColor,\n  midColor,\n  endColor,\n  startTitle,\n  midTitle,\n  endTitle,\n  height,\n  width,\n  className\n}) {\n  const colors = [startColor];\n  if (midColor) {\n    colors.push(midColor);\n  }\n  colors.push(endColor);\n  return (\n    <div\n      className={getCombinedClassName('rv-continuous-color-legend', className)}\n      style={{width, height}}\n    >\n      <div\n        className=\"rv-gradient\"\n        style={{background: `linear-gradient(to right, ${colors.join(',')})`}}\n      />\n      <div className=\"rv-legend-titles\">\n        <span className=\"rv-legend-titles__left\">{startTitle}</span>\n        <span className=\"rv-legend-titles__right\">{endTitle}</span>\n        {midTitle ? (\n          <span className=\"rv-legend-titles__center\">{midTitle}</span>\n        ) : null}\n      </div>\n    </div>\n  );\n}\n\nContinuousColorLegend.displayName = 'ContinuousColorLegend';\nContinuousColorLegend.propTypes = propTypes;\nContinuousColorLegend.defaultProps = defaultProps;\n\nexport default ContinuousColorLegend;\n"
  },
  {
    "path": "packages/react-vis/src/legends/continuous-size-legend.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst propTypes = {\n  className: PropTypes.string,\n  circlesTotal: PropTypes.number,\n  endSize: PropTypes.number,\n  endTitle: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n    .isRequired,\n  height: PropTypes.number,\n  startSize: PropTypes.number,\n  startTitle: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n    .isRequired,\n  width: PropTypes.number\n};\n\nconst defaultProps = {\n  circlesTotal: 10,\n  className: '',\n  endSize: 20,\n  startSize: 2\n};\n\nfunction ContinuousSizeLegend({\n  startTitle,\n  endTitle,\n  startSize,\n  endSize,\n  circlesTotal,\n  height,\n  width,\n  className\n}) {\n  const circles = [];\n  const step = (endSize - startSize) / (circlesTotal - 1);\n\n  for (let i = 0; i < circlesTotal; i++) {\n    const size = step * i + startSize;\n    circles.push(\n      <div\n        key={i}\n        className=\"rv-bubble\"\n        style={{\n          width: size,\n          height: size,\n          borderRadius: size / 2\n        }}\n      />\n    );\n    // Add the separator in order to justify the content (otherwise the tags\n    // will be stacked together without any margins around).\n    circles.push(' ');\n  }\n  return (\n    <div\n      className={getCombinedClassName('rv-continuous-size-legend', className)}\n      style={{width, height}}\n    >\n      <div className=\"rv-bubbles\" style={{height: endSize}}>\n        {circles}\n        <div className=\"rv-spacer\" />\n      </div>\n      <div className=\"rv-legend-titles\">\n        <span className=\"rv-legend-titles__left\">{startTitle}</span>\n        <span className=\"rv-legend-titles__right\">{endTitle}</span>\n      </div>\n    </div>\n  );\n}\n\nContinuousSizeLegend.displayName = 'ContinuousSizeLegend';\nContinuousSizeLegend.propTypes = propTypes;\nContinuousSizeLegend.defaultProps = defaultProps;\n\nexport default ContinuousSizeLegend;\n"
  },
  {
    "path": "packages/react-vis/src/legends/discrete-color-legend-item.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nconst STROKE_STYLES = {\n  dashed: '6, 2',\n  solid: null\n};\n\nfunction DiscreteColorLegendItem({\n  color,\n  strokeDasharray,\n  strokeStyle,\n  strokeWidth,\n  disabled,\n  onClick,\n  orientation,\n  onMouseEnter,\n  onMouseLeave,\n  title\n}) {\n  let className = `rv-discrete-color-legend-item ${orientation}`;\n  if (disabled) {\n    className += ' disabled';\n  }\n  if (onClick) {\n    className += ' clickable';\n  }\n  const strokeDasharrayStyle = STROKE_STYLES[strokeStyle] || strokeDasharray;\n  return (\n    <div {...{className, onClick, onMouseEnter, onMouseLeave}}>\n      <svg\n        className=\"rv-discrete-color-legend-item__color\"\n        height={2}\n        width={14}\n      >\n        <path\n          className=\"rv-discrete-color-legend-item__color__path\"\n          d=\"M 0, 1 L 14, 1\"\n          style={{\n            ...(strokeWidth ? {strokeWidth} : {}),\n            ...(strokeDasharrayStyle\n              ? {strokeDasharray: strokeDasharrayStyle}\n              : {}),\n            stroke: disabled ? null : color\n          }}\n        />\n      </svg>\n      <span className=\"rv-discrete-color-legend-item__title\">{title}</span>\n    </div>\n  );\n}\n\nDiscreteColorLegendItem.propTypes = {\n  color: PropTypes.string.isRequired,\n  disabled: PropTypes.bool,\n  title: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,\n  onClick: PropTypes.func,\n  onMouseEnter: PropTypes.func,\n  onMouseLeave: PropTypes.func,\n  orientation: PropTypes.oneOf(['vertical', 'horizontal']).isRequired,\n  strokeDasharray: PropTypes.string,\n  strokeWidth: PropTypes.number,\n  strokeStyle: PropTypes.oneOf(Object.keys(STROKE_STYLES))\n};\nDiscreteColorLegendItem.defaultProps = {\n  disabled: false,\n  strokeStyle: 'solid'\n};\nDiscreteColorLegendItem.displayName = 'DiscreteColorLegendItem';\n\nexport default DiscreteColorLegendItem;\n"
  },
  {
    "path": "packages/react-vis/src/legends/discrete-color-legend.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport DiscreteColorLegendItem from 'legends/discrete-color-legend-item';\nimport {DISCRETE_COLOR_RANGE} from 'theme';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nfunction DiscreteColorLegend({\n  className,\n  colors,\n  height,\n  items,\n  onItemClick,\n  onItemMouseEnter,\n  onItemMouseLeave,\n  orientation,\n  style,\n  width\n}) {\n  return (\n    <div\n      className={getCombinedClassName(\n        'rv-discrete-color-legend',\n        orientation,\n        className\n      )}\n      style={{width, height, ...style}}\n    >\n      {items.map((item, i) => (\n        <DiscreteColorLegendItem\n          title={item.title ? item.title : item}\n          color={item.color ? item.color : colors[i % colors.length]}\n          strokeDasharray={item.strokeDasharray}\n          strokeStyle={item.strokeStyle}\n          strokeWidth={item.strokeWidth}\n          disabled={Boolean(item.disabled)}\n          orientation={orientation}\n          key={i}\n          onClick={onItemClick ? e => onItemClick(item, i, e) : null}\n          onMouseEnter={\n            onItemMouseEnter ? e => onItemMouseEnter(item, i, e) : null\n          }\n          onMouseLeave={\n            onItemMouseEnter ? e => onItemMouseLeave(item, i, e) : null\n          }\n        />\n      ))}\n    </div>\n  );\n}\n\nDiscreteColorLegend.displayName = 'DiscreteColorLegendItem';\nDiscreteColorLegend.propTypes = {\n  className: PropTypes.string,\n  items: PropTypes.arrayOf(\n    PropTypes.oneOfType([\n      PropTypes.shape({\n        title: PropTypes.oneOfType([PropTypes.string, PropTypes.element])\n          .isRequired,\n        color: PropTypes.string,\n        disabled: PropTypes.bool\n      }),\n      PropTypes.string.isRequired,\n      PropTypes.element\n    ])\n  ).isRequired,\n  onItemClick: PropTypes.func,\n  onItemMouseEnter: PropTypes.func,\n  onItemMouseLeave: PropTypes.func,\n  height: PropTypes.number,\n  width: PropTypes.number,\n  orientation: PropTypes.oneOf(['vertical', 'horizontal'])\n};\n\nDiscreteColorLegend.defaultProps = {\n  className: '',\n  colors: DISCRETE_COLOR_RANGE,\n  orientation: 'vertical'\n};\n\nexport default DiscreteColorLegend;\n"
  },
  {
    "path": "packages/react-vis/src/legends/searchable-discrete-color-legend.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport DiscreteColorLegend from 'legends/discrete-color-legend';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst propTypes = {\n  ...DiscreteColorLegend.propTypes,\n  searchText: PropTypes.string,\n  onSearchChange: PropTypes.func,\n  searchPlaceholder: PropTypes.string,\n  searchFn: PropTypes.func\n};\n\nconst defaultProps = {\n  className: '',\n  searchText: '',\n  searchFn: (items, s) =>\n    items.filter(\n      item =>\n        String(item.title || item)\n          .toLowerCase()\n          .indexOf(s) !== -1\n    )\n};\n\nfunction SearchableDiscreteColorLegend(props) {\n  const {\n    className,\n    colors,\n    height,\n    items,\n    onItemClick,\n    onItemMouseEnter,\n    onItemMouseLeave,\n    onSearchChange,\n    orientation,\n    searchFn,\n    searchPlaceholder,\n    searchText,\n    width\n  } = props;\n  const onChange = onSearchChange\n    ? ({target: {value}}) => onSearchChange(value)\n    : null;\n  const filteredItems = searchFn(items, searchText);\n  return (\n    <div\n      className={getCombinedClassName('rv-search-wrapper', className)}\n      style={{width, height}}\n    >\n      <form className=\"rv-search-wrapper__form\">\n        <input\n          type=\"search\"\n          placeholder={searchPlaceholder}\n          className=\"rv-search-wrapper__form__input\"\n          value={searchText}\n          onChange={onChange}\n        />\n      </form>\n      <div className=\"rv-search-wrapper__contents\">\n        <DiscreteColorLegend\n          colors={colors}\n          items={filteredItems}\n          onItemClick={onItemClick}\n          onItemMouseEnter={onItemMouseEnter}\n          onItemMouseLeave={onItemMouseLeave}\n          orientation={orientation}\n        />\n      </div>\n    </div>\n  );\n}\n\nSearchableDiscreteColorLegend.propTypes = propTypes;\nSearchableDiscreteColorLegend.defaultProps = defaultProps;\nSearchableDiscreteColorLegend.displayName = 'SearchableDiscreteColorLegend';\n\nexport default SearchableDiscreteColorLegend;\n"
  },
  {
    "path": "packages/react-vis/src/main.scss",
    "content": "// special tag for using to check if the style file has been imported\n.react-vis-magic-css-import-rule {\n  display: inherit;\n}\n\n@import 'styles/treemap';\n@import 'styles/plot';\n@import 'styles/legends';\n@import 'styles/radial-chart';\n"
  },
  {
    "path": "packages/react-vis/src/make-vis-flexible.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport window from 'global/window';\n\nimport XYPlot from 'plot/xy-plot';\nimport {getDOMNode} from 'utils/react-utils';\n\nconst CONTAINER_REF = 'container';\n\n// As a performance enhancement, we want to only listen once\nconst resizeSubscribers = [];\nconst DEBOUNCE_DURATION = 100;\nlet timeoutId = null;\n\n/**\n * Calls each subscriber, debounced to the\n */\nfunction debounceEmitResize() {\n  window.clearTimeout(timeoutId);\n  timeoutId = window.setTimeout(emitResize, DEBOUNCE_DURATION);\n}\n\n/**\n * Calls each subscriber once syncronously.\n */\nfunction emitResize() {\n  resizeSubscribers.forEach(cb => cb());\n}\n\n/**\n * Add the given callback to the list of subscribers to be caled when the\n * window resizes. Returns a function that, when called, removes the given\n * callback from the list of subscribers. This function is also resposible for\n * adding and removing the resize listener on `window`.\n *\n * @param {Function} cb - Subscriber callback function\n * @returns {Function} Unsubscribe function\n */\nfunction subscribeToDebouncedResize(cb) {\n  resizeSubscribers.push(cb);\n\n  // if we go from zero to one Flexible components instances, add the listener\n  if (resizeSubscribers.length === 1) {\n    window.addEventListener('resize', debounceEmitResize);\n  }\n  return function unsubscribe() {\n    removeSubscriber(cb);\n\n    // if we have no Flexible components, remove the listener\n    if (resizeSubscribers.length === 0) {\n      window.clearTimeout(timeoutId);\n      window.removeEventListener('resize', debounceEmitResize);\n    }\n  };\n}\n\n/**\n * Helper for removing the given callback from the list of subscribers.\n *\n * @param {Function} cb - Subscriber callback function\n */\nfunction removeSubscriber(cb) {\n  const index = resizeSubscribers.indexOf(cb);\n  if (index > -1) {\n    resizeSubscribers.splice(index, 1);\n  }\n}\n\n/**\n * Helper for getting a display name for the child component\n * @param {*} Component React class for the child component.\n * @returns {String} The child components name\n */\nfunction getDisplayName(Component) {\n  return Component.displayName || Component.name || 'Component';\n}\n\n/**\n * Add the ability to stretch the visualization on window resize.\n * @param {*} Component React class for the child component.\n * @returns {*} Flexible component.\n */\n\nfunction makeFlexible(Component, isWidthFlexible, isHeightFlexible) {\n  const ResultClass = class extends React.Component {\n    static get propTypes() {\n      const {height, width, ...otherPropTypes} = Component.propTypes; // eslint-disable-line no-unused-vars\n      return otherPropTypes;\n    }\n\n    constructor(props) {\n      super(props);\n      this.state = {\n        height: 0,\n        width: 0\n      };\n    }\n\n    /**\n     * Get the width of the container and assign the width.\n     * @private\n     */\n    _onResize = () => {\n      const containerElement = getDOMNode(this[CONTAINER_REF]);\n      const {offsetHeight, offsetWidth} = containerElement;\n\n      const newHeight =\n        this.state.height === offsetHeight ? {} : {height: offsetHeight};\n\n      const newWidth =\n        this.state.width === offsetWidth ? {} : {width: offsetWidth};\n\n      this.setState({\n        ...newHeight,\n        ...newWidth\n      });\n    };\n\n    componentDidMount() {\n      this._onResize();\n      this.cancelSubscription = subscribeToDebouncedResize(this._onResize);\n    }\n\n    UNSAFE_componentWillReceiveProps() {\n      this._onResize();\n    }\n\n    componentWillUnmount() {\n      this.cancelSubscription();\n    }\n\n    render() {\n      const {height, width} = this.state;\n      const props = {\n        ...this.props,\n        animation: height === 0 && width === 0 ? null : this.props.animation\n      };\n\n      const updatedDimensions = {\n        ...(isHeightFlexible ? {height} : {}),\n        ...(isWidthFlexible ? {width} : {})\n      };\n\n      return (\n        <div\n          ref={ref => (this[CONTAINER_REF] = ref)}\n          style={{width: '100%', height: '100%'}}\n        >\n          <Component {...updatedDimensions} {...props} />\n        </div>\n      );\n    }\n  };\n\n  ResultClass.displayName = `Flexible${getDisplayName(Component)}`;\n\n  return ResultClass;\n}\n\nexport function makeHeightFlexible(component) {\n  return makeFlexible(component, false, true);\n}\n\nexport function makeVisFlexible(component) {\n  return makeFlexible(component, true, true);\n}\n\nexport function makeWidthFlexible(component) {\n  return makeFlexible(component, true, false);\n}\n\nexport const FlexibleWidthXYPlot = makeWidthFlexible(XYPlot);\nexport const FlexibleHeightXYPlot = makeHeightFlexible(XYPlot);\nexport const FlexibleXYPlot = makeVisFlexible(XYPlot);\n"
  },
  {
    "path": "packages/react-vis/src/parallel-coordinates/index.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\nimport PropTypes from 'prop-types';\nimport {scaleLinear} from 'd3-scale';\nimport {format} from 'd3-format';\n\nimport {AnimationPropType} from 'animation';\nimport XYPlot from 'plot/xy-plot';\nimport {DISCRETE_COLOR_RANGE} from 'theme';\nimport {\n  MarginPropType,\n  getInnerDimensions,\n  DEFAULT_MARGINS\n} from 'utils/chart-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\nimport LineSeries from 'plot/series/line-series';\nimport LineMarkSeries from 'plot/series/line-mark-series';\nimport LabelSeries from 'plot/series/label-series';\nimport DecorativeAxis from 'plot/axis/decorative-axis';\n\nimport Highlight from 'plot/highlight';\n\nconst predefinedClassName = 'rv-parallel-coordinates-chart';\nconst DEFAULT_FORMAT = format('.2r');\n/**\n * Generate axes for each of the domains\n * @param {Object} props\n - props.animation {Boolean}\n - props.domains {Array} array of object specifying the way each axis is to be plotted\n - props.style {object} style object for the whole chart\n - props.tickFormat {Function} formatting function for axes\n * @return {Array} the plotted axis components\n */\nfunction getAxes(props) {\n  const {animation, domains, style, tickFormat} = props;\n  return domains.map((domain, index) => {\n    const sortedDomain = domain.domain;\n\n    const domainTickFormat = t => {\n      return domain.tickFormat ? domain.tickFormat(t) : tickFormat(t);\n    };\n\n    return (\n      <DecorativeAxis\n        animation={animation}\n        key={`${index}-axis`}\n        axisStart={{x: domain.name, y: 0}}\n        axisEnd={{x: domain.name, y: 1}}\n        axisDomain={sortedDomain}\n        numberOfTicks={5}\n        tickValue={domainTickFormat}\n        style={style.axes}\n      />\n    );\n  });\n}\n\n/**\n * Generate labels for the ends of the axes\n * @param {Object} props\n - props.domains {Array} array of object specifying the way each axis is to be plotted\n - props.style {object} style object for just the labels\n * @return {Array} the prepped data for the labelSeries\n */\nfunction getLabels(props) {\n  const {domains, style} = props;\n  return domains.map(domain => {\n    return {\n      x: domain.name,\n      y: 1.1,\n      label: domain.name,\n      style\n    };\n  });\n}\n\n/**\n * Generate the actual lines to be plotted\n * @param {Object} props\n - props.animation {Boolean}\n - props.data {Array} array of object specifying what values are to be plotted\n - props.domains {Array} array of object specifying the way each axis is to be plotted\n - props.style {object} style object for the whole chart\n - props.showMarks {Bool} whether or not to use the line mark series\n * @return {Array} the plotted axis components\n */\nfunction getLines(props) {\n  const {\n    animation,\n    brushFilters,\n    colorRange,\n    domains,\n    data,\n    style,\n    showMarks\n  } = props;\n  const scales = domains.reduce((acc, {domain, name}) => {\n    acc[name] = scaleLinear()\n      .domain(domain)\n      .range([0, 1]);\n    return acc;\n  }, {});\n  // const\n\n  return data.map((row, rowIndex) => {\n    let withinFilteredRange = true;\n    const mappedData = domains.map(domain => {\n      const {getValue, name} = domain;\n\n      // watch out! Gotcha afoot\n      // yVal after being scale is in [0, 1] range\n      const yVal = scales[name](getValue ? getValue(row) : row[name]);\n      const filter = brushFilters[name];\n      // filter value after being scale back from pixel space is also in [0, 1]\n      if (filter && (yVal < filter.min || yVal > filter.max)) {\n        withinFilteredRange = false;\n      }\n      return {x: name, y: yVal};\n    });\n    const selectedName = `${predefinedClassName}-line`;\n    const unselectedName = `${selectedName} ${predefinedClassName}-line-unselected`;\n    const lineProps = {\n      animation,\n      className: withinFilteredRange ? selectedName : unselectedName,\n      key: `${rowIndex}-polygon`,\n      data: mappedData,\n      color: row.color || colorRange[rowIndex % colorRange.length],\n      style: {...style.lines, ...(row.style || {})}\n    };\n    if (!withinFilteredRange) {\n      lineProps.style = {\n        ...lineProps.style,\n        ...style.deselectedLineStyle\n      };\n    }\n    return showMarks ? (\n      <LineMarkSeries {...lineProps} />\n    ) : (\n      <LineSeries {...lineProps} />\n    );\n  });\n}\n\nclass ParallelCoordinates extends Component {\n  state = {\n    brushFilters: {}\n  };\n\n  render() {\n    const {brushFilters} = this.state;\n    const {\n      animation,\n      brushing,\n      className,\n      children,\n      colorRange,\n      data,\n      domains,\n      height,\n      hideInnerMostValues,\n      margin,\n      onMouseLeave,\n      onMouseEnter,\n      showMarks,\n      style,\n      tickFormat,\n      width\n    } = this.props;\n\n    const axes = getAxes({\n      domains,\n      animation,\n      hideInnerMostValues,\n      style,\n      tickFormat\n    });\n\n    const lines = getLines({\n      animation,\n      brushFilters,\n      colorRange,\n      domains,\n      data,\n      showMarks,\n      style\n    });\n    const labelSeries = (\n      <LabelSeries\n        animation\n        key={className}\n        className={`${predefinedClassName}-label`}\n        data={getLabels({domains, style: style.labels})}\n      />\n    );\n\n    const {marginLeft, marginRight} = getInnerDimensions(\n      this.props,\n      DEFAULT_MARGINS\n    );\n    return (\n      <XYPlot\n        height={height}\n        width={width}\n        margin={margin}\n        dontCheckIfEmpty\n        className={getCombinedClassName(className, predefinedClassName)}\n        onMouseLeave={onMouseLeave}\n        onMouseEnter={onMouseEnter}\n        xType=\"ordinal\"\n        yDomain={[0, 1]}\n      >\n        {children}\n        {axes.concat(lines).concat(labelSeries)}\n        {brushing &&\n          domains.map(d => {\n            const trigger = row => {\n              this.setState({\n                brushFilters: {\n                  ...brushFilters,\n                  [d.name]: row ? {min: row.bottom, max: row.top} : null\n                }\n              });\n            };\n            return (\n              <Highlight\n                key={d.name}\n                drag\n                highlightX={d.name}\n                onBrushEnd={trigger}\n                onDragEnd={trigger}\n                highlightWidth={\n                  (width - marginLeft - marginRight) / domains.length\n                }\n                enableX={false}\n              />\n            );\n          })}\n      </XYPlot>\n    );\n  }\n}\n\nParallelCoordinates.displayName = 'ParallelCoordinates';\nParallelCoordinates.propTypes = {\n  animation: AnimationPropType,\n  brushing: PropTypes.bool,\n  className: PropTypes.string,\n  colorType: PropTypes.string,\n  colorRange: PropTypes.arrayOf(PropTypes.string),\n  data: PropTypes.arrayOf(PropTypes.object).isRequired,\n  domains: PropTypes.arrayOf(\n    PropTypes.shape({\n      name: PropTypes.string.isRequired,\n      domain: PropTypes.arrayOf(PropTypes.number).isRequired,\n      tickFormat: PropTypes.func\n    })\n  ).isRequired,\n  height: PropTypes.number.isRequired,\n  margin: MarginPropType,\n  style: PropTypes.shape({\n    axes: PropTypes.object,\n    labels: PropTypes.object,\n    lines: PropTypes.object\n  }),\n  showMarks: PropTypes.bool,\n  tickFormat: PropTypes.func,\n  width: PropTypes.number.isRequired\n};\nParallelCoordinates.defaultProps = {\n  className: '',\n  colorType: 'category',\n  colorRange: DISCRETE_COLOR_RANGE,\n  style: {\n    axes: {\n      line: {},\n      ticks: {},\n      text: {}\n    },\n    labels: {\n      fontSize: 10,\n      textAnchor: 'middle'\n    },\n    lines: {\n      strokeWidth: 1,\n      strokeOpacity: 1\n    },\n    deselectedLineStyle: {\n      strokeOpacity: 0.1\n    }\n  },\n  tickFormat: DEFAULT_FORMAT\n};\n\nexport default ParallelCoordinates;\n"
  },
  {
    "path": "packages/react-vis/src/plot/axis/axis-line.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport {ORIENTATION} from 'utils/axis-utils';\n\nconst {LEFT, RIGHT, TOP, BOTTOM} = ORIENTATION;\n\nconst propTypes = {\n  height: PropTypes.number.isRequired,\n  style: PropTypes.object,\n  orientation: PropTypes.oneOf([LEFT, RIGHT, TOP, BOTTOM]).isRequired,\n  width: PropTypes.number.isRequired\n};\n\nconst defaultProps = {\n  style: {}\n};\n\nfunction AxisLine({orientation, width, height, style}) {\n  let lineProps;\n  if (orientation === LEFT) {\n    lineProps = {\n      x1: width,\n      x2: width,\n      y1: 0,\n      y2: height\n    };\n  } else if (orientation === RIGHT) {\n    lineProps = {\n      x1: 0,\n      x2: 0,\n      y1: 0,\n      y2: height\n    };\n  } else if (orientation === TOP) {\n    lineProps = {\n      x1: 0,\n      x2: width,\n      y1: height,\n      y2: height\n    };\n  } else {\n    lineProps = {\n      x1: 0,\n      x2: width,\n      y1: 0,\n      y2: 0\n    };\n  }\n  return (\n    <line {...lineProps} className=\"rv-xy-plot__axis__line\" style={style} />\n  );\n}\n\nAxisLine.defaultProps = defaultProps;\nAxisLine.displayName = 'AxisLine';\nAxisLine.propTypes = propTypes;\n\nexport default AxisLine;\n"
  },
  {
    "path": "packages/react-vis/src/plot/axis/axis-ticks.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport {ORIENTATION, getTickValues} from 'utils/axis-utils';\nimport {getAttributeScale} from 'utils/scales-utils';\n\nconst {LEFT, RIGHT, TOP, BOTTOM} = ORIENTATION;\n\nconst propTypes = {\n  height: PropTypes.number.isRequired,\n  orientation: PropTypes.oneOf([LEFT, RIGHT, TOP, BOTTOM]).isRequired,\n  style: PropTypes.object,\n  width: PropTypes.number.isRequired\n};\n\nconst defaultProps = {\n  style: {}\n};\n\nfunction _getTickFormatFn(scale, tickTotal, tickFormat) {\n  return !tickFormat\n    ? scale.tickFormat\n      ? scale.tickFormat(tickTotal)\n      : v => v\n    : tickFormat;\n}\n\nclass AxisTicks extends React.Component {\n  /**\n   * Check if axis ticks should be mirrored (for the right and top positions.\n   * @returns {boolean} True if mirrored.\n   * @private\n   */\n  _areTicksWrapped() {\n    const {orientation} = this.props;\n    return orientation === LEFT || orientation === TOP;\n  }\n\n  _getTickContainerPropsGetterFn() {\n    if (this._isAxisVertical()) {\n      return pos => {\n        return {transform: `translate(0, ${pos})`};\n      };\n    }\n    return pos => {\n      return {transform: `translate(${pos}, 0)`};\n    };\n  }\n\n  /**\n   * Get attributes for the label of the tick.\n   * @returns {Object} Object with properties.\n   * @private\n   */\n  _getTickLabelProps() {\n    const {\n      orientation,\n      tickLabelAngle,\n      tickSize,\n      tickSizeOuter = tickSize,\n      tickPadding = tickSize\n    } = this.props;\n\n    // Assign the text orientation inside the label of the tick mark.\n    let textAnchor;\n    if (orientation === LEFT || (orientation === BOTTOM && tickLabelAngle)) {\n      textAnchor = 'end';\n    } else if (\n      orientation === RIGHT ||\n      (orientation === TOP && tickLabelAngle)\n    ) {\n      textAnchor = 'start';\n    } else {\n      textAnchor = 'middle';\n    }\n\n    // The label's position is translated to the given padding and then the\n    // label is rotated to the given angle.\n    const isVertical = this._isAxisVertical();\n    const wrap = this._areTicksWrapped() ? -1 : 1;\n\n    const labelOffset = wrap * (tickSizeOuter + tickPadding);\n    const transform =\n      (isVertical\n        ? `translate(${labelOffset}, 0)`\n        : `translate(0, ${labelOffset})`) +\n      (tickLabelAngle ? ` rotate(${tickLabelAngle})` : '');\n\n    // Set the vertical offset of the label according to the position of\n    // the axis.\n    const dy =\n      orientation === TOP || tickLabelAngle\n        ? '0'\n        : orientation === BOTTOM\n        ? '0.72em'\n        : '0.32em';\n\n    return {\n      textAnchor,\n      dy,\n      transform\n    };\n  }\n\n  /**\n   * Get the props of the tick line.\n   * @returns {Object} Props.\n   * @private\n   */\n  _getTickLineProps() {\n    const {\n      tickSize,\n      tickSizeOuter = tickSize,\n      tickSizeInner = tickSize\n    } = this.props;\n    const isVertical = this._isAxisVertical();\n    const tickXAttr = isVertical ? 'y' : 'x';\n    const tickYAttr = isVertical ? 'x' : 'y';\n    const wrap = this._areTicksWrapped() ? -1 : 1;\n    return {\n      [`${tickXAttr}1`]: 0,\n      [`${tickXAttr}2`]: 0,\n      [`${tickYAttr}1`]: -wrap * tickSizeInner,\n      [`${tickYAttr}2`]: wrap * tickSizeOuter\n    };\n  }\n\n  /**\n   * Gets if the axis is vertical.\n   * @returns {boolean} True if vertical.\n   * @private\n   */\n  _isAxisVertical() {\n    const {orientation} = this.props;\n    return orientation === LEFT || orientation === RIGHT;\n  }\n\n  render() {\n    const {\n      attr,\n      orientation,\n      width,\n      height,\n      style,\n      tickFormat,\n      tickTotal,\n      tickValues\n    } = this.props;\n\n    const x = orientation === LEFT ? width : 0;\n    const y = orientation === TOP ? height : 0;\n\n    const scale = getAttributeScale(this.props, attr);\n\n    const values = getTickValues(scale, tickTotal, tickValues);\n    const tickFormatFn = _getTickFormatFn(scale, tickTotal, tickFormat);\n\n    const translateFn = this._getTickContainerPropsGetterFn();\n    const pathProps = this._getTickLineProps();\n    const textProps = this._getTickLabelProps();\n\n    const ticks = values.map((v, i) => {\n      const pos = scale(v);\n      const labelNode = tickFormatFn(v, i, scale, tickTotal);\n      const shouldRenderAsOwnNode =\n        React.isValidElement(labelNode) &&\n        !['tspan', 'textPath'].includes(labelNode.type);\n      const shouldAddProps = labelNode && typeof labelNode.type !== 'string';\n      return (\n        <g\n          key={i}\n          {...translateFn(pos, 0)}\n          className=\"rv-xy-plot__axis__tick\"\n          style={style}\n        >\n          <line\n            {...pathProps}\n            className=\"rv-xy-plot__axis__tick__line\"\n            style={{...style, ...style.line}}\n          />\n          {shouldRenderAsOwnNode ? (\n            React.cloneElement(\n              labelNode,\n              shouldAddProps\n                ? {\n                    ...textProps,\n                    containerWidth: width,\n                    tickCount: values.length\n                  }\n                : undefined\n            )\n          ) : (\n            <text\n              {...textProps}\n              className=\"rv-xy-plot__axis__tick__text\"\n              style={{...style, ...style.text}}\n            >\n              {labelNode}\n            </text>\n          )}\n        </g>\n      );\n    });\n\n    return (\n      <g\n        transform={`translate(${x}, ${y})`}\n        className=\"rv-xy-plot__axis__ticks\"\n      >\n        {ticks}\n      </g>\n    );\n  }\n}\n\nAxisTicks.defaultProps = defaultProps;\nAxisTicks.displayName = 'AxisTicks';\nAxisTicks.propTypes = propTypes;\nAxisTicks.requiresSVG = true;\n\nexport default AxisTicks;\n"
  },
  {
    "path": "packages/react-vis/src/plot/axis/axis-title.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport {ORIENTATION} from 'utils/axis-utils';\n\n// Assuming that 16px = 1em\nconst ADJUSTMENT_FOR_TEXT_SIZE = 16;\nconst MARGIN = 6;\nconst {LEFT, RIGHT, TOP, BOTTOM} = ORIENTATION;\nconst defaultProps = {\n  position: 'end'\n};\n\n/**\n * Compute transformations, keyed by orientation\n * @param {number} width - width of axis\n * @param {number} height - height of axis\n * @returns {Object} Object of transformations, keyed by orientation\n */\nconst transformation = (width, height) => ({\n  [LEFT]: {\n    end: {\n      x: ADJUSTMENT_FOR_TEXT_SIZE,\n      y: MARGIN,\n      rotation: -90,\n      textAnchor: 'end'\n    },\n    middle: {\n      x: ADJUSTMENT_FOR_TEXT_SIZE,\n      y: height / 2 - MARGIN,\n      rotation: -90,\n      textAnchor: 'middle'\n    },\n    start: {\n      x: ADJUSTMENT_FOR_TEXT_SIZE,\n      y: height - MARGIN,\n      rotation: -90,\n      textAnchor: 'start'\n    }\n  },\n  [RIGHT]: {\n    end: {\n      x: ADJUSTMENT_FOR_TEXT_SIZE * -0.5,\n      y: MARGIN,\n      rotation: -90,\n      textAnchor: 'end'\n    },\n    middle: {\n      x: ADJUSTMENT_FOR_TEXT_SIZE * -0.5,\n      y: height / 2 - MARGIN,\n      rotation: -90,\n      textAnchor: 'middle'\n    },\n    start: {\n      x: ADJUSTMENT_FOR_TEXT_SIZE * -0.5,\n      y: height - MARGIN,\n      rotation: -90,\n      textAnchor: 'start'\n    }\n  },\n  [TOP]: {\n    start: {\n      x: MARGIN,\n      y: ADJUSTMENT_FOR_TEXT_SIZE,\n      rotation: 0,\n      textAnchor: 'start'\n    },\n    middle: {\n      x: width / 2 - MARGIN,\n      y: ADJUSTMENT_FOR_TEXT_SIZE,\n      rotation: 0,\n      textAnchor: 'middle'\n    },\n    end: {\n      x: width - MARGIN,\n      y: ADJUSTMENT_FOR_TEXT_SIZE,\n      rotation: 0,\n      textAnchor: 'end'\n    }\n  },\n  [BOTTOM]: {\n    start: {\n      x: MARGIN,\n      y: -MARGIN,\n      rotation: 0,\n      textAnchor: 'start'\n    },\n    middle: {\n      x: width / 2 - MARGIN,\n      y: -MARGIN,\n      rotation: 0,\n      textAnchor: 'middle'\n    },\n    end: {\n      x: width - MARGIN,\n      y: -MARGIN,\n      rotation: 0,\n      textAnchor: 'end'\n    }\n  }\n});\n\nconst propTypes = {\n  width: PropTypes.number.isRequired,\n  height: PropTypes.number.isRequired,\n  orientation: PropTypes.oneOf([LEFT, RIGHT, TOP, BOTTOM]).isRequired,\n  style: PropTypes.object,\n  title: PropTypes.string.isRequired\n};\n\nfunction AxisTitle({orientation, position, width, height, style, title}) {\n  const outerGroupTranslateX = orientation === LEFT ? width : 0;\n  const outerGroupTranslateY = orientation === TOP ? height : 0;\n  const outerGroupTransform = `translate(${outerGroupTranslateX}, ${outerGroupTranslateY})`;\n  const {x, y, rotation, textAnchor} = transformation(width, height)[\n    orientation\n  ][position];\n  const innerGroupTransform = `translate(${x}, ${y}) rotate(${rotation})`;\n\n  return (\n    <g transform={outerGroupTransform} className=\"rv-xy-plot__axis__title\">\n      <g style={{textAnchor, ...style}} transform={innerGroupTransform}>\n        <text style={style}>{title}</text>\n      </g>\n    </g>\n  );\n}\n\nAxisTitle.displayName = 'AxisTitle';\nAxisTitle.propTypes = propTypes;\nAxisTitle.defaultProps = defaultProps;\nexport default AxisTitle;\n"
  },
  {
    "path": "packages/react-vis/src/plot/axis/axis.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {PureComponent} from 'react';\nimport PropTypes from 'prop-types';\n\nimport Animation from 'animation';\nimport {ORIENTATION, getTicksTotalFromSize} from 'utils/axis-utils';\nimport {getAttributeScale} from 'utils/scales-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nimport AxisLine from './axis-line';\nimport AxisTicks from './axis-ticks';\nimport AxisTitle from './axis-title';\n\nconst defaultAnimatedProps = [\n  'xRange',\n  'yRange',\n  'xDomain',\n  'yDomain',\n  'width',\n  'height',\n  'marginLeft',\n  'marginTop',\n  'marginRight',\n  'marginBottom',\n  'tickSize',\n  'tickTotal',\n  'tickSizeInner',\n  'tickSizeOuter'\n];\n\nconst {LEFT, RIGHT, TOP, BOTTOM} = ORIENTATION;\n\nconst propTypes = {\n  orientation: PropTypes.oneOf([LEFT, RIGHT, TOP, BOTTOM]),\n  attr: PropTypes.string.isRequired,\n  attrAxis: PropTypes.string,\n  width: PropTypes.number,\n  height: PropTypes.number,\n  top: PropTypes.number,\n  left: PropTypes.number,\n  title: PropTypes.string,\n\n  style: PropTypes.object,\n\n  className: PropTypes.string,\n  hideTicks: PropTypes.bool,\n  hideLine: PropTypes.bool,\n  on0: PropTypes.bool,\n  tickLabelAngle: PropTypes.number,\n  tickSize: PropTypes.number,\n  tickSizeInner: PropTypes.number,\n  tickSizeOuter: PropTypes.number,\n  tickPadding: PropTypes.number,\n  tickValues: PropTypes.arrayOf(\n    PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n  ),\n  tickFormat: PropTypes.func,\n  tickTotal: PropTypes.number,\n\n  // Not expected to be used by the users.\n  // TODO: Add underscore to these properties later.\n  marginTop: PropTypes.number,\n  marginBottom: PropTypes.number,\n  marginLeft: PropTypes.number,\n  marginRight: PropTypes.number,\n  innerWidth: PropTypes.number,\n  innerHeight: PropTypes.number\n};\n\nconst defaultProps = {\n  className: '',\n  on0: false,\n  style: {},\n  tickSize: 6,\n  tickPadding: 8,\n  orientation: BOTTOM\n};\n\nconst predefinedClassName = 'rv-xy-plot__axis';\nconst VERTICAL_CLASS_NAME = 'rv-xy-plot__axis--vertical';\nconst HORIZONTAL_CLASS_NAME = 'rv-xy-plot__axis--horizontal';\n\nclass Axis extends PureComponent {\n  /**\n   * Define the default values depending on the data passed from the outside.\n   * @returns {*} Object of default properties.\n   * @private\n   */\n  _getDefaultAxisProps() {\n    const {\n      innerWidth,\n      innerHeight,\n      marginTop,\n      marginBottom,\n      marginLeft,\n      marginRight,\n      orientation\n    } = this.props;\n    if (orientation === BOTTOM) {\n      return {\n        tickTotal: getTicksTotalFromSize(innerWidth),\n        top: innerHeight + marginTop,\n        left: marginLeft,\n        width: innerWidth,\n        height: marginBottom\n      };\n    } else if (orientation === TOP) {\n      return {\n        tickTotal: getTicksTotalFromSize(innerWidth),\n        top: 0,\n        left: marginLeft,\n        width: innerWidth,\n        height: marginTop\n      };\n    } else if (orientation === LEFT) {\n      return {\n        tickTotal: getTicksTotalFromSize(innerHeight),\n        top: marginTop,\n        left: 0,\n        width: marginLeft,\n        height: innerHeight\n      };\n    }\n    return {\n      tickTotal: getTicksTotalFromSize(innerHeight),\n      top: marginTop,\n      left: marginLeft + innerWidth,\n      width: marginRight,\n      height: innerHeight\n    };\n  }\n\n  render() {\n    const {animation} = this.props;\n\n    if (animation) {\n      const animatedProps = animation.nonAnimatedProps\n        ? defaultAnimatedProps.filter(\n            prop => animation.nonAnimatedProps.indexOf(prop) < 0\n          )\n        : defaultAnimatedProps;\n\n      return (\n        <Animation {...this.props} {...{animatedProps}}>\n          <Axis {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const props = {\n      ...this._getDefaultAxisProps(),\n      ...this.props\n    };\n\n    const {\n      attrAxis,\n      className,\n      height,\n      hideLine,\n      hideTicks,\n      left,\n      marginTop,\n      on0,\n      orientation,\n      position,\n      style,\n      title,\n      top,\n      width\n    } = props;\n    const isVertical = [LEFT, RIGHT].indexOf(orientation) > -1;\n    const axisClassName = isVertical\n      ? VERTICAL_CLASS_NAME\n      : HORIZONTAL_CLASS_NAME;\n\n    let leftPos = left;\n    let topPos = top;\n    if (on0) {\n      const scale = getAttributeScale(props, attrAxis);\n      if (isVertical) {\n        leftPos = scale(0);\n      } else {\n        topPos = marginTop + scale(0);\n      }\n    }\n\n    return (\n      <g\n        transform={`translate(${leftPos},${topPos})`}\n        className={getCombinedClassName(\n          predefinedClassName,\n          axisClassName,\n          className\n        )}\n        style={style}\n      >\n        {!hideLine && (\n          <AxisLine\n            height={height}\n            width={width}\n            orientation={orientation}\n            style={{...style, ...style.line}}\n          />\n        )}\n        {!hideTicks && (\n          <AxisTicks {...props} style={{...style, ...style.ticks}} />\n        )}\n        {title ? (\n          <AxisTitle\n            position={position}\n            title={title}\n            height={height}\n            width={width}\n            style={{...style, ...style.title}}\n            orientation={orientation}\n          />\n        ) : null}\n      </g>\n    );\n  }\n}\n\nAxis.displayName = 'Axis';\nAxis.propTypes = propTypes;\nAxis.defaultProps = defaultProps;\nAxis.requiresSVG = true;\n\nexport default Axis;\n"
  },
  {
    "path": "packages/react-vis/src/plot/axis/decorative-axis-ticks.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {generatePoints, getAxisAngle} from 'utils/axis-utils';\n\n/**\n * Generate the actual polygons to be plotted\n * @param {Object} props\n - props.animation {Boolean}\n - props.axisDomain {Array} a pair of values specifying the domain of the axis\n - props.numberOfTicks{Number} the number of ticks on the axis\n - props.axisStart {Object} a object specify in cartesian space the start of the axis\n example: {x: 0, y: 0}\n - props.axisEnd {Object} a object specify in cartesian space the start of the axis\n - props.tickValue {Func} a formatting function for the tick values\n - props.tickSize {Number} a pixel size of the axis\n - props.style {Object} The style object for the axis\n * @return {Component} the plotted axis\n */\nexport default function decorativeAxisTick(props) {\n  const {\n    axisDomain,\n    numberOfTicks,\n    axisStart,\n    axisEnd,\n    tickValue,\n    tickSize,\n    style\n  } = props;\n  const {points} = generatePoints({\n    axisStart,\n    axisEnd,\n    numberOfTicks,\n    axisDomain\n  });\n  // add a quarter rotation to make ticks orthogonal to axis\n  const tickAngle = getAxisAngle(axisStart, axisEnd) + Math.PI / 2;\n  return points.map((point, index) => {\n    const tickProps = {\n      x1: 0,\n      y1: 0,\n      x2: tickSize * Math.cos(tickAngle),\n      y2: tickSize * Math.sin(tickAngle),\n      ...style.ticks\n    };\n\n    const textProps = {\n      x: tickSize * Math.cos(tickAngle),\n      y: tickSize * Math.sin(tickAngle),\n      textAnchor: 'start',\n      ...style.text\n    };\n    return (\n      <g\n        key={index}\n        transform={`translate(${point.x}, ${point.y})`}\n        className=\"rv-xy-plot__axis__tick\"\n      >\n        <line {...tickProps} className=\"rv-xy-plot__axis__tick__line\" />\n        <text {...textProps} className=\"rv-xy-plot__axis__tick__text\">\n          {tickValue(point.text)}\n        </text>\n      </g>\n    );\n  });\n}\n"
  },
  {
    "path": "packages/react-vis/src/plot/axis/decorative-axis.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {format} from 'd3-format';\nimport PropTypes from 'prop-types';\n\nimport AbstractSeries from 'plot/series/abstract-series';\nimport DecorativeAxisTicks from './decorative-axis-ticks';\nimport Animation from 'animation';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst predefinedClassName = 'rv-xy-manipulable-axis rv-xy-plot__axis';\n\nconst animatedProps = [\n  'xRange',\n  'yRange',\n  'xDomain',\n  'yDomain',\n  'width',\n  'height',\n  'marginLeft',\n  'marginTop',\n  'marginRight',\n  'marginBottom',\n  'tickSize',\n  'tickTotal',\n  'tickSizeInner',\n  'tickSizeOuter'\n];\n\nclass DecorativeAxis extends AbstractSeries {\n  render() {\n    const {\n      animation,\n      className,\n      marginLeft,\n      marginTop,\n      axisStart,\n      axisEnd,\n      axisDomain,\n      numberOfTicks,\n      tickValue,\n      tickSize,\n      style\n    } = this.props;\n\n    if (animation) {\n      return (\n        <Animation {...this.props} {...{animatedProps}}>\n          <DecorativeAxis {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const x = this._getAttributeFunctor('x');\n    const y = this._getAttributeFunctor('y');\n\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n      >\n        <line\n          {...{\n            x1: x({x: axisStart.x}),\n            x2: x({x: axisEnd.x}),\n            y1: y({y: axisStart.y}),\n            y2: y({y: axisEnd.y}),\n            ...style.line\n          }}\n          className=\"rv-xy-plot__axis__line\"\n        />\n        <g className=\"rv-xy-manipulable-axis__ticks\">\n          {DecorativeAxisTicks({\n            axisDomain,\n            axisEnd: {x: x(axisEnd), y: y(axisEnd)},\n            axisStart: {x: x(axisStart), y: y(axisStart)},\n            numberOfTicks,\n            tickValue,\n            tickSize,\n            style\n          })}\n        </g>\n      </g>\n    );\n  }\n}\n\nconst DEFAULT_FORMAT = format('.2r');\n\nDecorativeAxis.defaultProps = {\n  className: '',\n  numberOfTicks: 10,\n  tickValue: d => DEFAULT_FORMAT(d),\n  tickSize: 5,\n  style: {\n    line: {\n      strokeWidth: 1\n    },\n    ticks: {\n      strokeWidth: 2\n    },\n    text: {}\n  }\n};\nDecorativeAxis.propTypes = {\n  ...AbstractSeries.propTypes,\n  axisDomain: PropTypes.arrayOf(PropTypes.number).isRequired,\n  axisEnd: PropTypes.shape({\n    x: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n    y: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n  }).isRequired,\n  axisStart: PropTypes.shape({\n    x: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n    y: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n  }).isRequired,\n  className: PropTypes.string,\n  numberOfTicks: PropTypes.number,\n  tickValue: PropTypes.func,\n  tickSize: PropTypes.number,\n  style: PropTypes.shape({\n    line: PropTypes.object,\n    ticks: PropTypes.object,\n    text: PropTypes.object\n  })\n};\nDecorativeAxis.displayName = 'DecorativeAxis';\nexport default DecorativeAxis;\n"
  },
  {
    "path": "packages/react-vis/src/plot/axis/x-axis.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport {ORIENTATION} from 'utils/axis-utils';\n\nimport Axis from './axis';\n\nconst {TOP, BOTTOM} = ORIENTATION;\n\nconst propTypes = {\n  ...Axis.propTypes,\n  orientation: PropTypes.oneOf([TOP, BOTTOM])\n};\n\nconst defaultProps = {\n  orientation: BOTTOM,\n  attr: 'x',\n  attrAxis: 'y'\n};\n\nfunction XAxis(props) {\n  return <Axis {...props} />;\n}\n\nXAxis.displayName = 'XAxis';\nXAxis.propTypes = propTypes;\nXAxis.defaultProps = defaultProps;\nXAxis.requiresSVG = true;\n\nexport default XAxis;\n"
  },
  {
    "path": "packages/react-vis/src/plot/axis/y-axis.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport {ORIENTATION} from 'utils/axis-utils';\n\nimport Axis from './axis';\n\nconst {LEFT, RIGHT} = ORIENTATION;\n\nconst propTypes = {\n  ...Axis.propTypes,\n  orientation: PropTypes.oneOf([LEFT, RIGHT])\n};\n\nconst defaultProps = {\n  orientation: LEFT,\n  attr: 'y',\n  attrAxis: 'x'\n};\n\nfunction YAxis(props) {\n  return <Axis {...props} />;\n}\n\nYAxis.displayName = 'YAxis';\nYAxis.propTypes = propTypes;\nYAxis.defaultProps = defaultProps;\nYAxis.requiresSVG = true;\n\nexport default YAxis;\n"
  },
  {
    "path": "packages/react-vis/src/plot/borders.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst propTypes = {\n  style: PropTypes.shape({\n    bottom: PropTypes.object,\n    left: PropTypes.object,\n    right: PropTypes.object,\n    top: PropTypes.object\n  }),\n  // supplied by xyplot\n  marginTop: PropTypes.number,\n  marginBottom: PropTypes.number,\n  marginLeft: PropTypes.number,\n  marginRight: PropTypes.number,\n  innerWidth: PropTypes.number,\n  innerHeight: PropTypes.number\n};\n\nconst CLASSES = {\n  bottom: 'rv-xy-plot__borders-bottom',\n  container: 'rv-xy-plot__borders',\n  left: 'rv-xy-plot__borders-left',\n  right: 'rv-xy-plot__borders-right',\n  top: 'rv-xy-plot__borders-top'\n};\n\nfunction Borders(props) {\n  const {\n    marginTop,\n    marginBottom,\n    marginLeft,\n    marginRight,\n    innerWidth,\n    innerHeight,\n    style,\n    className\n  } = props;\n  const height = innerHeight + marginTop + marginBottom;\n  const width = innerWidth + marginLeft + marginRight;\n  return (\n    <g className={getCombinedClassName(CLASSES.container, className)}>\n      <rect\n        className={getCombinedClassName(CLASSES.bottom, `${className}-bottom`)}\n        style={{...style.all, ...style.bottom}}\n        x={0}\n        y={height - marginBottom}\n        width={width}\n        height={marginBottom}\n      />\n      <rect\n        className={getCombinedClassName(CLASSES.left, `${className}-left`)}\n        style={{...style.all, ...style.left}}\n        x={0}\n        y={0}\n        width={marginLeft}\n        height={height}\n      />\n      <rect\n        className={getCombinedClassName(CLASSES.right, `${className}-right`)}\n        style={{...style.all, ...style.right}}\n        x={width - marginRight}\n        y={0}\n        width={marginRight}\n        height={height}\n      />\n      <rect\n        className={getCombinedClassName(CLASSES.top, `${className}-top`)}\n        style={{...style.all, ...style.top}}\n        x={0}\n        y={0}\n        width={width}\n        height={marginTop}\n      />\n    </g>\n  );\n}\n\nBorders.displayName = 'Borders';\nBorders.defaultProps = {\n  className: '',\n  style: {\n    all: {},\n    bottom: {},\n    left: {},\n    right: {},\n    top: {}\n  }\n};\nBorders.propTypes = propTypes;\nBorders.requiresSVG = true;\n\nexport default Borders;\n"
  },
  {
    "path": "packages/react-vis/src/plot/chart-label.js",
    "content": "// Copyright (c) 2018 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nclass ChartLabel extends React.PureComponent {\n  static get requiresSVG() {\n    return true;\n  }\n\n  render() {\n    const {\n      // rv defined\n      innerHeight,\n      innerWidth,\n      marginBottom,\n      marginLeft,\n      marginRight,\n      marginTop,\n      // user defined\n      className,\n      includeMargin,\n      style,\n      text,\n      xPercent,\n      yPercent\n    } = this.props;\n    const width = innerWidth + (includeMargin ? marginLeft + marginRight : 0);\n    const height = innerHeight + (includeMargin ? marginTop + marginBottom : 0);\n    const xPos = width * xPercent + (includeMargin ? 0 : marginLeft);\n    const yPos = height * yPercent + (includeMargin ? marginTop : 0);\n    return (\n      <g\n        transform={`translate(${xPos}, ${yPos})`}\n        className={getCombinedClassName('rv-xy-plot__axis__title', className)}\n      >\n        <text {...style}>{text}</text>\n      </g>\n    );\n  }\n}\n\nChartLabel.displayName = 'ChartLabel';\nChartLabel.propTypes = {\n  className: PropTypes.string,\n  includeMargin: PropTypes.bool,\n  style: PropTypes.object,\n  text: PropTypes.string.isRequired,\n  xPercent: PropTypes.number.isRequired,\n  yPercent: PropTypes.number.isRequired\n};\nChartLabel.defaultProps = {\n  className: '',\n  includeMargin: true,\n  text: '',\n  xPercent: 0,\n  yPercent: 0,\n  style: {}\n};\nexport default ChartLabel;\n"
  },
  {
    "path": "packages/react-vis/src/plot/circular-grid-lines.js",
    "content": "// Copyright (c) 2016 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {PureComponent} from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport {getAttributeScale} from 'utils/scales-utils';\nimport Animation, {AnimationPropType} from 'animation';\n\nimport {getTicksTotalFromSize, getTickValues} from '../utils/axis-utils';\n\nconst animatedProps = [\n  'xRange',\n  'yRange',\n  'xDomain',\n  'yDomain',\n  'width',\n  'height',\n  'marginLeft',\n  'marginTop',\n  'marginRight',\n  'marginBottom',\n  'tickTotal'\n];\n\nclass CircularGridLines extends PureComponent {\n  _getDefaultProps() {\n    const {innerWidth, innerHeight, marginTop, marginLeft} = this.props;\n    return {\n      left: marginLeft,\n      top: marginTop,\n      width: innerWidth,\n      height: innerHeight,\n      style: {},\n      tickTotal: getTicksTotalFromSize(Math.min(innerWidth, innerHeight))\n    };\n  }\n\n  render() {\n    const {animation, centerX, centerY} = this.props;\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={animatedProps}>\n          <CircularGridLines {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const props = {\n      ...this._getDefaultProps(),\n      ...this.props\n    };\n\n    const {tickTotal, tickValues, marginLeft, marginTop, rRange, style} = props;\n\n    const xScale = getAttributeScale(props, 'x');\n    const yScale = getAttributeScale(props, 'y');\n    const values = getTickValues(xScale, tickTotal, tickValues);\n    return (\n      <g\n        transform={`translate(${xScale(centerX) + marginLeft},${yScale(\n          centerY\n        ) + marginTop})`}\n        className=\"rv-xy-plot__circular-grid-lines\"\n      >\n        {values.reduce((res, value, index) => {\n          const radius = xScale(value);\n          if (rRange && (radius < rRange[0] || radius > rRange[1])) {\n            return res;\n          }\n          return res.concat([\n            <circle\n              {...{cx: 0, cy: 0, r: radius}}\n              key={index}\n              className=\"rv-xy-plot__circular-grid-lines__line\"\n              style={style}\n            />\n          ]);\n        }, [])}\n      </g>\n    );\n  }\n}\n\nCircularGridLines.displayName = 'CircularGridLines';\nCircularGridLines.propTypes = {\n  centerX: PropTypes.number,\n  centerY: PropTypes.number,\n  width: PropTypes.number,\n  height: PropTypes.number,\n  top: PropTypes.number,\n  left: PropTypes.number,\n  rRange: PropTypes.arrayOf(PropTypes.number),\n\n  style: PropTypes.object,\n\n  tickValues: PropTypes.arrayOf(PropTypes.number),\n  tickTotal: PropTypes.number,\n\n  animation: AnimationPropType,\n  // generally supplied by xyplot\n  marginTop: PropTypes.number,\n  marginBottom: PropTypes.number,\n  marginLeft: PropTypes.number,\n  marginRight: PropTypes.number,\n  innerWidth: PropTypes.number,\n  innerHeight: PropTypes.number\n};\nCircularGridLines.defaultProps = {\n  centerX: 0,\n  centerY: 0\n};\nCircularGridLines.requiresSVG = true;\n\nexport default CircularGridLines;\n"
  },
  {
    "path": "packages/react-vis/src/plot/content-clip-path.js",
    "content": "import React from 'react';\n\nexport default function ContentClipPath(props) {\n  const {id = 'content-area', innerWidth, innerHeight} = props;\n  return (\n    <defs>\n      <clipPath id={id}>\n        <rect x={0} y={0} width={innerWidth} height={innerHeight} />\n      </clipPath>\n    </defs>\n  );\n}\n\nContentClipPath.requiresSVG = true;\nContentClipPath.displayName = 'ContentClipPath';\n"
  },
  {
    "path": "packages/react-vis/src/plot/crosshair.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {PureComponent} from 'react';\nimport PropTypes from 'prop-types';\n\nimport {transformValueToString} from 'utils/data-utils';\nimport {getAttributeFunctor} from 'utils/scales-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\n/**\n * Format title by detault.\n * @param {Array} values List of values.\n * @returns {*} Formatted value or undefined.\n */\nfunction defaultTitleFormat(values) {\n  const value = getFirstNonEmptyValue(values);\n  if (value) {\n    return {\n      title: 'x',\n      value: transformValueToString(value.x)\n    };\n  }\n}\n\n/**\n * Format items by default.\n * @param {Array} values Array of values.\n * @returns {*} Formatted list of items.\n */\nfunction defaultItemsFormat(values) {\n  return values.map((v, i) => {\n    if (v) {\n      return {value: v.y, title: i};\n    }\n  });\n}\n\n/**\n * Get the first non-empty item from an array.\n * @param {Array} values Array of values.\n * @returns {*} First non-empty value or undefined.\n */\nfunction getFirstNonEmptyValue(values) {\n  return (values || []).find(v => Boolean(v));\n}\n\nclass Crosshair extends PureComponent {\n  static get defaultProps() {\n    return {\n      titleFormat: defaultTitleFormat,\n      itemsFormat: defaultItemsFormat,\n      style: {\n        line: {},\n        title: {},\n        box: {}\n      }\n    };\n  }\n\n  static get propTypes() {\n    return {\n      className: PropTypes.string,\n      values: PropTypes.arrayOf(\n        PropTypes.oneOfType([\n          PropTypes.number,\n          PropTypes.string,\n          PropTypes.object,\n          PropTypes.bool\n        ])\n      ),\n      series: PropTypes.object,\n      innerWidth: PropTypes.number,\n      innerHeight: PropTypes.number,\n      marginLeft: PropTypes.number,\n      marginTop: PropTypes.number,\n      orientation: PropTypes.oneOf(['left', 'right']),\n      itemsFormat: PropTypes.func,\n      titleFormat: PropTypes.func,\n      style: PropTypes.shape({\n        line: PropTypes.object,\n        title: PropTypes.object,\n        box: PropTypes.object\n      })\n    };\n  }\n\n  /**\n   * Render crosshair items (title + value for each series).\n   * @returns {*} Array of React classes with the crosshair values.\n   * @private\n   */\n  _renderCrosshairItems() {\n    const {values, itemsFormat} = this.props;\n    const items = itemsFormat(values);\n    if (!items) {\n      return null;\n    }\n    return items\n      .filter(i => i)\n      .map(function renderValue(item, i) {\n        return (\n          <div className=\"rv-crosshair__item\" key={`item${i}`}>\n            <span className=\"rv-crosshair__item__title\">{item.title}</span>\n            {': '}\n            <span className=\"rv-crosshair__item__value\">{item.value}</span>\n          </div>\n        );\n      });\n  }\n\n  /**\n   * Render crosshair title.\n   * @returns {*} Container with the crosshair title.\n   * @private\n   */\n  _renderCrosshairTitle() {\n    const {values, titleFormat, style} = this.props;\n    const titleItem = titleFormat(values);\n    if (!titleItem) {\n      return null;\n    }\n    return (\n      <div className=\"rv-crosshair__title\" key=\"title\" style={style.title}>\n        <span className=\"rv-crosshair__title__title\">{titleItem.title}</span>\n        {': '}\n        <span className=\"rv-crosshair__title__value\">{titleItem.value}</span>\n      </div>\n    );\n  }\n\n  render() {\n    const {\n      children,\n      className,\n      values,\n      marginTop,\n      marginLeft,\n      innerWidth,\n      innerHeight,\n      style\n    } = this.props;\n    const value = getFirstNonEmptyValue(values);\n    if (!value) {\n      return null;\n    }\n    const x = getAttributeFunctor(this.props, 'x');\n    const innerLeft = x(value);\n\n    const {\n      orientation = innerLeft > innerWidth / 2 ? 'left' : 'right'\n    } = this.props;\n    const left = marginLeft + innerLeft;\n    const top = marginTop;\n    const innerClassName = `rv-crosshair__inner rv-crosshair__inner--${orientation}`;\n\n    return (\n      <div\n        className={getCombinedClassName('rv-crosshair', className)}\n        style={{left: `${left}px`, top: `${top}px`}}\n      >\n        <div\n          className=\"rv-crosshair__line\"\n          style={{height: `${innerHeight}px`, ...style.line}}\n        />\n\n        <div className={innerClassName}>\n          {children ? (\n            children\n          ) : (\n            <div className=\"rv-crosshair__inner__content\" style={style.box}>\n              <div>\n                {this._renderCrosshairTitle()}\n                {this._renderCrosshairItems()}\n              </div>\n            </div>\n          )}\n        </div>\n      </div>\n    );\n  }\n}\n\nCrosshair.displayName = 'Crosshair';\n\nexport default Crosshair;\n"
  },
  {
    "path": "packages/react-vis/src/plot/gradient-defs.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst predefinedClassName = 'rv-gradient-defs';\n\nfunction GradientDefs(props) {\n  const {className} = props;\n  return (\n    <defs className={getCombinedClassName(predefinedClassName, className)}>\n      {props.children}\n    </defs>\n  );\n}\n\nGradientDefs.displayName = 'GradientDefs';\nGradientDefs.requiresSVG = true;\nGradientDefs.propTypes = {\n  className: PropTypes.string\n};\nGradientDefs.defaultProps = {\n  className: ''\n};\n\nexport default GradientDefs;\n"
  },
  {
    "path": "packages/react-vis/src/plot/grid-lines.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {PureComponent} from 'react';\nimport PropTypes from 'prop-types';\n\nimport {getAttributeScale} from 'utils/scales-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\nimport Animation, {AnimationPropType} from 'animation';\n\nimport {\n  getTicksTotalFromSize,\n  getTickValues,\n  DIRECTION\n} from '../utils/axis-utils';\n\nconst {VERTICAL, HORIZONTAL} = DIRECTION;\n\nconst propTypes = {\n  direction: PropTypes.oneOf([VERTICAL, HORIZONTAL]),\n  attr: PropTypes.string.isRequired,\n  width: PropTypes.number,\n  height: PropTypes.number,\n  top: PropTypes.number,\n  left: PropTypes.number,\n\n  style: PropTypes.object,\n\n  tickValues: PropTypes.arrayOf(\n    PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n  ),\n  tickTotal: PropTypes.number,\n\n  animation: AnimationPropType,\n\n  // generally supplied by xyplot\n  marginTop: PropTypes.number,\n  marginBottom: PropTypes.number,\n  marginLeft: PropTypes.number,\n  marginRight: PropTypes.number,\n  innerWidth: PropTypes.number,\n  innerHeight: PropTypes.number\n};\n\nconst defaultProps = {\n  direction: VERTICAL\n};\n\nconst animatedProps = [\n  'xRange',\n  'yRange',\n  'xDomain',\n  'yDomain',\n  'width',\n  'height',\n  'marginLeft',\n  'marginTop',\n  'marginRight',\n  'marginBottom',\n  'tickTotal'\n];\n\nclass GridLines extends PureComponent {\n  _getDefaultProps() {\n    const {\n      innerWidth,\n      innerHeight,\n      marginTop,\n      marginLeft,\n      direction\n    } = this.props;\n    return {\n      left: marginLeft,\n      top: marginTop,\n      width: innerWidth,\n      height: innerHeight,\n      tickTotal: getTicksTotalFromSize(\n        direction === VERTICAL ? innerWidth : innerHeight\n      )\n    };\n  }\n\n  render() {\n    const {animation, className} = this.props;\n    if (animation) {\n      return (\n        <Animation {...this.props} {...{animatedProps}}>\n          <GridLines {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const props = {\n      ...this._getDefaultProps(),\n      ...this.props\n    };\n\n    const {\n      attr,\n      direction,\n      width,\n      height,\n      style,\n      tickTotal,\n      tickValues,\n      top,\n      left\n    } = props;\n    const isVertical = direction === VERTICAL;\n    const tickXAttr = isVertical ? 'y' : 'x';\n    const tickYAttr = isVertical ? 'x' : 'y';\n    const length = isVertical ? height : width;\n\n    const scale = getAttributeScale(props, attr);\n    const values = getTickValues(scale, tickTotal, tickValues);\n\n    return (\n      <g\n        transform={`translate(${left},${top})`}\n        className={getCombinedClassName('rv-xy-plot__grid-lines', className)}\n      >\n        {values.map((v, i) => {\n          const pos = scale(v);\n          const pathProps = {\n            [`${tickYAttr}1`]: pos,\n            [`${tickYAttr}2`]: pos,\n            [`${tickXAttr}1`]: 0,\n            [`${tickXAttr}2`]: length\n          };\n          return (\n            <line\n              {...pathProps}\n              key={i}\n              className=\"rv-xy-plot__grid-lines__line\"\n              style={style}\n            />\n          );\n        })}\n      </g>\n    );\n  }\n}\n\nGridLines.displayName = 'GridLines';\nGridLines.defaultProps = defaultProps;\nGridLines.propTypes = propTypes;\nGridLines.requiresSVG = true;\n\nexport default GridLines;\n"
  },
  {
    "path": "packages/react-vis/src/plot/highlight.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport AbstractSeries from './series/abstract-series';\nimport {getAttributeScale} from 'utils/scales-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nfunction getLocs(evt) {\n  const xLoc = evt.type === 'touchstart' ? evt.pageX : evt.offsetX;\n  const yLoc = evt.type === 'touchstart' ? evt.pageY : evt.offsetY;\n  return {xLoc, yLoc};\n}\n\nclass Highlight extends AbstractSeries {\n  state = {\n    dragging: false,\n    brushArea: {top: 0, right: 0, bottom: 0, left: 0},\n    brushing: false,\n    startLocX: 0,\n    startLocY: 0,\n    dragArea: null\n  };\n\n  _getDrawArea(xLoc, yLoc) {\n    const {startLocX, startLocY} = this.state;\n    const {\n      enableX,\n      enableY,\n      highlightWidth,\n      highlightHeight,\n      innerWidth,\n      innerHeight,\n      marginLeft,\n      marginRight,\n      marginBottom,\n      marginTop\n    } = this.props;\n    const plotHeight = innerHeight + marginTop + marginBottom;\n    const plotWidth = innerWidth + marginLeft + marginRight;\n    const touchWidth = highlightWidth || plotWidth;\n    const touchHeight = highlightHeight || plotHeight;\n\n    return {\n      bottom: enableY ? Math.max(startLocY, yLoc) : touchHeight,\n      right: enableX ? Math.max(startLocX, xLoc) : touchWidth,\n      left: enableX ? Math.min(xLoc, startLocX) : 0,\n      top: enableY ? Math.min(yLoc, startLocY) : 0\n    };\n  }\n\n  _getDragArea(xLoc, yLoc) {\n    const {enableX, enableY} = this.props;\n    const {startLocX, startLocY, dragArea} = this.state;\n\n    return {\n      bottom: dragArea.bottom + (enableY ? yLoc - startLocY : 0),\n      left: dragArea.left + (enableX ? xLoc - startLocX : 0),\n      right: dragArea.right + (enableX ? xLoc - startLocX : 0),\n      top: dragArea.top + (enableY ? yLoc - startLocY : 0)\n    };\n  }\n\n  _clickedOutsideDrag(xLoc, yLoc) {\n    const {enableX, enableY} = this.props;\n    const {\n      dragArea,\n      brushArea: {left, right, top, bottom}\n    } = this.state;\n    const clickedOutsideDragX = dragArea && (xLoc < left || xLoc > right);\n    const clickedOutsideDragY = dragArea && (yLoc < top || yLoc > bottom);\n    if (enableX && enableY) {\n      return clickedOutsideDragX || clickedOutsideDragY;\n    }\n    if (enableX) {\n      return clickedOutsideDragX;\n    }\n    if (enableY) {\n      return clickedOutsideDragY;\n    }\n    return true;\n  }\n\n  _convertAreaToCoordinates(brushArea) {\n    // NOTE only continuous scales are supported for brushing/getting coordinates back\n    const {enableX, enableY, marginLeft, marginTop} = this.props;\n    const xScale = getAttributeScale(this.props, 'x');\n    const yScale = getAttributeScale(this.props, 'y');\n\n    // Ensure that users wishes are being respected about which scales are evaluated\n    // this is specifically enabled to ensure brushing on mixed categorical and linear\n    // charts will run as expected\n\n    if (enableX && enableY) {\n      return {\n        bottom: yScale.invert(brushArea.bottom),\n        left: xScale.invert(brushArea.left - marginLeft),\n        right: xScale.invert(brushArea.right - marginLeft),\n        top: yScale.invert(brushArea.top)\n      };\n    }\n\n    if (enableY) {\n      return {\n        bottom: yScale.invert(brushArea.bottom - marginTop),\n        top: yScale.invert(brushArea.top - marginTop)\n      };\n    }\n\n    if (enableX) {\n      return {\n        left: xScale.invert(brushArea.left - marginLeft),\n        right: xScale.invert(brushArea.right - marginLeft)\n      };\n    }\n\n    return {};\n  }\n\n  startBrushing(e) {\n    const {onBrushStart, onDragStart, drag} = this.props;\n    const {dragArea} = this.state;\n    const {xLoc, yLoc} = getLocs(e.nativeEvent);\n\n    const startArea = (dragging, resetDrag) => {\n      const emptyBrush = {\n        bottom: yLoc,\n        left: xLoc,\n        right: xLoc,\n        top: yLoc\n      };\n      this.setState({\n        dragging,\n        brushArea: dragArea && !resetDrag ? dragArea : emptyBrush,\n        brushing: !dragging,\n        startLocX: xLoc,\n        startLocY: yLoc\n      });\n    };\n\n    const clickedOutsideDrag = this._clickedOutsideDrag(xLoc, yLoc);\n    if ((drag && !dragArea) || !drag || clickedOutsideDrag) {\n      startArea(false, clickedOutsideDrag);\n\n      if (onBrushStart) {\n        onBrushStart(e);\n      }\n      return;\n    }\n\n    if (drag && dragArea) {\n      startArea(true, clickedOutsideDrag);\n      if (onDragStart) {\n        onDragStart(e);\n      }\n    }\n  }\n\n  stopBrushing() {\n    const {brushing, dragging, brushArea} = this.state;\n    // Quickly short-circuit if the user isn't brushing in our component\n    if (!brushing && !dragging) {\n      return;\n    }\n    const {onBrushEnd, onDragEnd, drag} = this.props;\n    const noHorizontal = Math.abs(brushArea.right - brushArea.left) < 5;\n    const noVertical = Math.abs(brushArea.top - brushArea.bottom) < 5;\n    // Invoke the callback with null if the selected area was < 5px\n    const isNulled = noVertical || noHorizontal;\n    // Clear the draw area\n    this.setState({\n      brushing: false,\n      dragging: false,\n      brushArea: drag ? brushArea : {top: 0, right: 0, bottom: 0, left: 0},\n      startLocX: 0,\n      startLocY: 0,\n      dragArea: drag && !isNulled && brushArea\n    });\n\n    if (brushing && onBrushEnd) {\n      onBrushEnd(!isNulled ? this._convertAreaToCoordinates(brushArea) : null);\n    }\n\n    if (drag && onDragEnd) {\n      onDragEnd(!isNulled ? this._convertAreaToCoordinates(brushArea) : null);\n    }\n  }\n\n  onBrush(e) {\n    const {onBrush, onDrag, drag} = this.props;\n    const {brushing, dragging} = this.state;\n    const {xLoc, yLoc} = getLocs(e.nativeEvent);\n    if (brushing) {\n      const brushArea = this._getDrawArea(xLoc, yLoc);\n      this.setState({brushArea});\n\n      if (onBrush) {\n        onBrush(this._convertAreaToCoordinates(brushArea));\n      }\n    }\n\n    if (drag && dragging) {\n      const brushArea = this._getDragArea(xLoc, yLoc);\n      this.setState({brushArea});\n      if (onDrag) {\n        onDrag(this._convertAreaToCoordinates(brushArea));\n      }\n    }\n  }\n\n  render() {\n    const {\n      color,\n      className,\n      highlightHeight,\n      highlightWidth,\n      highlightX,\n      highlightY,\n      innerWidth,\n      innerHeight,\n      marginLeft,\n      marginRight,\n      marginTop,\n      marginBottom,\n      opacity\n    } = this.props;\n    const {\n      brushArea: {left, right, top, bottom}\n    } = this.state;\n\n    let leftPos = 0;\n    if (highlightX) {\n      const xScale = getAttributeScale(this.props, 'x');\n      leftPos = xScale(highlightX);\n    }\n\n    let topPos = 0;\n    if (highlightY) {\n      const yScale = getAttributeScale(this.props, 'y');\n      topPos = yScale(highlightY);\n    }\n\n    const plotWidth = marginLeft + marginRight + innerWidth;\n    const plotHeight = marginTop + marginBottom + innerHeight;\n    const touchWidth = highlightWidth || plotWidth;\n    const touchHeight = highlightHeight || plotHeight;\n\n    return (\n      <g\n        transform={`translate(${leftPos}, ${topPos})`}\n        className={getCombinedClassName(className, 'rv-highlight-container')}\n      >\n        <rect\n          className=\"rv-mouse-target\"\n          fill=\"black\"\n          opacity=\"0\"\n          x=\"0\"\n          y=\"0\"\n          width={Math.max(touchWidth, 0)}\n          height={Math.max(touchHeight, 0)}\n          onMouseDown={e => this.startBrushing(e)}\n          onMouseMove={e => this.onBrush(e)}\n          onMouseUp={e => this.stopBrushing(e)}\n          onMouseLeave={e => this.stopBrushing(e)}\n          // preventDefault() so that mouse event emulation does not happen\n          onTouchEnd={e => {\n            e.preventDefault();\n            this.stopBrushing(e);\n          }}\n          onTouchCancel={e => {\n            e.preventDefault();\n            this.stopBrushing(e);\n          }}\n          onContextMenu={e => e.preventDefault()}\n          onContextMenuCapture={e => e.preventDefault()}\n        />\n        <rect\n          className=\"rv-highlight\"\n          pointerEvents=\"none\"\n          opacity={opacity}\n          fill={color}\n          x={left}\n          y={top}\n          width={Math.min(Math.max(0, right - left), touchWidth)}\n          height={Math.min(Math.max(0, bottom - top), touchHeight)}\n        />\n      </g>\n    );\n  }\n}\n\nHighlight.displayName = 'HighlightOverlay';\nHighlight.defaultProps = {\n  color: 'rgb(77, 182, 172)',\n  className: '',\n  enableX: true,\n  enableY: true,\n  opacity: 0.3\n};\n\nHighlight.propTypes = {\n  ...AbstractSeries.propTypes,\n  enableX: PropTypes.bool,\n  enableY: PropTypes.bool,\n  highlightHeight: PropTypes.number,\n  highlightWidth: PropTypes.number,\n  highlightX: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n  highlightY: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n  onBrushStart: PropTypes.func,\n  onDragStart: PropTypes.func,\n  onBrush: PropTypes.func,\n  onDrag: PropTypes.func,\n  onBrushEnd: PropTypes.func,\n  onDragEnd: PropTypes.func\n};\n\nexport default Highlight;\n"
  },
  {
    "path": "packages/react-vis/src/plot/hint.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {PureComponent} from 'react';\nimport PropTypes from 'prop-types';\n\nimport {transformValueToString} from 'utils/data-utils';\nimport {getAttributeFunctor} from 'utils/scales-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\n/*\n * Hint provides two options for placement of hint:\n * a) around a data point in one of four quadrants (imagine the point bisected\n *    by two axes -vertical, horizontal- creating 4 quadrants around a data\n *    point).\n * b) **New** pin to an edge of chart/plot area and position along that edge\n *    using data point's other dimension value.\n *\n * To support these two options, deprecate one Hint props (orientation) with two\n * new Hint align prop object (horizontal, vertical) with following values:\n *\n *   horizontal: auto, left, right, leftEdge, rightEdge\n *   vertical: auto, bottom, top, bottomEdge, topEdge\n *\n * Thus, the following ALIGN constants are the values for horizontal\n * and vertical\n */\nconst ALIGN = {\n  AUTO: 'auto',\n  LEFT: 'left',\n  RIGHT: 'right',\n  LEFT_EDGE: 'leftEdge',\n  RIGHT_EDGE: 'rightEdge',\n  BOTTOM: 'bottom',\n  TOP: 'top',\n  BOTTOM_EDGE: 'bottomEdge',\n  TOP_EDGE: 'topEdge'\n};\n\n/**\n * For backwards support, retain the ORIENTATION prop constants\n */\nconst ORIENTATION = {\n  BOTTOM_LEFT: 'bottomleft',\n  BOTTOM_RIGHT: 'bottomright',\n  TOP_LEFT: 'topleft',\n  TOP_RIGHT: 'topright'\n};\n\n/**\n * Default format function for the value.\n * @param {Object} value Value.\n * @returns {Array} title-value pairs.\n */\nfunction defaultFormat(value) {\n  return Object.keys(value).map(function getProp(key) {\n    return {title: key, value: transformValueToString(value[key])};\n  });\n}\n\nclass Hint extends PureComponent {\n  static get defaultProps() {\n    return {\n      format: defaultFormat,\n      align: {\n        horizontal: ALIGN.AUTO,\n        vertical: ALIGN.AUTO\n      },\n      style: {}\n    };\n  }\n\n  static get propTypes() {\n    return {\n      marginTop: PropTypes.number,\n      marginLeft: PropTypes.number,\n      innerWidth: PropTypes.number,\n      innerHeight: PropTypes.number,\n      scales: PropTypes.object,\n      value: PropTypes.object,\n      format: PropTypes.func,\n      style: PropTypes.object,\n      className: PropTypes.string,\n      align: PropTypes.shape({\n        horizontal: PropTypes.oneOf([\n          ALIGN.AUTO,\n          ALIGN.LEFT,\n          ALIGN.RIGHT,\n          ALIGN.LEFT_EDGE,\n          ALIGN.RIGHT_EDGE\n        ]),\n        vertical: PropTypes.oneOf([\n          ALIGN.AUTO,\n          ALIGN.BOTTOM,\n          ALIGN.TOP,\n          ALIGN.BOTTOM_EDGE,\n          ALIGN.TOP_EDGE\n        ])\n      }),\n      getAlignStyle: PropTypes.func,\n      orientation: PropTypes.oneOf([\n        ORIENTATION.BOTTOM_LEFT,\n        ORIENTATION.BOTTOM_RIGHT,\n        ORIENTATION.TOP_LEFT,\n        ORIENTATION.TOP_RIGHT\n      ])\n    };\n  }\n\n  /**\n   * Obtain align object with horizontal and vertical settings\n   * but convert any AUTO values to the non-auto ALIGN depending on the\n   * values of x and y.\n   * @param {number} x X value.\n   * @param {number} y Y value.\n   * @returns {Object} Align object w/ horizontal, vertical prop strings.\n   * @private\n   */\n  _getAlign(x, y) {\n    const {\n      innerWidth,\n      innerHeight,\n      orientation,\n      align: {horizontal, vertical}\n    } = this.props;\n    const align = orientation\n      ? this._mapOrientationToAlign(orientation)\n      : {horizontal, vertical};\n    if (horizontal === ALIGN.AUTO) {\n      align.horizontal = x > innerWidth / 2 ? ALIGN.LEFT : ALIGN.RIGHT;\n    }\n    if (vertical === ALIGN.AUTO) {\n      align.vertical = y > innerHeight / 2 ? ALIGN.TOP : ALIGN.BOTTOM;\n    }\n    return align;\n  }\n\n  /**\n   * Get the class names from align values.\n   * @param {Object} align object with horizontal and vertical prop strings.\n   * @returns {string} Class names.\n   * @private\n   */\n  _getAlignClassNames(align) {\n    const {orientation} = this.props;\n    const orientationClass = orientation\n      ? `rv-hint--orientation-${orientation}`\n      : '';\n    return `${orientationClass} rv-hint--horizontalAlign-${align.horizontal}\n     rv-hint--verticalAlign-${align.vertical}`;\n  }\n\n  /**\n   * Get a CSS mixin for a proper positioning of the element.\n   * @param {Object} align object with horizontal and vertical prop strings.\n   * @param {number} x X position.\n   * @param {number} y Y position.\n   * @returns {Object} Object, that may contain `left` or `right, `top` or\n   * `bottom` properties.\n   * @private\n   */\n  _getAlignStyle(align, x, y) {\n    return {\n      ...this._getXCSS(align.horizontal, x),\n      ...this._getYCSS(align.vertical, y)\n    };\n  }\n\n  /**\n   * Get the bottom coordinate of the hint.\n   * When y undefined or null, edge case, pin bottom.\n   * @param {number} y Y.\n   * @returns {{bottom: *}} Mixin.\n   * @private\n   */\n  _getCSSBottom(y) {\n    if (y === undefined || y === null) {\n      return {\n        bottom: 0\n      };\n    }\n\n    const {innerHeight, marginBottom} = this.props;\n    return {\n      bottom: marginBottom + innerHeight - y\n    };\n  }\n\n  /**\n   * Get the left coordinate of the hint.\n   * When x undefined or null, edge case, pin left.\n   * @param {number} x X.\n   * @returns {{left: *}} Mixin.\n   * @private\n   */\n  _getCSSLeft(x) {\n    if (x === undefined || x === null) {\n      return {\n        left: 0\n      };\n    }\n\n    const {marginLeft} = this.props;\n    return {\n      left: marginLeft + x\n    };\n  }\n\n  /**\n   * Get the right coordinate of the hint.\n   * When x undefined or null, edge case, pin right.\n   * @param {number} x X.\n   * @returns {{right: *}} Mixin.\n   * @private\n   */\n  _getCSSRight(x) {\n    if (x === undefined || x === null) {\n      return {\n        right: 0\n      };\n    }\n\n    const {innerWidth, marginRight} = this.props;\n    return {\n      right: marginRight + innerWidth - x\n    };\n  }\n\n  /**\n   * Get the top coordinate of the hint.\n   * When y undefined or null, edge case, pin top.\n   * @param {number} y Y.\n   * @returns {{top: *}} Mixin.\n   * @private\n   */\n  _getCSSTop(y) {\n    if (y === undefined || y === null) {\n      return {\n        top: 0\n      };\n    }\n\n    const {marginTop} = this.props;\n    return {\n      top: marginTop + y\n    };\n  }\n\n  /**\n   * Get the position for the hint and the appropriate class name.\n   * @returns {{style: Object, positionClassName: string}} Style and className for the\n   * hint.\n   * @private\n   */\n  _getPositionInfo() {\n    const {value, getAlignStyle} = this.props;\n\n    const x = getAttributeFunctor(this.props, 'x')(value);\n    const y = getAttributeFunctor(this.props, 'y')(value);\n\n    const align = this._getAlign(x, y);\n\n    return {\n      position: getAlignStyle\n        ? getAlignStyle(align, x, y)\n        : this._getAlignStyle(align, x, y),\n      positionClassName: this._getAlignClassNames(align)\n    };\n  }\n\n  _getXCSS(horizontal, x) {\n    // obtain xCSS\n    switch (horizontal) {\n      case ALIGN.LEFT_EDGE:\n        // this pins x to left edge\n        return this._getCSSLeft(null);\n      case ALIGN.RIGHT_EDGE:\n        // this pins x to left edge\n        return this._getCSSRight(null);\n      case ALIGN.LEFT:\n        // this places hint text to the left of center, so set its right edge\n        return this._getCSSRight(x);\n      case ALIGN.RIGHT:\n      default:\n        // this places hint text to the right of center, so set its left edge\n        // default case should not be possible but if it happens set to RIGHT\n        return this._getCSSLeft(x);\n    }\n  }\n\n  _getYCSS(verticalAlign, y) {\n    // obtain yCSS\n    switch (verticalAlign) {\n      case ALIGN.TOP_EDGE:\n        // this pins x to top edge\n        return this._getCSSTop(null);\n      case ALIGN.BOTTOM_EDGE:\n        // this pins x to bottom edge\n        return this._getCSSBottom(null);\n      case ALIGN.BOTTOM:\n        // this places hint text to the bottom of center, so set its top edge\n        return this._getCSSTop(y);\n      case ALIGN.TOP:\n      default:\n        // this places hint text to the top of center, so set its bottom edge\n        // default case should not be possible but if it happens set to BOTTOM\n        return this._getCSSBottom(y);\n    }\n  }\n\n  _mapOrientationToAlign(orientation) {\n    // TODO: print warning that this feature is deprecated and support will be\n    // removed in next major release.\n    switch (orientation) {\n      case ORIENTATION.BOTTOM_LEFT:\n        return {\n          horizontal: ALIGN.LEFT,\n          vertical: ALIGN.BOTTOM\n        };\n      case ORIENTATION.BOTTOM_RIGHT:\n        return {\n          horizontal: ALIGN.RIGHT,\n          vertical: ALIGN.BOTTOM\n        };\n      case ORIENTATION.TOP_LEFT:\n        return {\n          horizontal: ALIGN.LEFT,\n          vertical: ALIGN.TOP\n        };\n      case ORIENTATION.TOP_RIGHT:\n        return {\n          horizontal: ALIGN.RIGHT,\n          vertical: ALIGN.TOP\n        };\n      default:\n        // fall back to horizontalAlign, verticalAlign that are either\n        // provided or defaulted to AUTO.  So, don't change things\n        break;\n    }\n  }\n\n  render() {\n    const {value, format, children, style, className} = this.props;\n\n    const {position, positionClassName} = this._getPositionInfo();\n    return (\n      <div\n        className={getCombinedClassName(\n          'rv-hint',\n          positionClassName,\n          className\n        )}\n        style={{\n          ...style,\n          ...position,\n          position: 'absolute'\n        }}\n      >\n        {children ? (\n          children\n        ) : (\n          <div className=\"rv-hint__content\" style={style.content}>\n            {format(value).map((formattedProp, i) => (\n              <div key={`rv-hint${i}`} style={style.row}>\n                <span className=\"rv-hint__title\" style={style.title}>\n                  {formattedProp.title}\n                </span>\n                {': '}\n                <span className=\"rv-hint__value\" style={style.value}>\n                  {formattedProp.value}\n                </span>\n              </div>\n            ))}\n          </div>\n        )}\n      </div>\n    );\n  }\n}\n\nHint.displayName = 'Hint';\nHint.ORIENTATION = ORIENTATION;\nHint.ALIGN = ALIGN;\n\nexport default Hint;\n"
  },
  {
    "path": "packages/react-vis/src/plot/horizontal-grid-lines.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport {DIRECTION} from 'utils/axis-utils';\nimport GridLines from 'plot/grid-lines';\n\nconst {HORIZONTAL} = DIRECTION;\n\nconst propTypes = {\n  ...GridLines.propTypes,\n  direction: PropTypes.oneOf([HORIZONTAL])\n};\n\nconst defaultProps = {\n  direction: HORIZONTAL,\n  attr: 'y'\n};\n\nfunction HorizontalGridLines(props) {\n  return <GridLines {...props} />;\n}\n\nHorizontalGridLines.displayName = 'HorizontalGridLines';\nHorizontalGridLines.propTypes = propTypes;\nHorizontalGridLines.defaultProps = defaultProps;\nHorizontalGridLines.requiresSVG = true;\n\nexport default HorizontalGridLines;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/abstract-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport PropTypes from 'prop-types';\nimport {voronoi} from 'd3-voronoi';\nimport {PureComponent} from 'react';\n\nimport {AnimationPropType} from 'animation';\nimport {\n  getAttributeFunctor,\n  getAttr0Functor,\n  getAttributeValue,\n  getScaleObjectFromProps,\n  getScalePropTypesByAttribute\n} from 'utils/scales-utils';\n\nconst propTypes = {\n  ...getScalePropTypesByAttribute('x'),\n  ...getScalePropTypesByAttribute('y'),\n  ...getScalePropTypesByAttribute('size'),\n  ...getScalePropTypesByAttribute('opacity'),\n  ...getScalePropTypesByAttribute('color'),\n  width: PropTypes.number,\n  height: PropTypes.number,\n  data: PropTypes.arrayOf(\n    PropTypes.oneOfType([PropTypes.object, PropTypes.array])\n  ),\n  onValueMouseOver: PropTypes.func,\n  onValueMouseOut: PropTypes.func,\n  onValueClick: PropTypes.func,\n  onValueRightClick: PropTypes.func,\n  onSeriesMouseOver: PropTypes.func,\n  onSeriesMouseOut: PropTypes.func,\n  onSeriesClick: PropTypes.func,\n  onSeriesRightClick: PropTypes.func,\n  onNearestX: PropTypes.func,\n  onNearestXY: PropTypes.func,\n  style: PropTypes.object,\n  animation: AnimationPropType,\n  stack: PropTypes.bool\n};\n\nconst defaultProps = {\n  className: '',\n  stack: false,\n  style: {}\n};\n\nclass AbstractSeries extends PureComponent {\n  /**\n   * Get a default config for the parent.\n   * @returns {Object} Empty config.\n   */\n  static getParentConfig() {\n    return {};\n  }\n\n  /**\n   * Tells the rest of the world that it requires SVG to work.\n   * @returns {boolean} Result.\n   */\n  static get requiresSVG() {\n    return true;\n  }\n\n  onParentMouseMove(event) {\n    const {onNearestX, onNearestXY, data} = this.props;\n    if ((!onNearestX && !onNearestXY) || !data) {\n      return;\n    }\n    if (onNearestXY) {\n      this._handleNearestXY(event);\n    } else {\n      this._handleNearestX(event);\n    }\n  }\n\n  onParentTouchMove(e) {\n    e.preventDefault();\n    this.onParentMouseMove(e);\n  }\n\n  onParentTouchStart(e) {\n    // prevent mouse event emulation\n    e.preventDefault();\n  }\n\n  /**\n   * Get the attr0 functor.\n   * @param {string} attr Attribute name.\n   * @returns {*} Functor.\n   * @private\n   */\n  _getAttr0Functor(attr) {\n    return getAttr0Functor(this.props, attr);\n  }\n\n  /**\n   * Get attribute functor.\n   * @param {string} attr Attribute name\n   * @returns {*} Functor.\n   * @protected\n   */\n  _getAttributeFunctor(attr) {\n    return getAttributeFunctor(this.props, attr);\n  }\n\n  /**\n   * Get the attribute value if it is available.\n   * @param {string} attr Attribute name.\n   * @returns {*} Attribute value if available, fallback value or undefined\n   * otherwise.\n   * @protected\n   */\n  _getAttributeValue(attr) {\n    return getAttributeValue(this.props, attr);\n  }\n\n  /**\n   * Get the scale object distance by the attribute from the list of properties.\n   * @param {string} attr Attribute name.\n   * @returns {number} Scale distance.\n   * @protected\n   */\n  _getScaleDistance(attr) {\n    const scaleObject = getScaleObjectFromProps(this.props, attr);\n    return scaleObject ? scaleObject.distance : 0;\n  }\n\n  _getXYCoordinateInContainer(event) {\n    const {marginTop = 0, marginLeft = 0} = this.props;\n    const {nativeEvent: evt, currentTarget} = event;\n    const rect = currentTarget.getBoundingClientRect();\n    let x = evt.clientX;\n    let y = evt.clientY;\n    if (evt.type === 'touchmove') {\n      x = evt.touches[0].pageX;\n      y = evt.touches[0].pageY;\n    }\n    return {\n      x: x - rect.left - currentTarget.clientLeft - marginLeft,\n      y: y - rect.top - currentTarget.clientTop - marginTop\n    };\n  }\n\n  _handleNearestX(event) {\n    const {onNearestX, data} = this.props;\n    let minDistance = Number.POSITIVE_INFINITY;\n    let value = null;\n    let valueIndex = null;\n\n    const coordinate = this._getXYCoordinateInContainer(event);\n    const xScaleFn = this._getAttributeFunctor('x');\n\n    data.forEach((item, i) => {\n      const currentCoordinate = xScaleFn(item);\n      const newDistance = Math.abs(coordinate.x - currentCoordinate);\n      if (newDistance < minDistance) {\n        minDistance = newDistance;\n        value = item;\n        valueIndex = i;\n      }\n    });\n    if (!value) {\n      return;\n    }\n    onNearestX(value, {\n      innerX: xScaleFn(value),\n      index: valueIndex,\n      event: event.nativeEvent\n    });\n  }\n\n  _handleNearestXY(event) {\n    const {onNearestXY, data} = this.props;\n\n    const coordinate = this._getXYCoordinateInContainer(event);\n    const xScaleFn = this._getAttributeFunctor('x');\n    const yScaleFn = this._getAttributeFunctor('y');\n\n    // Create a voronoi with each node center points\n    const voronoiInstance = voronoi()\n      .x(xScaleFn)\n      .y(yScaleFn);\n\n    const foundPoint = voronoiInstance(data).find(coordinate.x, coordinate.y);\n    const value = foundPoint.data;\n\n    if (!value) {\n      return;\n    }\n    onNearestXY(value, {\n      innerX: foundPoint[0],\n      innerY: foundPoint[1],\n      index: foundPoint.index,\n      event: event.nativeEvent\n    });\n  }\n\n  /**\n   * Click handler for the entire series.\n   * @param {Object} event Event.\n   * @protected\n   */\n  _seriesClickHandler = event => {\n    const {onSeriesClick} = this.props;\n    if (onSeriesClick) {\n      onSeriesClick({event});\n    }\n  };\n\n  /**\n   * Mouse out handler for the entire series.\n   * @param {Object} event Event.\n   * @protected\n   */\n  _seriesMouseOutHandler = event => {\n    const {onSeriesMouseOut} = this.props;\n    if (onSeriesMouseOut) {\n      onSeriesMouseOut({event});\n    }\n  };\n\n  /**\n   * Mouse over handler for the entire series.\n   * @param {Object} event Event.\n   * @protected\n   */\n  _seriesMouseOverHandler = event => {\n    const {onSeriesMouseOver} = this.props;\n    if (onSeriesMouseOver) {\n      onSeriesMouseOver({event});\n    }\n  };\n\n  /**\n   * Right Click handler for the entire series.\n   * @param {Object} event Event.\n   * @protected\n   */\n  _seriesRightClickHandler = event => {\n    const {onSeriesRightClick} = this.props;\n    if (onSeriesRightClick) {\n      onSeriesRightClick({event});\n    }\n  };\n\n  /**\n   * Click handler for the specific series' value.\n   * @param {Object} d Value object\n   * @param {Object} event Event.\n   * @protected\n   */\n  _valueClickHandler = (d, event) => {\n    const {onValueClick, onSeriesClick} = this.props;\n    if (onValueClick) {\n      onValueClick(d, {event});\n    }\n    if (onSeriesClick) {\n      onSeriesClick({event});\n    }\n  };\n\n  /**\n   * Mouse out handler for the specific series' value.\n   * @param {Object} d Value object\n   * @param {Object} event Event.\n   * @protected\n   */\n  _valueMouseOutHandler = (d, event) => {\n    const {onValueMouseOut, onSeriesMouseOut} = this.props;\n    if (onValueMouseOut) {\n      onValueMouseOut(d, {event});\n    }\n    if (onSeriesMouseOut) {\n      onSeriesMouseOut({event});\n    }\n  };\n\n  /**\n   * Mouse over handler for the specific series' value.\n   * @param {Object} d Value object\n   * @param {Object} event Event.\n   * @protected\n   */\n  _valueMouseOverHandler = (d, event) => {\n    const {onValueMouseOver, onSeriesMouseOver} = this.props;\n    if (onValueMouseOver) {\n      onValueMouseOver(d, {event});\n    }\n    if (onSeriesMouseOver) {\n      onSeriesMouseOver({event});\n    }\n  };\n\n  /**\n   * Right Click handler for the specific series' value.\n   * @param {Object} d Value object\n   * @param {Object} event Event.\n   * @protected\n   */\n  _valueRightClickHandler = (d, event) => {\n    const {onValueRightClick, onSeriesRightClick} = this.props;\n    if (onValueRightClick) {\n      onValueRightClick(d, {event});\n    }\n    if (onSeriesRightClick) {\n      onSeriesRightClick({event});\n    }\n  };\n}\n\nAbstractSeries.displayName = 'AbstractSeries';\nAbstractSeries.propTypes = propTypes;\nAbstractSeries.defaultProps = defaultProps;\n\nexport default AbstractSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/arc-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport Animation from 'animation';\nimport {arc as arcBuilder} from 'd3-shape';\n\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport AbstractSeries from './abstract-series';\nimport {\n  getAttributeFunctor,\n  getAttr0Functor,\n  extractScalePropsFromProps,\n  getMissingScaleProps,\n  getScalePropTypesByAttribute\n} from 'utils/scales-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--arc';\nconst ATTRIBUTES = ['radius', 'angle'];\n\nconst defaultProps = {\n  ...AbstractSeries.defaultProps,\n  center: {x: 0, y: 0},\n  arcClassName: '',\n  className: '',\n  style: {},\n  padAngle: 0\n};\n\n/**\n * Prepare the internal representation of row for real use.\n * This is necessary because d3 insists on starting at 12 oclock and moving\n * clockwise, rather than starting at 3 oclock and moving counter clockwise\n * as one might expect from polar\n * @param {Object} row - coordinate object to be modifed\n * @return {Object} angle corrected object\n */\nfunction modifyRow(row) {\n  const {radius, angle, angle0} = row;\n  const truedAngle = -1 * angle + Math.PI / 2;\n  const truedAngle0 = -1 * angle0 + Math.PI / 2;\n  return {\n    ...row,\n    x: radius * Math.cos(truedAngle),\n    y: radius * Math.sin(truedAngle),\n    angle: truedAngle,\n    angle0: truedAngle0\n  };\n}\n\nclass ArcSeries extends AbstractSeries {\n  constructor(props) {\n    super(props);\n    const scaleProps = this._getAllScaleProps(props);\n    this.state = {scaleProps};\n  }\n\n  UNSAFE_componentWillReceiveProps(nextProps) {\n    this.setState({scaleProps: this._getAllScaleProps(nextProps)});\n  }\n\n  /**\n   * Get the map of scales from the props.\n   * @param {Object} props Props.\n   * @param {Array} data Array of all data.\n   * @returns {Object} Map of scales.\n   * @private\n   */\n  _getAllScaleProps(props) {\n    const defaultScaleProps = this._getDefaultScaleProps(props);\n    const userScaleProps = extractScalePropsFromProps(props, ATTRIBUTES);\n    const missingScaleProps = getMissingScaleProps(\n      {\n        ...defaultScaleProps,\n        ...userScaleProps\n      },\n      props.data,\n      ATTRIBUTES\n    );\n\n    return {\n      ...defaultScaleProps,\n      ...userScaleProps,\n      ...missingScaleProps\n    };\n  }\n\n  /**\n   * Get the list of scale-related settings that should be applied by default.\n   * @param {Object} props Object of props.\n   * @returns {Object} Defaults.\n   * @private\n   */\n  _getDefaultScaleProps(props) {\n    const {innerWidth, innerHeight} = props;\n    const radius = Math.min(innerWidth / 2, innerHeight / 2);\n    return {\n      radiusRange: [0, radius],\n      _radiusValue: radius,\n      angleType: 'literal'\n    };\n  }\n\n  render() {\n    const {\n      arcClassName,\n      animation,\n      className,\n      center,\n      data,\n      disableSeries,\n      hideSeries,\n      marginLeft,\n      marginTop,\n      padAngle,\n      style\n    } = this.props;\n\n    if (!data) {\n      return null;\n    }\n\n    if (animation) {\n      const cloneData = data.map(d => ({...d}));\n      return (\n        <g className=\"rv-xy-plot__series--arc__animation-wrapper\">\n          <Animation\n            {...this.props}\n            animatedProps={ANIMATED_SERIES_PROPS}\n            data={cloneData}\n          >\n            <ArcSeries\n              {...this.props}\n              animation={null}\n              disableSeries={true}\n              data={cloneData}\n            />\n          </Animation>\n          <ArcSeries\n            {...this.props}\n            animation={null}\n            hideSeries\n            style={{stroke: 'red'}}\n          />\n        </g>\n      );\n    }\n\n    const {scaleProps} = this.state;\n    const {radiusDomain} = scaleProps;\n    // need to generate our own functors as abstract series doesnt have anythign for us\n    const radius = getAttributeFunctor(scaleProps, 'radius');\n    const radius0 = getAttr0Functor(scaleProps, 'radius');\n    const angle = getAttributeFunctor(scaleProps, 'angle');\n    const angle0 = getAttr0Functor(scaleProps, 'angle');\n    // but it does have good color support!\n    const fill =\n      this._getAttributeFunctor('fill') || this._getAttributeFunctor('color');\n    const stroke =\n      this._getAttributeFunctor('stroke') || this._getAttributeFunctor('color');\n    const opacity = this._getAttributeFunctor('opacity');\n    const x = this._getAttributeFunctor('x');\n    const y = this._getAttributeFunctor('y');\n\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        onMouseOver={this._seriesMouseOverHandler}\n        onMouseOut={this._seriesMouseOutHandler}\n        onClick={this._seriesClickHandler}\n        onContextMenu={this._seriesRightClickHandler}\n        opacity={hideSeries ? 0 : 1}\n        pointerEvents={disableSeries ? 'none' : 'all'}\n        transform={`translate(${marginLeft + x(center)},${marginTop +\n          y(center)})`}\n      >\n        {data.map((row, i) => {\n          const noRadius = radiusDomain[1] === radiusDomain[0];\n          const arcArg = {\n            innerRadius: noRadius ? 0 : radius0(row),\n            outerRadius: radius(row),\n            startAngle: angle0(row) || 0,\n            endAngle: angle(row)\n          };\n          const arcedData = arcBuilder().padAngle(padAngle);\n          const rowStyle = row.style || {};\n          const rowClassName = row.className || '';\n          return (\n            <path\n              key={`path-${i}`}\n              style={{\n                opacity: opacity && opacity(row),\n                stroke: stroke && stroke(row),\n                fill: fill && fill(row),\n                ...style,\n                ...rowStyle\n              }}\n              onClick={e => this._valueClickHandler(modifyRow(row), e)}\n              onContextMenu={e =>\n                this._valueRightClickHandler(modifyRow(row), e)\n              }\n              onMouseOver={e => this._valueMouseOverHandler(modifyRow(row), e)}\n              onMouseOut={e => this._valueMouseOutHandler(modifyRow(row), e)}\n              className={`${predefinedClassName}-path ${arcClassName} ${rowClassName}`}\n              d={arcedData(arcArg)}\n            />\n          );\n        })}\n      </g>\n    );\n  }\n}\nArcSeries.propTypes = {\n  ...AbstractSeries.propTypes,\n  ...getScalePropTypesByAttribute('radius'),\n  ...getScalePropTypesByAttribute('angle'),\n  center: PropTypes.shape({\n    x: PropTypes.number,\n    y: PropTypes.number\n  }),\n  arcClassName: PropTypes.string,\n  padAngle: PropTypes.oneOfType([PropTypes.func, PropTypes.number])\n};\nArcSeries.defaultProps = defaultProps;\nArcSeries.displayName = 'ArcSeries';\n\nexport default ArcSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/area-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport * as d3Shape from 'd3-shape';\n\nimport Animation from 'animation';\nimport {DEFAULT_OPACITY} from 'theme';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {warning} from 'utils/react-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nimport AbstractSeries from './abstract-series';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--line';\n\nclass AreaSeries extends AbstractSeries {\n  _renderArea(data, x, y0, y, curve, getNull) {\n    let area = d3Shape.area();\n    if (curve !== null) {\n      if (typeof curve === 'string' && d3Shape[curve]) {\n        area = area.curve(d3Shape[curve]);\n      } else if (typeof curve === 'function') {\n        area = area.curve(curve);\n      }\n    }\n    area = area.defined(getNull);\n    area = area\n      .x(x)\n      .y0(y0)\n      .y1(y);\n    return area(data);\n  }\n\n  render() {\n    const {\n      animation,\n      className,\n      curve,\n      data,\n      marginLeft,\n      marginTop,\n      style\n    } = this.props;\n\n    if (this.props.nullAccessor) {\n      warning('nullAccessor has been renamed to getNull', true);\n    }\n\n    if (!data) {\n      return null;\n    }\n\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <AreaSeries {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const x = this._getAttributeFunctor('x');\n    const y = this._getAttributeFunctor('y');\n    const y0 = this._getAttr0Functor('y');\n    const stroke =\n      this._getAttributeValue('stroke') || this._getAttributeValue('color');\n    const fill =\n      this._getAttributeValue('fill') || this._getAttributeValue('color');\n    const newOpacity = this._getAttributeValue('opacity');\n    const opacity = Number.isFinite(newOpacity) ? newOpacity : DEFAULT_OPACITY;\n    const getNull = this.props.nullAccessor || this.props.getNull;\n    const d = this._renderArea(data, x, y0, y, curve, getNull);\n\n    return (\n      <path\n        d={d}\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n        onMouseOver={this._seriesMouseOverHandler}\n        onMouseOut={this._seriesMouseOutHandler}\n        onClick={this._seriesClickHandler}\n        onContextMenu={this._seriesRightClickHandler}\n        style={{\n          opacity,\n          stroke,\n          fill,\n          ...style\n        }}\n      />\n    );\n  }\n}\n\nAreaSeries.displayName = 'AreaSeries';\nAreaSeries.propTypes = {\n  ...AbstractSeries.propTypes,\n  getNull: PropTypes.func\n};\nAreaSeries.defaultProps = {\n  ...AbstractSeries.defaultProps,\n  getNull: () => true\n};\n\nexport default AreaSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/bar-series-canvas.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nimport PropTypes from 'prop-types';\nimport {rgb} from 'd3-color';\n\nimport {DEFAULT_OPACITY} from 'theme';\nimport {\n  getAttributeFunctor,\n  getScaleObjectFromProps,\n  getAttr0Functor\n} from 'utils/scales-utils';\nimport {getStackParams} from 'utils/series-utils';\nimport AbstractSeries from './abstract-series';\n\nfunction getScaleDistance(props, attr) {\n  const scaleObject = getScaleObjectFromProps(props, attr);\n  return scaleObject ? scaleObject.distance : 0;\n}\n\nclass BarSeriesCanvas extends AbstractSeries {\n  static get requiresSVG() {\n    return false;\n  }\n\n  static get isCanvas() {\n    return true;\n  }\n\n  static renderLayer(props, ctx) {\n    const {\n      data,\n      linePosAttr,\n      lineSizeAttr,\n      valuePosAttr,\n      marginTop,\n      marginBottom\n    } = props;\n    if (!data || data.length === 0) {\n      return;\n    }\n\n    const distance = getScaleDistance(props, linePosAttr);\n    const line = getAttributeFunctor(props, linePosAttr);\n    const value = getAttributeFunctor(props, valuePosAttr);\n    const value0 = getAttr0Functor(props, valuePosAttr);\n    const fill =\n      getAttributeFunctor(props, 'fill') || getAttributeFunctor(props, 'color');\n    const stroke =\n      getAttributeFunctor(props, 'stroke') ||\n      getAttributeFunctor(props, 'color');\n    const opacity = getAttributeFunctor(props, 'opacity');\n\n    const halfSpace = (distance / 2) * 0.85;\n    // totalSpaceAvailable is the space we have available to draw all the\n    // bars of a same 'linePosAttr' value (a.k.a. sameTypeTotal)\n    const totalSpaceAvailable = halfSpace * 2;\n\n    const {sameTypeTotal, sameTypeIndex} = getStackParams(props);\n    data.forEach(row => {\n      const totalSpaceCenter = line(row);\n      // totalSpaceStartingPoint is the first pixel were we can start drawing\n      const totalSpaceStartingPoint = totalSpaceCenter - halfSpace;\n\n      // spaceTakenByInterBarsPixels has the overhead space consumed by each bar of sameTypeTotal\n      const spaceTakenByInterBarsPixels = (sameTypeTotal - 1) / sameTypeTotal;\n      // lineSize is the space we have available to draw sameTypeIndex bar\n      const lineSize =\n        totalSpaceAvailable / sameTypeTotal - spaceTakenByInterBarsPixels;\n\n      const fillColor = rgb(fill(row));\n      const strokeColor = rgb(stroke(row));\n      const rowOpacity = opacity(row) || DEFAULT_OPACITY;\n\n      // linePos is the first pixel were we can start drawing sameTypeIndex bar\n      const linePos =\n        totalSpaceStartingPoint + lineSize * sameTypeIndex + sameTypeIndex;\n      const valuePos = Math.min(value0(row), value(row));\n      const x = valuePosAttr === 'x' ? valuePos : linePos;\n      const y = valuePosAttr === 'y' ? valuePos : linePos;\n\n      const valueSize = Math.abs(-value0(row) + value(row));\n      const height = lineSizeAttr === 'height' ? lineSize : valueSize;\n      const width = lineSizeAttr === 'width' ? lineSize : valueSize;\n\n      ctx.beginPath();\n      ctx.rect(x + marginBottom, y + marginTop, width, height);\n      ctx.fillStyle = `rgba(${fillColor.r}, ${fillColor.g}, ${fillColor.b}, ${rowOpacity})`;\n      ctx.fill();\n      ctx.strokeStyle = `rgba(${strokeColor.r}, ${strokeColor.g}, ${strokeColor.b}, ${rowOpacity})`;\n      ctx.stroke();\n    });\n  }\n\n  render() {\n    return null;\n  }\n}\n\nBarSeriesCanvas.displayName = 'BarSeriesCanvas';\nBarSeriesCanvas.defaultProps = {\n  ...AbstractSeries.defaultProps,\n  linePosAttr: PropTypes.string.isRequired,\n  valuePosAttr: PropTypes.string.isRequired,\n  lineSizeAttr: PropTypes.string.isRequired,\n  valueSizeAttr: PropTypes.string.isRequired\n};\n\nBarSeriesCanvas.propTypes = {\n  ...AbstractSeries.propTypes\n};\n\nexport default BarSeriesCanvas;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/bar-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport Animation from 'animation';\nimport {ANIMATED_SERIES_PROPS, getStackParams} from 'utils/series-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nimport AbstractSeries from './abstract-series';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--bar';\n\nclass BarSeries extends AbstractSeries {\n  static get propTypes() {\n    return {\n      ...AbstractSeries.propTypes,\n      linePosAttr: PropTypes.string,\n      valuePosAttr: PropTypes.string,\n      lineSizeAttr: PropTypes.string,\n      valueSizeAttr: PropTypes.string,\n      cluster: PropTypes.string,\n      barWidth: PropTypes.number\n    };\n  }\n\n  static get defaultProps() {\n    return {\n      barWidth: 0.85\n    };\n  }\n\n  render() {\n    const {\n      animation,\n      className,\n      data,\n      linePosAttr,\n      lineSizeAttr,\n      marginLeft,\n      marginTop,\n      style,\n      valuePosAttr,\n      valueSizeAttr,\n      barWidth\n    } = this.props;\n\n    if (!data) {\n      return null;\n    }\n\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <BarSeries {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const {sameTypeTotal, sameTypeIndex} = getStackParams(this.props);\n\n    const distance = this._getScaleDistance(linePosAttr);\n    const lineFunctor = this._getAttributeFunctor(linePosAttr);\n    const valueFunctor = this._getAttributeFunctor(valuePosAttr);\n    const value0Functor = this._getAttr0Functor(valuePosAttr);\n    const fillFunctor =\n      this._getAttributeFunctor('fill') || this._getAttributeFunctor('color');\n    const strokeFunctor =\n      this._getAttributeFunctor('stroke') || this._getAttributeFunctor('color');\n    const opacityFunctor = this._getAttributeFunctor('opacity');\n\n    const halfSpace = (distance / 2) * barWidth;\n\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n      >\n        {data.map((d, i) => {\n          // totalSpaceAvailable is the space we have available to draw all the\n          // bars of a same 'linePosAttr' value (a.k.a. sameTypeTotal)\n          const totalSpaceAvailable = halfSpace * 2;\n          const totalSpaceCenter = lineFunctor(d);\n          // totalSpaceStartingPoint is the first pixel were we can start drawing\n          const totalSpaceStartingPoint = totalSpaceCenter - halfSpace;\n          // spaceTakenByInterBarsPixels has the overhead space consumed by each bar of sameTypeTotal\n          const spaceTakenByInterBarsPixels =\n            (sameTypeTotal - 1) / sameTypeTotal;\n          // spacePerBar is the space we have available to draw sameTypeIndex bar\n          const spacePerBar =\n            totalSpaceAvailable / sameTypeTotal - spaceTakenByInterBarsPixels;\n          // barStartingPoint is the first pixel were we can start drawing sameTypeIndex bar\n          const barStartingPoint =\n            totalSpaceStartingPoint +\n            spacePerBar * sameTypeIndex +\n            sameTypeIndex;\n\n          const attrs = {\n            style: {\n              opacity: opacityFunctor && opacityFunctor(d),\n              stroke: strokeFunctor && strokeFunctor(d),\n              fill: fillFunctor && fillFunctor(d),\n              ...style\n            },\n            [linePosAttr]: barStartingPoint,\n            [lineSizeAttr]: spacePerBar,\n            [valuePosAttr]: Math.min(value0Functor(d), valueFunctor(d)),\n            [valueSizeAttr]: Math.abs(-value0Functor(d) + valueFunctor(d)),\n            onClick: e => this._valueClickHandler(d, e),\n            onContextMenu: e => this._valueRightClickHandler(d, e),\n            onMouseOver: e => this._valueMouseOverHandler(d, e),\n            onMouseOut: e => this._valueMouseOutHandler(d, e)\n          };\n          return <rect key={`${i}`} {...attrs} />;\n        })}\n      </g>\n    );\n  }\n}\n\nBarSeries.displayName = 'BarSeries';\n\nexport default BarSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/canvas-wrapper.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\nimport PropTypes from 'prop-types';\n\nimport {interpolate} from 'd3-interpolate';\nimport {extractAnimatedPropValues} from 'animation';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\n\nconst MAX_DRAWS = 30;\n\n/**\n * Draw loop draws each of the layers until it should draw more\n * @param {CanvasContext} ctx - the context where the drawing will take place\n * @param {Number} height - height of the canvas\n * @param {Number} width - width of the canvas\n * @param {Array} layers - the layer objects to render\n */\nfunction engageDrawLoop(ctx, height, width, layers) {\n  let drawIteration = 0;\n  // using setInterval because request animation frame goes too fast\n  const drawCycle = setInterval(() => {\n    if (!ctx) {\n      clearInterval(drawCycle);\n      return;\n    }\n    drawLayers(ctx, height, width, layers, drawIteration);\n    if (drawIteration > MAX_DRAWS) {\n      clearInterval(drawCycle);\n    }\n    drawIteration += 1;\n  }, 1);\n}\n\n/**\n * Loops across each of the layers to be drawn and draws them\n * @param {CanvasContext} ctx - the context where the drawing will take place\n * @param {Number} height - height of the canvas\n * @param {Number} width - width of the canvas\n * @param {Array} layers - the layer objects to render\n * @param {Number} drawIteration - width of the canvas\n */\nfunction drawLayers(ctx, height, width, layers, drawIteration) {\n  ctx.clearRect(0, 0, width, height);\n  layers.forEach(layer => {\n    const {interpolator, newProps, animation} = layer;\n    // return an empty object if dont need to be animating\n    const interpolatedProps = animation\n      ? interpolator\n        ? interpolator(drawIteration / MAX_DRAWS)\n        : interpolator\n      : () => ({});\n    layer.renderLayer(\n      {\n        ...newProps,\n        ...interpolatedProps\n      },\n      ctx\n    );\n  });\n}\n\n/**\n * Build an array of layer of objects the contain the method for drawing each series\n * as well as an interpolar (specifically a d3-interpolate interpolator)\n * @param {Object} newChildren the new children to be rendered.\n * @param {Object} oldChildren the old children to be rendered.\n * @returns {Array} Object for rendering\n */\nfunction buildLayers(newChildren, oldChildren) {\n  return newChildren.map((child, index) => {\n    const oldProps = oldChildren[index] ? oldChildren[index].props : {};\n    const newProps = child.props;\n\n    const oldAnimatedProps = extractAnimatedPropValues({\n      ...oldProps,\n      animatedProps: ANIMATED_SERIES_PROPS\n    });\n    const newAnimatedProps = newProps\n      ? extractAnimatedPropValues({\n          ...newProps,\n          animatedProps: ANIMATED_SERIES_PROPS\n        })\n      : null;\n    const interpolator = interpolate(oldAnimatedProps, newAnimatedProps);\n\n    return {\n      renderLayer: child.type.renderLayer,\n      newProps: child.props,\n      animation: child.props.animation,\n      interpolator\n    };\n  });\n}\nclass CanvasWrapper extends Component {\n  static get defaultProps() {\n    return {\n      pixelRatio: (window && window.devicePixelRatio) || 1\n    };\n  }\n\n  componentDidMount() {\n    const ctx = this.canvas.getContext('2d');\n    if (!ctx) {\n      return;\n    }\n    const {pixelRatio} = this.props;\n    if (!ctx) {\n      return;\n    }\n    ctx.scale(pixelRatio, pixelRatio);\n\n    this.drawChildren(null, this.props, ctx);\n  }\n\n  componentDidUpdate(oldProps) {\n    this.drawChildren(oldProps, this.props, this.canvas.getContext('2d'));\n  }\n\n  /**\n   * Check that we can and should be animating, then kick off animations as apporpriate\n   * @param {Object} newProps the new props to be interpolated to\n   * @param {Object} oldProps the old props to be interpolated against\n   * @param {DomRef} ctx the canvas context to be drawn on.\n   * @returns {Array} Object for rendering\n   */\n  drawChildren(oldProps, newProps, ctx) {\n    const {\n      children,\n      innerHeight,\n      innerWidth,\n      marginBottom,\n      marginLeft,\n      marginRight,\n      marginTop\n    } = newProps;\n    if (!ctx) {\n      return;\n    }\n\n    const childrenShouldAnimate = children.find(child => child.props.animation);\n\n    const height = innerHeight + marginTop + marginBottom;\n    const width = innerWidth + marginLeft + marginRight;\n    const layers = buildLayers(\n      newProps.children,\n      oldProps ? oldProps.children : []\n    );\n    // if we don't need to be animating, dont! cut short\n    if (!childrenShouldAnimate) {\n      drawLayers(ctx, height, width, layers);\n      return;\n    }\n\n    engageDrawLoop(ctx, height, width, layers);\n  }\n\n  render() {\n    const {\n      innerHeight,\n      innerWidth,\n      marginBottom,\n      marginLeft,\n      marginRight,\n      marginTop,\n      pixelRatio\n    } = this.props;\n\n    const height = innerHeight + marginTop + marginBottom;\n    const width = innerWidth + marginLeft + marginRight;\n\n    return (\n      <div style={{left: 0, top: 0}} className=\"rv-xy-canvas\">\n        <canvas\n          className=\"rv-xy-canvas-element\"\n          height={height * pixelRatio}\n          width={width * pixelRatio}\n          style={{\n            height: `${height}px`,\n            width: `${width}px`\n          }}\n          ref={ref => (this.canvas = ref)}\n        />\n        {this.props.children}\n      </div>\n    );\n  }\n}\n\nCanvasWrapper.displayName = 'CanvasWrapper';\nCanvasWrapper.propTypes = {\n  marginBottom: PropTypes.number.isRequired,\n  marginLeft: PropTypes.number.isRequired,\n  marginRight: PropTypes.number.isRequired,\n  marginTop: PropTypes.number.isRequired,\n  innerHeight: PropTypes.number.isRequired,\n  innerWidth: PropTypes.number.isRequired,\n  pixelRatio: PropTypes.number.isRequired\n};\n\nexport default CanvasWrapper;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/contour-series.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport {contourDensity} from 'd3-contour';\nimport {geoPath} from 'd3-geo';\nimport {scaleLinear} from 'd3-scale';\n\nimport AbstractSeries from './abstract-series';\nimport Animation from 'animation';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\nimport {CONTINUOUS_COLOR_RANGE} from 'theme';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--contour';\n\nfunction getDomain(data) {\n  return data.reduce(\n    (acc, row) => {\n      return {\n        min: Math.min(acc.min, row.value),\n        max: Math.max(acc.max, row.value)\n      };\n    },\n    {min: Infinity, max: -Infinity}\n  );\n}\n\nclass ContourSeries extends AbstractSeries {\n  render() {\n    const {\n      animation,\n      bandwidth,\n      className,\n      colorRange,\n      data,\n      innerHeight,\n      innerWidth,\n      marginLeft,\n      marginTop,\n      style\n    } = this.props;\n\n    if (!data || !innerWidth || !innerHeight) {\n      return null;\n    }\n\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <ContourSeries {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const x = this._getAttributeFunctor('x');\n    const y = this._getAttributeFunctor('y');\n\n    const contouredData = contourDensity()\n      .x(d => x(d))\n      .y(d => y(d))\n      .size([innerWidth, innerHeight])\n      .bandwidth(bandwidth)(data);\n\n    const geo = geoPath();\n    const {min, max} = getDomain(contouredData);\n    const colorScale = scaleLinear()\n      .domain([min, max])\n      .range(colorRange || CONTINUOUS_COLOR_RANGE);\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n      >\n        {contouredData.map((polygon, index) => {\n          return (\n            <path\n              className=\"rv-xy-plot__series--contour-line\"\n              key={`rv-xy-plot__series--contour-line-${index}`}\n              d={geo(polygon)}\n              style={{\n                fill: colorScale(polygon.value),\n                ...style\n              }}\n            />\n          );\n        })}\n      </g>\n    );\n  }\n}\n\nContourSeries.propTypes = {\n  ...AbstractSeries.propTypes,\n  animation: PropTypes.bool,\n  bandwidth: PropTypes.number,\n  className: PropTypes.string,\n  marginLeft: PropTypes.number,\n  marginTop: PropTypes.number,\n  style: PropTypes.object\n};\n\nContourSeries.defaultProps = {\n  ...AbstractSeries.defaultProps,\n  bandwidth: 40,\n  style: {}\n};\n\nexport default ContourSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/custom-svg-series.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport AbstractSeries from './abstract-series';\nimport Animation from 'animation';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst predefinedClassName =\n  'rv-xy-plot__series rv-xy-plot__series--custom-svg-wrapper';\n\nconst DEFAULT_STYLE = {\n  stroke: 'blue',\n  fill: 'blue'\n};\n\nfunction predefinedComponents(type, size = 2, style = DEFAULT_STYLE) {\n  switch (type) {\n    case 'diamond':\n      return (\n        <polygon\n          style={style}\n          points={`0 0 ${size / 2} ${size / 2} 0 ${size} ${-size / 2} ${size /\n            2} 0 0`}\n        />\n      );\n    case 'star': {\n      const starPoints = [...new Array(5)]\n        .map((c, index) => {\n          const angle = (index / 5) * Math.PI * 2;\n          const innerAngle = angle + Math.PI / 10;\n          const outerAngle = angle - Math.PI / 10;\n          // ratio of inner polygon to outer polgyon\n          const innerRadius = size / 2.61;\n          return `\n        ${Math.cos(outerAngle) * size} ${Math.sin(outerAngle) * size}\n        ${Math.cos(innerAngle) * innerRadius} ${Math.sin(innerAngle) *\n            innerRadius}\n      `;\n        })\n        .join(' ');\n      return (\n        <polygon\n          points={starPoints}\n          x=\"0\"\n          y=\"0\"\n          height={size}\n          width={size}\n          style={style}\n        />\n      );\n    }\n    case 'square':\n      return (\n        <rect\n          x={`${-size / 2}`}\n          y={`${-size / 2}`}\n          height={size}\n          width={size}\n          style={style}\n        />\n      );\n    default:\n    case 'circle':\n      return <circle cx=\"0\" cy=\"0\" r={size / 2} style={style} />;\n  }\n}\n\nfunction getInnerComponent({\n  customComponent,\n  defaultType,\n  positionInPixels,\n  positionFunctions,\n  style,\n  propsSize\n}) {\n  const {size} = customComponent;\n  const aggStyle = {...style, ...(customComponent.style || {})};\n  const innerComponent = customComponent.customComponent;\n  if (!innerComponent && typeof defaultType === 'string') {\n    return predefinedComponents(defaultType, size || propsSize, aggStyle);\n  }\n  // if default component is a function\n  if (!innerComponent) {\n    return defaultType(\n      customComponent,\n      positionInPixels,\n      aggStyle,\n      positionFunctions\n    );\n  }\n  if (typeof innerComponent === 'string') {\n    return predefinedComponents(innerComponent || defaultType, size, aggStyle);\n  }\n  // if inner component is a function\n  return innerComponent(\n    customComponent,\n    positionInPixels,\n    aggStyle,\n    positionFunctions\n  );\n}\n\nclass CustomSVGSeries extends AbstractSeries {\n  render() {\n    const {\n      animation,\n      className,\n      customComponent,\n      data,\n      innerHeight,\n      innerWidth,\n      marginLeft,\n      marginTop,\n      style,\n      size\n    } = this.props;\n\n    if (!data || !innerWidth || !innerHeight) {\n      return null;\n    }\n\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <CustomSVGSeries {...this.props} animation={false} />\n        </Animation>\n      );\n    }\n\n    const x = this._getAttributeFunctor('x');\n    const y = this._getAttributeFunctor('y');\n    const contents = data.map((seriesComponent, index) => {\n      const positionInPixels = {\n        x: x(seriesComponent),\n        y: y(seriesComponent)\n      };\n      const innerComponent = getInnerComponent({\n        customComponent: seriesComponent,\n        positionInPixels,\n        defaultType: customComponent,\n        positionFunctions: {x, y},\n        style,\n        propsSize: size\n      });\n      return (\n        <g\n          className=\"rv-xy-plot__series--custom-svg\"\n          key={`rv-xy-plot__series--custom-svg-${index}`}\n          transform={`translate(${positionInPixels.x},${positionInPixels.y})`}\n          onMouseEnter={e => this._valueMouseOverHandler(seriesComponent, e)}\n          onMouseLeave={e => this._valueMouseOutHandler(seriesComponent, e)}\n        >\n          {innerComponent}\n        </g>\n      );\n    });\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n      >\n        {contents}\n      </g>\n    );\n  }\n}\n\nCustomSVGSeries.propTypes = {\n  animation: PropTypes.bool,\n  className: PropTypes.string,\n  customComponent: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),\n  data: PropTypes.arrayOf(\n    PropTypes.shape({\n      x: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,\n      y: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired\n    })\n  ).isRequired,\n  marginLeft: PropTypes.number,\n  marginTop: PropTypes.number,\n  style: PropTypes.object,\n  size: PropTypes.number,\n  onValueMouseOver: PropTypes.func,\n  onValueMouseOut: PropTypes.func\n};\n\nCustomSVGSeries.defaultProps = {\n  ...AbstractSeries.defaultProps,\n  animation: false,\n  customComponent: 'circle',\n  style: {},\n  size: 2\n};\n\nexport default CustomSVGSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/heatmap-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport Animation from 'animation';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nimport AbstractSeries from './abstract-series';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--heatmap';\n\nclass HeatmapSeries extends AbstractSeries {\n  static getParentConfig(attr) {\n    const isDomainAdjustmentNeeded = attr === 'x' || attr === 'y';\n    return {isDomainAdjustmentNeeded};\n  }\n\n  render() {\n    const {\n      animation,\n      className,\n      data,\n      marginLeft,\n      marginTop,\n      style\n    } = this.props;\n    if (!data) {\n      return null;\n    }\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <HeatmapSeries {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n    const {rectStyle} = {rectStyle: {}, ...style};\n    const x = this._getAttributeFunctor('x');\n    const y = this._getAttributeFunctor('y');\n    const opacity = this._getAttributeFunctor('opacity');\n    const fill =\n      this._getAttributeFunctor('fill') || this._getAttributeFunctor('color');\n    const stroke =\n      this._getAttributeFunctor('stroke') || this._getAttributeFunctor('color');\n    const xDistance = this._getScaleDistance('x');\n    const yDistance = this._getScaleDistance('y');\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n      >\n        {data.map((d, i) => {\n          const attrs = {\n            style: {\n              stroke: stroke && stroke(d),\n              fill: fill && fill(d),\n              opacity: opacity && opacity(d),\n              ...style\n            },\n            ...rectStyle,\n            x: x(d) - xDistance / 2,\n            y: y(d) - yDistance / 2,\n            width: xDistance,\n            height: yDistance,\n            onClick: e => this._valueClickHandler(d, e),\n            onContextMenu: e => this._valueRightClickHandler(d, e),\n            onMouseOver: e => this._valueMouseOverHandler(d, e),\n            onMouseOut: e => this._valueMouseOutHandler(d, e)\n          };\n          return <rect key={i} {...attrs} />;\n        })}\n      </g>\n    );\n  }\n}\n\nHeatmapSeries.propTypes = {\n  ...AbstractSeries.propTypes\n};\n\nHeatmapSeries.displayName = 'HeatmapSeries';\n\nexport default HeatmapSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/hexbin-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport Animation from 'animation';\nimport {hexbin} from 'd3-hexbin';\nimport {scaleLinear} from 'd3-scale';\n\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\nimport {CONTINUOUS_COLOR_RANGE} from 'theme';\nimport AbstractSeries from './abstract-series';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--hexbin';\n\nfunction getColorDomain({countDomain}, hexes) {\n  if (countDomain) {\n    return countDomain;\n  }\n  return [0, Math.max(...hexes.map(row => row.length))];\n}\n\nclass HexbinSeries extends AbstractSeries {\n  render() {\n    const {\n      animation,\n      className,\n      colorRange,\n      data,\n      innerHeight,\n      innerWidth,\n      marginLeft,\n      marginTop,\n      radius,\n      sizeHexagonsWithCount,\n      style,\n      xOffset,\n      yOffset\n    } = this.props;\n\n    if (!data) {\n      return null;\n    }\n\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <HexbinSeries {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n    const x = this._getAttributeFunctor('x');\n    const y = this._getAttributeFunctor('y');\n\n    const hex = hexbin()\n      .x(d => x(d) + xOffset)\n      .y(d => y(d) + yOffset)\n      .radius(radius)\n      .size([innerWidth, innerHeight]);\n\n    const hexagonPath = hex.hexagon();\n    const hexes = hex(data);\n\n    const countDomain = getColorDomain(this.props, hexes);\n    const color = scaleLinear()\n      .domain(countDomain)\n      .range(colorRange);\n    const size = scaleLinear()\n      .domain(countDomain)\n      .range([0, radius]);\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n      >\n        {hexes.map((d, i) => {\n          const attrs = {\n            style,\n            d: sizeHexagonsWithCount\n              ? hex.hexagon(size(d.length))\n              : hexagonPath,\n            fill: color(d.length),\n            transform: `translate(${d.x}, ${d.y})`,\n            onClick: e => this._valueClickHandler(d, e),\n            onContextMenu: e => this._valueRightClickHandler(d, e),\n            onMouseOver: e => this._valueMouseOverHandler(d, e),\n            onMouseOut: e => this._valueMouseOutHandler(d, e)\n          };\n          return <path key={String(i)} {...attrs} />;\n        })}\n      </g>\n    );\n  }\n}\n\nHexbinSeries.propTypes = {\n  ...AbstractSeries.propTypes,\n  radius: PropTypes.number\n};\n\nHexbinSeries.defaultProps = {\n  radius: 20,\n  colorRange: CONTINUOUS_COLOR_RANGE,\n  xOffset: 0,\n  yOffset: 0\n};\n\nHexbinSeries.displayName = 'HexbinSeries';\n\nexport default HexbinSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/horizontal-bar-series-canvas.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport AbstractSeries from './abstract-series';\nimport BarSeries from './bar-series-canvas';\n\nclass HorizontalBarSeriesCanvas extends AbstractSeries {\n  static get requiresSVG() {\n    return false;\n  }\n\n  static get isCanvas() {\n    return true;\n  }\n\n  static getParentConfig(attr) {\n    const isDomainAdjustmentNeeded = attr === 'y';\n    const zeroBaseValue = attr === 'x';\n    return {\n      isDomainAdjustmentNeeded,\n      zeroBaseValue\n    };\n  }\n\n  static renderLayer(props, ctx) {\n    BarSeries.renderLayer(\n      {\n        ...props,\n        linePosAttr: 'y',\n        valuePosAttr: 'x',\n        lineSizeAttr: 'height',\n        valueSizeAttr: 'width'\n      },\n      ctx\n    );\n  }\n\n  render() {\n    return null;\n  }\n}\n\nHorizontalBarSeriesCanvas.displayName = 'HorizontalBarSeriesCanvas';\nHorizontalBarSeriesCanvas.propTypes = {\n  ...AbstractSeries.propTypes\n};\n\nexport default HorizontalBarSeriesCanvas;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/horizontal-bar-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport AbstractSeries from './abstract-series';\nimport BarSeries from './bar-series';\n\nclass HorizontalBarSeries extends AbstractSeries {\n  static getParentConfig(attr) {\n    const isDomainAdjustmentNeeded = attr === 'y';\n    const zeroBaseValue = attr === 'x';\n    return {\n      isDomainAdjustmentNeeded,\n      zeroBaseValue\n    };\n  }\n\n  render() {\n    return (\n      <BarSeries\n        {...this.props}\n        linePosAttr=\"y\"\n        valuePosAttr=\"x\"\n        lineSizeAttr=\"height\"\n        valueSizeAttr=\"width\"\n      />\n    );\n  }\n}\n\nHorizontalBarSeries.displayName = 'HorizontalBarSeries';\n\nexport default HorizontalBarSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/horizontal-rect-series-canvas.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport AbstractSeries from './abstract-series';\nimport RectSeries from './rect-series-canvas';\n\nclass HorizontalRectSeriesCanvas extends AbstractSeries {\n  static get requiresSVG() {\n    return false;\n  }\n\n  static get isCanvas() {\n    return true;\n  }\n\n  static getParentConfig(attr) {\n    const isDomainAdjustmentNeeded = false;\n    const zeroBaseValue = attr === 'x';\n    return {\n      isDomainAdjustmentNeeded,\n      zeroBaseValue\n    };\n  }\n\n  static renderLayer(props, ctx) {\n    RectSeries.renderLayer(\n      {\n        ...props,\n        linePosAttr: 'y',\n        valuePosAttr: 'x',\n        lineSizeAttr: 'height',\n        valueSizeAttr: 'width'\n      },\n      ctx\n    );\n  }\n\n  render() {\n    return null;\n  }\n}\n\nHorizontalRectSeriesCanvas.displayName = 'HorizontalRectSeriesCanvas';\nHorizontalRectSeriesCanvas.propTypes = {\n  ...AbstractSeries.propTypes\n};\n\nexport default HorizontalRectSeriesCanvas;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/horizontal-rect-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport AbstractSeries from './abstract-series';\nimport RectSeries from './rect-series';\n\nclass HorizontalRectSeries extends AbstractSeries {\n  static getParentConfig(attr) {\n    const isDomainAdjustmentNeeded = false;\n    const zeroBaseValue = attr === 'x';\n    return {\n      isDomainAdjustmentNeeded,\n      zeroBaseValue\n    };\n  }\n\n  render() {\n    return (\n      <RectSeries\n        {...this.props}\n        linePosAttr=\"y\"\n        valuePosAttr=\"x\"\n        lineSizeAttr=\"height\"\n        valueSizeAttr=\"width\"\n      />\n    );\n  }\n}\n\nHorizontalRectSeries.displayName = 'HorizontalRectSeries';\n\nexport default HorizontalRectSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/label-series.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport AbstractSeries from './abstract-series';\nimport Animation from 'animation';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--label';\n\nconst getTextAnchor = (labelAnchorX, leftOfMiddle) => {\n  return labelAnchorX ? labelAnchorX : leftOfMiddle ? 'start' : 'end';\n};\nconst getDominantBaseline = (labelAnchorY, aboveMiddle) => {\n  return labelAnchorY\n    ? labelAnchorY\n    : aboveMiddle\n    ? 'text-before-edge'\n    : 'text-after-edge';\n};\n\nclass LabelSeries extends AbstractSeries {\n  render() {\n    const {\n      animation,\n      allowOffsetToBeReversed,\n      className,\n      data,\n      _data,\n      getLabel,\n      marginLeft,\n      marginTop,\n      rotation,\n      style,\n      xRange,\n      yRange,\n      labelAnchorX,\n      labelAnchorY\n    } = this.props;\n    if (!data) {\n      return null;\n    }\n\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <LabelSeries {...this.props} animation={null} _data={data} />\n        </Animation>\n      );\n    }\n\n    const xFunctor = this._getAttributeFunctor('x');\n    const yFunctor = this._getAttributeFunctor('y');\n\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n        style={style}\n      >\n        {data.reduce((res, d, i) => {\n          const {style: markStyle, xOffset, yOffset} = d;\n          if (!getLabel(d)) {\n            return res;\n          }\n          const xVal = xFunctor(d);\n          const yVal = yFunctor(d);\n          const leftOfMiddle = xVal < (xRange[1] - xRange[0]) / 2;\n          const aboveMiddle = yVal < Math.abs(yRange[1] - yRange[0]) / 2;\n\n          const x =\n            xVal +\n            (allowOffsetToBeReversed && leftOfMiddle ? -1 : 1) * (xOffset || 0);\n          const y =\n            yVal +\n            (allowOffsetToBeReversed && aboveMiddle ? -1 : 1) * (yOffset || 0);\n\n          const hasRotationValueSet = d.rotation === 0 || d.rotation;\n          const labelRotation = hasRotationValueSet ? d.rotation : rotation;\n          const attrs = {\n            dominantBaseline: getDominantBaseline(labelAnchorY, aboveMiddle),\n            className: 'rv-xy-plot__series--label-text',\n            onClick: e => this._valueClickHandler(d, e),\n            onContextMenu: e => this._valueRightClickHandler(d, e),\n            onMouseOver: e => this._valueMouseOverHandler(d, e),\n            onMouseOut: e => this._valueMouseOutHandler(d, e),\n            textAnchor: getTextAnchor(labelAnchorX, leftOfMiddle),\n            x,\n            y,\n            transform: `rotate(${labelRotation},${x},${y})`,\n            ...markStyle\n          };\n          const textContent = getLabel(_data ? _data[i] : d);\n          return res.concat([\n            <text key={String(i)} {...attrs}>\n              {textContent}\n            </text>\n          ]);\n        }, [])}\n      </g>\n    );\n  }\n}\n\nLabelSeries.propTypes = {\n  animation: PropTypes.bool,\n  allowOffsetToBeReversed: PropTypes.bool,\n  className: PropTypes.string,\n  data: PropTypes.arrayOf(\n    PropTypes.shape({\n      x: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n      y: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n      angle: PropTypes.number,\n      radius: PropTypes.number,\n      label: PropTypes.string,\n      xOffset: PropTypes.number,\n      yOffset: PropTypes.number,\n      style: PropTypes.object\n    })\n  ).isRequired,\n  marginLeft: PropTypes.number,\n  marginTop: PropTypes.number,\n  rotation: PropTypes.number,\n  style: PropTypes.object,\n  xRange: PropTypes.arrayOf(PropTypes.number),\n  yRange: PropTypes.arrayOf(PropTypes.number),\n  labelAnchorX: PropTypes.string,\n  labelAnchorY: PropTypes.string\n};\nLabelSeries.defaultProps = {\n  ...AbstractSeries.defaultProps,\n  animation: false,\n  rotation: 0,\n  getLabel: d => d.label\n};\nLabelSeries.displayName = 'LabelSeries';\nexport default LabelSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/line-mark-series-canvas.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport AbstractSeries from './abstract-series';\nimport MarkSeriesCanvas from './mark-series-canvas';\nimport LineSeriesCanvas from './line-series-canvas';\n\nclass LineMarkSeriesCanvas extends AbstractSeries {\n  static get requiresSVG() {\n    return false;\n  }\n\n  static get isCanvas() {\n    return true;\n  }\n\n  static renderLayer(props, ctx) {\n    LineSeriesCanvas.renderLayer(props, ctx);\n    MarkSeriesCanvas.renderLayer(props, ctx);\n  }\n\n  render() {\n    return null;\n  }\n}\n\nLineMarkSeriesCanvas.displayName = 'LineMarkSeriesCanvas';\nLineMarkSeriesCanvas.propTypes = {\n  ...AbstractSeries.propTypes\n};\n\nexport default LineMarkSeriesCanvas;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/line-mark-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport AbstractSeries from './abstract-series';\nimport LineSeries from './line-series';\nimport MarkSeries from './mark-series';\n\nconst propTypes = {\n  ...LineSeries.propTypes,\n  lineStyle: PropTypes.object,\n  markStyle: PropTypes.object\n};\n\nclass LineMarkSeries extends AbstractSeries {\n  static get defaultProps() {\n    return {\n      ...LineSeries.defaultProps,\n      lineStyle: {},\n      markStyle: {}\n    };\n  }\n\n  render() {\n    const {lineStyle, markStyle, style} = this.props;\n    return (\n      <g className=\"rv-xy-plot__series rv-xy-plot__series--linemark\">\n        <LineSeries {...this.props} style={{...style, ...lineStyle}} />\n        <MarkSeries {...this.props} style={{...style, ...markStyle}} />\n      </g>\n    );\n  }\n}\n\nLineMarkSeries.displayName = 'LineMarkSeries';\nLineMarkSeries.propTypes = propTypes;\n\nexport default LineMarkSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/line-series-canvas.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nimport PropTypes from 'prop-types';\nimport {rgb} from 'd3-color';\nimport * as d3Shape from 'd3-shape';\nimport React from 'react';\n\nimport {DEFAULT_OPACITY} from 'theme';\nimport {getAttributeFunctor, getAttributeValue} from 'utils/scales-utils';\nimport AbstractSeries from './abstract-series';\n\nclass LineSeriesCanvas extends AbstractSeries {\n  static get requiresSVG() {\n    return false;\n  }\n\n  static get isCanvas() {\n    return true;\n  }\n\n  static renderLayer(props, ctx) {\n    const {\n      curve,\n      data,\n      marginLeft,\n      marginTop,\n      strokeWidth,\n      strokeDasharray\n    } = props;\n    if (!data || data.length === 0) {\n      return;\n    }\n\n    const x = getAttributeFunctor(props, 'x');\n    const y = getAttributeFunctor(props, 'y');\n    const stroke =\n      getAttributeValue(props, 'stroke') || getAttributeValue(props, 'color');\n    const strokeColor = rgb(stroke);\n    const newOpacity = getAttributeValue(props, 'opacity');\n    const opacity = Number.isFinite(newOpacity) ? newOpacity : DEFAULT_OPACITY;\n    let line = d3Shape\n      .line()\n      .x(row => x(row) + marginLeft)\n      .y(row => y(row) + marginTop);\n    if (typeof curve === 'string' && d3Shape[curve]) {\n      line = line.curve(d3Shape[curve]);\n    } else if (typeof curve === 'function') {\n      line = line.curve(curve);\n    }\n\n    ctx.beginPath();\n    ctx.strokeStyle = `rgba(${strokeColor.r}, ${strokeColor.g}, ${strokeColor.b}, ${opacity})`;\n    ctx.lineWidth = strokeWidth;\n\n    if (strokeDasharray) {\n      ctx.setLineDash(strokeDasharray);\n    }\n\n    line.context(ctx)(data);\n    ctx.stroke();\n    ctx.closePath();\n    // set back to default\n    ctx.lineWidth = 1;\n    ctx.setLineDash([]);\n  }\n\n  render() {\n    return <div />;\n  }\n}\n\nLineSeriesCanvas.displayName = 'LineSeriesCanvas';\nLineSeriesCanvas.defaultProps = {\n  ...AbstractSeries.defaultProps,\n  strokeWidth: 2\n};\n\nLineSeriesCanvas.propTypes = {\n  ...AbstractSeries.propTypes,\n  strokeWidth: PropTypes.number\n};\n\nexport default LineSeriesCanvas;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/line-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport * as d3Shape from 'd3-shape';\n\nimport Animation from 'animation';\nimport {DEFAULT_OPACITY} from 'theme';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {warning} from 'utils/react-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nimport AbstractSeries from './abstract-series';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--line';\n\nconst STROKE_STYLES = {\n  dashed: '6, 2',\n  solid: null\n};\n\nclass LineSeries extends AbstractSeries {\n  _renderLine(data, x, y, curve, getNull) {\n    let line = d3Shape.line();\n    if (curve !== null) {\n      if (typeof curve === 'string' && d3Shape[curve]) {\n        line = line.curve(d3Shape[curve]);\n      } else if (typeof curve === 'function') {\n        line = line.curve(curve);\n      }\n    }\n    line = line.defined(getNull);\n    line = line.x(x).y(y);\n    return line(data);\n  }\n\n  render() {\n    const {animation, className, data} = this.props;\n\n    if (this.props.nullAccessor) {\n      warning('nullAccessor has been renamed to getNull', true);\n    }\n\n    if (!data) {\n      return null;\n    }\n\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <LineSeries {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const {\n      curve,\n      marginLeft,\n      marginTop,\n      strokeDasharray,\n      strokeStyle,\n      strokeWidth,\n      style\n    } = this.props;\n\n    const x = this._getAttributeFunctor('x');\n    const y = this._getAttributeFunctor('y');\n    const stroke =\n      this._getAttributeValue('stroke') || this._getAttributeValue('color');\n    const newOpacity = this._getAttributeValue('opacity');\n    const opacity = Number.isFinite(newOpacity) ? newOpacity : DEFAULT_OPACITY;\n    const getNull = this.props.nullAccessor || this.props.getNull;\n    const d = this._renderLine(data, x, y, curve, getNull);\n\n    return (\n      <path\n        d={d}\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n        onMouseOver={this._seriesMouseOverHandler}\n        onMouseOut={this._seriesMouseOutHandler}\n        onClick={this._seriesClickHandler}\n        onContextMenu={this._seriesRightClickHandler}\n        style={{\n          opacity,\n          strokeDasharray: STROKE_STYLES[strokeStyle] || strokeDasharray,\n          strokeWidth,\n          stroke,\n          ...style\n        }}\n      />\n    );\n  }\n}\n\nLineSeries.displayName = 'LineSeries';\nLineSeries.propTypes = {\n  ...AbstractSeries.propTypes,\n  strokeStyle: PropTypes.oneOf(Object.keys(STROKE_STYLES)),\n  curve: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),\n  getNull: PropTypes.func\n};\nLineSeries.defaultProps = {\n  ...AbstractSeries.defaultProps,\n  strokeStyle: 'solid',\n  style: {},\n  opacity: 1,\n  curve: null,\n  className: '',\n  getNull: () => true\n};\n\nexport default LineSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/mark-series-canvas.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport {rgb} from 'd3-color';\n\nimport {DEFAULT_SIZE, DEFAULT_OPACITY} from 'theme';\nimport {getAttributeFunctor} from 'utils/scales-utils';\n\nimport AbstractSeries from './abstract-series';\n\nclass MarkSeriesCanvas extends AbstractSeries {\n  static get requiresSVG() {\n    return false;\n  }\n\n  static get isCanvas() {\n    return true;\n  }\n\n  static renderLayer(props, ctx) {\n    const {data, marginLeft, marginTop} = props;\n\n    const x = getAttributeFunctor(props, 'x');\n    const y = getAttributeFunctor(props, 'y');\n    const size = getAttributeFunctor(props, 'size') || (() => DEFAULT_SIZE);\n    const fill =\n      getAttributeFunctor(props, 'fill') || getAttributeFunctor(props, 'color');\n    const stroke =\n      getAttributeFunctor(props, 'stroke') ||\n      getAttributeFunctor(props, 'color');\n    const opacity = getAttributeFunctor(props, 'opacity');\n\n    data.forEach(row => {\n      const fillColor = rgb(fill(row));\n      const strokeColor = rgb(stroke(row));\n      const rowOpacity = opacity(row) || DEFAULT_OPACITY;\n      ctx.beginPath();\n      ctx.arc(\n        x(row) + marginLeft,\n        y(row) + marginTop,\n        size(row),\n        0,\n        2 * Math.PI\n      );\n      ctx.fillStyle = `rgba(${fillColor.r}, ${fillColor.g}, ${fillColor.b}, ${rowOpacity})`;\n      ctx.fill();\n      ctx.strokeStyle = `rgba(${strokeColor.r}, ${strokeColor.g}, ${strokeColor.b}, ${rowOpacity})`;\n      ctx.stroke();\n    });\n  }\n\n  render() {\n    return null;\n  }\n}\n\nMarkSeriesCanvas.displayName = 'MarkSeriesCanvas';\n\nMarkSeriesCanvas.propTypes = {\n  ...AbstractSeries.propTypes\n};\n\nexport default MarkSeriesCanvas;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/mark-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport Animation from 'animation';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {warning} from 'utils/react-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\nimport {DEFAULT_SIZE, DEFAULT_OPACITY} from 'theme';\n\nimport AbstractSeries from './abstract-series';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--mark';\nconst DEFAULT_STROKE_WIDTH = 1;\n\nclass MarkSeries extends AbstractSeries {\n  _renderCircle(d, i, strokeWidth, style, scalingFunctions) {\n    const {fill, opacity, size, stroke, x, y} = scalingFunctions;\n\n    const attrs = {\n      r: size ? size(d) : DEFAULT_SIZE,\n      cx: x(d),\n      cy: y(d),\n      style: {\n        opacity: opacity ? opacity(d) : DEFAULT_OPACITY,\n        stroke: stroke && stroke(d),\n        fill: fill && fill(d),\n        strokeWidth: strokeWidth || DEFAULT_STROKE_WIDTH,\n        ...style\n      },\n      key: i,\n      onClick: e => this._valueClickHandler(d, e),\n      onContextMenu: e => this._valueRightClickHandler(d, e),\n      onMouseOver: e => this._valueMouseOverHandler(d, e),\n      onMouseOut: e => this._valueMouseOutHandler(d, e)\n    };\n    return <circle {...attrs} />;\n  }\n\n  render() {\n    const {\n      animation,\n      className,\n      data,\n      marginLeft,\n      marginTop,\n      strokeWidth,\n      style\n    } = this.props;\n\n    if (this.props.nullAccessor) {\n      warning('nullAccessor has been renamed to getNull', true);\n    }\n\n    const getNull = this.props.nullAccessor || this.props.getNull;\n\n    if (!data) {\n      return null;\n    }\n\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <MarkSeries {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const scalingFunctions = {\n      fill:\n        this._getAttributeFunctor('fill') || this._getAttributeFunctor('color'),\n      opacity: this._getAttributeFunctor('opacity'),\n      size: this._getAttributeFunctor('size'),\n      stroke:\n        this._getAttributeFunctor('stroke') ||\n        this._getAttributeFunctor('color'),\n      x: this._getAttributeFunctor('x'),\n      y: this._getAttributeFunctor('y')\n    };\n\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n      >\n        {data.map((d, i) => {\n          return (\n            getNull(d) &&\n            this._renderCircle(d, i, strokeWidth, style, scalingFunctions)\n          );\n        })}\n      </g>\n    );\n  }\n}\n\nMarkSeries.displayName = 'MarkSeries';\nMarkSeries.propTypes = {\n  ...AbstractSeries.propTypes,\n  getNull: PropTypes.func,\n  strokeWidth: PropTypes.number\n};\nMarkSeries.defaultProps = {\n  getNull: () => true\n};\n\nexport default MarkSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/polygon-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport Animation from 'animation';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nimport AbstractSeries from './abstract-series';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--polygon';\nconst DEFAULT_COLOR = '#12939A';\n\nconst generatePath = (data, xFunctor, yFunctor) =>\n  `${data.reduce(\n    (res, row, i) => `${res} ${i ? 'L' : 'M'}${xFunctor(row)} ${yFunctor(row)}`,\n    ''\n  )} Z`;\n\nclass PolygonSeries extends AbstractSeries {\n  static get propTypes() {\n    return {\n      ...AbstractSeries.propTypes\n    };\n  }\n\n  render() {\n    const {\n      animation,\n      color,\n      className,\n      data,\n      marginLeft,\n      marginTop,\n      style\n    } = this.props;\n\n    if (!data) {\n      return null;\n    }\n\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <PolygonSeries {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n    const xFunctor = this._getAttributeFunctor('x');\n    const yFunctor = this._getAttributeFunctor('y');\n\n    return (\n      <path\n        {...{\n          className: getCombinedClassName(predefinedClassName, className),\n          onMouseOver: e => this._seriesMouseOverHandler(data, e),\n          onMouseOut: e => this._seriesMouseOutHandler(data, e),\n          onClick: this._seriesClickHandler,\n          onContextMenu: this._seriesRightClickHandler,\n          fill: color || DEFAULT_COLOR,\n          style,\n          d: generatePath(data, xFunctor, yFunctor),\n          transform: `translate(${marginLeft},${marginTop})`\n        }}\n      />\n    );\n  }\n}\n\nPolygonSeries.displayName = 'PolygonSeries';\n\nexport default PolygonSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/rect-series-canvas.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nimport PropTypes from 'prop-types';\nimport {rgb} from 'd3-color';\n\nimport {DEFAULT_OPACITY} from 'theme';\nimport {getAttributeFunctor, getAttr0Functor} from 'utils/scales-utils';\nimport AbstractSeries from './abstract-series';\n\nclass RectSeriesCanvas extends AbstractSeries {\n  static get requiresSVG() {\n    return false;\n  }\n\n  static get isCanvas() {\n    return true;\n  }\n\n  static renderLayer(props, ctx) {\n    const {\n      data,\n      linePosAttr,\n      lineSizeAttr,\n      marginLeft,\n      marginTop,\n      valuePosAttr\n    } = props;\n    if (!data || data.length === 0) {\n      return;\n    }\n\n    const line = getAttributeFunctor(props, linePosAttr);\n    const line0 = getAttr0Functor(props, linePosAttr);\n    const value = getAttributeFunctor(props, valuePosAttr);\n    const value0 = getAttr0Functor(props, valuePosAttr);\n    const fill =\n      getAttributeFunctor(props, 'fill') || getAttributeFunctor(props, 'color');\n    const stroke =\n      getAttributeFunctor(props, 'stroke') ||\n      getAttributeFunctor(props, 'color');\n    const opacity = getAttributeFunctor(props, 'opacity');\n\n    data.forEach(row => {\n      const fillColor = rgb(fill(row));\n      const strokeColor = rgb(stroke(row));\n      const rowOpacity = opacity(row) || DEFAULT_OPACITY;\n\n      const linePos = line0(row);\n      const valuePos = Math.min(value0(row), value(row));\n      const x = valuePosAttr === 'x' ? valuePos : linePos;\n      const y = valuePosAttr === 'y' ? valuePos : linePos;\n\n      const lineSize = Math.abs(line(row) - line0(row));\n      const valueSize = Math.abs(-value0(row) + value(row));\n      const height = lineSizeAttr === 'height' ? lineSize : valueSize;\n      const width = lineSizeAttr === 'width' ? lineSize : valueSize;\n\n      ctx.beginPath();\n      ctx.rect(x + marginLeft, y + marginTop, width, height);\n      ctx.fillStyle = `rgba(${fillColor.r}, ${fillColor.g}, ${fillColor.b}, ${rowOpacity})`;\n      ctx.fill();\n      ctx.strokeStyle = `rgba(${strokeColor.r}, ${strokeColor.g}, ${strokeColor.b}, ${rowOpacity})`;\n      ctx.stroke();\n    });\n  }\n\n  render() {\n    return null;\n  }\n}\n\nRectSeriesCanvas.displayName = 'RectSeriesCanvas';\nRectSeriesCanvas.defaultProps = {\n  ...AbstractSeries.defaultProps,\n  linePosAttr: PropTypes.string.isRequired,\n  valuePosAttr: PropTypes.string.isRequired,\n  lineSizeAttr: PropTypes.string.isRequired,\n  valueSizeAttr: PropTypes.string.isRequired\n};\n\nRectSeriesCanvas.propTypes = {\n  ...AbstractSeries.propTypes\n};\n\nexport default RectSeriesCanvas;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/rect-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport Animation from 'animation';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nimport AbstractSeries from './abstract-series';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--rect';\n\nclass RectSeries extends AbstractSeries {\n  static get propTypes() {\n    return {\n      ...AbstractSeries.propTypes,\n      linePosAttr: PropTypes.string,\n      valuePosAttr: PropTypes.string,\n      lineSizeAttr: PropTypes.string,\n      valueSizeAttr: PropTypes.string\n    };\n  }\n\n  render() {\n    const {\n      animation,\n      className,\n      data,\n      linePosAttr,\n      lineSizeAttr,\n      marginLeft,\n      marginTop,\n      style,\n      valuePosAttr,\n      valueSizeAttr\n    } = this.props;\n\n    if (!data) {\n      return null;\n    }\n\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <RectSeries {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const lineFunctor = this._getAttributeFunctor(linePosAttr);\n    const line0Functor = this._getAttr0Functor(linePosAttr);\n    const valueFunctor = this._getAttributeFunctor(valuePosAttr);\n    const value0Functor = this._getAttr0Functor(valuePosAttr);\n    const fillFunctor =\n      this._getAttributeFunctor('fill') || this._getAttributeFunctor('color');\n    const strokeFunctor =\n      this._getAttributeFunctor('stroke') || this._getAttributeFunctor('color');\n    const opacityFunctor = this._getAttributeFunctor('opacity');\n\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n      >\n        {data.map((d, i) => {\n          const attrs = {\n            style: {\n              opacity: opacityFunctor && opacityFunctor(d),\n              stroke: strokeFunctor && strokeFunctor(d),\n              fill: fillFunctor && fillFunctor(d),\n              ...style\n            },\n            [linePosAttr]: line0Functor(d),\n            [lineSizeAttr]: Math.abs(lineFunctor(d) - line0Functor(d)),\n            [valuePosAttr]: Math.min(value0Functor(d), valueFunctor(d)),\n            [valueSizeAttr]: Math.abs(-value0Functor(d) + valueFunctor(d)),\n            onClick: e => this._valueClickHandler(d, e),\n            onContextMenu: e => this._valueRightClickHandler(d, e),\n            onMouseOver: e => this._valueMouseOverHandler(d, e),\n            onMouseOut: e => this._valueMouseOutHandler(d, e)\n          };\n          return <rect key={String(i)} {...attrs} />;\n        })}\n      </g>\n    );\n  }\n}\n\nRectSeries.displayName = 'RectSeries';\n\nexport default RectSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/vertical-bar-series-canvas.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport AbstractSeries from './abstract-series';\nimport BarSeries from './bar-series-canvas';\n\nclass HorizontalBarSeriesCanvas extends AbstractSeries {\n  static get requiresSVG() {\n    return false;\n  }\n\n  static get isCanvas() {\n    return true;\n  }\n\n  static getParentConfig(attr) {\n    const isDomainAdjustmentNeeded = attr === 'x';\n    const zeroBaseValue = attr === 'y';\n    return {\n      isDomainAdjustmentNeeded,\n      zeroBaseValue\n    };\n  }\n\n  static renderLayer(props, ctx) {\n    BarSeries.renderLayer(\n      {\n        ...props,\n        linePosAttr: 'x',\n        valuePosAttr: 'y',\n        lineSizeAttr: 'width',\n        valueSizeAttr: 'height'\n      },\n      ctx\n    );\n  }\n\n  render() {\n    return null;\n  }\n}\n\nHorizontalBarSeriesCanvas.displayName = 'HorizontalBarSeriesCanvas';\nHorizontalBarSeriesCanvas.propTypes = {\n  ...AbstractSeries.propTypes\n};\n\nexport default HorizontalBarSeriesCanvas;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/vertical-bar-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport AbstractSeries from './abstract-series';\nimport BarSeries from './bar-series';\n\nclass VerticalBarSeries extends AbstractSeries {\n  static getParentConfig(attr) {\n    const isDomainAdjustmentNeeded = attr === 'x';\n    const zeroBaseValue = attr === 'y';\n    return {\n      isDomainAdjustmentNeeded,\n      zeroBaseValue\n    };\n  }\n\n  render() {\n    return (\n      <BarSeries\n        {...this.props}\n        linePosAttr=\"x\"\n        valuePosAttr=\"y\"\n        lineSizeAttr=\"width\"\n        valueSizeAttr=\"height\"\n      />\n    );\n  }\n}\n\nVerticalBarSeries.displayName = 'VerticalBarSeries';\n\nexport default VerticalBarSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/vertical-rect-series-canvas.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport AbstractSeries from './abstract-series';\nimport RectSeries from './rect-series-canvas';\n\nclass HorizontalRectSeriesCanvas extends AbstractSeries {\n  static get requiresSVG() {\n    return false;\n  }\n\n  static get isCanvas() {\n    return true;\n  }\n\n  static getParentConfig(attr) {\n    const isDomainAdjustmentNeeded = false;\n    const zeroBaseValue = attr === 'y';\n    return {\n      isDomainAdjustmentNeeded,\n      zeroBaseValue\n    };\n  }\n\n  static renderLayer(props, ctx) {\n    RectSeries.renderLayer(\n      {\n        ...props,\n        linePosAttr: 'x',\n        valuePosAttr: 'y',\n        lineSizeAttr: 'width',\n        valueSizeAttr: 'height'\n      },\n      ctx\n    );\n  }\n\n  render() {\n    return null;\n  }\n}\n\nHorizontalRectSeriesCanvas.displayName = 'HorizontalRectSeriesCanvas';\nHorizontalRectSeriesCanvas.propTypes = {\n  ...AbstractSeries.propTypes\n};\n\nexport default HorizontalRectSeriesCanvas;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/vertical-rect-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport AbstractSeries from './abstract-series';\nimport RectSeries from './rect-series';\n\nclass VerticalRectSeries extends AbstractSeries {\n  static getParentConfig(attr) {\n    const isDomainAdjustmentNeeded = false;\n    const zeroBaseValue = attr === 'y';\n    return {\n      isDomainAdjustmentNeeded,\n      zeroBaseValue\n    };\n  }\n\n  render() {\n    return (\n      <RectSeries\n        {...this.props}\n        linePosAttr=\"x\"\n        valuePosAttr=\"y\"\n        lineSizeAttr=\"width\"\n        valueSizeAttr=\"height\"\n      />\n    );\n  }\n}\n\nVerticalRectSeries.displayName = 'VerticalRectSeries';\n\nexport default VerticalRectSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/series/whisker-series.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport Animation from 'animation';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\nimport {DEFAULT_OPACITY} from 'theme';\n\nimport AbstractSeries from './abstract-series';\n\nconst predefinedClassName = 'rv-xy-plot__series rv-xy-plot__series--whisker';\nconst DEFAULT_STROKE_WIDTH = 1;\nconst DEFAULT_CROSS_BAR_WIDTH = 6;\n\n/**\n * Render whisker lines for a data point.\n * @param {Object} whiskerMarkProps All the properties of the whisker mark.\n * @private\n */\nconst renderWhiskerMark = whiskerMarkProps => (d, i) => {\n  const {\n    crossBarWidth,\n    opacityFunctor,\n    sizeFunctor,\n    strokeFunctor,\n    strokeWidth,\n    style,\n    valueClickHandler,\n    valueMouseOutHandler,\n    valueMouseOverHandler,\n    valueRightClickHandler,\n    xFunctor,\n    yFunctor\n  } = whiskerMarkProps;\n\n  const r = sizeFunctor ? sizeFunctor(d) : 0;\n  const cx = xFunctor(d);\n  const cy = yFunctor(d);\n  const positiveXVariance = xFunctor({x: d.x + d.xVariance / 2});\n  const negativeXVariance = xFunctor({x: d.x - d.xVariance / 2});\n  const positiveYVariance = yFunctor({y: d.y + d.yVariance / 2});\n  const negativeYVariance = yFunctor({y: d.y - d.yVariance / 2});\n  /**\n   * Determine whether on not we should draw whiskers in each direction.\n   * We need to see an actual variance value, and also have that value extend past the\n   * radius \"buffer\" region in which we won't be drawing (if any).\n   */\n  const hasXWhiskers = positiveXVariance && cx + r < positiveXVariance;\n  const hasYWhiskers = positiveYVariance && cy - r > positiveYVariance;\n  if (!hasXWhiskers && !hasYWhiskers) {\n    return null;\n  }\n\n  const styleAttr = {\n    opacity: opacityFunctor ? opacityFunctor(d) : DEFAULT_OPACITY,\n    stroke: strokeFunctor && strokeFunctor(d),\n    strokeWidth: strokeWidth || DEFAULT_STROKE_WIDTH,\n    ...style\n  };\n  const crossBarExtension = crossBarWidth / 2;\n\n  const rightLineAttrs = {\n    x1: cx + r,\n    y1: cy,\n    x2: positiveXVariance,\n    y2: cy,\n    style: styleAttr\n  };\n  const leftLineAttrs = {\n    x1: cx - r,\n    y1: cy,\n    x2: negativeXVariance,\n    y2: cy,\n    style: styleAttr\n  };\n  const rightCrossBarAttrs = {\n    x1: positiveXVariance,\n    y1: cy - crossBarExtension,\n    x2: positiveXVariance,\n    y2: cy + crossBarExtension,\n    style: styleAttr\n  };\n  const leftCrossBarAttrs = {\n    x1: negativeXVariance,\n    y1: cy - crossBarExtension,\n    x2: negativeXVariance,\n    y2: cy + crossBarExtension,\n    style: styleAttr\n  };\n\n  const upperLineAttrs = {\n    x1: cx,\n    y1: cy - r,\n    x2: cx,\n    y2: positiveYVariance,\n    style: styleAttr\n  };\n  const lowerLineAttrs = {\n    x1: cx,\n    y1: cy + r,\n    x2: cx,\n    y2: negativeYVariance,\n    style: styleAttr\n  };\n  const upperCrossBarAttrs = {\n    x1: cx - crossBarExtension,\n    y1: positiveYVariance,\n    x2: cx + crossBarExtension,\n    y2: positiveYVariance,\n    style: styleAttr\n  };\n  const lowerCrossBarAttrs = {\n    x1: cx - crossBarExtension,\n    y1: negativeYVariance,\n    x2: cx + crossBarExtension,\n    y2: negativeYVariance,\n    style: styleAttr\n  };\n\n  return (\n    <g\n      className=\"mark-whiskers\"\n      key={i}\n      onClick={e => valueClickHandler(d, e)}\n      onContextMenu={e => valueRightClickHandler(d, e)}\n      onMouseOver={e => valueMouseOverHandler(d, e)}\n      onMouseOut={e => valueMouseOutHandler(d, e)}\n    >\n      {hasXWhiskers ? (\n        <g className=\"x-whiskers\">\n          <line {...rightLineAttrs} />\n          <line {...leftLineAttrs} />\n          <line {...rightCrossBarAttrs} />\n          <line {...leftCrossBarAttrs} />\n        </g>\n      ) : null}\n      {hasYWhiskers ? (\n        <g className=\"y-whiskers\">\n          <line {...upperLineAttrs} />\n          <line {...lowerLineAttrs} />\n          <line {...upperCrossBarAttrs} />\n          <line {...lowerCrossBarAttrs} />\n        </g>\n      ) : null}\n    </g>\n  );\n};\n\nclass WhiskerSeries extends AbstractSeries {\n  render() {\n    const {\n      animation,\n      className,\n      crossBarWidth,\n      data,\n      marginLeft,\n      marginTop,\n      strokeWidth,\n      style\n    } = this.props;\n    if (!data) {\n      return null;\n    }\n    if (animation) {\n      return (\n        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>\n          <WhiskerSeries {...this.props} animation={null} />\n        </Animation>\n      );\n    }\n\n    const whiskerMarkProps = {\n      crossBarWidth,\n      opacityFunctor: this._getAttributeFunctor('opacity'),\n      sizeFunctor: this._getAttributeFunctor('size'),\n      strokeFunctor:\n        this._getAttributeFunctor('stroke') ||\n        this._getAttributeFunctor('color'),\n      strokeWidth,\n      style,\n      xFunctor: this._getAttributeFunctor('x'),\n      yFunctor: this._getAttributeFunctor('y'),\n      valueClickHandler: this._valueClickHandler,\n      valueRightClickHandler: this._valueRightClickHandler,\n      valueMouseOverHandler: this._valueMouseOverHandler,\n      valueMouseOutHandler: this._valueMouseOutHandler\n    };\n\n    return (\n      <g\n        className={getCombinedClassName(predefinedClassName, className)}\n        transform={`translate(${marginLeft},${marginTop})`}\n      >\n        {data.map(renderWhiskerMark(whiskerMarkProps))}\n      </g>\n    );\n  }\n}\n\nWhiskerSeries.displayName = 'WhiskerSeries';\nWhiskerSeries.propTypes = {\n  ...AbstractSeries.propTypes,\n  strokeWidth: PropTypes.number\n};\nWhiskerSeries.defaultProps = {\n  ...AbstractSeries.defaultProps,\n  crossBarWidth: DEFAULT_CROSS_BAR_WIDTH,\n  size: 0,\n  strokeWidth: DEFAULT_STROKE_WIDTH\n};\nexport default WhiskerSeries;\n"
  },
  {
    "path": "packages/react-vis/src/plot/vertical-grid-lines.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport GridLines from 'plot/grid-lines';\nimport {DIRECTION} from 'utils/axis-utils';\n\nconst {VERTICAL} = DIRECTION;\n\nconst propTypes = {\n  ...GridLines.propTypes,\n  direction: PropTypes.oneOf([VERTICAL])\n};\n\nconst defaultProps = {\n  direction: VERTICAL,\n  attr: 'x'\n};\n\nfunction VerticalGridLines(props) {\n  return <GridLines {...props} />;\n}\n\nVerticalGridLines.displayName = 'VerticalGridLines';\nVerticalGridLines.propTypes = propTypes;\nVerticalGridLines.defaultProps = defaultProps;\nVerticalGridLines.requiresSVG = true;\n\nexport default VerticalGridLines;\n"
  },
  {
    "path": "packages/react-vis/src/plot/voronoi.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport {voronoi} from 'd3-voronoi';\n\nimport {getAttributeFunctor} from 'utils/scales-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst NOOP = f => f;\n\n// Find the index of the node at coordinates of a touch point\nfunction getNodeIndex(evt) {\n  const {\n    nativeEvent: {pageX, pageY}\n  } = evt;\n  const target = document.elementFromPoint(pageX, pageY);\n  if (!target) {\n    return -1;\n  }\n  const {parentNode} = target;\n  return Array.prototype.indexOf.call(parentNode.childNodes, target);\n}\n\nfunction getExtent({innerWidth, innerHeight, marginLeft, marginTop}) {\n  return [\n    [marginLeft, marginTop],\n    [innerWidth + marginLeft, innerHeight + marginTop]\n  ];\n}\n\nfunction Voronoi(props) {\n  const {\n    className,\n    extent,\n    nodes,\n    onBlur,\n    onClick,\n    onMouseUp,\n    onMouseDown,\n    onHover,\n    polygonStyle,\n    style,\n    x,\n    y\n  } = props;\n  // Create a voronoi with each node center points\n  const voronoiInstance = voronoi()\n    .x(x || getAttributeFunctor(props, 'x'))\n    .y(y || getAttributeFunctor(props, 'y'))\n    .extent(extent || getExtent(props));\n\n  // Create an array of polygons corresponding to the cells in voronoi\n  const polygons = voronoiInstance.polygons(nodes);\n\n  // Create helper function to handle special logic for touch events\n  const handleTouchEvent = handler => evt => {\n    evt.preventDefault();\n    const index = getNodeIndex(evt);\n    if (index > -1 && index < polygons.length) {\n      const d = polygons[index];\n      handler(d.data);\n    }\n  };\n\n  return (\n    <g\n      className={getCombinedClassName(className, 'rv-voronoi')}\n      style={style}\n      // Because of the nature of how touch events, and more specifically touchmove\n      // and how it differs from mouseover, we must manage touch events on the parent\n      onTouchEnd={handleTouchEvent(onMouseUp)}\n      onTouchStart={handleTouchEvent(onMouseDown)}\n      onTouchMove={handleTouchEvent(onHover)}\n      onTouchCancel={handleTouchEvent(onBlur)}\n    >\n      {polygons.map((d, i) => (\n        <path\n          className={`rv-voronoi__cell ${(d.data && d.data.className) || ''}`}\n          d={`M${d.join('L')}Z`}\n          onClick={() => onClick(d.data)}\n          onMouseUp={() => onMouseUp(d.data)}\n          onMouseDown={() => onMouseDown(d.data)}\n          onMouseOver={() => onHover(d.data)}\n          onMouseOut={() => onBlur(d.data)}\n          fill=\"none\"\n          style={{\n            pointerEvents: 'all',\n            ...polygonStyle,\n            ...(d.data && d.data.style)\n          }}\n          key={i}\n        />\n      ))}\n    </g>\n  );\n}\n\nVoronoi.requiresSVG = true;\nVoronoi.displayName = 'Voronoi';\nVoronoi.defaultProps = {\n  className: '',\n  onBlur: NOOP,\n  onClick: NOOP,\n  onHover: NOOP,\n  onMouseDown: NOOP,\n  onMouseUp: NOOP\n};\n\nVoronoi.propTypes = {\n  className: PropTypes.string,\n  extent: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)),\n  nodes: PropTypes.arrayOf(PropTypes.object).isRequired,\n  onBlur: PropTypes.func,\n  onClick: PropTypes.func,\n  onHover: PropTypes.func,\n  onMouseDown: PropTypes.func,\n  onMouseUp: PropTypes.func,\n  x: PropTypes.func,\n  y: PropTypes.func\n};\n\nexport default Voronoi;\n"
  },
  {
    "path": "packages/react-vis/src/plot/xy-plot.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport equal from 'deep-equal';\n\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nimport {\n  extractScalePropsFromProps,\n  getMissingScaleProps,\n  getOptionalScaleProps,\n  getXYPlotValues\n} from 'utils/scales-utils';\nimport {\n  getStackedData,\n  getSeriesChildren,\n  getSeriesPropsFromChildren\n} from 'utils/series-utils';\nimport {\n  getInnerDimensions,\n  MarginPropType,\n  DEFAULT_MARGINS\n} from 'utils/chart-utils';\nimport {AnimationPropType} from 'animation';\nimport {\n  CONTINUOUS_COLOR_RANGE,\n  EXTENDED_DISCRETE_COLOR_RANGE,\n  SIZE_RANGE,\n  OPACITY_TYPE\n} from 'theme';\n\nimport CanvasWrapper from './series/canvas-wrapper';\n\nconst ATTRIBUTES = [\n  'x',\n  'y',\n  'radius',\n  'angle',\n  'color',\n  'fill',\n  'stroke',\n  'opacity',\n  'size'\n];\n\n/**\n * Remove parents from tree formatted data. deep-equal doesnt play nice with data\n * that has circular structures, so we make every node single directional by pruning the parents.\n * @param {Array} data - the data object to have circular deps resolved in\n * @returns {Array} the sanitized data\n */\nfunction cleanseData(data) {\n  return data.map(series => {\n    if (!Array.isArray(series)) {\n      return series;\n    }\n    return series.map(row => ({...row, parent: null}));\n  });\n}\n\n/**\n * Wrapper on the deep-equal method for checking equality of next props vs current props\n * @param {Object} scaleMixins - Scale object.\n * @param {Object} nextScaleMixins - Scale object.\n * @param {Boolean} hasTreeStructure - Whether or not to cleanse the data of possible cyclic structures\n * @returns {Boolean} whether or not the two mixins objects are equal\n */\nfunction checkIfMixinsAreEqual(nextScaleMixins, scaleMixins, hasTreeStructure) {\n  const newMixins = {\n    ...nextScaleMixins,\n    _allData: hasTreeStructure\n      ? cleanseData(nextScaleMixins._allData)\n      : nextScaleMixins._allData\n  };\n  const oldMixins = {\n    ...scaleMixins,\n    _allData: hasTreeStructure\n      ? cleanseData(scaleMixins._allData)\n      : scaleMixins._allData\n  };\n  // it's hard to say if this function is reasonable?\n  return equal(newMixins, oldMixins);\n}\n\nclass XYPlot extends React.Component {\n  static get defaultProps() {\n    return {\n      className: ''\n    };\n  }\n\n  static get propTypes() {\n    return {\n      animation: AnimationPropType,\n      className: PropTypes.string,\n      dontCheckIfEmpty: PropTypes.bool,\n      height: PropTypes.number.isRequired,\n      margin: MarginPropType,\n      onClick: PropTypes.func,\n      onDoubleClick: PropTypes.func,\n      onMouseDown: PropTypes.func,\n      onMouseUp: PropTypes.func,\n      onMouseEnter: PropTypes.func,\n      onMouseLeave: PropTypes.func,\n      onMouseMove: PropTypes.func,\n      onTouchStart: PropTypes.func,\n      onTouchMove: PropTypes.func,\n      onTouchEnd: PropTypes.func,\n      onTouchCancel: PropTypes.func,\n      onWheel: PropTypes.func,\n      stackBy: PropTypes.oneOf(ATTRIBUTES),\n      style: PropTypes.object,\n      width: PropTypes.number.isRequired\n    };\n  }\n\n  constructor(props) {\n    super(props);\n    const {stackBy} = props;\n    const children = getSeriesChildren(props.children);\n    const data = getStackedData(children, stackBy);\n    this.state = {\n      scaleMixins: XYPlot._getScaleMixins(data, props),\n      data\n    };\n  }\n\n  static getDerivedStateFromProps(nextProps) {\n    const children = getSeriesChildren(nextProps.children);\n    const nextData = getStackedData(children, nextProps.stackBy);\n    const {scaleMixins} = this.state;\n    const nextScaleMixins = XYPlot._getScaleMixins(nextData, nextProps);\n    if (\n      !checkIfMixinsAreEqual(\n        nextScaleMixins,\n        scaleMixins,\n        nextProps.hasTreeStructure\n      )\n    ) {\n      return {\n        scaleMixins: nextScaleMixins,\n        data: nextData\n      };\n    }\n\n    return null;\n  }\n\n  /**\n   * Trigger click related callbacks if they are available.\n   * @param {React.SyntheticEvent} event Click event.\n   * @private\n   */\n  _clickHandler = event => {\n    const {onClick} = this.props;\n    if (onClick) {\n      onClick(event);\n    }\n  };\n\n  /**\n   * Trigger doule-click related callbacks if they are available.\n   * @param {React.SyntheticEvent} event Double-click event.\n   * @private\n   */\n  _doubleClickHandler = event => {\n    const {onDoubleClick} = this.props;\n    if (onDoubleClick) {\n      onDoubleClick(event);\n    }\n  };\n\n  /**\n   * Prepare the child components (including series) for rendering.\n   * @returns {Array} Array of child components.\n   * @private\n   */\n  _getClonedChildComponents() {\n    const props = this.props;\n    const {animation} = this.props;\n    const {scaleMixins, data} = this.state;\n    const dimensions = getInnerDimensions(this.props, DEFAULT_MARGINS);\n    const children = React.Children.toArray(this.props.children);\n    const seriesProps = getSeriesPropsFromChildren(children);\n    const XYPlotValues = getXYPlotValues(props, children);\n    return children.map((child, index) => {\n      let dataProps = null;\n      if (seriesProps[index]) {\n        // Get the index of the series in the list of props and retrieve\n        // the data property from it.\n        const {seriesIndex} = seriesProps[index];\n        dataProps = {data: data[seriesIndex]};\n      }\n      return React.cloneElement(child, {\n        ...dimensions,\n        animation,\n        ...(dataProps && child.type.prototype && child.type.prototype.render\n          ? {\n              ref: ref =>\n                (this[`series${seriesProps[index].seriesIndex}`] = ref)\n            }\n          : {}),\n        ...seriesProps[index],\n        ...scaleMixins,\n        ...child.props,\n        ...XYPlotValues[index],\n        ...dataProps\n      });\n    });\n  }\n  /**\n   * Get the list of scale-related settings that should be applied by default.\n   * @param {Object} props Object of props.\n   * @returns {Object} Defaults.\n   * @private\n   */\n  static _getDefaultScaleProps(props) {\n    const {innerWidth, innerHeight} = getInnerDimensions(\n      props,\n      DEFAULT_MARGINS\n    );\n\n    const colorRanges = ['color', 'fill', 'stroke'].reduce((acc, attr) => {\n      const range =\n        props[`${attr}Type`] === 'category'\n          ? EXTENDED_DISCRETE_COLOR_RANGE\n          : CONTINUOUS_COLOR_RANGE;\n      return {...acc, [`${attr}Range`]: range};\n    }, {});\n\n    return {\n      xRange: [0, innerWidth],\n      yRange: [innerHeight, 0],\n      ...colorRanges,\n      opacityType: OPACITY_TYPE,\n      sizeRange: SIZE_RANGE\n    };\n  }\n\n  /**\n   * Get the map of scales from the props, apply defaults to them and then pass\n   * them further.\n   * @param {Object} data Array of all data.\n   * @param {Object} props Props of the component.\n   * @returns {Object} Map of scale-related props.\n   * @private\n   */\n  static _getScaleMixins(data, props) {\n    const filteredData = data.filter(d => d);\n    const allData = [].concat(...filteredData);\n\n    const defaultScaleProps = XYPlot._getDefaultScaleProps(props);\n    const optionalScaleProps = getOptionalScaleProps(props);\n    const userScaleProps = extractScalePropsFromProps(props, ATTRIBUTES);\n    const missingScaleProps = getMissingScaleProps(\n      {\n        ...defaultScaleProps,\n        ...optionalScaleProps,\n        ...userScaleProps\n      },\n      allData,\n      ATTRIBUTES\n    );\n    const children = getSeriesChildren(props.children);\n    const zeroBaseProps = {};\n    const adjustBy = new Set();\n    const adjustWhat = new Set();\n    children.forEach((child, index) => {\n      if (!child || !data[index]) {\n        return;\n      }\n      ATTRIBUTES.forEach(attr => {\n        const {\n          isDomainAdjustmentNeeded,\n          zeroBaseValue\n        } = child.type.getParentConfig(attr, child.props);\n        if (isDomainAdjustmentNeeded) {\n          adjustBy.add(attr);\n          adjustWhat.add(index);\n        }\n        if (zeroBaseValue) {\n          const specifiedDomain = props[`${attr}Domain`];\n          zeroBaseProps[`${attr}BaseValue`] = specifiedDomain\n            ? specifiedDomain[0]\n            : 0;\n        }\n      });\n    });\n    return {\n      ...defaultScaleProps,\n      ...zeroBaseProps,\n      ...userScaleProps,\n      ...missingScaleProps,\n      _allData: data,\n      _adjustBy: Array.from(adjustBy),\n      _adjustWhat: Array.from(adjustWhat),\n      _stackBy: props.stackBy\n    };\n  }\n\n  /**\n   * Checks if the plot is empty or not.\n   * Currently checks the data only.\n   * @returns {boolean} True for empty.\n   * @private\n   */\n  _isPlotEmpty() {\n    const {data} = this.state;\n    return (\n      !data ||\n      !data.length ||\n      !data.some(series => series && series.some(d => d))\n    );\n  }\n\n  /**\n   * Trigger mouse-down related callbacks if they are available.\n   * @param {React.SyntheticEvent} event Mouse down event.\n   * @private\n   */\n  _mouseDownHandler = event => {\n    const {onMouseDown, children} = this.props;\n    if (onMouseDown) {\n      onMouseDown(event);\n    }\n    const seriesChildren = getSeriesChildren(children);\n    seriesChildren.forEach((child, index) => {\n      const component = this[`series${index}`];\n      if (component && component.onParentMouseDown) {\n        component.onParentMouseDown(event);\n      }\n    });\n  };\n\n  /**\n   * Trigger onMouseEnter handler if it was passed in props.\n   * @param {React.SyntheticEvent} event Mouse enter event.\n   * @private\n   */\n  _mouseEnterHandler = event => {\n    const {onMouseEnter, children} = this.props;\n    if (onMouseEnter) {\n      onMouseEnter(event);\n    }\n    const seriesChildren = getSeriesChildren(children);\n    seriesChildren.forEach((child, index) => {\n      const component = this[`series${index}`];\n      if (component && component.onParentMouseEnter) {\n        component.onParentMouseEnter(event);\n      }\n    });\n  };\n\n  /**\n   * Trigger onMouseLeave handler if it was passed in props.\n   * @param {React.SyntheticEvent} event Mouse leave event.\n   * @private\n   */\n  _mouseLeaveHandler = event => {\n    const {onMouseLeave, children} = this.props;\n    if (onMouseLeave) {\n      onMouseLeave(event);\n    }\n    const seriesChildren = getSeriesChildren(children);\n    seriesChildren.forEach((child, index) => {\n      const component = this[`series${index}`];\n      if (component && component.onParentMouseLeave) {\n        component.onParentMouseLeave(event);\n      }\n    });\n  };\n\n  /**\n   * Trigger movement-related callbacks if they are available.\n   * @param {React.SyntheticEvent} event Mouse move event.\n   * @private\n   */\n  _mouseMoveHandler = event => {\n    const {onMouseMove, children} = this.props;\n    if (onMouseMove) {\n      onMouseMove(event);\n    }\n    const seriesChildren = getSeriesChildren(children);\n    seriesChildren.forEach((child, index) => {\n      const component = this[`series${index}`];\n      if (component && component.onParentMouseMove) {\n        component.onParentMouseMove(event);\n      }\n    });\n  };\n\n  /**\n   * Trigger mouse-up related callbacks if they are available.\n   * @param {React.SyntheticEvent} event Mouse up event.\n   * @private\n   */\n  _mouseUpHandler = event => {\n    const {onMouseUp, children} = this.props;\n    if (onMouseUp) {\n      onMouseUp(event);\n    }\n    const seriesChildren = getSeriesChildren(children);\n    seriesChildren.forEach((child, index) => {\n      const component = this[`series${index}`];\n      if (component && component.onParentMouseUp) {\n        component.onParentMouseUp(event);\n      }\n    });\n  };\n\n  /**\n   * Trigger onTouchCancel handler if it was passed in props.\n   * @param {React.SyntheticEvent} event Touch Cancel event.\n   * @private\n   */\n  _touchCancelHandler = event => {\n    const {onTouchCancel} = this.props;\n    if (onTouchCancel) {\n      onTouchCancel(event);\n    }\n  };\n\n  /**\n   * Trigger onTouchEnd handler if it was passed in props.\n   * @param {React.SyntheticEvent} event Touch End event.\n   * @private\n   */\n  _touchEndHandler = event => {\n    const {onTouchEnd} = this.props;\n    if (onTouchEnd) {\n      onTouchEnd(event);\n    }\n  };\n\n  /**\n   * Trigger touch movement-related callbacks if they are available.\n   * @param {React.SyntheticEvent} event Touch move event.\n   * @private\n   */\n  _touchMoveHandler = event => {\n    const {onTouchMove, children} = this.props;\n    if (onTouchMove) {\n      onTouchMove(event);\n    }\n    const seriesChildren = getSeriesChildren(children);\n    seriesChildren.forEach((child, index) => {\n      const component = this[`series${index}`];\n      if (component && component.onParentTouchMove) {\n        component.onParentTouchMove(event);\n      }\n    });\n  };\n\n  /**\n   * Trigger touch-start related callbacks if they are available.\n   * @param {React.SyntheticEvent} event Touch start event.\n   * @private\n   */\n  _touchStartHandler = event => {\n    const {onTouchStart, children} = this.props;\n    if (onTouchStart) {\n      onTouchStart(event);\n    }\n    const seriesChildren = getSeriesChildren(children);\n    seriesChildren.forEach((child, index) => {\n      const component = this[`series${index}`];\n      if (component && component.onParentTouchStart) {\n        component.onParentTouchStart(event);\n      }\n    });\n  };\n\n  renderCanvasComponents(components) {\n    const componentsToRender = components.filter(\n      c => c && !c.type.requiresSVG && c.type.isCanvas\n    );\n\n    if (componentsToRender.length === 0) {\n      return null;\n    }\n    const {\n      marginLeft,\n      marginTop,\n      marginBottom,\n      marginRight,\n      innerHeight,\n      innerWidth\n    } = componentsToRender[0].props;\n    return (\n      <CanvasWrapper\n        {...{\n          innerHeight,\n          innerWidth,\n          marginLeft,\n          marginTop,\n          marginBottom,\n          marginRight\n        }}\n      >\n        {componentsToRender}\n      </CanvasWrapper>\n    );\n  }\n\n  render() {\n    const {\n      className,\n      dontCheckIfEmpty,\n      style,\n      width,\n      height,\n      onWheel\n    } = this.props;\n\n    if (!dontCheckIfEmpty && this._isPlotEmpty()) {\n      return (\n        <div\n          className={getCombinedClassName('rv-xy-plot', className)}\n          style={{\n            width: `${width}px`,\n            height: `${height}px`,\n            ...this.props.style\n          }}\n        />\n      );\n    }\n    const components = this._getClonedChildComponents();\n    return (\n      <div\n        style={{\n          width: `${width}px`,\n          height: `${height}px`\n        }}\n        className={getCombinedClassName('rv-xy-plot', className)}\n      >\n        <svg\n          className=\"rv-xy-plot__inner\"\n          width={width}\n          height={height}\n          style={style}\n          onClick={this._clickHandler}\n          onDoubleClick={this._doubleClickHandler}\n          onMouseDown={this._mouseDownHandler}\n          onMouseUp={this._mouseUpHandler}\n          onMouseMove={this._mouseMoveHandler}\n          onMouseLeave={this._mouseLeaveHandler}\n          onMouseEnter={this._mouseEnterHandler}\n          onTouchStart={this._mouseDownHandler}\n          onTouchMove={this._touchMoveHandler}\n          onTouchEnd={this._touchEndHandler}\n          onTouchCancel={this._touchCancelHandler}\n          onWheel={onWheel}\n        >\n          {components.filter(c => c && c.type.requiresSVG)}\n        </svg>\n        {this.renderCanvasComponents(components)}\n        {components.filter(c => c && !c.type.requiresSVG && !c.type.isCanvas)}\n      </div>\n    );\n  }\n}\n\nXYPlot.displayName = 'XYPlot';\n\nexport default XYPlot;\n"
  },
  {
    "path": "packages/react-vis/src/radar-chart/index.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport {scaleLinear} from 'd3-scale';\nimport {format} from 'd3-format';\n\nimport {AnimationPropType} from 'animation';\nimport XYPlot from 'plot/xy-plot';\nimport {DISCRETE_COLOR_RANGE} from 'theme';\nimport {MarginPropType} from 'utils/chart-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\nimport MarkSeries from 'plot/series/mark-series';\nimport PolygonSeries from 'plot/series/polygon-series';\nimport LabelSeries from 'plot/series/label-series';\nimport DecorativeAxis from 'plot/axis/decorative-axis';\n\nconst predefinedClassName = 'rv-radar-chart';\nconst DEFAULT_FORMAT = format('.2r');\n/**\n * Generate axes for each of the domains\n * @param {Object} props\n - props.animation {Boolean}\n - props.domains {Array} array of object specifying the way each axis is to be plotted\n - props.style {object} style object for the whole chart\n - props.tickFormat {Function} formatting function for axes\n - props.startingAngle {number} the initial angle offset\n * @return {Array} the plotted axis components\n */\nfunction getAxes(props) {\n  const {\n    animation,\n    domains,\n    startingAngle,\n    style,\n    tickFormat,\n    hideInnerMostValues\n  } = props;\n  return domains.map((domain, index) => {\n    const angle = (index / domains.length) * Math.PI * 2 + startingAngle;\n    const sortedDomain = domain.domain;\n\n    const domainTickFormat = t => {\n      if (hideInnerMostValues && t === sortedDomain[0]) {\n        return '';\n      }\n      return domain.tickFormat ? domain.tickFormat(t) : tickFormat(t);\n    };\n\n    return (\n      <DecorativeAxis\n        animation={animation}\n        key={`${index}-axis`}\n        axisStart={{x: 0, y: 0}}\n        axisEnd={{\n          x: getCoordinate(Math.cos(angle)),\n          y: getCoordinate(Math.sin(angle))\n        }}\n        axisDomain={sortedDomain}\n        numberOfTicks={5}\n        tickValue={domainTickFormat}\n        style={style.axes}\n      />\n    );\n  });\n}\n\n/**\n * Generate x or y coordinate for axisEnd\n * @param {Number} axisEndPoint\n - epsilon is an arbitrarily chosen small number to approximate axisEndPoints\n - to true values resulting from trigonometry functions (sin, cos) on angles\n * @return {Number} the x or y coordinate accounting for exact trig values\n */\nfunction getCoordinate(axisEndPoint) {\n  const epsilon = 10e-13;\n  if (Math.abs(axisEndPoint) <= epsilon) {\n    axisEndPoint = 0;\n  } else if (axisEndPoint > 0) {\n    if (Math.abs(axisEndPoint - 0.5) <= epsilon) {\n      axisEndPoint = 0.5;\n    }\n  } else if (axisEndPoint < 0) {\n    if (Math.abs(axisEndPoint + 0.5) <= epsilon) {\n      axisEndPoint = -0.5;\n    }\n  }\n  return axisEndPoint;\n}\n\n/**\n * Generate labels for the ends of the axes\n * @param {Object} props\n - props.domains {Array} array of object specifying the way each axis is to be plotted\n  - props.startingAngle {number} the initial angle offset\n - props.style {object} style object for just the labels\n * @return {Array} the prepped data for the labelSeries\n */\nfunction getLabels(props) {\n  const {domains, startingAngle, style} = props;\n  return domains.map(({name}, index) => {\n    const angle = (index / domains.length) * Math.PI * 2 + startingAngle;\n    const radius = 1.2;\n    return {\n      x: radius * Math.cos(angle),\n      y: radius * Math.sin(angle),\n      label: name,\n      style\n    };\n  });\n}\n\n/**\n * Generate the actual polygons to be plotted\n * @param {Object} props\n - props.animation {Boolean}\n - props.data {Array} array of object specifying what values are to be plotted\n - props.domains {Array} array of object specifying the way each axis is to be plotted\n - props.startingAngle {number} the initial angle offset\n - props.style {object} style object for the whole chart\n * @return {Array} the plotted axis components\n */\nfunction getPolygons(props) {\n  const {\n    animation,\n    colorRange,\n    domains,\n    data,\n    style,\n    startingAngle,\n    onSeriesMouseOver,\n    onSeriesMouseOut\n  } = props;\n\n  const scales = domains.reduce((acc, {domain, name}) => {\n    acc[name] = scaleLinear()\n      .domain(domain)\n      .range([0, 1]);\n    return acc;\n  }, {});\n\n  return data.map((row, rowIndex) => {\n    const mappedData = domains.map(({name, getValue}, index) => {\n      const dataPoint = getValue ? getValue(row) : row[name];\n      // error handling if point doesn't exist\n      const angle = (index / domains.length) * Math.PI * 2 + startingAngle;\n      // dont let the radius become negative\n      const radius = Math.max(scales[name](dataPoint), 0);\n      return {\n        x: radius * Math.cos(angle),\n        y: radius * Math.sin(angle),\n        name: row.name\n      };\n    });\n\n    return (\n      <PolygonSeries\n        animation={animation}\n        className={`${predefinedClassName}-polygon`}\n        key={`${rowIndex}-polygon`}\n        data={mappedData}\n        style={{\n          stroke:\n            row.color || row.stroke || colorRange[rowIndex % colorRange.length],\n          fill:\n            row.color || row.fill || colorRange[rowIndex % colorRange.length],\n          ...style.polygons\n        }}\n        onSeriesMouseOver={onSeriesMouseOver}\n        onSeriesMouseOut={onSeriesMouseOut}\n      />\n    );\n  });\n}\n\n/**\n * Generate circles at the polygon points for Hover functionality\n * @param {Object} props\n - props.animation {Boolean}\n - props.data {Array} array of object specifying what values are to be plotted\n - props.domains {Array} array of object specifying the way each axis is to be plotted\n - props.startingAngle {number} the initial angle offset\n - props.style {object} style object for the whole chart\n - props.onValueMouseOver {function} function to call on mouse over a polygon point\n - props.onValueMouseOver {function} function to call when mouse leaves a polygon point\n * @return {Array} the plotted axis components\n */\nfunction getPolygonPoints(props) {\n  const {\n    animation,\n    domains,\n    data,\n    startingAngle,\n    style,\n    onValueMouseOver,\n    onValueMouseOut\n  } = props;\n  if (!onValueMouseOver) {\n    return;\n  }\n  const scales = domains.reduce((acc, {domain, name}) => {\n    acc[name] = scaleLinear()\n      .domain(domain)\n      .range([0, 1]);\n    return acc;\n  }, {});\n  return data.map((row, rowIndex) => {\n    const mappedData = domains.map(({name, getValue}, index) => {\n      const dataPoint = getValue ? getValue(row) : row[name];\n      // error handling if point doesn't exist\n      const angle = (index / domains.length) * Math.PI * 2 + startingAngle;\n      // dont let the radius become negative\n      const radius = Math.max(scales[name](dataPoint), 0);\n      return {\n        x: radius * Math.cos(angle),\n        y: radius * Math.sin(angle),\n        domain: name,\n        value: dataPoint,\n        dataName: row.name\n      };\n    });\n\n    return (\n      <MarkSeries\n        animation={animation}\n        className={`${predefinedClassName}-polygonPoint`}\n        key={`${rowIndex}-polygonPoint`}\n        data={mappedData}\n        size={10}\n        style={{\n          ...style.polygons,\n          fill: 'transparent',\n          stroke: 'transparent'\n        }}\n        onValueMouseOver={onValueMouseOver}\n        onValueMouseOut={onValueMouseOut}\n      />\n    );\n  });\n}\n\nfunction RadarChart(props) {\n  const {\n    animation,\n    className,\n    children,\n    colorRange,\n    data,\n    domains,\n    height,\n    hideInnerMostValues,\n    margin,\n    onMouseLeave,\n    onMouseEnter,\n    startingAngle,\n    style,\n    tickFormat,\n    width,\n    renderAxesOverPolygons,\n    onValueMouseOver,\n    onValueMouseOut,\n    onSeriesMouseOver,\n    onSeriesMouseOut\n  } = props;\n\n  const axes = getAxes({\n    domains,\n    animation,\n    hideInnerMostValues,\n    startingAngle,\n    style,\n    tickFormat\n  });\n\n  const polygons = getPolygons({\n    animation,\n    colorRange,\n    domains,\n    data,\n    startingAngle,\n    style,\n    onSeriesMouseOver,\n    onSeriesMouseOut\n  });\n\n  const polygonPoints = getPolygonPoints({\n    animation,\n    colorRange,\n    domains,\n    data,\n    startingAngle,\n    style,\n    onValueMouseOver,\n    onValueMouseOut\n  });\n\n  const labelSeries = (\n    <LabelSeries\n      animation={animation}\n      key={className}\n      className={`${predefinedClassName}-label`}\n      data={getLabels({domains, style: style.labels, startingAngle})}\n    />\n  );\n  return (\n    <XYPlot\n      height={height}\n      width={width}\n      margin={margin}\n      dontCheckIfEmpty\n      className={getCombinedClassName(className, predefinedClassName)}\n      onMouseLeave={onMouseLeave}\n      onMouseEnter={onMouseEnter}\n      xDomain={[-1, 1]}\n      yDomain={[-1, 1]}\n    >\n      {children}\n      {!renderAxesOverPolygons &&\n        axes\n          .concat(polygons)\n          .concat(labelSeries)\n          .concat(polygonPoints)}\n      {renderAxesOverPolygons &&\n        polygons\n          .concat(labelSeries)\n          .concat(axes)\n          .concat(polygonPoints)}\n    </XYPlot>\n  );\n}\n\nRadarChart.displayName = 'RadarChart';\nRadarChart.propTypes = {\n  animation: AnimationPropType,\n  className: PropTypes.string,\n  colorType: PropTypes.string,\n  colorRange: PropTypes.arrayOf(PropTypes.string),\n  data: PropTypes.arrayOf(PropTypes.object).isRequired,\n  domains: PropTypes.arrayOf(\n    PropTypes.shape({\n      name: PropTypes.string.isRequired,\n      domain: PropTypes.arrayOf(PropTypes.number).isRequired,\n      tickFormat: PropTypes.func\n    })\n  ).isRequired,\n  height: PropTypes.number.isRequired,\n  hideInnerMostValues: PropTypes.bool,\n  margin: MarginPropType,\n  startingAngle: PropTypes.number,\n  style: PropTypes.shape({\n    axes: PropTypes.object,\n    labels: PropTypes.object,\n    polygons: PropTypes.object\n  }),\n  tickFormat: PropTypes.func,\n  width: PropTypes.number.isRequired,\n  renderAxesOverPolygons: PropTypes.bool,\n  onValueMouseOver: PropTypes.func,\n  onValueMouseOut: PropTypes.func,\n  onSeriesMouseOver: PropTypes.func,\n  onSeriesMouseOut: PropTypes.func\n};\nRadarChart.defaultProps = {\n  className: '',\n  colorType: 'category',\n  colorRange: DISCRETE_COLOR_RANGE,\n  hideInnerMostValues: true,\n  startingAngle: Math.PI / 2,\n  style: {\n    axes: {\n      line: {},\n      ticks: {},\n      text: {}\n    },\n    labels: {\n      fontSize: 10,\n      textAnchor: 'middle'\n    },\n    polygons: {\n      strokeWidth: 0.5,\n      strokeOpacity: 1,\n      fillOpacity: 0.1\n    }\n  },\n  tickFormat: DEFAULT_FORMAT,\n  renderAxesOverPolygons: false\n};\n\nexport default RadarChart;\n"
  },
  {
    "path": "packages/react-vis/src/radial-chart/index.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport {pie as pieBuilder} from 'd3-shape';\n\nimport {AnimationPropType} from 'animation';\nimport ArcSeries from 'plot/series/arc-series';\nimport LabelSeries from 'plot/series/label-series';\nimport XYPlot from 'plot/xy-plot';\nimport {DISCRETE_COLOR_RANGE} from 'theme';\nimport {MarginPropType, getRadialLayoutMargin} from 'utils/chart-utils';\nimport {getRadialDomain} from 'utils/series-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst predefinedClassName = 'rv-radial-chart';\n\nconst DEFAULT_RADIUS_MARGIN = 15;\n\n/**\n * Create the list of wedges to render.\n * @param {Object} props\n   props.data {Object} - tree structured data (each node has a name anc an array of children)\n * @returns {Array} Array of nodes.\n */\nfunction getWedgesToRender({data, getAngle}) {\n  const pie = pieBuilder()\n    .sort(null)\n    .value(getAngle);\n  const pieData = pie(data).reverse();\n  return pieData.map((row, index) => {\n    return {\n      ...row.data,\n      angle0: row.startAngle,\n      angle: row.endAngle,\n      radius0: row.data.innerRadius || 0,\n      radius: row.data.radius || 1,\n      color: row.data.color || index\n    };\n  });\n}\n\nfunction generateLabels(mappedData, accessors, labelsRadiusMultiplier = 1.1) {\n  const {getLabel, getSubLabel} = accessors;\n  return mappedData.reduce((res, row) => {\n    const {angle, angle0, radius} = row;\n    const centeredAngle = (angle + angle0) / 2;\n\n    // unfortunate, but true fact: d3 starts its radians at 12 oclock rather than 3\n    // and move clockwise rather than counter clockwise. why why why!\n    const updatedAngle = -1 * centeredAngle + Math.PI / 2;\n    const newLabels = [];\n    if (getLabel(row)) {\n      newLabels.push({\n        angle: updatedAngle,\n        radius: radius * labelsRadiusMultiplier,\n        label: getLabel(row)\n      });\n    }\n\n    if (getSubLabel(row)) {\n      newLabels.push({\n        angle: updatedAngle,\n        radius: radius * labelsRadiusMultiplier,\n        label: getSubLabel(row),\n        style: {fontSize: 10},\n        yOffset: 12\n      });\n    }\n    return res.concat(newLabels);\n  }, []);\n  // could add force direction here to make sure the labels dont overlap\n}\n\n/**\n * Get the max radius so the chart can extend to the margin.\n * @param  {Number} width - container width\n * @param  {Number} height - container height\n * @return {Number} radius\n */\nfunction getMaxRadius(width, height) {\n  return Math.min(width, height) / 2 - DEFAULT_RADIUS_MARGIN;\n}\n\nfunction RadialChart(props) {\n  const {\n    animation,\n    className,\n    children,\n    colorType,\n    data,\n    getAngle,\n    getLabel,\n    getSubLabel,\n    height,\n    hideRootNode,\n    innerRadius,\n    labelsAboveChildren,\n    labelsRadiusMultiplier,\n    labelsStyle,\n    margin,\n    onMouseLeave,\n    onMouseEnter,\n    radius,\n    showLabels,\n    style,\n    width\n  } = props;\n  const mappedData = getWedgesToRender({\n    data,\n    height,\n    hideRootNode,\n    width,\n    getAngle\n  });\n  const radialDomain = getRadialDomain(mappedData);\n  const arcProps = {\n    colorType,\n    ...props,\n    animation,\n    radiusDomain: [0, radialDomain],\n    data: mappedData,\n    radiusNoFallBack: true,\n    style,\n    arcClassName: 'rv-radial-chart__series--pie__slice'\n  };\n  if (radius) {\n    arcProps.radiusDomain = [0, 1];\n    arcProps.radiusRange = [innerRadius || 0, radius];\n    arcProps.radiusType = 'linear';\n  }\n  const maxRadius = radius ? radius : getMaxRadius(width, height);\n  const defaultMargin = getRadialLayoutMargin(width, height, maxRadius);\n\n  const labels = generateLabels(\n    mappedData,\n    {\n      getLabel,\n      getSubLabel\n    },\n    labelsRadiusMultiplier\n  );\n  return (\n    <XYPlot\n      height={height}\n      width={width}\n      margin={{\n        ...defaultMargin,\n        ...margin\n      }}\n      className={getCombinedClassName(className, predefinedClassName)}\n      onMouseLeave={onMouseLeave}\n      onMouseEnter={onMouseEnter}\n      xDomain={[-radialDomain, radialDomain]}\n      yDomain={[-radialDomain, radialDomain]}\n    >\n      <ArcSeries {...arcProps} getAngle={d => d.angle} />\n      {showLabels && !labelsAboveChildren && (\n        <LabelSeries data={labels} style={labelsStyle} />\n      )}\n      {children}\n      {showLabels && labelsAboveChildren && (\n        <LabelSeries data={labels} style={labelsStyle} />\n      )}\n    </XYPlot>\n  );\n}\n\nRadialChart.displayName = 'RadialChart';\nRadialChart.propTypes = {\n  animation: AnimationPropType,\n  className: PropTypes.string,\n  colorType: PropTypes.string,\n  data: PropTypes.arrayOf(\n    PropTypes.shape({\n      angle: PropTypes.number,\n      className: PropTypes.string,\n      label: PropTypes.string,\n      radius: PropTypes.number,\n      style: PropTypes.object\n    })\n  ).isRequired,\n  getAngle: PropTypes.func,\n  getAngle0: PropTypes.func,\n  padAngle: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),\n  getRadius: PropTypes.func,\n  getRadius0: PropTypes.func,\n  getLabel: PropTypes.func,\n  height: PropTypes.number.isRequired,\n  labelsAboveChildren: PropTypes.bool,\n  labelsStyle: PropTypes.object,\n  margin: MarginPropType,\n  onValueClick: PropTypes.func,\n  onValueMouseOver: PropTypes.func,\n  onValueMouseOut: PropTypes.func,\n  showLabels: PropTypes.bool,\n  style: PropTypes.object,\n  subLabel: PropTypes.func,\n  width: PropTypes.number.isRequired\n};\nRadialChart.defaultProps = {\n  className: '',\n  colorType: 'category',\n  colorRange: DISCRETE_COLOR_RANGE,\n  padAngle: 0,\n  getAngle: d => d.angle,\n  getAngle0: d => d.angle0,\n  getRadius: d => d.radius,\n  getRadius0: d => d.radius0,\n  getLabel: d => d.label,\n  getSubLabel: d => d.subLabel\n};\n\nexport default RadialChart;\n"
  },
  {
    "path": "packages/react-vis/src/sankey/index.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  sankey,\n  sankeyLinkHorizontal,\n  sankeyLeft,\n  sankeyRight,\n  sankeyCenter,\n  sankeyJustify\n} from 'd3-sankey';\nimport XYPlot from 'plot/xy-plot';\n\nimport {MarginPropType, getInnerDimensions} from 'utils/chart-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\nimport VerticalRectSeries from 'plot/series/vertical-rect-series';\nimport LabelSeries from 'plot/series/label-series';\nimport Voronoi from 'plot/voronoi';\nimport {DISCRETE_COLOR_RANGE} from 'theme';\n\nimport SankeyLink from './sankey-link';\nconst NOOP = f => f;\n\nconst ALIGNMENTS = {\n  justify: sankeyJustify,\n  center: sankeyCenter,\n  left: sankeyLeft,\n  right: sankeyRight\n};\n\nconst DEFAULT_MARGINS = {\n  top: 20,\n  left: 20,\n  right: 20,\n  bottom: 20\n};\n\nfunction Sankey(props) {\n  const {\n    align,\n    animation,\n    children,\n    className,\n    hasVoronoi,\n    height,\n    hideLabels,\n    labelRotation,\n    layout,\n    links,\n    linkOpacity,\n    margin,\n    nodePadding,\n    nodes,\n    nodeWidth,\n    onValueClick,\n    onValueMouseOver,\n    onValueMouseOut,\n    onLinkClick,\n    onLinkMouseOver,\n    onLinkMouseOut,\n    style,\n    width\n  } = props;\n  // d3-sankey sankeyInstance no longer accepts empty nodes array, return empty XYPlot by default\n  if (nodes.length === 0) {\n    return (\n      <XYPlot\n        {...props}\n        yType=\"literal\"\n        className={getCombinedClassName('rv-sankey', className)}\n      />\n    );\n  }\n\n  const nodesCopy = [...new Array(nodes.length)].map((e, i) => ({\n    ...nodes[i]\n  }));\n  const linksCopy = [...new Array(links.length)].map((e, i) => ({\n    ...links[i]\n  }));\n\n  const {marginLeft, marginTop, marginRight, marginBottom} = getInnerDimensions(\n    {\n      margin,\n      height,\n      width\n    },\n    DEFAULT_MARGINS\n  );\n  const sankeyInstance = sankey()\n    .extent([\n      [marginLeft, marginTop],\n      [width - marginRight, height - marginBottom - marginTop]\n    ])\n    .nodeWidth(nodeWidth)\n    .nodePadding(nodePadding)\n    .nodes(nodesCopy)\n    .links(linksCopy)\n    .nodeAlign(ALIGNMENTS[align])\n    .iterations(layout);\n  sankeyInstance(nodesCopy);\n\n  const nWidth = sankeyInstance.nodeWidth();\n  const path = sankeyLinkHorizontal();\n\n  return (\n    <XYPlot\n      {...props}\n      yType=\"literal\"\n      className={getCombinedClassName('rv-sankey', className)}\n    >\n      {linksCopy.map((link, i) => (\n        <SankeyLink\n          style={style.links}\n          data={path(link)}\n          opacity={link.opacity || linkOpacity}\n          color={link.color}\n          onLinkClick={onLinkClick}\n          onLinkMouseOver={onLinkMouseOver}\n          onLinkMouseOut={onLinkMouseOut}\n          strokeWidth={Math.max(link.width, 1)}\n          node={link}\n          nWidth={nWidth}\n          key={`link-${i}`}\n        />\n      ))}\n      <VerticalRectSeries\n        animation={animation}\n        className={getCombinedClassName(className, 'rv-sankey__node')}\n        data={nodesCopy.map(node => ({\n          ...node,\n          y: node.y1 - marginTop,\n          y0: node.y0 - marginTop,\n          x: node.x1,\n          x0: node.x0,\n          color: node.color || DISCRETE_COLOR_RANGE[0],\n          sourceLinks: null,\n          targetLinks: null\n        }))}\n        style={style.rects}\n        onValueClick={onValueClick}\n        onValueMouseOver={onValueMouseOver}\n        onValueMouseOut={onValueMouseOut}\n        colorType=\"literal\"\n      />\n      {!hideLabels && (\n        <LabelSeries\n          animation={animation}\n          className={className}\n          rotation={labelRotation}\n          labelAnchorY=\"text-before-edge\"\n          data={nodesCopy.map((node, i) => {\n            return {\n              x: node.x0 + (node.x0 < width / 2 ? nWidth + 10 : -10),\n              y: (node.y0 + node.y1) / 2 - marginTop,\n              label: node.name,\n              style: {\n                textAnchor: node.x0 < width / 2 ? 'start' : 'end',\n                dy: '-.5em',\n                ...style.labels\n              },\n              // unfortunately this can not be ...node as the version\n              // found in nodesCopy is modified by the sankey process\n              ...nodes[i]\n            };\n          })}\n        />\n      )}\n      {hasVoronoi && (\n        <Voronoi\n          className=\"rv-sankey__voronoi\"\n          extent={[\n            [-marginLeft, -marginTop],\n            [width + marginRight, height + marginBottom]\n          ]}\n          nodes={nodesCopy}\n          onClick={onValueClick}\n          onHover={onValueMouseOver}\n          onBlur={onValueMouseOut}\n          x={d => d.x0 + (d.x1 - d.x0) / 2}\n          y={d => d.y0 + (d.y1 - d.y0) / 2}\n        />\n      )}\n      {children}\n    </XYPlot>\n  );\n}\n\nSankey.defaultProps = {\n  align: 'justify',\n  className: '',\n  hasVoronoi: false,\n  hideLabels: false,\n  labelRotation: 0,\n  layout: 50,\n  margin: DEFAULT_MARGINS,\n  nodePadding: 10,\n  nodeWidth: 10,\n  onValueMouseOver: NOOP,\n  onValueClick: NOOP,\n  onValueMouseOut: NOOP,\n  onLinkClick: NOOP,\n  onLinkMouseOver: NOOP,\n  onLinkMouseOut: NOOP,\n  style: {\n    links: {},\n    rects: {},\n    labels: {}\n  }\n};\n\nSankey.propTypes = {\n  align: PropTypes.oneOf(['justify', 'left', 'right', 'center']),\n  className: PropTypes.string,\n  hasVoronoi: PropTypes.bool,\n  height: PropTypes.number.isRequired,\n  hideLabels: PropTypes.bool,\n  labelRotation: PropTypes.number,\n  layout: PropTypes.number,\n  links: PropTypes.arrayOf(\n    PropTypes.shape({\n      source: PropTypes.oneOfType([PropTypes.number, PropTypes.object])\n        .isRequired,\n      target: PropTypes.oneOfType([PropTypes.number, PropTypes.object])\n        .isRequired\n    })\n  ).isRequired,\n  margin: MarginPropType,\n  nodePadding: PropTypes.number,\n  nodes: PropTypes.arrayOf(PropTypes.object).isRequired,\n  nodeWidth: PropTypes.number,\n  onValueMouseOver: PropTypes.func,\n  onValueClick: PropTypes.func,\n  onValueMouseOut: PropTypes.func,\n  onLinkClick: PropTypes.func,\n  onLinkMouseOver: PropTypes.func,\n  onLinkMouseOut: PropTypes.func,\n  style: PropTypes.shape({\n    links: PropTypes.object,\n    rects: PropTypes.object,\n    labels: PropTypes.object\n  }),\n  width: PropTypes.number.isRequired\n};\nexport default Sankey;\n"
  },
  {
    "path": "packages/react-vis/src/sankey/sankey-link.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {DISCRETE_COLOR_RANGE} from 'theme';\nimport Animation from 'animation';\nimport {ANIMATED_SERIES_PROPS} from 'utils/series-utils';\n\nconst DEFAULT_LINK_COLOR = DISCRETE_COLOR_RANGE[1];\nconst DEFAULT_LINK_OPACITY = 0.7;\n\nfunction SankeyLink(props) {\n  const {\n    animation,\n    data,\n    node,\n    opacity,\n    color,\n    strokeWidth,\n    style,\n    onLinkClick,\n    onLinkMouseOver,\n    onLinkMouseOut\n  } = props;\n  if (animation) {\n    return (\n      <Animation {...props} animatedProps={ANIMATED_SERIES_PROPS}>\n        <SankeyLink {...props} animation={null} />\n      </Animation>\n    );\n  }\n  return (\n    <path\n      d={data}\n      {...style}\n      className=\"rv-sankey__link\"\n      opacity={Number.isFinite(opacity) ? opacity : DEFAULT_LINK_OPACITY}\n      stroke={color || DEFAULT_LINK_COLOR}\n      onClick={e => onLinkClick(node, e)}\n      onMouseOver={e => onLinkMouseOver(node, e)}\n      onMouseOut={e => onLinkMouseOut(node, e)}\n      strokeWidth={strokeWidth}\n      fill=\"none\"\n    />\n  );\n}\n\nSankeyLink.displayName = 'SankeyLink';\nSankeyLink.requiresSVG = true;\nexport default SankeyLink;\n"
  },
  {
    "path": "packages/react-vis/src/styles/examples.scss",
    "content": "@import '../main.scss';\n\n$black: #000;\n$white: #fff;\n\nbody {\n  font-family: Sintony, Helvetica, sans-serif;\n  font-size: 14px;\n  margin: 0;\n  padding: 0;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5 {\n  font-weight: normal;\n}\n\nh1 {\n  font-size: 36px;\n  margin: 20px 0;\n}\n\nh2 {\n  font-size: 24px;\n  margin: 15px 0;\n}\n\nmain {\n  padding: 40px 0;\n}\n\nheader {\n  background: #f0f0f0;\n  line-height: 40px;\n  position: fixed;\n  top: 0;\n  width: 100%;\n  z-index: 1000;\n}\n\n.flex {\n  display: flex;\n}\n\n.docs-link {\n  font-weight: 500;\n  font-size: 11px;\n  margin-right: 5px;\n  text-transform: uppercase;\n  border-left: 1px solid #c0c0c0;\n  padding-left: 5px;\n  line-height: 1;\n}\n\n.docs-link:first-child {\n  border-left: 0px;\n  padding-left: 0px;\n}\n\n.docs-comment {\n  display: flex;\n  max-width: 300px;\n}\n\n.header-contents {\n  align-items: center;\n  display: flex;\n  justify-content: space-between;\n  padding: 0 20px;\n}\n\n.header-logo {\n  color: $black;\n  float: left;\n  font-size: 20px;\n  text-decoration: none;\n}\n\n.background-overlay {\n  bottom: 0;\n  left: 0;\n  position: fixed;\n  right: 0;\n  top: 0;\n  z-index: 1;\n}\n\n.dropdown-button {\n  cursor: pointer;\n  z-index: 10;\n}\n\n.dropdown-wrapper {\n  display: flex;\n  position: relative;\n\n  .dropdown-inner-wrapper {\n    background: $white;\n    border: 2px solid $black;\n    display: flex;\n    flex-direction: column;\n    font-size: 11px;\n    height: auto;\n    list-style: none;\n    padding: 10px;\n    position: absolute;\n    right: -5px;\n    top: 25px;\n    width: 150px;\n    z-index: 10;\n  }\n\n  a {\n    display: flex;\n    height: auto;\n    line-height: 15px;\n    text-decoration: none;\n  }\n\n  li {\n    display: flex;\n    height: 100%;\n  }\n\n  .subsection-label {\n    font-weight: 600;\n    line-height: 15px;\n  }\n}\n\n\narticle {\n  display: flex;\n  flex-direction: row;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n  margin: 0 auto;\n  max-width: 1200px;\n  min-width: 650px;\n  padding: 30px 20px 0;\n\n  h1,\n  h2 {\n    flex: 1 100%;\n\n    small {\n      color: #6b6b76;\n      font-size: 50%;\n    }\n  }\n\n  section {\n    flex-basis: 400px;\n    flex-grow: 1;\n    margin: 0 0 40px;\n  }\n\n  .section-title {\n    margin-bottom: 5px;\n  }\n\n  .section-header {\n    margin-bottom: 1em;\n  }\n}\n\n.click-me {\n  border: 0;\n  background: #ef5d28;\n  color: $white;\n  cursor: pointer;\n  font-family: Sintony, Helvetica, sans-serif;\n  font-size: 14px;\n  outline: none;\n  padding: 11px 20px;\n  text-transform: uppercase;\n\n  &:hover {\n    background: #ff9833;\n  }\n\n  animation: shake 5s 1s cubic-bezier(0.36, 0.07, 0.19, 0.97) both infinite;\n  transform: translate3d(0, 0, 0);\n}\n\n@keyframes shake {\n  1%,\n  9% {\n    transform: translate3d(-1px, 0, 0);\n  }\n\n  2%,\n  8% {\n    transform: translate3d(2px, 0, 0);\n  }\n\n  3%,\n  5%,\n  7% {\n    transform: translate3d(-4px, 0, 0);\n  }\n\n  4%,\n  6% {\n    transform: translate3d(4px, 0, 0);\n  }\n}\n\n.example-with-click-me {\n  position: relative;\n  text-align: center;\n  width: 100%;\n\n  &:hover {\n    .click-me {\n      animation: none;\n    }\n  }\n\n  .chart {\n    margin-right: 200px;\n    .rv-xy-plot__axis__tick__line {\n      stroke: $rv-xy-plot-axis-font-color;\n    }\n  }\n\n  .legend {\n    position: absolute;\n    text-align: left;\n    right: 0;\n  }\n}\n\n.custom-hint {\n  background: #f9e7bb;\n  border-radius: 3px;\n  border: 1px solid #edaf00;\n  padding: 10px;\n  color: #333;\n  font-size: 10px;\n  position: relative;\n  margin: 12px 0 0 -10px;\n\n  &::after {\n    border-radius: 5px;\n    border: 2px solid #edaf00;\n    background: $white;\n    display: block;\n    content: ' ';\n    height: 6px;\n    width: 6px;\n    top: -17px;\n    left: 5px;\n    position: absolute;\n  }\n}\n\n.complex-hint {\n  margin-top: 40px;\n\n  .rv-hint {\n    /* must be positioned in a parent with relative positioning */\n    position: absolute;\n    width: 0;\n    height: 100%;\n    $hint-color: black;\n    $margin-left: 30px;\n    $margin-right: 10px;\n    $margin-top: 10px;\n    $margin-bottom: 25px;\n\n    & .hint--text-container {\n      position: absolute;\n\n      /*\n       * set to 0,0 so that its content (including children)\n       * can overflow out in vertical and horizontal\n       */\n      width: 0;\n      height: 0;\n\n      /*\n       * use flex to place its children (centered) and aligned (bottom).\n       * As its height is 0, align-items flex-end paints its items from cross-axis\n       * up.  flex-start, its items would paint from cross-axis down.\n       */\n      display: flex;\n      justify-content: center;\n\n      &.rightEdge-top {\n        flex-direction: column-reverse;\n        align-items: flex-start;\n      }\n\n      &.left-topEdge {\n        flex-direction: row;\n        align-items: flex-end;\n      }\n\n      &.left-bottomEdge {\n        flex-direction: row;\n        align-items: flex-start;\n      }\n\n      &.leftEdge-top {\n        flex-direction: column;\n        align-items: flex-end;\n      }\n\n      & .hint--text {\n        /* text content uses -micro padding */\n        padding: 4px;\n        border: 2px solid $hint-color;\n        color: $hint-color;\n        white-space: nowrap;\n      }\n    }\n\n    & .hint--pole {\n      position: absolute;\n\n      &.rightEdge-top {\n        top: -1px;\n        left: -$margin-right;\n        border-top: 2px solid $hint-color;\n        width: $margin-right;\n        height: 0;\n      }\n\n      &.left-topEdge {\n        border-left: 2px solid $hint-color;\n        left: -1px;\n        height: $margin-top;\n        width: 0;\n        top: 0;\n      }\n\n      &.left-bottomEdge {\n        border-left: 2px solid $hint-color;\n        left: -1px;\n        height: $margin-bottom;\n        width: 0;\n        top: -$margin-bottom;\n      }\n\n      &.leftEdge-top {\n        top: -1px;\n        border-top: 2px solid $hint-color;\n        width: $margin-left;\n        height: 0;\n      }\n    }\n  }\n\n  .rv-hint--horizontalAlign-rightEdge.rv-hint--verticalAlign-top {\n    width: 0;\n    height: 0;\n  }\n\n  .rv-hint--horizontalAlign-left.rv-hint--verticalAlign-topEdge {\n    width: 0;\n    height: 100%;\n  }\n\n  .rv-hint--horizontalAlign-left.rv-hint--verticalAlign-bottomEdge {\n    width: 0;\n    height: 0;\n  }\n\n  .rv-hint--horizontalAlign-leftEdge.rv-hint--verticalAlign-top {\n    width: 100%;\n    height: 0;\n  }\n}\n\n.centered-and-flexed {\n  align-items: center;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  padding: 0 10px;\n\n  .centered-and-flexed-controls {\n    align-items: center;\n    display: flex;\n    justify-content: space-between;\n    padding: 10px 0;\n    width: 75%;\n  }\n}\n\n.dynamic-treemap-example {\n  .rv-treemap__leaf--circle {\n    border: thin solid white;\n  }\n}\n\n.clustered-stacked-bar-chart-example {\n  .rv-discrete-color-legend {\n    left: 40px;\n    position: absolute;\n    top: 0;\n  }\n}\n\n.basic-sunburst-example-path-name {\n  height: 20px;\n}\n\n.showcase-button {\n  background: $white;\n  border: thin solid #333;\n  border-radius: 5px;\n  cursor: pointer;\n  font-size: 10px;\n  font-weight: 600;\n  padding: 5px 10px;\n}\n\n.donut-chart-example {\n  .rv-radial-chart__series--pie__slice:hover {\n    stroke: $black !important;\n    stroke-width: 2px !important;\n  }\n}\n\n.parallel-coordinates-example {\n  .rv-xy-plot__series--line {\n    stroke: #12939A !important;\n\n    &:hover {\n      stroke: #F15C17 !important;\n    }\n  }\n}\n\n\n.canvas-example-controls {\n  display: flex;\n}\n\n.canvas-wrapper {\n  align-items: center;\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n}\n\n.highlight-container {\n  cursor: crosshair;\n}\n\n.no-select {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n"
  },
  {
    "path": "packages/react-vis/src/styles/legends.scss",
    "content": "$rv-legend-enabled-color: #3a3a48;\n$rv-legend-disabled-color: #b8b8b8;\n\n.rv-discrete-color-legend {\n  box-sizing: border-box;\n  overflow-y: auto;\n  font-size: 12px;\n\n  &.horizontal {\n    white-space: nowrap;\n  }\n}\n\n.rv-discrete-color-legend-item {\n  color: $rv-legend-enabled-color;\n  border-radius: 1px;\n  padding: 9px 10px;\n\n  &.horizontal {\n    display: inline-block;\n\n    .rv-discrete-color-legend-item__title {\n      margin-left: 0;\n      display: block;\n    }\n  }\n}\n\n.rv-discrete-color-legend-item__color {\n  display: inline-block;\n  vertical-align: middle;\n  overflow: visible;\n}\n\n.rv-discrete-color-legend-item__color__path {\n  stroke: #dcdcdc;\n  stroke-width: 2px;\n}\n\n.rv-discrete-color-legend-item__title {\n  margin-left: 10px;\n}\n\n.rv-discrete-color-legend-item.disabled {\n  color: $rv-legend-disabled-color;\n}\n\n.rv-discrete-color-legend-item.clickable {\n  cursor: pointer;\n\n  &:hover {\n    background: #f9f9f9;\n  }\n}\n\n.rv-search-wrapper {\n  display: flex;\n  flex-direction: column;\n}\n\n.rv-search-wrapper__form {\n  flex: 0;\n}\n\n.rv-search-wrapper__form__input {\n  width: 100%;\n  color: #a6a6a5;\n  border: 1px solid #e5e5e4;\n  padding: 7px 10px;\n  font-size: 12px;\n  box-sizing: border-box;\n  border-radius: 2px;\n  margin: 0 0 9px;\n  outline: 0;\n}\n\n.rv-search-wrapper__contents {\n  flex: 1;\n  overflow: auto;\n}\n\n.rv-continuous-color-legend {\n  font-size: 12px;\n\n  .rv-gradient {\n    height: 4px;\n    border-radius: 2px;\n    margin-bottom: 5px;\n  }\n}\n\n.rv-continuous-size-legend {\n  font-size: 12px;\n\n  .rv-bubbles {\n    text-align: justify;\n    overflow: hidden;\n    margin-bottom: 5px;\n    width: 100%;\n  }\n\n  .rv-bubble {\n    background: #d8d9dc;\n    display: inline-block;\n    vertical-align: bottom;\n  }\n\n  .rv-spacer {\n    display: inline-block;\n    font-size: 0;\n    line-height: 0;\n    width: 100%;\n  }\n}\n\n.rv-legend-titles {\n  height: 16px;\n  position: relative;\n}\n\n.rv-legend-titles__left,\n.rv-legend-titles__right,\n.rv-legend-titles__center {\n  position: absolute;\n  white-space: nowrap;\n  overflow: hidden;\n}\n\n.rv-legend-titles__center {\n  display: block;\n  text-align: center;\n  width: 100%;\n}\n\n.rv-legend-titles__right {\n  right: 0;\n}\n"
  },
  {
    "path": "packages/react-vis/src/styles/plot.scss",
    "content": "$rv-xy-plot-axis-font-color: #6b6b76;\n$rv-xy-plot-axis-line-color: #e6e6e9;\n$rv-xy-plot-axis-font-size: 11px;\n$rv-xy-plot-tooltip-background: #3a3a48;\n$rv-xy-plot-tooltip-color: #fff;\n$rv-xy-plot-tooltip-font-size: 12px;\n$rv-xy-plot-tooltip-border-radius: 4px;\n$rv-xy-plot-tooltip-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);\n$rv-xy-plot-tooltip-padding: 7px 10px;\n\n.rv-xy-plot {\n  color: #c3c3c3;\n  position: relative;\n\n  canvas {\n    pointer-events: none;\n  }\n\n  .rv-xy-canvas {\n    pointer-events: none;\n    position: absolute;\n  }\n}\n\n.rv-xy-plot__inner {\n  display: block;\n}\n\n.rv-xy-plot__axis__line {\n  fill: none;\n  stroke-width: 2px;\n  stroke: $rv-xy-plot-axis-line-color;\n}\n\n.rv-xy-plot__axis__tick__line {\n  stroke: $rv-xy-plot-axis-line-color;\n}\n\n.rv-xy-plot__axis__tick__text {\n  fill: $rv-xy-plot-axis-font-color;\n  font-size: $rv-xy-plot-axis-font-size;\n}\n\n.rv-xy-plot__axis__title {\n  text {\n    fill: $rv-xy-plot-axis-font-color;\n    font-size: $rv-xy-plot-axis-font-size;\n  }\n}\n\n.rv-xy-plot__grid-lines__line {\n  stroke: $rv-xy-plot-axis-line-color;\n}\n\n.rv-xy-plot__circular-grid-lines__line {\n  fill-opacity: 0;\n  stroke: $rv-xy-plot-axis-line-color;\n}\n\n.rv-xy-plot__series,\n.rv-xy-plot__series path {\n  pointer-events: all;\n}\n\n.rv-xy-plot__series--line {\n  fill: none;\n  stroke: #000;\n  stroke-width: 2px;\n}\n\n.rv-crosshair {\n  position: absolute;\n  font-size: 11px;\n  pointer-events: none;\n}\n\n.rv-crosshair__line {\n  background: #47d3d9;\n  width: 1px;\n}\n\n.rv-crosshair__inner {\n  position: absolute;\n  text-align: left;\n  top: 0;\n}\n\n.rv-crosshair__inner__content {\n  border-radius: $rv-xy-plot-tooltip-border-radius;\n  background: $rv-xy-plot-tooltip-background;\n  color: $rv-xy-plot-tooltip-color;\n  font-size: $rv-xy-plot-tooltip-font-size;\n  padding: $rv-xy-plot-tooltip-padding;\n  box-shadow: $rv-xy-plot-tooltip-shadow;\n}\n\n.rv-crosshair__inner--left {\n  right: 4px;\n}\n\n.rv-crosshair__inner--right {\n  left: 4px;\n}\n\n.rv-crosshair__title {\n  font-weight: bold;\n  white-space: nowrap;\n}\n\n.rv-crosshair__item {\n  white-space: nowrap;\n}\n\n.rv-hint {\n  position: absolute;\n  pointer-events: none;\n}\n\n.rv-hint__content {\n  border-radius: $rv-xy-plot-tooltip-border-radius;\n  padding: $rv-xy-plot-tooltip-padding;\n  font-size: $rv-xy-plot-tooltip-font-size;\n  background: $rv-xy-plot-tooltip-background;\n  box-shadow: $rv-xy-plot-tooltip-shadow;\n  color: $rv-xy-plot-tooltip-color;\n  text-align: left;\n  white-space: nowrap;\n}\n"
  },
  {
    "path": "packages/react-vis/src/styles/radial-chart.scss",
    "content": ".rv-radial-chart {\n\n  .rv-xy-plot__series--label {\n    pointer-events: none;\n  }\n}\n"
  },
  {
    "path": "packages/react-vis/src/styles/treemap.scss",
    "content": ".rv-treemap {\n  font-size: 12px;\n  position: relative;\n}\n\n.rv-treemap__leaf {\n  overflow: hidden;\n  position: absolute;\n}\n\n.rv-treemap__leaf--circle {\n  align-items: center;\n  border-radius: 100%;\n  display: flex;\n  justify-content: center;\n}\n\n.rv-treemap__leaf__content {\n  overflow: hidden;\n  padding: 10px;\n  text-overflow: ellipsis;\n}\n"
  },
  {
    "path": "packages/react-vis/src/sunburst/index.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport {hierarchy, partition} from 'd3-hierarchy';\nimport {scaleLinear, scaleSqrt} from 'd3-scale';\n\nimport {AnimationPropType} from 'animation';\nimport LabelSeries from 'plot/series/label-series';\nimport ArcSeries from 'plot/series/arc-series';\nimport XYPlot from 'plot/xy-plot';\nimport {getRadialDomain} from 'utils/series-utils';\nimport {getRadialLayoutMargin} from 'utils/chart-utils';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst predefinedClassName = 'rv-sunburst';\n\nconst LISTENERS_TO_OVERWRITE = [\n  'onValueMouseOver',\n  'onValueMouseOut',\n  'onValueClick',\n  'onValueRightClick',\n  'onSeriesMouseOver',\n  'onSeriesMouseOut',\n  'onSeriesClick',\n  'onSeriesRightClick'\n];\n\n/**\n * Create the list of nodes to render.\n * @param {Object} props\n   props.data {Object} - tree structured data (each node has a name anc an array of children)\n   props.height {number} - the height of the graphic to be rendered\n   props.hideRootNode {boolean} - whether or not to hide the root node\n   props.width {number} - the width of the graphic to be rendered\n   props.getSize {function} - accessor for the size\n * @returns {Array} Array of nodes.\n */\nfunction getNodesToRender({data, height, hideRootNode, width, getSize}) {\n  const partitionFunction = partition();\n  const structuredInput = hierarchy(data).sum(getSize);\n  const radius = Math.min(width, height) / 2 - 10;\n  const x = scaleLinear().range([0, 2 * Math.PI]);\n  const y = scaleSqrt().range([0, radius]);\n\n  return partitionFunction(structuredInput)\n    .descendants()\n    .reduce((res, cell, index) => {\n      if (hideRootNode && index === 0) {\n        return res;\n      }\n\n      return res.concat([\n        {\n          angle0: Math.max(0, Math.min(2 * Math.PI, x(cell.x0))),\n          angle: Math.max(0, Math.min(2 * Math.PI, x(cell.x1))),\n          radius0: Math.max(0, y(cell.y0)),\n          radius: Math.max(0, y(cell.y1)),\n          depth: cell.depth,\n          parent: cell.parent,\n          ...cell.data\n        }\n      ]);\n    }, []);\n}\n\n/**\n * Convert arc nodes into label rows.\n * Important to use mappedData rather than regular data, bc it is already unrolled\n * @param {Array} mappedData - Array of nodes.\n * @param {Object} accessors - object of accessors\n * @returns {Array} array of node for rendering as labels\n */\nfunction buildLabels(mappedData, accessors) {\n  const {getAngle, getAngle0, getLabel, getRadius0} = accessors;\n\n  return mappedData.filter(getLabel).map(row => {\n    const truedAngle = -1 * getAngle(row) + Math.PI / 2;\n    const truedAngle0 = -1 * getAngle0(row) + Math.PI / 2;\n    const angle = (truedAngle0 + truedAngle) / 2;\n    const rotateLabels = !row.dontRotateLabel;\n    const rotAngle = (-angle / (2 * Math.PI)) * 360;\n\n    return {\n      ...row,\n      children: null,\n      angle: null,\n      radius: null,\n      x: getRadius0(row) * Math.cos(angle),\n      y: getRadius0(row) * Math.sin(angle),\n      style: {\n        textAnchor: rotAngle > 90 ? 'end' : 'start',\n        ...row.labelStyle\n      },\n      rotation: rotateLabels\n        ? rotAngle > 90\n          ? rotAngle + 180\n          : rotAngle === 90\n          ? 90\n          : rotAngle\n        : null\n    };\n  });\n}\n\nconst NOOP = () => {};\n\nfunction Sunburst(props) {\n  const {\n    getAngle,\n    getAngle0,\n    animation,\n    className,\n    children,\n    data,\n    height,\n    hideRootNode,\n    getLabel,\n    width,\n    getSize,\n    colorType\n  } = props;\n  const mappedData = getNodesToRender({\n    data,\n    height,\n    hideRootNode,\n    width,\n    getSize\n  });\n  const radialDomain = getRadialDomain(mappedData);\n  const margin = getRadialLayoutMargin(width, height, radialDomain);\n\n  const labelData = buildLabels(mappedData, {\n    getAngle,\n    getAngle0,\n    getLabel,\n    getRadius0: d => d.radius0\n  });\n\n  const hofBuilder = f => (e, i) => (f ? f(mappedData[e.index], i) : NOOP);\n  return (\n    <XYPlot\n      height={height}\n      hasTreeStructure\n      width={width}\n      className={getCombinedClassName(predefinedClassName, className)}\n      margin={margin}\n      xDomain={[-radialDomain, radialDomain]}\n      yDomain={[-radialDomain, radialDomain]}\n    >\n      <ArcSeries\n        {...{\n          colorType,\n          ...props,\n          animation,\n          radiusDomain: [0, radialDomain],\n          // need to present a stripped down version for interpolation\n          data: animation\n            ? mappedData.map((row, index) => ({\n                ...row,\n                parent: null,\n                children: null,\n                index\n              }))\n            : mappedData,\n          _data: animation ? mappedData : null,\n          arcClassName: `${predefinedClassName}__series--radial__arc`,\n          ...LISTENERS_TO_OVERWRITE.reduce((acc, propName) => {\n            const prop = props[propName];\n            acc[propName] = animation ? hofBuilder(prop) : prop;\n            return acc;\n          }, {})\n        }}\n      />\n      {labelData.length > 0 && (\n        <LabelSeries data={labelData} getLabel={getLabel} />\n      )}\n      {children}\n    </XYPlot>\n  );\n}\n\nSunburst.displayName = 'Sunburst';\nSunburst.propTypes = {\n  animation: AnimationPropType,\n  getAngle: PropTypes.func,\n  getAngle0: PropTypes.func,\n  className: PropTypes.string,\n  colorType: PropTypes.string,\n  data: PropTypes.object.isRequired,\n  height: PropTypes.number.isRequired,\n  hideRootNode: PropTypes.bool,\n  getLabel: PropTypes.func,\n  onValueClick: PropTypes.func,\n  onValueMouseOver: PropTypes.func,\n  onValueMouseOut: PropTypes.func,\n  getSize: PropTypes.func,\n  width: PropTypes.number.isRequired,\n  padAngle: PropTypes.oneOfType([PropTypes.func, PropTypes.number])\n};\nSunburst.defaultProps = {\n  getAngle: d => d.angle,\n  getAngle0: d => d.angle0,\n  className: '',\n  colorType: 'literal',\n  getColor: d => d.color,\n  hideRootNode: false,\n  getLabel: d => d.label,\n  getSize: d => d.size,\n  padAngle: 0\n};\n\nexport default Sunburst;\n"
  },
  {
    "path": "packages/react-vis/src/theme.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nexport const DISCRETE_COLOR_RANGE = [\n  '#12939A',\n  '#79C7E3',\n  '#1A3177',\n  '#FF9833',\n  '#EF5D28'\n];\n\nexport const EXTENDED_DISCRETE_COLOR_RANGE = [\n  '#19CDD7',\n  '#DDB27C',\n  '#88572C',\n  '#FF991F',\n  '#F15C17',\n  '#223F9A',\n  '#DA70BF',\n  '#125C77',\n  '#4DC19C',\n  '#776E57',\n  '#12939A',\n  '#17B8BE',\n  '#F6D18A',\n  '#B7885E',\n  '#FFCB99',\n  '#F89570',\n  '#829AE3',\n  '#E79FD5',\n  '#1E96BE',\n  '#89DAC1',\n  '#B3AD9E'\n];\n\nexport const CONTINUOUS_COLOR_RANGE = ['#EF5D28', '#FF9833'];\n\nexport const SIZE_RANGE = [1, 10];\n\nexport const OPACITY_RANGE = [0.1, 1];\nexport const OPACITY_TYPE = 'literal';\nexport const DEFAULT_OPACITY = 1;\n\nexport const DEFAULT_SIZE = 5;\n\nexport const DEFAULT_COLOR = DISCRETE_COLOR_RANGE[0];\n\nexport const DEFAULT_TICK_SIZE = 7;\n"
  },
  {
    "path": "packages/react-vis/src/treemap/index.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  hierarchy,\n  pack,\n  partition,\n  treemapSquarify,\n  treemapResquarify,\n  treemapSlice,\n  treemapDice,\n  treemapSliceDice,\n  treemapBinary,\n  treemap\n} from 'd3-hierarchy';\n\nimport {\n  CONTINUOUS_COLOR_RANGE,\n  DEFAULT_COLOR,\n  DEFAULT_OPACITY,\n  OPACITY_TYPE\n} from 'theme';\nimport {AnimationPropType} from 'animation';\nimport {getAttributeFunctor, getMissingScaleProps} from 'utils/scales-utils';\nimport {MarginPropType, getInnerDimensions} from 'utils/chart-utils';\n\nimport TreemapDOM from './treemap-dom';\nimport TreemapSVG from './treemap-svg';\n\nconst TREEMAP_TILE_MODES = {\n  squarify: treemapSquarify,\n  resquarify: treemapResquarify,\n  slice: treemapSlice,\n  dice: treemapDice,\n  slicedice: treemapSliceDice,\n  binary: treemapBinary\n};\n\nconst TREEMAP_LAYOUT_MODES = ['circlePack', 'partition', 'partition-pivot'];\n\nconst NOOP = d => d;\n\nconst ATTRIBUTES = ['opacity', 'color'];\n\nconst DEFAULT_MARGINS = {\n  left: 40,\n  right: 10,\n  top: 10,\n  bottom: 40\n};\n\n/**\n * Get the map of scale functions from the given props.\n * @param {Object} props Props for the component.\n * @returns {Object} Map of scale functions.\n * @private\n */\nfunction _getScaleFns(props) {\n  const {data} = props;\n  const allData = data.children || [];\n\n  // Adding _allData property to the object to reuse the existing\n  // getAttributeFunctor function.\n  const compatibleProps = {\n    ...props,\n    ...getMissingScaleProps(props, allData, ATTRIBUTES),\n    _allData: allData\n  };\n  return {\n    opacity: getAttributeFunctor(compatibleProps, 'opacity'),\n    color: getAttributeFunctor(compatibleProps, 'color')\n  };\n}\n\nfunction Treemap(props) {\n  const scales = _getScaleFns(props);\n  const innerDimensions = getInnerDimensions(props, props.margin);\n\n  /**\n   * Create the list of nodes to render.\n   * @returns {Array} Array of nodes.\n   * @private\n   */\n  function _getNodesToRender() {\n    const {innerWidth, innerHeight} = innerDimensions;\n    const {data, mode, padding, sortFunction, getSize} = props;\n    if (!data) {\n      return [];\n    }\n\n    if (mode === 'partition' || mode === 'partition-pivot') {\n      const partitionFunction = partition()\n        .size(\n          mode === 'partition-pivot'\n            ? [innerHeight, innerWidth]\n            : [innerWidth, innerHeight]\n        )\n        .padding(padding);\n      const structuredInput = hierarchy(data)\n        .sum(getSize)\n        .sort((a, b) => sortFunction(a, b, getSize));\n      const mappedNodes = partitionFunction(structuredInput).descendants();\n      if (mode === 'partition-pivot') {\n        return mappedNodes.map(node => ({\n          ...node,\n          x0: node.y0,\n          x1: node.y1,\n          y0: node.x0,\n          y1: node.x1\n        }));\n      }\n      return mappedNodes;\n    }\n    if (mode === 'circlePack') {\n      const packingFunction = pack()\n        .size([innerWidth, innerHeight])\n        .padding(padding);\n      const structuredInput = hierarchy(data)\n        .sum(getSize)\n        .sort((a, b) => sortFunction(a, b, getSize));\n      return packingFunction(structuredInput).descendants();\n    }\n\n    const tileFn = TREEMAP_TILE_MODES[mode];\n    const treemapingFunction = treemap(tileFn)\n      .tile(tileFn)\n      .size([innerWidth, innerHeight])\n      .padding(padding);\n    const structuredInput = hierarchy(data)\n      .sum(getSize)\n      .sort((a, b) => sortFunction(a, b, getSize));\n    return treemapingFunction(structuredInput).descendants();\n  }\n\n  const {renderMode} = props;\n  const nodes = _getNodesToRender();\n  const TreemapElement = renderMode === 'SVG' ? TreemapSVG : TreemapDOM;\n\n  return <TreemapElement {...props} nodes={nodes} scales={scales} />;\n}\n\nTreemap.displayName = 'Treemap';\nTreemap.propTypes = {\n  animation: AnimationPropType,\n  className: PropTypes.string,\n  data: PropTypes.object.isRequired,\n  height: PropTypes.number.isRequired,\n  hideRootNode: PropTypes.bool,\n  margin: MarginPropType,\n  mode: PropTypes.oneOf(\n    Object.keys(TREEMAP_TILE_MODES).concat(TREEMAP_LAYOUT_MODES)\n  ),\n  onLeafClick: PropTypes.func,\n  onLeafMouseOver: PropTypes.func,\n  onLeafMouseOut: PropTypes.func,\n  useCirclePacking: PropTypes.bool,\n  padding: PropTypes.number.isRequired,\n  sortFunction: PropTypes.func,\n  width: PropTypes.number.isRequired,\n  getSize: PropTypes.func,\n  getColor: PropTypes.func\n};\n\nTreemap.defaultProps = {\n  className: '',\n  colorRange: CONTINUOUS_COLOR_RANGE,\n  _colorValue: DEFAULT_COLOR,\n  data: {\n    children: []\n  },\n  hideRootNode: false,\n  margin: DEFAULT_MARGINS,\n  mode: 'squarify',\n  onLeafClick: NOOP,\n  onLeafMouseOver: NOOP,\n  onLeafMouseOut: NOOP,\n  opacityType: OPACITY_TYPE,\n  _opacityValue: DEFAULT_OPACITY,\n  padding: 1,\n  sortFunction: (a, b, accessor) => {\n    if (!accessor) {\n      return 0;\n    }\n    return accessor(a) - accessor(b);\n  },\n  getSize: d => d.size,\n  getColor: d => d.color,\n  getLabel: d => d.title\n};\nexport default Treemap;\n"
  },
  {
    "path": "packages/react-vis/src/treemap/treemap-dom.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nimport React from 'react';\n\nimport TreemapLeaf from './treemap-leaf';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nfunction TreemapDOM(props) {\n  const {\n    animation,\n    className,\n    height,\n    hideRootNode,\n    getLabel,\n    mode,\n    nodes,\n    width,\n    scales,\n    style\n  } = props;\n  const useCirclePacking = mode === 'circlePack';\n  return (\n    <div\n      className={getCombinedClassName(\n        'rv-treemap',\n        useCirclePacking && 'rv-treemap-circle-paked',\n        className\n      )}\n      style={{height, width}}\n    >\n      {nodes.map((node, index) => {\n        // throw out the rootest node\n        if (hideRootNode && !index) {\n          return null;\n        }\n\n        const nodeProps = {\n          animation,\n          node,\n          getLabel,\n          ...props,\n          x0: useCirclePacking ? node.x : node.x0,\n          x1: useCirclePacking ? node.x : node.x1,\n          y0: useCirclePacking ? node.y : node.y0,\n          y1: useCirclePacking ? node.y : node.y1,\n          r: useCirclePacking ? node.r : 1,\n          scales,\n          style\n        };\n        return <TreemapLeaf {...nodeProps} key={`leaf-${index}`} />;\n      })}\n    </div>\n  );\n}\n\nTreemapDOM.displayName = 'TreemapDOM';\nexport default TreemapDOM;\n"
  },
  {
    "path": "packages/react-vis/src/treemap/treemap-leaf.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nimport Animation, {AnimationPropType} from 'animation';\nimport {getFontColorFromBackground} from 'utils/scales-utils';\n\nconst ANIMATED_PROPS = [\n  'colorRange',\n  'colorDomain',\n  'color',\n  'opacityRange',\n  'opacityDomain',\n  'opacity',\n  'x0',\n  'x1',\n  'y0',\n  'y1',\n  'r'\n];\n\nfunction TreemapLeaf(props) {\n  const {\n    animation,\n    getLabel,\n    mode,\n    node,\n    onLeafClick,\n    onLeafMouseOver,\n    onLeafMouseOut,\n    r,\n    scales,\n    x0,\n    x1,\n    y0,\n    y1,\n    style\n  } = props;\n\n  if (animation) {\n    return (\n      <Animation {...props} animatedProps={ANIMATED_PROPS}>\n        <TreemapLeaf {...props} animation={null} />\n      </Animation>\n    );\n  }\n  const useCirclePacking = mode === 'circlePack';\n  const background = scales.color(node);\n  const opacity = scales.opacity(node);\n  const color = getFontColorFromBackground(background);\n  const {data} = node;\n  const title = getLabel(data);\n  const leafStyle = {\n    top: useCirclePacking ? y0 - r : y0,\n    left: useCirclePacking ? x0 - r : x0,\n    width: useCirclePacking ? r * 2 : x1 - x0,\n    height: useCirclePacking ? r * 2 : y1 - y0,\n    background,\n    opacity,\n    color,\n    ...style,\n    ...node.data.style\n  };\n\n  return (\n    <div\n      className={`rv-treemap__leaf ${\n        useCirclePacking ? 'rv-treemap__leaf--circle' : ''\n      }`}\n      onMouseEnter={event => onLeafMouseOver(node, event)}\n      onMouseLeave={event => onLeafMouseOut(node, event)}\n      onClick={event => onLeafClick(node, event)}\n      style={leafStyle}\n    >\n      <div className=\"rv-treemap__leaf__content\">{title}</div>\n    </div>\n  );\n}\n\nTreemapLeaf.propTypes = {\n  animation: AnimationPropType,\n  height: PropTypes.number.isRequired,\n  mode: PropTypes.string,\n  node: PropTypes.object.isRequired,\n  onLeafClick: PropTypes.func,\n  onLeafMouseOver: PropTypes.func,\n  onLeafMouseOut: PropTypes.func,\n  scales: PropTypes.object.isRequired,\n  width: PropTypes.number.isRequired,\n  r: PropTypes.number.isRequired,\n  x0: PropTypes.number.isRequired,\n  x1: PropTypes.number.isRequired,\n  y0: PropTypes.number.isRequired,\n  y1: PropTypes.number.isRequired\n};\nexport default TreemapLeaf;\n"
  },
  {
    "path": "packages/react-vis/src/treemap/treemap-svg.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport XYPlot from 'plot/xy-plot';\nimport PolygonSeries from 'plot/series/polygon-series';\nimport MarkSeries from 'plot/series/mark-series';\nimport LabelSeries from 'plot/series/label-series';\nimport {getCombinedClassName} from 'utils/styling-utils';\n\nconst MARGIN_ADJUST = 1.2;\n\nclass TreemapSVG extends React.Component {\n  getCircularNodes() {\n    const {\n      animation,\n      hideRootNode,\n      nodes,\n      onLeafMouseOver,\n      onLeafMouseOut,\n      onLeafClick,\n      scales,\n      style\n    } = this.props;\n\n    const {rows, minY, maxY, minX, maxX} = nodes.reduce(\n      (acc, node, index) => {\n        if (!index && hideRootNode) {\n          return acc;\n        }\n        const {x, y, r} = node;\n        return {\n          maxY: Math.max(y + r, acc.maxY),\n          minY: Math.min(y - r, acc.minY),\n          maxX: Math.max(x + MARGIN_ADJUST * r, acc.maxX),\n          minX: Math.min(x - MARGIN_ADJUST * r, acc.minX),\n          rows: acc.rows.concat([\n            {\n              x,\n              y,\n              size: r,\n              color: scales.color(node)\n            }\n          ])\n        };\n      },\n      {\n        rows: [],\n        maxY: -Infinity,\n        minY: Infinity,\n        maxX: -Infinity,\n        minX: Infinity\n      }\n    );\n    return {\n      updatedNodes: (\n        <MarkSeries\n          animation={animation}\n          className=\"rv-treemap__leaf rv-treemap__leaf--circle\"\n          onSeriesMouseEnter={onLeafMouseOver}\n          onSeriesMouseLeave={onLeafMouseOut}\n          onSeriesClick={onLeafClick}\n          data={rows}\n          colorType=\"literal\"\n          getColor={d => d.color}\n          sizeType=\"literal\"\n          getSize={d => d.size}\n          style={style}\n        />\n      ),\n      minY,\n      maxY,\n      minX,\n      maxX\n    };\n  }\n\n  getNonCircularNodes() {\n    const {\n      animation,\n      hideRootNode,\n      nodes,\n      onLeafMouseOver,\n      onLeafMouseOut,\n      onLeafClick,\n      scales,\n      style\n    } = this.props;\n    const {color} = scales;\n    return nodes.reduce(\n      (acc, node, index) => {\n        if (!index && hideRootNode) {\n          return acc;\n        }\n        const {x0, x1, y1, y0} = node;\n        const x = x0;\n        const y = y0;\n        const nodeHeight = y1 - y0;\n        const nodeWidth = x1 - x0;\n\n        acc.maxY = Math.max(y + nodeHeight, acc.maxY);\n        acc.minY = Math.min(y, acc.minY);\n        acc.maxX = Math.max(x + nodeWidth, acc.maxX);\n        acc.minX = Math.min(x, acc.minX);\n\n        const data = [\n          {x, y},\n          {x, y: y + nodeHeight},\n          {x: x + nodeWidth, y: y + nodeHeight},\n          {x: x + nodeWidth, y}\n        ];\n\n        acc.updatedNodes = acc.updatedNodes.concat([\n          <PolygonSeries\n            animation={animation}\n            className=\"rv-treemap__leaf\"\n            key={index}\n            color={color(node)}\n            type=\"literal\"\n            onSeriesMouseEnter={onLeafMouseOver}\n            onSeriesMouseLeave={onLeafMouseOut}\n            onSeriesClick={onLeafClick}\n            data={data}\n            style={{\n              ...style,\n              ...node.style\n            }}\n          />\n        ]);\n        return acc;\n      },\n      {\n        updatedNodes: [],\n        maxY: -Infinity,\n        minY: Infinity,\n        maxX: -Infinity,\n        minX: Infinity\n      }\n    );\n  }\n\n  render() {\n    const {className, height, mode, nodes, width} = this.props;\n    const useCirclePacking = mode === 'circlePack';\n\n    const {minY, maxY, minX, maxX, updatedNodes} = useCirclePacking\n      ? this.getCircularNodes()\n      : this.getNonCircularNodes();\n\n    const labels = nodes.reduce((acc, node) => {\n      if (!node.data.title) {\n        return acc;\n      }\n      return acc.concat({\n        ...node.data,\n        x: node.x0 || node.x,\n        y: node.y0 || node.y,\n        label: `${node.data.title}`\n      });\n    }, []);\n\n    return (\n      <XYPlot\n        className={getCombinedClassName(\n          'rv-treemap',\n          useCirclePacking && 'rv-treemap-circle-paked',\n          className\n        )}\n        width={width}\n        height={height}\n        yDomain={[maxY, minY]}\n        xDomain={[minX, maxX]}\n        colorType=\"literal\"\n        hasTreeStructure\n        {...this.props}\n      >\n        {updatedNodes}\n        <LabelSeries data={labels} />\n      </XYPlot>\n    );\n  }\n}\n\nTreemapSVG.displayName = 'TreemapSVG';\n\nexport default TreemapSVG;\n"
  },
  {
    "path": "packages/react-vis/src/utils/axis-utils.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport {range} from 'd3-array';\nimport {scaleLinear} from 'd3-scale';\n\nexport const ORIENTATION = {\n  TOP: 'top',\n  LEFT: 'left',\n  RIGHT: 'right',\n  BOTTOM: 'bottom',\n  VERTICAL: 'vertical',\n  HORIZONTAL: 'horizontal'\n};\n\nexport const DIRECTION = {\n  VERTICAL: 'vertical',\n  HORIZONTAL: 'horizontal'\n};\n\n/**\n * Get total amount of ticks from a given size in pixels.\n * @param {number} size Size of the axis in pixels.\n * @returns {number} Total amount of ticks.\n */\nexport function getTicksTotalFromSize(size) {\n  if (size < 700) {\n    if (size > 300) {\n      return 10;\n    }\n    return 5;\n  }\n  return 20;\n}\n\n/**\n * Get the tick values from a given d3 scale.\n * @param {d3.scale} scale Scale function.\n * @param {number} tickTotal Total number of ticks\n * @param {Array} tickValues Array of tick values if they exist.\n * @returns {Array} Array of tick values.\n */\nexport function getTickValues(scale, tickTotal, tickValues) {\n  return !tickValues\n    ? scale.ticks\n      ? scale.ticks(tickTotal)\n      : scale.domain()\n    : tickValues;\n}\n\n/**\n * Generate a description of a decorative axis in terms of a linear equation\n * y = slope * x + offset in coordinates\n * @param {Object} axisStart Object of format {x, y} describing in coordinates\n * the start position of the decorative axis\n * @param {Object} axisEnd Object of format {x, y} describing in coordinates\n * the start position of the decorative axis\n * @returns {Number} Object describing each the line in coordinates\n */\nexport function generateFit(axisStart, axisEnd) {\n  // address the special case when the slope is infinite\n  if (axisStart.x === axisEnd.x) {\n    return {\n      left: axisStart.y,\n      right: axisEnd.y,\n      slope: 0,\n      offset: axisStart.x\n    };\n  }\n  const slope = (axisStart.y - axisEnd.y) / (axisStart.x - axisEnd.x);\n  return {\n    left: axisStart.x,\n    right: axisEnd.x,\n    // generate the linear projection of the axis direction\n    slope,\n    offset: axisStart.y - slope * axisStart.x\n  };\n}\n\n/**\n * Generate a description of a decorative axis in terms of a linear equation\n * y = slope * x + offset in coordinates\n * @param props\n * props.@param {Object} axisStart Object of format {x, y} describing in coordinates\n * the start position of the decorative axis\n * props.@param {Object} axisEnd Object of format {x, y} describing in coordinates\n * the start position of the decorative axis\n * props.@param {Number} numberOfTicks The number of ticks on the axis\n * props.@param {Array.Numbers} axisDomain The values to be interpolated across for the axis\n * @returns {Number} Object describing the slope and the specific coordinates of the points\n */\nexport function generatePoints({\n  axisStart,\n  axisEnd,\n  numberOfTicks,\n  axisDomain\n}) {\n  const {left, right, slope, offset} = generateFit(axisStart, axisEnd);\n  // construct a linear band of points, then map them\n  const pointSlope = (right - left) / numberOfTicks;\n  const axisScale = scaleLinear()\n    .domain([left, right])\n    .range(axisDomain);\n\n  const slopeVertical = axisStart.x === axisEnd.x;\n  return {\n    slope: slopeVertical ? Infinity : slope,\n    points: range(left, right + pointSlope, pointSlope)\n      .map(val => {\n        if (slopeVertical) {\n          return {y: val, x: slope * val + offset, text: axisScale(val)};\n        }\n        return {x: val, y: slope * val + offset, text: axisScale(val)};\n      })\n      .slice(0, numberOfTicks + 1)\n  };\n}\n\n/**\n * Compute the angle (in radians) of a decorative axis\n * @param {Object} axisStart Object of format {x, y} describing in coordinates\n * the start position of the decorative axis\n * @param {Object} axisEnd Object of format {x, y} describing in coordinates\n * the start position of the decorative axis\n * @returns {Number} Angle in radials\n */\nexport function getAxisAngle(axisStart, axisEnd) {\n  if (axisStart.x === axisEnd.x) {\n    return axisEnd.y > axisStart.y ? Math.PI / 2 : (3 * Math.PI) / 2;\n  }\n  return Math.atan((axisEnd.y - axisStart.y) / (axisEnd.x - axisStart.x));\n}\n\nexport default {\n  DIRECTION,\n  ORIENTATION,\n  getTicksTotalFromSize,\n  getTickValues\n};\n"
  },
  {
    "path": "packages/react-vis/src/utils/chart-utils.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport PropTypes from 'prop-types';\n\n/**\n * Get the dimensions of the component for the future use.\n * @param {Object} props Props.\n * @param {Object} defaultMargins Object with default margins.\n * @returns {Object} Dimensions of the component.\n */\nexport function getInnerDimensions(props, defaultMargins) {\n  const {margin, width, height} = props;\n  const marginProps = {\n    ...defaultMargins,\n    ...(typeof margin === 'number'\n      ? {\n          left: margin,\n          right: margin,\n          top: margin,\n          bottom: margin\n        }\n      : margin)\n  };\n  const {\n    left: marginLeft = 0,\n    top: marginTop = 0,\n    right: marginRight = 0,\n    bottom: marginBottom = 0\n  } = marginProps;\n  return {\n    marginLeft,\n    marginTop,\n    marginRight,\n    marginBottom,\n    innerHeight: height - marginBottom - marginTop,\n    innerWidth: width - marginLeft - marginRight\n  };\n}\n\n/**\n * Calculate the margin of the sunburst,\n * so it can be at the center of the container\n * @param  {Number} width - the width of the container\n * @param  {Number} height - the height of the container\n * @param  {Number} radius - the max radius of the sunburst\n * @return {Object} an object includes {bottom, left, right, top}\n */\nexport function getRadialLayoutMargin(width, height, radius) {\n  const marginX = width / 2 - radius;\n  const marginY = height / 2 - radius;\n  return {\n    bottom: marginY,\n    left: marginX,\n    right: marginX,\n    top: marginY\n  };\n}\n\nexport const MarginPropType = PropTypes.oneOfType([\n  PropTypes.shape({\n    left: PropTypes.number,\n    top: PropTypes.number,\n    right: PropTypes.number,\n    bottom: PropTypes.number\n  }),\n  PropTypes.number\n]);\n\nexport const DEFAULT_MARGINS = {\n  left: 40,\n  right: 10,\n  top: 10,\n  bottom: 40\n};\n"
  },
  {
    "path": "packages/react-vis/src/utils/data-utils.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n/**\n * Get unique property values from an array.\n * @param {Array} arr Array of data.\n * @param {string} propertyName Prop name.\n * @returns {Array} Array of unique values.\n */\nexport function getUniquePropertyValues(arr, accessor) {\n  const setOfValues = new Set(arr.map(accessor));\n  return Array.from(setOfValues);\n}\n\n/**\n * Add zero to the domain.\n * @param {Array} arr Add zero to the domain.\n * @param {Number} value Add zero to domain.\n * @returns {Array} Adjusted domain.\n */\nexport function addValueToArray(arr, value) {\n  const result = [].concat(arr);\n  if (result[0] > value) {\n    result[0] = value;\n  }\n  if (result[result.length - 1] < value) {\n    result[result.length - 1] = value;\n  }\n  return result;\n}\n\n/**\n * Transforms a value ( number or date ) to a string.\n * @param {Date | number} value The value as date or number.\n * @returns {string | number} The value as string.\n */\nexport function transformValueToString(value) {\n  return Object.prototype.toString.call(value) === '[object Date]'\n    ? value.toDateString()\n    : value;\n}\n"
  },
  {
    "path": "packages/react-vis/src/utils/react-utils.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nconst [major, minor] = React.version.split('.');\nconst versionHigherThanThirteen = Number(minor) > 13 || Number(major) > 13;\n\nexport const isReactDOMSupported = () => versionHigherThanThirteen;\n\n/**\n * Support React 0.13 and greater where refs are React components, not DOM\n * nodes.\n * @param {*} ref React's ref.\n * @returns {Element} DOM element.\n */\nexport const getDOMNode = ref => {\n  if (!isReactDOMSupported()) {\n    return ref && ref.getDOMNode();\n  }\n  return ref;\n};\n\nconst USED_MESSAGES = {};\nconst HIDDEN_PROCESSES = {\n  test: true,\n  production: true\n};\n\n/**\n * Warn the user about something\n * @param {String} message - the message to be shown\n * @param {Boolean} onlyShowMessageOnce - whether or not we allow the\n - message to be show multiple times\n */\nexport function warning(message, onlyShowMessageOnce = false) {\n  /* eslint-disable no-undef, no-process-env */\n  if (global.process && HIDDEN_PROCESSES[process.env.NODE_ENV]) {\n    return;\n  }\n  /* eslint-enable no-undef, no-process-env */\n  if (!onlyShowMessageOnce || !USED_MESSAGES[message]) {\n    /* eslint-disable no-console */\n    console.warn(message);\n    /* eslint-enable no-console */\n    USED_MESSAGES[message] = true;\n  }\n}\n\n/**\n * Convience wrapper for warning\n * @param {String} message - the message to be shown\n */\nexport function warnOnce(message) {\n  warning(message, true);\n}\n"
  },
  {
    "path": "packages/react-vis/src/utils/scales-utils.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport {\n  scaleLinear,\n  scalePoint,\n  scaleOrdinal,\n  scaleLog,\n  scaleTime,\n  scaleUtc\n} from 'd3-scale';\nimport {extent} from 'd3-array';\nimport {set} from 'd3-collection';\nimport {hsl} from 'd3-color';\n\nimport PropTypes from 'prop-types';\n\nimport {warning} from './react-utils';\nimport {getUniquePropertyValues, addValueToArray} from './data-utils';\n\n/**\n * Linear scale name.\n * @type {string}\n * @const\n */\nconst LINEAR_SCALE_TYPE = 'linear';\n\n/**\n * Ordinal scale name.\n * @type {string}\n * @const\n */\nconst ORDINAL_SCALE_TYPE = 'ordinal';\n\n/**\n * Category scale.\n * @type {string}\n * @const\n */\nconst CATEGORY_SCALE_TYPE = 'category';\n\n/**\n * Literal scale.\n * Differs slightly from d3's identity scale in that it does not coerce value\n * into numbers, it simply returns exactly what you give it\n * @type {string}\n * @const\n */\nconst LITERAL_SCALE_TYPE = 'literal';\n\n/**\n * Log scale name.\n * @type {string}\n * @const\n */\nconst LOG_SCALE_TYPE = 'log';\n\n/**\n * Time scale name.\n * @type {string}\n * @const\n */\nconst TIME_SCALE_TYPE = 'time';\n\n/**\n * Time UTC scale name.\n * @type {string}\n * @const\n */\nconst TIME_UTC_SCALE_TYPE = 'time-utc';\n\n/**\n * Scale functions that are supported in the library.\n * @type {Object}\n * @const\n */\nconst SCALE_FUNCTIONS = {\n  [LINEAR_SCALE_TYPE]: scaleLinear,\n  [ORDINAL_SCALE_TYPE]: scalePoint,\n  [CATEGORY_SCALE_TYPE]: scaleOrdinal,\n  [LITERAL_SCALE_TYPE]: literalScale,\n  [LOG_SCALE_TYPE]: scaleLog,\n  [TIME_SCALE_TYPE]: scaleTime,\n  [TIME_UTC_SCALE_TYPE]: scaleUtc\n};\n\n/**\n * Attrs for which a scale can be set up at XYPlot level\n * @type {Array}\n * @const\n */\n\nconst XYPLOT_ATTR = ['color', 'fill', 'opacity', 'stroke'];\n\n/**\n * Title case a given string\n * @param {String} str Array of values.\n * @returns {String} titlecased string\n */\nfunction toTitleCase(str) {\n  return `${str[0].toUpperCase()}${str.slice(1)}`;\n}\n\n/**\n * Find the smallest distance between the values on a given scale and return\n * the index of the element, where the smallest distance was found.\n * It returns the first occurrence of i where\n * `scale(value[i]) - scale(value[i - 1])` is minimal\n * @param {Array} values Array of values.\n * @param {Object} scaleObject Scale object.\n * @returns {number} Index of an element where the smallest distance was found.\n * @private\n */\nexport function _getSmallestDistanceIndex(values, scaleObject) {\n  const scaleFn = getScaleFnFromScaleObject(scaleObject);\n  let result = 0;\n  if (scaleFn) {\n    let nextValue;\n    let currentValue = scaleFn(values[0]);\n    let distance = Infinity;\n    let nextDistance;\n\n    for (let i = 1; i < values.length; i++) {\n      nextValue = scaleFn(values[i]);\n      nextDistance = Math.abs(nextValue - currentValue);\n      if (nextDistance < distance) {\n        distance = nextDistance;\n        result = i;\n      }\n      currentValue = nextValue;\n    }\n  }\n  return result;\n}\n\n/**\n * This is a workaround for issue that ordinal scale\n * does not have invert method implemented in d3-scale.\n * @param {Object} Ordinal d3-scale object.\n * @returns {void}\n * @private\n */\n\nfunction addInvertFunctionToOrdinalScaleObject(scale) {\n  if (scale.invert) {\n    return;\n  }\n\n  scale.invert = function invert(value) {\n    const [lower, upper] = scale.range();\n    const start = Math.min(lower, upper);\n    const stop = Math.max(lower, upper);\n\n    if (value < start + scale.padding() * scale.step()) {\n      return scale.domain()[0];\n    }\n\n    if (value > stop - scale.padding() * scale.step()) {\n      return scale.domain()[scale.domain().length - 1];\n    }\n\n    const index = Math.floor(\n      (value - start - scale.padding() * scale.step()) / scale.step()\n    );\n    return scale.domain()[index];\n  };\n}\n\n/**\n * Crate a scale function from the scale object.\n * @param {Object} scaleObject Scale object.\n - scaleObject.domain {Array}\n - scaleObject.range {Array}\n - scaleObject.type {string}\n - scaleObject.attr {string}\n * @returns {*} Scale function.\n * @private\n */\nexport function getScaleFnFromScaleObject(scaleObject) {\n  if (!scaleObject) {\n    return null;\n  }\n  const {type, domain, range} = scaleObject;\n  const modDomain =\n    domain[0] === domain[1]\n      ? domain[0] === 0\n        ? [-1, 0]\n        : [-domain[0], domain[0]]\n      : domain;\n  if (type === LITERAL_SCALE_TYPE) {\n    return literalScale(range[0]);\n  }\n  const scale = SCALE_FUNCTIONS[type]()\n    .domain(modDomain)\n    .range(range);\n  if (type === ORDINAL_SCALE_TYPE) {\n    scale.padding(0.5);\n    addInvertFunctionToOrdinalScaleObject(scale);\n  }\n  return scale;\n}\n\n/**\n * Get the domain from the array of data.\n * @param {Array} allData All data.\n * @param {function} accessor - accessor for main value.\n * @param {function} accessor0 - accessor for the naught value.\n * @param {string} type Scale type.\n * @returns {Array} Domain.\n * @private\n */\nexport function getDomainByAccessor(allData, accessor, accessor0, type) {\n  let domain;\n\n  // Collect both attr and available attr0 values from the array of data.\n  const values = allData.reduce((data, d) => {\n    const value = accessor(d);\n    const value0 = accessor0(d);\n    if (_isDefined(value)) {\n      data.push(value);\n    }\n    if (_isDefined(value0)) {\n      data.push(value0);\n    }\n    return data;\n  }, []);\n\n  if (!values.length) {\n    return [];\n  }\n\n  // Create proper domain depending on the type of the scale.\n  if (type !== ORDINAL_SCALE_TYPE && type !== CATEGORY_SCALE_TYPE) {\n    domain = extent(values);\n  } else {\n    domain = set(values).values();\n  }\n  return domain;\n}\n\n/**\n * Create custom scale object from the value. When the scale is created from\n * this object, it should return the same value all time.\n * @param {string} attr Attribute.\n * @param {*} value Value.\n * @param {string} type - the type of scale being used\n * @param {function} accessor - the accessor function\n * @param {function} accessor0 - the accessor function for the potential naught value\n * @returns {Object} Custom scale object.\n * @private\n */\nfunction _createScaleObjectForValue(attr, value, type, accessor, accessor0) {\n  if (type === LITERAL_SCALE_TYPE) {\n    return {\n      type: LITERAL_SCALE_TYPE,\n      domain: [],\n      range: [value],\n      distance: 0,\n      attr,\n      baseValue: undefined,\n      isValue: true,\n      accessor,\n      accessor0\n    };\n  }\n  if (typeof value === 'undefined') {\n    return null;\n  }\n  return {\n    type: CATEGORY_SCALE_TYPE,\n    range: [value],\n    domain: [],\n    distance: 0,\n    attr,\n    baseValue: undefined,\n    isValue: true,\n    accessor,\n    accessor0\n  };\n}\n\n/**\n * Create a regular scale object for a further use from the existing parameters.\n * @param {Array} domain - Domain.\n * @param {Array} range - Range.\n * @param {string} type - Type.\n * @param {number} distance - Distance.\n * @param {string} attr - Attribute.\n * @param {number} baseValue - Base value.\n * @param {function} accessor - Attribute accesor\n * @param {function} accessor0 - Attribute accesor for potential naught value\n * @returns {Object} Scale object.\n * @private\n */\nfunction _createScaleObjectForFunction({\n  domain,\n  range,\n  type,\n  distance,\n  attr,\n  baseValue,\n  accessor,\n  accessor0\n}) {\n  return {\n    domain,\n    range,\n    type,\n    distance,\n    attr,\n    baseValue,\n    isValue: false,\n    accessor,\n    accessor0\n  };\n}\n\n/**\n * Get scale object from props. E. g. object like {xRange, xDomain, xDistance,\n * xType} is transformed into {range, domain, distance, type}.\n * @param {Object} props Props.\n * @param {string} attr Attribute.\n * @returns {*} Null or an object with the scale.\n * @private\n */\nfunction _collectScaleObjectFromProps(props, attr) {\n  const {\n    [attr]: value,\n    [`_${attr}Value`]: fallbackValue,\n    [`${attr}Range`]: range,\n    [`${attr}Distance`]: distance = 0,\n    [`${attr}BaseValue`]: baseValue,\n    [`${attr}Type`]: type = LINEAR_SCALE_TYPE,\n    [`${attr}NoFallBack`]: noFallBack,\n    [`get${toTitleCase(attr)}`]: accessor = d => d[attr],\n    [`get${toTitleCase(attr)}0`]: accessor0 = d => d[`${attr}0`]\n  } = props;\n\n  let {[`${attr}Domain`]: domain} = props;\n  // Return value-based scale if the value is assigned.\n  if (!noFallBack && typeof value !== 'undefined') {\n    return _createScaleObjectForValue(\n      attr,\n      value,\n      props[`${attr}Type`],\n      accessor,\n      accessor0\n    );\n  }\n  // Pick up the domain from the properties and create a new one if it's not\n  // available.\n  if (typeof baseValue !== 'undefined') {\n    domain = addValueToArray(domain, baseValue);\n  }\n\n  // Make sure that the minimum necessary properties exist.\n  if (!range || !domain || !domain.length) {\n    // Try to use the fallback value if it is available.\n    return _createScaleObjectForValue(\n      attr,\n      fallbackValue,\n      props[`${attr}Type`],\n      accessor,\n      accessor0\n    );\n  }\n\n  return _createScaleObjectForFunction({\n    domain,\n    range,\n    type,\n    distance,\n    attr,\n    baseValue,\n    accessor,\n    accessor0\n  });\n}\n\n/**\n * Compute left domain adjustment for the given values.\n * @param {Array} values Array of values.\n * @returns {number} Domain adjustment.\n * @private\n */\nfunction _computeLeftDomainAdjustment(values) {\n  if (values.length > 1) {\n    return (values[1] - values[0]) / 2;\n  }\n  if (values.length === 1) {\n    return values[0] - 0.5;\n  }\n  return 0;\n}\n\n/**\n * Compute right domain adjustment for the given values.\n * @param {Array} values Array of values.\n * @returns {number} Domain adjustment.\n * @private\n */\nfunction _computeRightDomainAdjustment(values) {\n  if (values.length > 1) {\n    return (values[values.length - 1] - values[values.length - 2]) / 2;\n  }\n  if (values.length === 1) {\n    return values[0] - 0.5;\n  }\n  return 0;\n}\n\n/**\n * Compute distance for the given values.\n * @param {Array} values Array of values.\n * @param {Array} domain Domain.\n * @param {number} bestDistIndex Index of a best distance found.\n * @param {function} scaleFn Scale function.\n * @returns {number} Domain adjustment.\n * @private\n */\nfunction _computeScaleDistance(values, domain, bestDistIndex, scaleFn) {\n  if (values.length > 1) {\n    // Avoid zero indexes.\n    const i = Math.max(bestDistIndex, 1);\n    return Math.abs(scaleFn(values[i]) - scaleFn(values[i - 1]));\n  }\n  if (values.length === 1) {\n    return Math.abs(scaleFn(domain[1]) - scaleFn(domain[0]));\n  }\n  return 0;\n}\n\n/**\n * Normilize array of values with a single value.\n * @param {Array} arr Array of data.\n * @param {Array} values Array of values.\n * @param {string} attr Attribute.\n * @param {string} type Type.\n * @private\n */\nfunction _normalizeValues(data, values, accessor0, type) {\n  if (type === TIME_SCALE_TYPE && values.length === 1) {\n    const attr0 = accessor0(data[0]);\n\n    return [attr0, ...values];\n  }\n\n  return values;\n}\n\n/**\n * Get the distance, the smallest and the largest value of the domain.\n * @param {Array} data Array of data for the single series.\n * @param {Object} scaleObject Scale object.\n * @returns {{domain0: number, domainN: number, distance: number}} Result.\n * @private\n */\nexport function _getScaleDistanceAndAdjustedDomain(data, scaleObject) {\n  const {domain, type, accessor, accessor0} = scaleObject;\n\n  const uniqueValues = getUniquePropertyValues(data, accessor);\n\n  // Fix time scale if a data has only one value.\n  const values = _normalizeValues(data, uniqueValues, accessor0, type);\n  const index = _getSmallestDistanceIndex(values, scaleObject);\n\n  const adjustedDomain = [].concat(domain);\n\n  adjustedDomain[0] -= _computeLeftDomainAdjustment(values);\n  adjustedDomain[domain.length - 1] += _computeRightDomainAdjustment(values);\n  // Fix log scale if it's too small.\n  if (type === LOG_SCALE_TYPE && domain[0] <= 0) {\n    adjustedDomain[0] = Math.min(domain[1] / 10, 1);\n  }\n\n  const adjustedScaleFn = getScaleFnFromScaleObject({\n    ...scaleObject,\n    domain: adjustedDomain\n  });\n\n  const distance = _computeScaleDistance(\n    values,\n    adjustedDomain,\n    index,\n    adjustedScaleFn\n  );\n\n  return {\n    domain0: adjustedDomain[0],\n    domainN: adjustedDomain[adjustedDomain.length - 1],\n    distance\n  };\n}\n\n/**\n * Returns true if scale adjustments are possible for a given scale.\n * @param {Object} props Props.\n * @param {Object} scaleObject Scale object.\n * @returns {boolean} True if scale adjustments possible.\n * @private\n */\nfunction _isScaleAdjustmentPossible(props, scaleObject) {\n  const {attr} = scaleObject;\n  const {_adjustBy: adjustBy = [], _adjustWhat: adjustWhat = []} = props;\n\n  // The scale cannot be adjusted if there's no attributes to adjust, no\n  // suitable values\n  return adjustWhat.length && adjustBy.length && adjustBy.indexOf(attr) !== -1;\n}\n\n/**\n * Adjust continuous scales (e.g. 'linear', 'log' and 'time') by adding the\n * space from the left and right of them and by computing the best distance.\n * @param {Object} props Props.\n * @param {Object} scaleObject Scale object.\n * @returns {*} Scale object with adjustments.\n * @private\n */\nfunction _adjustContinuousScale(props, scaleObject) {\n  const {_allData: allSeriesData, _adjustWhat: adjustWhat = []} = props;\n\n  // Assign the initial values.\n  const domainLength = scaleObject.domain.length;\n  const {domain} = scaleObject;\n  let scaleDomain0 = domain[0];\n  let scaleDomainN = domain[domainLength - 1];\n  let scaleDistance = scaleObject.distance;\n\n  // Find the smallest left position of the domain, the largest right position\n  // of the domain and the best distance for them.\n  allSeriesData.forEach((data, index) => {\n    if (adjustWhat.indexOf(index) === -1) {\n      return;\n    }\n    if (data && data.length) {\n      const {domain0, domainN, distance} = _getScaleDistanceAndAdjustedDomain(\n        data,\n        scaleObject\n      );\n      scaleDomain0 = Math.min(scaleDomain0, domain0);\n      scaleDomainN = Math.max(scaleDomainN, domainN);\n      scaleDistance = Math.max(scaleDistance, distance);\n    }\n  });\n\n  scaleObject.domain = [scaleDomain0, ...domain.slice(1, -1), scaleDomainN];\n\n  scaleObject.distance = scaleDistance;\n\n  return scaleObject;\n}\n\n/**\n * Get an adjusted scale. Suitable for 'category' and 'ordinal' scales.\n * @param {Object} scaleObject Scale object.\n * @returns {*} Scale object with adjustments.\n * @private\n */\nexport function _adjustCategoricalScale(scaleObject) {\n  const scaleFn = getScaleFnFromScaleObject(scaleObject);\n  const {domain, range} = scaleObject;\n  if (domain.length > 1) {\n    scaleObject.distance = Math.abs(scaleFn(domain[1]) - scaleFn(domain[0]));\n  } else {\n    scaleObject.distance = Math.abs(range[1] - range[0]);\n  }\n\n  return scaleObject;\n}\n\n/**\n * Retrieve a scale object or a value from the properties passed.\n * @param {Object} props Object of props.\n * @param {string} attr Attribute.\n * @returns {*} Scale object, value or null.\n */\nexport function getScaleObjectFromProps(props, attr) {\n  // Create the initial scale object.\n  const scaleObject = _collectScaleObjectFromProps(props, attr);\n  if (!scaleObject) {\n    return null;\n  }\n\n  // Make sure if it's possible to add space to the scale object. If not,\n  // return the object immediately.\n  if (!_isScaleAdjustmentPossible(props, scaleObject)) {\n    return scaleObject;\n  }\n\n  const {type} = scaleObject;\n  // Depending on what type the scale is, apply different adjustments. Distances\n  // for the ordinal and category scales are even, equal domains cannot be\n  // adjusted.\n  if (type === ORDINAL_SCALE_TYPE || type === CATEGORY_SCALE_TYPE) {\n    return _adjustCategoricalScale(scaleObject);\n  }\n  return _adjustContinuousScale(props, scaleObject);\n}\n\n/**\n * Get d3 scale for a given prop.\n * @param {Object} props Props.\n * @param {string} attr Attribute.\n * @returns {function} d3 scale function.\n */\nexport function getAttributeScale(props, attr) {\n  const scaleObject = getScaleObjectFromProps(props, attr);\n  return getScaleFnFromScaleObject(scaleObject);\n}\n\n/**\n * Get the value of `attr` from the object.\n * @param {Object} d - data Object.\n * @param {Function} accessor - accessor function.\n * @returns {*} Value of the point.\n * @private\n */\nfunction _getAttrValue(d, accessor) {\n  return accessor(d.data ? d.data : d);\n}\n\nfunction _isDefined(value) {\n  return typeof value !== 'undefined';\n}\n\n/*\n * Adds a percentage of padding to a given domain\n * @param {Array} domain X or Y domain to pad.\n * @param {Number} padding Percentage of padding to add to domain\n * @returns {Array} Padded Domain\n */\nfunction _padDomain(domain, padding) {\n  if (!domain) {\n    return domain;\n  }\n  if (isNaN(parseFloat(domain[0])) || isNaN(parseFloat(domain[1]))) {\n    return domain;\n  }\n  const [min, max] = domain;\n  const domainPadding = (max - min) * (padding * 0.01);\n  return [min - domainPadding, max + domainPadding];\n}\n\n/**\n * Get prop functor (either a value or a function) for a given attribute.\n * @param {Object} props Series props.\n * @param {Function} accessor - Property accessor.\n * @returns {*} Function or value.\n */\nexport function getAttributeFunctor(props, attr) {\n  const scaleObject = getScaleObjectFromProps(props, attr);\n  if (scaleObject) {\n    const scaleFn = getScaleFnFromScaleObject(scaleObject);\n    return d => scaleFn(_getAttrValue(d, scaleObject.accessor));\n  }\n  return null;\n}\n\n/**\n * Get the functor which extracts value form [attr]0 property. Use baseValue if\n * no attr0 property for a given object is defined. Fall back to domain[0] if no\n * base value is available.\n * @param {Object} props Object of props.\n * @param {string} attr Attribute name.\n * @returns {*} Function which returns value or null if no values available.\n */\nexport function getAttr0Functor(props, attr) {\n  const scaleObject = getScaleObjectFromProps(props, attr);\n  if (scaleObject) {\n    const {domain} = scaleObject;\n    const {baseValue = domain[0]} = scaleObject;\n    const scaleFn = getScaleFnFromScaleObject(scaleObject);\n    return d => {\n      const value = _getAttrValue(d, scaleObject.accessor0);\n      return scaleFn(_isDefined(value) ? value : baseValue);\n    };\n  }\n  return null;\n}\n\n/**\n * Tries to get the string|number value of the attr and falls back to\n * a fallback property in case if the value is a scale.\n * @param {Object} props Series props.\n * @param {string} attr Property name.\n * @returns {*} Function or value.\n */\nexport function getAttributeValue(props, attr) {\n  const scaleObject = getScaleObjectFromProps(props, attr);\n  if (scaleObject) {\n    if (!scaleObject.isValue && props[`_${attr}Value`] === undefined) {\n      warning(\n        `[React-vis] Cannot use data defined ${attr} for this ` +\n          'series type. Using fallback value instead.'\n      );\n    }\n    return props[`_${attr}Value`] || scaleObject.range[0];\n  }\n  return null;\n}\n\n/**\n * Get prop types by the attribute.\n * @param {string} attr Attribute.\n * @returns {Object} Object of xDomain, xRange, xType, xDistance and _xValue,\n * where x is an attribute passed to the function.\n */\nexport function getScalePropTypesByAttribute(attr) {\n  return {\n    [`_${attr}Value`]: PropTypes.any,\n    [`${attr}Domain`]: PropTypes.array,\n    [`get${toTitleCase(attr)}`]: PropTypes.func,\n    [`get${toTitleCase(attr)}0`]: PropTypes.func,\n    [`${attr}Range`]: PropTypes.array,\n    [`${attr}Type`]: PropTypes.oneOf(Object.keys(SCALE_FUNCTIONS)),\n    [`${attr}Distance`]: PropTypes.number,\n    [`${attr}BaseValue`]: PropTypes.any\n  };\n}\n\n/**\n * Extract the list of scale properties from the entire props object.\n * @param {Object} props Props.\n * @param {Array<String>} attributes Array of attributes for the given\n * components (for instance, `['x', 'y', 'color']`).\n * @returns {Object} Collected props.\n */\nexport function extractScalePropsFromProps(props, attributes) {\n  const result = {};\n  Object.keys(props).forEach(key => {\n    // this filtering is critical for extracting the correct accessors!\n    const attr = attributes.find(a => {\n      // width\n      const isPlainSet = key.indexOf(a) === 0;\n      // Ex: _data\n      const isUnderscoreSet = key.indexOf(`_${a}`) === 0;\n      // EX: getX\n      const usesGet = key.indexOf(`get${toTitleCase(a)}`) === 0;\n      return isPlainSet || isUnderscoreSet || usesGet;\n    });\n    if (!attr) {\n      return;\n    }\n    result[key] = props[key];\n  });\n  return result;\n}\n\n/**\n * Extract the missing scale props from the given data and return them as\n * an object.\n * @param {Object} props Props.\n * @param {Array} data Array of all data.\n * @param {Array<String>} attributes Array of attributes for the given\n * components (for instance, `['x', 'y', 'color']`).\n * @returns {Object} Collected props.\n */\nexport function getMissingScaleProps(props, data, attributes) {\n  const result = {};\n  // Make sure that the domain is set pad it if specified\n  attributes.forEach(attr => {\n    if (!props[`get${toTitleCase(attr)}`]) {\n      result[`get${toTitleCase(attr)}`] = d => d[attr];\n    }\n    if (!props[`get${toTitleCase(attr)}0`]) {\n      result[`get${toTitleCase(attr)}0`] = d => d[`${attr}0`];\n    }\n    if (!props[`${attr}Domain`]) {\n      result[`${attr}Domain`] = getDomainByAccessor(\n        data,\n        props[`get${toTitleCase(attr)}`] || result[`get${toTitleCase(attr)}`],\n        props[`get${toTitleCase(attr)}0`] || result[`get${toTitleCase(attr)}0`],\n        props[`${attr}Type`]\n      );\n      if (props[`${attr}Padding`]) {\n        result[`${attr}Domain`] = _padDomain(\n          result[`${attr}Domain`],\n          props[`${attr}Padding`]\n        );\n      }\n    }\n  });\n\n  return result;\n}\n\n/**\n * Return a d3 scale that returns the literal value that was given to it\n * @returns {function} literal scale.\n */\nexport function literalScale(defaultValue) {\n  function scale(d) {\n    if (d === undefined) {\n      return defaultValue;\n    }\n    return d;\n  }\n\n  function response() {\n    return scale;\n  }\n\n  scale.domain = response;\n  scale.range = response;\n  scale.unknown = response;\n  scale.copy = response;\n\n  return scale;\n}\n\nexport function getFontColorFromBackground(background) {\n  if (background) {\n    return hsl(background).l > 0.57 ? '#222' : '#fff';\n  }\n  return null;\n}\n\n/**\n * Creates fallback values for series from scales defined at XYPlot level.\n * @param {Object} props Props of the XYPlot object.\n * @param {Array<Object>} children Array of components, children of XYPlot\n * @returns {Array<Object>} Collected props.\n */\n\nexport function getXYPlotValues(props, children) {\n  const XYPlotScales = XYPLOT_ATTR.reduce((prev, attr) => {\n    const {\n      [`${attr}Domain`]: domain,\n      [`${attr}Range`]: range,\n      [`${attr}Type`]: type\n    } = props;\n\n    if (domain && range && type) {\n      return {\n        ...prev,\n        [attr]: SCALE_FUNCTIONS[type]()\n          .domain(domain)\n          .range(range)\n      };\n    }\n    return prev;\n  }, {});\n\n  return children.map(child =>\n    XYPLOT_ATTR.reduce((prev, attr) => {\n      if (child.props && child.props[attr] !== undefined) {\n        const scaleInput = child.props[attr];\n        const scale = XYPlotScales[attr];\n        const fallbackValue = scale ? scale(scaleInput) : scaleInput;\n        return {\n          ...prev,\n          [`_${attr}Value`]: fallbackValue\n        };\n      }\n      return prev;\n    }, {})\n  );\n}\n\nconst OPTIONAL_SCALE_PROPS = ['Padding'];\nconst OPTIONAL_SCALE_PROPS_REGS = OPTIONAL_SCALE_PROPS.map(\n  str => new RegExp(`${str}$`, 'i')\n);\n/**\n * Get the list of optional scale-related settings for XYPlot\n * mostly just used to find padding properties\n * @param {Object} props Object of props.\n * @returns {Object} Optional Props.\n * @private\n */\nexport function getOptionalScaleProps(props) {\n  return Object.keys(props).reduce((acc, prop) => {\n    const propIsNotOptional = OPTIONAL_SCALE_PROPS_REGS.every(\n      reg => !prop.match(reg)\n    );\n    if (propIsNotOptional) {\n      return acc;\n    }\n    acc[prop] = props[prop];\n    return acc;\n  }, {});\n}\n\nexport default {\n  extractScalePropsFromProps,\n  getAttributeScale,\n  getAttributeFunctor,\n  getAttr0Functor,\n  getAttributeValue,\n  getDomainByAccessor,\n  getFontColorFromBackground,\n  getMissingScaleProps,\n  getOptionalScaleProps,\n  getScaleObjectFromProps,\n  getScalePropTypesByAttribute,\n  getXYPlotValues,\n  literalScale\n};\n"
  },
  {
    "path": "packages/react-vis/src/utils/series-utils.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport AbstractSeries from 'plot/series/abstract-series';\nimport {DISCRETE_COLOR_RANGE, DEFAULT_OPACITY} from 'theme';\n\n/**\n * Check if the component is series or not.\n * @param {React.Component} child Component.\n * @returns {boolean} True if the child is series, false otherwise.\n */\nexport function isSeriesChild(child) {\n  const {prototype} = child.type;\n  return prototype instanceof AbstractSeries;\n}\n\n/**\n * Get all series from the 'children' object of the component.\n * @param {Object} children Children.\n * @returns {Array} Array of children.\n */\nexport function getSeriesChildren(children) {\n  return React.Children.toArray(children).filter(\n    child => child && isSeriesChild(child)\n  );\n}\n\n/**\n * Collect the map of repetitions of the series type for all children.\n * @param {Array} children Array of children.\n * @returns {{}} Map of repetitions where sameTypeTotal is the total amount and\n * sameTypeIndex is always 0.\n */\nfunction collectSeriesTypesInfo(children) {\n  const result = {};\n  children.filter(isSeriesChild).forEach(child => {\n    const {displayName} = child.type;\n    const {cluster} = child.props;\n    if (!result[displayName]) {\n      result[displayName] = {\n        sameTypeTotal: 0,\n        sameTypeIndex: 0,\n        clusters: new Set()\n      };\n    }\n    result[displayName].clusters.add(cluster);\n    result[displayName].sameTypeTotal++;\n  });\n  return result;\n}\n\n/**\n * Check series to see if it has angular data that needs to be converted\n * @param {Array} data - an array of objects to check\n * @returns {Boolean} whether or not this series contains polar configuration\n */\nfunction seriesHasAngleRadius(data = []) {\n  if (!data) {\n    return false;\n  }\n  return data.some(row => row.radius && row.angle);\n}\n\n/**\n * Possibly convert polar coordinates to x/y for computing domain\n * @param {Array} data - an array of objects to check\n * @param {String} attr - the property being checked\n * @returns {Boolean} whether or not this series contains polar configuration\n */\nfunction prepareData(data) {\n  if (!seriesHasAngleRadius(data)) {\n    return data;\n  }\n\n  return data.map(row => ({\n    ...row,\n    x: row.radius * Math.cos(row.angle),\n    y: row.radius * Math.sin(row.angle)\n  }));\n}\n\n/**\n * Collect the stacked data for all children in use. If the children don't have\n * the data (e.g. the child is invalid series or something else), then the child\n * is skipped.\n * Each next value of attr is equal to the previous value plus the difference\n * between attr0 and attr.\n * @param {Array} children Array of children.\n * @param {string} attr Attribute to stack by.\n * @returns {Array} New array of children for the series.\n */\nexport function getStackedData(children, attr) {\n  const areSomeSeriesStacked = children.some(\n    series => series && series.props.stack\n  );\n  // It stores the last segment position added to each bar, separated by cluster.\n  const latestAttrPositions = {};\n\n  return children.reduce((accumulator, series) => {\n    // Skip the children that are not series (e.g. don't have any data).\n    if (!series) {\n      accumulator.push(null);\n      return accumulator;\n    }\n    const seriesType = series.type.displayName;\n\n    const {data, cluster = 'default', stack} = series.props;\n    const preppedData = prepareData(data, attr);\n\n    if (\n      !attr ||\n      !preppedData ||\n      !preppedData.length ||\n      (areSomeSeriesStacked && !stack)\n    ) {\n      accumulator.push(preppedData);\n      return accumulator;\n    }\n\n    const attr0 = `${attr}0`;\n    const baseAttr = attr === 'y' ? 'x' : 'y';\n\n    accumulator.push(\n      preppedData.map(d => {\n        if (!latestAttrPositions[cluster]) {\n          latestAttrPositions[cluster] = {};\n        }\n        if (!latestAttrPositions[cluster][seriesType]) {\n          latestAttrPositions[cluster][seriesType] = {};\n        }\n\n        const prevD = latestAttrPositions[cluster][seriesType][d[baseAttr]];\n        // It is the first segment of a bar.\n        if (!prevD) {\n          latestAttrPositions[cluster][seriesType][d[baseAttr]] = {\n            [attr0]: d[attr0],\n            [attr]: d[attr]\n          };\n\n          return {...d};\n        }\n\n        // Calculate the position of the next segment in a bar.\n        const nextD = {\n          ...d,\n          [attr0]: prevD[attr],\n          [attr]: prevD[attr] + d[attr] - (d[attr0] || 0)\n        };\n\n        latestAttrPositions[cluster][seriesType][d[baseAttr]] = {\n          [attr0]: nextD[attr0],\n          [attr]: nextD[attr]\n        };\n\n        return nextD;\n      })\n    );\n\n    return accumulator;\n  }, []);\n}\n\n/**\n * Get the list of series props for a child.\n * @param {Array} children Array of all children.\n * @returns {Array} Array of series props for each child. If a child is not a\n * series, than it's undefined.\n */\nexport function getSeriesPropsFromChildren(children) {\n  const result = [];\n  const seriesTypesInfo = collectSeriesTypesInfo(children);\n  let seriesIndex = 0;\n  const _opacityValue = DEFAULT_OPACITY;\n  children.forEach(child => {\n    let props;\n    if (isSeriesChild(child)) {\n      const seriesTypeInfo = seriesTypesInfo[child.type.displayName];\n      const _colorValue =\n        DISCRETE_COLOR_RANGE[seriesIndex % DISCRETE_COLOR_RANGE.length];\n      props = {\n        ...seriesTypeInfo,\n        seriesIndex,\n        _colorValue,\n        _opacityValue\n      };\n      seriesTypeInfo.sameTypeIndex++;\n      seriesIndex++;\n      if (child.props.cluster) {\n        props.cluster = child.props.cluster;\n        // Using Array.from() so we can use .indexOf\n        props.clusters = Array.from(seriesTypeInfo.clusters);\n        props.sameTypeTotal = props.clusters.length;\n        props.sameTypeIndex = props.clusters.indexOf(child.props.cluster);\n      }\n    }\n    result.push(props);\n  });\n  return result;\n}\n\n/**\n * Find the max radius value from the nodes to be rendered after they have been\n * transformed into an array\n * @param {Array} data - the tree data after it has been broken into a iterable\n * it is an array of objects!\n * @returns {number} the maximum value in coordinates for the radial variable\n */\nexport function getRadialDomain(data) {\n  return data.reduce((res, row) => Math.max(row.radius, res), 0);\n}\n\nexport const ANIMATED_SERIES_PROPS = [\n  'xRange',\n  'xDomain',\n  'x',\n  'yRange',\n  'yDomain',\n  'y',\n  'colorRange',\n  'colorDomain',\n  'color',\n  'opacityRange',\n  'opacityDomain',\n  'opacity',\n  'strokeRange',\n  'strokeDomain',\n  'stroke',\n  'fillRange',\n  'fillDomain',\n  'fill',\n  'width',\n  'height',\n  'marginLeft',\n  'marginTop',\n  'marginRight',\n  'marginBottom',\n  'data',\n  'angleDomain',\n  'angleRange',\n  'angle',\n  'radiusDomain',\n  'radiusRange',\n  'radius',\n  'innerRadiusDomain',\n  'innerRadiusRange',\n  'innerRadius'\n];\n\nexport function getStackParams(props) {\n  const {_stackBy, valuePosAttr, cluster} = props;\n  let {sameTypeTotal = 1, sameTypeIndex = 0} = props;\n\n  // If bars are stacked, but not clustering, override `sameTypeTotal` and\n  // `sameTypeIndex` such that bars are stacked and not staggered.\n  if (_stackBy === valuePosAttr && !cluster) {\n    sameTypeTotal = 1;\n    sameTypeIndex = 0;\n  }\n  return {sameTypeTotal, sameTypeIndex};\n}\n"
  },
  {
    "path": "packages/react-vis/src/utils/styling-utils.js",
    "content": "// Copyright (c) 2016 - 2019 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n/**\n * Generates interpolated class names signature based on multiple class names\n * ignoring the falsy and non-string values\n * @param {...string} classNames CSS class signatures.\n * @returns {string} Interpolated string containing all valid class names.\n */\n\nexport function getCombinedClassName(...classNames) {\n  return classNames.filter(cn => cn && typeof cn === 'string').join(' ');\n}\n"
  },
  {
    "path": "packages/react-vis/tests/.eslintrc",
    "content": "{\n  \"rules\": {\n    \"max-len\": \"off\",\n    \"react/jsx-key\": \"off\"\n  }\n}\n"
  },
  {
    "path": "packages/react-vis/tests/components/animation.test.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {mount} from 'enzyme';\n\nimport Animation from 'animation';\nimport Axis from 'plot/axis/axis';\nimport AxisTicks from 'plot/axis/axis-ticks';\nimport VerticalBarSeries from 'plot/series/vertical-bar-series';\nimport XYPlot from 'plot/xy-plot';\n\ndescribe('Animation', () => {\n  test('interpolates xDomain when specified', () => {\n    const wrapper = mount(\n      <XYPlot width={300} height={300}>\n        <VerticalBarSeries data={[{x: 1, y: 0}]} />\n        <Axis\n          attr={'x'}\n          animation={{nonAnimatedProps: ['xDomain']}}\n          xDomain={['Black']}\n        />\n      </XYPlot>\n    );\n\n    const renderedAnimationWrapper = wrapper.find(Animation);\n\n    expect(renderedAnimationWrapper.find(AxisTicks).prop('xDomain')).toEqual([\n      'Black'\n    ]);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/arc-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport ArcSeries from 'plot/series/arc-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport ArcSeriesExample from '../../../showcase/radial-chart/arc-series-example';\n\ntestRenderWithProps(ArcSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\ndescribe('ArcSeries', () => {\n  test('Showcase Example - ArcSeriesExample', () => {\n    const $ = mount(\n      <svg>\n        <ArcSeriesExample />\n      </svg>\n    );\n    expect($.text()).toBe('UPDATE−4−2024−4−2024');\n    // multiplied by two to account for shadow listeners\n    expect($.find('.rv-xy-plot__series--arc').length).toBe(4);\n    expect($.find('.rv-xy-plot__series--arc path').length).toBe(2 * 8);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/area-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\n\nimport XYPlot from 'plot/xy-plot';\nimport AreaSeries from 'plot/series/area-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport AreaChartElevated from '../../../showcase/plot/area-chart-elevated';\nimport AreaChart from '../../../showcase/plot/area-chart';\n\ntestRenderWithProps(AreaSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\nconst AREA_PROPS = {\n  className: 'area-chart-example',\n  color: '#12939a',\n  data: [\n    {x: 1, y: 5, y0: 6},\n    {x: 2, y: 20, y0: 11},\n    {x: 3, y: 10, y0: 9}\n  ]\n};\n\ndescribe('AreaSeries', () => {\n  test('basic rendering', () => {\n    const $ = mount(\n      <XYPlot width={300} height={300}>\n        <AreaSeries {...AREA_PROPS} />\n      </XYPlot>\n    );\n    expect($.find('.rv-xy-plot__series').length).toBe(1);\n    expect($.find('path.rv-xy-plot__series').length).toBe(1);\n    expect($.find('path.area-chart-example').length).toBe(1);\n\n    $.setProps({children: <AreaSeries {...{...AREA_PROPS, data: null}} />});\n    expect($.find('.rv-xy-plot__series').length).toBe(0);\n    expect($.find('.rv-xy-plot__series path').length).toBe(0);\n    expect($.find('.area-chart-example').length).toBe(0);\n  });\n\n  test('AreaSeries: Showcase Example - AreaChart', () => {\n    const $ = mount(<AreaChart />);\n    expect($.find('.rv-xy-plot__series').length).toBe(1);\n    expect($.find('path.rv-xy-plot__series').length).toBe(1);\n    expect($.find('path.area-series-example').length).toBe(1);\n  });\n\n  test('AreaSeries: Showcase Example - AreaChartElevated', () => {\n    const $ = mount(<AreaChartElevated />);\n    expect($.find('.rv-xy-plot__series').length).toBe(5);\n    expect($.find('path.rv-xy-plot__series').length).toBe(3);\n    expect($.find('path.area-elevated-series-1').length).toBe(1);\n    expect($.find('path.area-elevated-series-2').length).toBe(1);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/axes.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\n\nimport CustomAxes from '../../../showcase/axes/custom-axes';\nimport CustomAxis from '../../../showcase/axes/custom-axis';\nimport PaddedAxis from '../../../showcase/axes/padded-axis';\nimport CustomAxesOrientation from '../../../showcase/axes/custom-axes-orientation';\nimport AxisWithTurnedLabels from '../../../showcase/plot/axis-with-turned-labels';\nimport AxisOn0 from '../../../showcase/axes/axis-on-0';\n\ndescribe('Axis', () => {\n  test('Showcase Example - CustomAxesOrientation', () => {\n    const $ = mount(<CustomAxesOrientation />);\n    expect($.text()).toBe('1.01.52.02.53.03.54.0X Axis246810Y Axis');\n    expect($.find('.rv-xy-plot__series--line').length).toBe(2);\n    expect($.find('line').length).toBe(26);\n  });\n\n  test('Showcase Example - Custom axis', () => {\n    const $ = mount(<CustomAxis />);\n    expect($.text()).toBe('1.01.52.03.0X');\n    expect($.find('.rv-xy-plot__series--line').length).toBe(1);\n    expect($.find('line').length).toBe(15);\n\n    const titleStyle = $.find('.rv-xy-plot__axis__title text').prop('style');\n    expect(titleStyle.fontSize).toBe('16px');\n  });\n\n  test('Showcase Example - Even more Custom axes', () => {\n    const $ = mount(<CustomAxes />);\n    expect($.text()).toBe(\n      '01345XValue is 0Value is 1Value is 2Value is 3Value is 4Value is 501491625cooldogskateboardwowsuchMultilinedogs'\n    );\n    expect($.find('line').length).toBe(26);\n  });\n\n  test('Showcase Example - AxisWithTurnedLabels', () => {\n    const $ = mount(<AxisWithTurnedLabels />);\n    expect($.text()).toBe('ApplesBananasCranberries02468101214');\n    expect($.find('rect').length).toBe(6);\n    expect($.find('line').length).toBe(24);\n  });\n\n  test('Showcase Example - Padded', () => {\n    const $ = mount(<PaddedAxis />);\n    expect($.find('.rv-xy-plot__series--line').length).toBe(4);\n    expect($.find('line').length > 30).toBeTruthy();\n  });\n\n  test('axis crosses on 0', () => {\n    // vertical axes\n    const $0 = mount(\n      <AxisOn0\n        verticalTickValues={[0]}\n        horizontalTickValues={[]}\n        yAxisOn0={true}\n      />\n    ).render();\n\n    const xOfGridlines0 = $0.find('.rv-xy-plot__grid-lines line')[0].attribs.x1;\n    const xOfAxisSetOn0 = translateToXY(\n      $0.find('.rv-xy-plot__axis.rv-xy-plot__axis--vertical')[0].attribs\n        .transform\n    )[0];\n\n    expect(xOfGridlines0).toBe(xOfAxisSetOn0);\n\n    const $1 = mount(\n      <AxisOn0\n        verticalTickValues={[0]}\n        horizontalTickValues={[]}\n        yAxisOn0={false}\n      />\n    ).render();\n\n    const xOfAxisNotSetOn0 = $1\n      .find('.rv-xy-plot__axis.rv-xy-plot__axis--vertical')[0]\n      .attribs.transform.replace('translate(', '')\n      .split(',')[0];\n\n    expect(xOfGridlines0 !== xOfAxisNotSetOn0).toBeTruthy();\n\n    // horizontal axes\n    const $2 = mount(\n      <AxisOn0\n        verticalTickValue={[]}\n        horizontalTickValues={[0]}\n        xAxisOn0={true}\n      />\n    ).render();\n    const gridlinesY = Number(\n      translateToXY($2.find('.rv-xy-plot__grid-lines')[0].attribs.transform)[1]\n    );\n    const yOfGridlines0 = String(\n      gridlinesY +\n        Number($2.find('.rv-xy-plot__grid-lines__line')[0].attribs.y1)\n    );\n    const yOfAxisSetOn0 = translateToXY(\n      $2.find('.rv-xy-plot__axis.rv-xy-plot__axis--horizontal')[0].attribs\n        .transform\n    )[1];\n\n    expect(yOfAxisSetOn0).toBe(yOfGridlines0);\n\n    const $3 = mount(\n      <AxisOn0\n        verticalTickValue={[]}\n        horizontalTickValues={[0]}\n        xAxisOn0={false}\n      />\n    ).render();\n\n    const yOfAxisNotSetOn0 = translateToXY(\n      $3.find('.rv-xy-plot__axis.rv-xy-plot__axis--horizontal')[0].attribs\n        .transform\n    )[1];\n    expect(yOfAxisNotSetOn0 !== yOfGridlines0).toBeTruthy();\n  });\n});\n\nfunction translateToXY(translate) {\n  // 'translate(50,100)' => ['50', '100']\n  const results = /translate\\(\\s*([^\\s,)]+)[ ,]([^\\s,)]+)/.exec(translate);\n  return [results[1], results[2]];\n}\n"
  },
  {
    "path": "packages/react-vis/tests/components/axis-tick-format.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\n\nimport CustomAxisTickElement from '../../../showcase/axes/custom-axis-tick-element';\n\ndescribe('Axis Format', () => {\n  test('correctly renders return values from tickFormat', () => {\n    const element = mount(<CustomAxisTickElement />);\n    const ticks = element.find(\n      '.rv-xy-plot__axis--horizontal .rv-xy-plot__axis__tick'\n    );\n    expect(ticks.map(tick => tick.find('text').length)).toEqual([\n      0,\n      0,\n      1,\n      0,\n      1\n    ]);\n    expect(\n      ticks\n        .at(2)\n        .find('text')\n        .find('tspan').length\n    ).toBe(1);\n    expect(\n      ticks\n        .at(4)\n        .find('text')\n        .text()\n    ).toBe('Label');\n  });\n\n  test('passes props to custom element', () => {\n    const CustomLabel = props => {\n      expect(Object.keys(props).sort()).toEqual([\n        'containerWidth',\n        'dy',\n        'textAnchor',\n        'tickCount',\n        'transform'\n      ]);\n      return <text>Custom Label</text>;\n    };\n    const element = mount(<CustomAxisTickElement />);\n    element.setState({\n      data: [...element.state().data, {x: 5, y: 600, label: <CustomLabel />}]\n    });\n    expect(\n      element\n        .find('.rv-xy-plot__axis--horizontal .rv-xy-plot__axis__tick')\n        .at(5)\n        .find('text')\n        .text()\n    ).toBe('Custom Label');\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/axis-title.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport AxisTitle from 'plot/axis/axis-title';\nimport {ORIENTATION} from 'utils/axis-utils';\n\nconst {LEFT, RIGHT, TOP, BOTTOM} = ORIENTATION;\n\nconst baseProps = {\n  width: 400,\n  height: 400,\n  title: 'Title'\n};\n\ndescribe('AxisTitle', () => {\n  test('horizontal bottom axis title', () => {\n    const props = Object.assign({}, baseProps, {\n      orientation: BOTTOM\n    });\n    const $ = mount(\n      <svg>\n        <AxisTitle {...props} />\n      </svg>\n    );\n    const innerGroupHtml = $.find('g > g').html();\n    expect(innerGroupHtml.includes('text-anchor: end')).toBeTruthy();\n    expect($.find('text').text()).toBe(baseProps.title);\n  });\n\n  test('horizontal top axis title', () => {\n    const props = Object.assign({}, baseProps, {\n      orientation: TOP,\n      position: 'start'\n    });\n    const $ = mount(\n      <svg>\n        <AxisTitle {...props} />\n      </svg>\n    );\n    const innerGroupHtml = $.find('g > g').html();\n    expect(innerGroupHtml.includes('text-anchor: start')).toBeTruthy();\n    expect($.find('text').text()).toBe(baseProps.title);\n  });\n\n  test('vertical left title', () => {\n    const props = Object.assign({}, baseProps, {\n      orientation: LEFT\n    });\n    const $ = mount(\n      <svg>\n        <AxisTitle {...props} />\n      </svg>\n    );\n    const innerGroupHtml = $.find('g > g').html();\n    expect(innerGroupHtml.includes('text-anchor: end')).toBeTruthy();\n    expect($.find('text').text()).toBe(baseProps.title);\n  });\n\n  test('vertical right title', () => {\n    const props = Object.assign({}, baseProps, {\n      orientation: RIGHT,\n      position: 'start'\n    });\n    const $ = mount(\n      <svg>\n        <AxisTitle {...props} />\n      </svg>\n    );\n    const innerGroupHtml = $.find('g > g').html();\n    expect(innerGroupHtml.includes('text-anchor: start')).toBeTruthy();\n    expect($.find('text').text()).toBe(baseProps.title);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/bar-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport XYPlot from 'plot/xy-plot';\nimport HorizontalBarSeries from 'plot/series/horizontal-bar-series';\nimport VerticalBarSeries from 'plot/series/vertical-bar-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport StackedHorizontalBarChart from '../../../showcase/plot/stacked-horizontal-bar-chart';\nimport StackedVerticalBarChart from '../../../showcase/plot/stacked-vertical-bar-chart';\nimport BarChart from '../../../showcase/plot/bar-chart';\nimport BigBaseBarChart from '../../../showcase/plot/big-base-bar-chart';\nimport ClusteredStackedVerticalBarChart from '../../../showcase/plot/clustered-stacked-bar-chart';\nimport DifferenceChart from '../../../showcase/plot/difference-chart';\n\ndescribe('BarSeries', () => {\n  testRenderWithProps(HorizontalBarSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\n  testRenderWithProps(VerticalBarSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\n  test('Showcase Example - BarChart', () => {\n    const $ = mount(<BarChart />);\n    expect($.text()).toBe('TOGGLE TO CANVASABC02468101214ABC');\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(6);\n    expect($.find('g.vertical-bar-series-example').length).toBe(1);\n\n    $.find('.showcase-button').simulate('click');\n    expect($.find('rect.rv-xy-plot__series--bar').length).toBe(0);\n    expect($.find('.rv-xy-canvas canvas').length).toBe(1);\n  });\n\n  test('Showcase Example - StackedHorizontalBarChart & StackedVerticalBarChart', () => {\n    [StackedHorizontalBarChart, StackedVerticalBarChart].forEach(\n      (Component, i) => {\n        const $ = mount(<Component />);\n        const textContent = ['0510152025', '12345'];\n        const expectedContent = `TOGGLE TO CANVAS${(i === 1\n          ? textContent.reverse()\n          : textContent\n        ).join('')}`;\n        expect($.text()).toBe(expectedContent);\n        expect($.find('.rv-xy-plot__series--bar rect').length).toBe(6);\n        $.find('.showcase-button').simulate('click');\n        expect($.find('.rv-xy-plot__series--bar rect').length).toBe(0);\n        expect($.find('.rv-xy-canvas canvas').length).toBe(1);\n      }\n    );\n  });\n\n  test('Ordinal Y-Axis HorizontalBarSeries', () => {\n    const $ = mount(\n      <XYPlot width={300} height={300} yType=\"ordinal\">\n        <HorizontalBarSeries\n          data={[\n            {y: 'a', x: 10},\n            {y: 'b', x: 5},\n            {y: 'c', x: 15}\n          ]}\n        />\n      </XYPlot>\n    );\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(3);\n    expect(\n      $.find('.rv-xy-plot__series--bar rect')\n        .at(0)\n        .prop('height') > 0\n    ).toBe(true);\n  });\n\n  test('No data', () => {\n    const $ = mount(\n      <XYPlot width={300} height={300} yType=\"ordinal\">\n        <HorizontalBarSeries data={null} />\n      </XYPlot>\n    );\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(0);\n  });\n\n  test('Showcase Example - ClusteredStackedVerticalBarChart', () => {\n    const $ = mount(<ClusteredStackedVerticalBarChart />);\n    expect($.text()).toBe('TOGGLE TO CANVASQ1Q2Q3Q40102030ApplesOranges');\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(16);\n    expect($.find('.rv-xy-plot__series').length).toBe(4);\n\n    $.find('.showcase-button').simulate('click');\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(0);\n    expect($.find('.rv-xy-canvas canvas').length).toBe(1);\n  });\n\n  test('Showcase Example - BigBaseBarChart', () => {\n    const $ = mount(<BigBaseBarChart />);\n    expect($.text()).toBe(\n      'TOGGLE TO CANVAS:38:39:40:41199,800199,900200,000200,100200,200200,300200,400'\n    );\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(15);\n    expect($.find('.rv-xy-plot__series').length).toBe(1);\n\n    $.find('.showcase-button').simulate('click');\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(0);\n    expect($.find('.rv-xy-canvas canvas').length).toBe(1);\n  });\n\n  test('Showcase Example - DifferenceChart', () => {\n    const $ = mount(<DifferenceChart />);\n    expect($.text()).toBe('TOGGLE TO CANVAS02468101214−4−20246810');\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(15);\n    expect($.find('.rv-xy-plot__series').length).toBe(1);\n\n    $.find('.showcase-button').simulate('click');\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(0);\n    expect($.find('.rv-xy-canvas canvas').length).toBe(1);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/borders.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport Borders from 'plot/borders';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport GradientExample from '../../../showcase/misc/gradient-example';\n\ntestRenderWithProps(\n  Borders,\n  {\n    ...GENERIC_XYPLOT_SERIES_PROPS,\n    marginLeft: 0,\n    marginRight: 0,\n    innerWidth: 100,\n    marginTop: 0,\n    marginBottom: 0,\n    innerHeight: 100\n  },\n  true\n);\n\ndescribe('Borders', () => {\n  test('GradientExample', () => {\n    const $ = mount(<GradientExample />);\n    expect($.find('.rv-xy-plot__borders').length).toBe(1);\n    expect($.find('.rv-xy-plot__borders rect').length).toBe(4);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/canvas-component.test.js",
    "content": "import HorizontalBarSeriesCanvas from 'plot/series/horizontal-bar-series-canvas';\nimport VerticalBarSeriesCanvas from 'plot/series/vertical-bar-series-canvas';\nimport HorizontalRectSeriesCanvas from 'plot/series/horizontal-rect-series-canvas';\nimport VerticalRectSeriesCanvas from 'plot/series/vertical-rect-series-canvas';\nimport RectSeriesCanvas from 'plot/series/rect-series-canvas';\nimport BarSeriesCanvas from 'plot/series/bar-series-canvas';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\n\ntestRenderWithProps(HorizontalBarSeriesCanvas, GENERIC_XYPLOT_SERIES_PROPS);\ntestRenderWithProps(VerticalBarSeriesCanvas, GENERIC_XYPLOT_SERIES_PROPS);\ntestRenderWithProps(HorizontalRectSeriesCanvas, GENERIC_XYPLOT_SERIES_PROPS);\ntestRenderWithProps(VerticalRectSeriesCanvas, GENERIC_XYPLOT_SERIES_PROPS);\ntestRenderWithProps(RectSeriesCanvas, GENERIC_XYPLOT_SERIES_PROPS);\ntestRenderWithProps(BarSeriesCanvas, GENERIC_XYPLOT_SERIES_PROPS);\n"
  },
  {
    "path": "packages/react-vis/tests/components/circular-grid-lines.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport CircularGridLines from 'plot/circular-grid-lines';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport FauxRadialScatterplot from '../../../showcase/plot/faux-radial-scatterplot';\n\ndescribe('CircularGridLines', () => {\n  testRenderWithProps(CircularGridLines, GENERIC_XYPLOT_SERIES_PROPS, true);\n\n  test('Showcase Example - FauxRadialScatterplot', () => {\n    const $ = mount(<FauxRadialScatterplot />);\n    expect($.text()).toBe('−3−2−10123−3−2−10123');\n    expect($.find('.rv-xy-plot__circular-grid-lines__line').length).toBe(7);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/color-article.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\n\nimport {\n  SensibleDefaults,\n  ColorInXYPlot,\n  ColorSpecificity,\n  CategoryColorAtMarkLevel,\n  CategoryColorAtMarkLevelCustomPalette,\n  CategoryColorAtMarkLevelFixedStroke,\n  GradientCharts,\n  LinearColorAtMarkLevel,\n  LinearColorAtMarkLevelNoPalette,\n  LineSeriesMarkSeries,\n  LiteralColorAtMarkLevel,\n  CategoryColorAtSeriesLevel,\n  LinearColorAtSeriesLevel,\n  LiteralColorAtSeriesLevel,\n  ReactVis5,\n  ReactVis20,\n  Continuous,\n  CustomPalette\n} from '../../../showcase/color/mini-color-examples';\n\ndescribe('Color Article Test', () => {\n  test('generateCharts', () => {\n    [\n      {name: 'SensibleDefaults', Item: SensibleDefaults},\n      {name: 'ColorInXYPlot', Item: ColorInXYPlot},\n      {name: 'LiteralColorAtSeriesLevel', Item: LiteralColorAtSeriesLevel},\n      {name: 'LinearColorAtSeriesLevel', Item: LinearColorAtSeriesLevel},\n      {name: 'CategoryColorAtSeriesLevel', Item: CategoryColorAtSeriesLevel},\n      {name: 'LiteralColorAtMarkLevel', Item: LiteralColorAtMarkLevel},\n      {name: 'CategoryColorAtMarkLevel', Item: CategoryColorAtMarkLevel},\n      {\n        name: 'CategoryColorAtMarkLevelCustomPalette',\n        Item: CategoryColorAtMarkLevelCustomPalette\n      },\n      {\n        name: 'CategoryColorAtMarkLevelFixedStroke',\n        Item: CategoryColorAtMarkLevelFixedStroke\n      },\n      {\n        name: 'LinearColorAtMarkLevelNoPalette',\n        Item: LinearColorAtMarkLevelNoPalette\n      },\n      {name: 'LinearColorAtMarkLevel', Item: LinearColorAtMarkLevel}\n    ].forEach(obj => {\n      const {Item} = obj;\n      const $ = mount(<Item />);\n      expect($.find('.rv-xy-plot').length).toBe(3);\n      expect($.find('.rv-xy-plot__series--bar rect').length).toBe(30);\n      expect($.find('path.rv-xy-plot__series--line').length).toBe(3);\n      expect($.find('.rv-xy-plot__series--mark circle').length).toBe(30);\n    });\n  });\n\n  test('GradientCharts', () => {\n    const $ = mount(<GradientCharts />);\n\n    expect($.find('.rv-xy-plot').length).toBe(3);\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(10);\n    expect($.find('path.rv-xy-plot__series--line').length).toBe(1);\n    expect($.find('.rv-xy-plot__series--mark circle').length).toBe(10);\n  });\n\n  test('ColorSpecificity', () => {\n    const $ = mount(<ColorSpecificity />);\n\n    expect($.find('.rv-xy-plot').length).toBe(3);\n    expect($.find('.rv-xy-plot__series--bar rect').length).toBe(10);\n    expect($.find('path.rv-xy-plot__series--line').length).toBe(3);\n    expect($.find('.rv-xy-plot__series--mark circle').length).toBe(30);\n  });\n\n  test('generatePalette', () => {\n    [\n      {\n        name: 'ReactVis5',\n        Item: ReactVis5,\n        expectedText: '#12939A#79C7E3#1A3177#FF9833#EF5D28',\n        numberOfBoxes: 5\n      },\n      {\n        name: 'ReactVis20',\n        Item: ReactVis20,\n        expectedText:\n          '#19CDD7#DDB27C#88572C#FF991F#F15C17#223F9A#DA70BF#125C77#4DC19C#776E57#12939A#17B8BE#F6D18A#B7885E#FFCB99#F89570#829AE3#E79FD5#1E96BE#89DAC1#B3AD9E',\n        numberOfBoxes: 21\n      },\n      {\n        name: 'Continuous',\n        Item: Continuous,\n        expectedText: '#EF5D28#FF9833',\n        numberOfBoxes: 2\n      },\n      {\n        name: 'CustomPalette',\n        Item: CustomPalette,\n        expectedText:\n          '#cd3b54#59b953#ba4fb9#99b53e#7f61d3#c9a83a#626dbc#e08b39#5ea0d8#cf4d2a#4fb79b#d24691#528240#c388d2#80742b#9c4a6d#caaa70#e0829f#9d5d30#dc7666',\n        numberOfBoxes: 20\n      }\n    ].forEach(obj => {\n      const {Item, expectedText, numberOfBoxes} = obj;\n      const $ = mount(<Item />);\n      expect($.find('.color-box').length).toBe(numberOfBoxes);\n      expect($.text()).toBe(expectedText);\n    });\n  });\n\n  test('LineSeriesMarkSeries', () => {\n    const $ = mount(<LineSeriesMarkSeries />);\n    expect($.find('path.rv-xy-plot__series--line').length).toBe(3);\n    expect($.find('.rv-xy-plot__series--mark circle').length).toBe(30);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/contour-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport ContourSeries from 'plot/series/contour-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport ContourSeriesExample from '../../../showcase/plot/contour-series-example';\n\ndescribe('ContourSeries', () => {\n  testRenderWithProps(ContourSeries, GENERIC_XYPLOT_SERIES_PROPS);\n\n  test('Showcase Example - ContourSeriesExample', () => {\n    const $ = mount(<ContourSeriesExample />);\n    expect($.text()).toBe('4045505560657075808590951002345678UPDATE');\n    expect($.find('.rv-xy-plot__series--contour').length).toBe(1);\n    expect($.find('.rv-xy-plot__series--contour-line').length).toBe(17);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/crosshair.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\n\nimport DynamicCrosshair from '../../../showcase/axes/dynamic-crosshair';\n\ndescribe('Crosshair', () => {\n  test('Dynamic Crosshair - Example', () => {\n    const $ = mount(<DynamicCrosshair />);\n    simulateMouseMove(100);\n    expect($.find('.rv-crosshair').hasClass('test-class-name')).toBe(true);\n\n    function simulateMouseMove(x) {\n      $.find('.rv-xy-plot__inner').simulate('mousemove', {\n        nativeEvent: {clientX: x, clientY: 150}\n      });\n    }\n  });\n\n  test('Dynamic Crosshair - Touch Example', () => {\n    const $ = mount(<DynamicCrosshair />);\n    simulateMouseMove(100);\n    expect($.find('.rv-crosshair').hasClass('test-class-name')).toBe(true);\n\n    function simulateMouseMove(x) {\n      $.find('.rv-xy-plot__inner').simulate('touchmove', {\n        nativeEvent: {type: 'touchmove', touches: [{pageX: x, pageY: 150}]}\n      });\n    }\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/custom-svg-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport CustomSVGSeries from 'plot/series/custom-svg-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport CustomSVGExample from '../../../showcase/plot/custom-svg-example';\nimport CustomSVGAllTheMarks from '../../../showcase/plot/custom-svg-all-the-marks';\nimport CustomSVGRootLevelComponent from '../../../showcase/plot/custom-svg-root-level';\n\ndescribe('CustomSVGSeries', () => {\n  testRenderWithProps(CustomSVGSeries, GENERIC_XYPLOT_SERIES_PROPS);\n\n  test('Showcase Example - CustomSVGExample', () => {\n    const $ = mount(<CustomSVGExample />);\n    expect($.text()).toBe('1.01.52.02.53.068101214x: 187.5y: 200');\n    expect($.find('.rv-xy-plot__series--custom-svg').length).toBe(5);\n    expect($.find('.rv-xy-plot__series--custom-svg polygon').length).toBe(0);\n    expect($.find('.rv-xy-plot__series--custom-svg circle').length).toBe(2);\n    expect($.find('.rv-xy-plot__series--custom-svg rect').length).toBe(3);\n  });\n\n  test('Showcase Example - CustomSVGRootLevelComponent', () => {\n    const $ = mount(<CustomSVGRootLevelComponent />);\n    expect($.text()).toBe(\n      '1.01.52.02.53.068101214x: 0y: 125x: 87.5y: 75.00000000000001x: 125y: 250x: 250y: 0x: 187.5y: 200'\n    );\n    expect($.find('.rv-xy-plot__series--custom-svg').length).toBe(5);\n    expect($.find('.rv-xy-plot__series--custom-svg polygon').length).toBe(0);\n    expect($.find('.rv-xy-plot__series--custom-svg circle').length).toBe(5);\n    expect($.find('.rv-xy-plot__series--custom-svg rect').length).toBe(0);\n    expect($.find('.rv-xy-plot__series--custom-svg text').length).toBe(5);\n  });\n\n  test('Showcase Example - CustomSVGAllTheMarks', () => {\n    const textContent = 'REVERSE0123402468101214';\n    const hoverText = 'star';\n\n    const $ = mount(<CustomSVGAllTheMarks />);\n    expect($.text()).toBe(textContent);\n    $.find('.rv-xy-plot__series--custom-svg')\n      .at(0)\n      .simulate('mouseEnter');\n    expect($.text()).toBe(`${textContent}${hoverText}`);\n    expect($.find('.rv-xy-plot__series--custom-svg').length).toBe(20);\n    expect($.find('.rv-xy-plot__series--custom-svg polygon').length).toBe(10);\n    expect($.find('.rv-xy-plot__series--custom-svg circle').length).toBe(5);\n    expect($.find('.rv-xy-plot__series--custom-svg rect').length).toBe(5);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/data-article.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\n\nimport {MiniCharts} from '../../../showcase/data/mini-data-examples';\n\ndescribe('Scales and data examples', () => {\n  test('MiniCharts', () => {\n    const $ = mount(<MiniCharts />);\n    expect($.find('.rv-xy-plot').length).toBe(3);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/decorative-axis.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport DecorativeAxis from 'plot/axis/decorative-axis';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport DecorativeAxisCrissCross from '../../../showcase/axes/decorative-axes-criss-cross';\nimport ParallelCoordinatesExample from '../../../showcase/axes/parallel-coordinates-example';\n\ntestRenderWithProps(\n  DecorativeAxis,\n  {\n    ...GENERIC_XYPLOT_SERIES_PROPS,\n    axisStart: {x: 0, y: 1},\n    axisEnd: {x: 0, y: 1},\n    axisDomain: [0, 1]\n  },\n  true\n);\n\ndescribe('DecorativeAxis', () => {\n  test('Showcase Example - DecorativeAxisCrissCross', () => {\n    const $ = mount(<DecorativeAxisCrissCross />);\n    expect($.text()).toBe(\n      '−101.01223344556677889100¡1000!¡990!¡980!¡970!¡960!¡950!¡940!¡930!¡920!¡910!¡900!'\n    );\n    expect($.find('.rv-xy-manipulable-axis').length).toBe(2);\n    expect($.find('.rv-xy-plot__axis__tick__line').length).toBe(22);\n    expect($.find('.rv-xy-plot__axis__tick__text').length).toBe(22);\n  });\n\n  test('Showcase Example - ParallelCoordinatesExample', () => {\n    const $ = mount(<ParallelCoordinatesExample />);\n    expect($.text()).toBe(\n      '0.04.79.314192328333742473.03.54.04.55.05.56.06.57.07.58.0681101501802202603003403804204600.023466992120140160180210230160020002300270030003400370041004400480051008.09.71113151618202123257071727475767778808182'\n    );\n    expect($.find('.rv-xy-manipulable-axis').length).toBe(7);\n    expect($.find('.rv-xy-plot__axis__tick__line').length).toBe(77);\n    expect($.find('.rv-xy-plot__axis__tick__text').length).toBe(77);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/gradient.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport GradientDefs from 'plot/gradient-defs';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport TriangleExample from '../../../showcase/misc/triangle-example';\nimport GradientExample from '../../../showcase/misc/gradient-example';\n\ndescribe('GradientDefs', () => {\n  testRenderWithProps(GradientDefs, GENERIC_XYPLOT_SERIES_PROPS, true);\n\n  test('TriangleExample', () => {\n    const $ = mount(<TriangleExample />);\n    expect($.find('.rv-xy-plot__series--polygon').length).toBe(121);\n    expect($.find('.rv-gradient-defs').length).toBe(1);\n    expect($.find('#grad1').length).toBe(1);\n  });\n\n  test('GradientExample', () => {\n    const $ = mount(<GradientExample />);\n    expect($.find('.rv-xy-plot__series--line').length).toBe(2);\n    expect($.find('.rv-gradient-defs').length).toBe(1);\n    expect($.find('#CoolGradient').length).toBe(1);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/grid-lines.test.js",
    "content": "import React from 'react';\nimport {shallow} from 'enzyme';\nimport XYPlot from 'plot/xy-plot';\nimport LineSeries from 'plot/series/line-series';\nimport HorizontalGridLines from 'plot/horizontal-grid-lines';\nimport VerticalGridLines from 'plot/vertical-grid-lines';\n\ndescribe('GridLines', () => {\n  test('HorizontalGridLines', () => {\n    const wrapper = shallow(\n      <XYPlot width={300} height={300} stackBy=\"y\">\n        <HorizontalGridLines className=\"test-class-name\" />\n        <LineSeries data={[{x: 1, y: 3}]} />\n      </XYPlot>\n    );\n\n    expect(\n      wrapper\n        .find(HorizontalGridLines)\n        .at(0)\n        .hasClass('test-class-name')\n    ).toBe(true);\n  });\n\n  test('VerticalGridLines', () => {\n    const wrapper = shallow(\n      <XYPlot width={300} height={300} stackBy=\"y\">\n        <VerticalGridLines className=\"test-class-name\" />\n        <LineSeries data={[{x: 1, y: 3}]} />\n      </XYPlot>\n    );\n\n    expect(\n      wrapper\n        .find(VerticalGridLines)\n        .at(0)\n        .hasClass('test-class-name')\n    ).toBe(true);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/heatmap.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport XYPlot from 'plot/xy-plot';\nimport HeatmapSeries from 'plot/series/heatmap-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport HeatmapChart from '../../../showcase/plot/heatmap-chart';\nimport LabeledHeatmap from '../../../showcase/plot/labeled-heatmap';\n\nconst HEATMAP_PROPS = {\n  className: 'heatmap-series-example',\n  data: [\n    {x: 1, y: 0, color: 10},\n    {x: 1, y: 5, color: 10},\n    {x: 1, y: 10, color: 6},\n    {x: 1, y: 15, color: 7},\n    {x: 2, y: 0, color: 12},\n    {x: 2, y: 5, color: 2},\n    {x: 2, y: 10, color: 1},\n    {x: 2, y: 15, color: 12},\n    {x: 3, y: 0, color: 9},\n    {x: 3, y: 5, color: 2},\n    {x: 3, y: 10, color: 6},\n    {x: 3, y: 15, color: 12}\n  ]\n};\n\ndescribe('Heatmap', () => {\n  testRenderWithProps(HeatmapSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\n  test('basic rendering', () => {\n    const $ = mount(\n      <XYPlot width={300} height={300}>\n        <HeatmapSeries {...HEATMAP_PROPS} />\n      </XYPlot>\n    );\n    expect($.find('.rv-xy-plot__series--heatmap').length).toBe(1);\n    expect($.find('.rv-xy-plot__series--heatmap rect').length).toBe(12);\n    expect($.find('g.heatmap-series-example').length).toBe(1);\n\n    $.setProps({\n      children: <HeatmapSeries {...{...HEATMAP_PROPS, data: null}} />\n    });\n    expect($.find('.rv-xy-plot__series--heatmap').length).toBe(0);\n    expect($.find('.rv-xy-plot__series--heatmap rect').length).toBe(0);\n    expect($.find('.heatmap-series-example').length).toBe(0);\n  });\n\n  test('Showcase Example - HeatmapChart', () => {\n    const $ = mount(<HeatmapChart />);\n    expect($.find('.rv-xy-plot__series--heatmap').length).toBe(1);\n    expect($.find('.rv-xy-plot__series--heatmap rect').length).toBe(12);\n    expect($.find('g.heatmap-series-example').length).toBe(1);\n    expect($.text()).toBe('0.51.01.52.02.53.03.5051015');\n  });\n\n  test('Showcase Example - LabeledHeatmap', () => {\n    const $ = mount(<LabeledHeatmap />);\n    expect($.find('.rv-xy-plot__series--heatmap').length).toBe(1);\n    expect($.find('.rv-xy-plot__series--label').length).toBe(1);\n    expect($.find('.rv-xy-plot__series--heatmap rect').length).toBe(100);\n    expect($.find('g.heatmap-series-example').length).toBe(1);\n    expect($.text()).toBe(\n      'A1B1C1D1E1F1G1H1I1J1J2I2H2G2F2E2D2C2B2A20123456789111111111122222122233333331313444444444155555555556666666666777777777788888888889999999999'\n    );\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/hexbin-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport HexbinSeries from 'plot/series/hexbin-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport HexHeatmap from '../../../showcase/plot/hex-heatmap';\nimport HexbinSizeExample from '../../../showcase/plot/hexbin-size-example';\n\ndescribe('HexbinSeries', () => {\n  testRenderWithProps(HexbinSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\n  test('Showcase Example - HexHeatmap', () => {\n    const $ = mount(<HexHeatmap />);\n    expect($.find('.rv-xy-plot__series--hexbin').length).toBe(1);\n    expect($.find('.rv-xy-plot__series--hexbin path').length).toBe(53);\n    expect($.find('g.hexbin-example').length).toBe(1);\n    expect($.text()).toBe(\n      '4050607080901002345678UPDATE DATAUPDATE RADIUSUPDATE OFFSET'\n    );\n\n    $.find('.rv-xy-plot__series--hexbin path')\n      .at(2)\n      .simulate('mouseOver');\n    expect($.text()).toBe(\n      '4050607080901002345678x: 138.56406460551017y: 180value: 1UPDATE DATAUPDATE RADIUSUPDATE OFFSET'\n    );\n  });\n\n  test('Showcase Example - HexbinSizeExample', () => {\n    const $ = mount(<HexbinSizeExample />);\n    expect($.find('g.alt-x-label').length).toBe(1);\n    expect($.find('g.alt-y-label').length).toBe(1);\n    [\n      {\n        numHexes: 56,\n        text:\n          'PREV X X AXIS economy (mpg) NEXT XPREV Y Y AXIS power (hp) NEXT Y051015202530354045050100150200economy (mpg)power (hp)',\n        buttonToPress: null\n      },\n\n      // click next x\n      {\n        numHexes: 56,\n        text:\n          'PREV X X AXIS cylinders NEXT XPREV Y Y AXIS power (hp) NEXT Y3.03.54.04.55.05.56.06.57.07.58.0050100150200cylinderspower (hp)',\n        buttonToPress: 1\n      },\n\n      // click next y\n      {\n        numHexes: 20,\n        text:\n          'PREV X X AXIS cylinders NEXT XPREV Y Y AXIS weight (lb) NEXT Y3.03.54.04.55.05.56.06.57.07.58.02,0002,5003,0003,5004,0004,5005,000cylindersweight (lb)',\n        buttonToPress: 3\n      },\n\n      // click prev y\n      {\n        numHexes: 20,\n        text:\n          'PREV X X AXIS cylinders NEXT XPREV Y Y AXIS weight (lb) NEXT Y3.03.54.04.55.05.56.06.57.07.58.02,0002,5003,0003,5004,0004,5005,000cylindersweight (lb)',\n        buttonToPress: 0\n      }\n    ].forEach(({numHexes, text, buttonToPress}) => {\n      if (buttonToPress) {\n        $.find('.showcase-button')\n          .at(buttonToPress)\n          .simulate('click');\n      }\n      expect($.find('.rv-xy-plot__series--hexbin').length).toBe(1);\n      expect($.find('.rv-xy-plot__series--hexbin path').length).toBe(numHexes);\n      expect($.find('g.hexbin-size-example').length).toBe(1);\n      expect($.text()).toBe(text);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/highlight.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport Highlight from 'plot/highlight';\nimport DragableExample from '../../../showcase/misc/dragable-chart-example';\nimport ZoomableChartExample from '../../../showcase/misc/zoomable-chart-example';\nimport SelectionPlotExample from '../../../showcase/misc/selection-plot-example';\nimport BidirectionDragChart from '../../../showcase/misc/2d-dragable-plot';\n\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\n\ndescribe('Highlight', () => {\n  testRenderWithProps(\n    Highlight,\n    {\n      ...GENERIC_XYPLOT_SERIES_PROPS,\n      marginLeft: 0,\n      marginRight: 0,\n      innerWidth: 100,\n      marginTop: 0,\n      marginBottom: 0,\n      innerHeight: 100\n    },\n    true\n  );\n\n  test('DragableExample', () => {\n    const $ = mount(<DragableExample />);\n    const initialText =\n      '0.00.51.01.52.02.53.03.54.04.55.05.56.06.57.00246810selectionStart: 0,selectionEnd: 0,';\n    expect($.text()).toBe(initialText);\n\n    $.find('.rv-mouse-target').simulate('mouseDown', {\n      nativeEvent: {offsetX: 100, offsetY: 100}\n    });\n    for (let i = 0; i < 100; i++) {\n      $.find('.rv-mouse-target').simulate('mouseMove', {\n        nativeEvent: {offsetX: 100 + i, offsetY: 100}\n      });\n    }\n    expect($.text()).toBe(initialText);\n    $.find('.rv-mouse-target').simulate('mouseUp', {\n      nativeEvent: {offsetX: 200, offsetY: 100}\n    });\n    expect($.text()).toBe(\n      '0.00.51.01.52.02.53.03.54.04.55.05.56.06.57.00246810selectionStart: 0.93,selectionEnd: 2.47,'\n    );\n\n    // click to clear\n    $.find('.rv-mouse-target').simulate('mouseDown', {\n      nativeEvent: {offsetX: 0, offsetY: 0}\n    });\n    $.find('.rv-mouse-target').simulate('mouseUp', {\n      nativeEvent: {offsetX: 0, offsetY: 0}\n    });\n    expect($.text()).toBe(initialText);\n  });\n\n  test('ZoomableChartExample', () => {\n    const $ = mount(<ZoomableChartExample />);\n    const initialText =\n      '−5051015200102030405060708090Reset ZoomLast Draw AreaN/A';\n    expect($.text()).toBe(initialText);\n\n    // brush in a drag area\n    $.find('.rv-mouse-target').simulate('mouseDown', {\n      nativeEvent: {offsetX: 100, offsetY: 100}\n    });\n    for (let i = 0; i < 100; i++) {\n      $.find('.rv-mouse-target').simulate('mouseMove', {\n        nativeEvent: {offsetX: 100 + i, offsetY: 100 + i}\n      });\n    }\n    expect($.text()).toBe(initialText);\n\n    $.find('.rv-mouse-target').simulate('mouseUp', {\n      nativeEvent: {offsetX: 200, offsetY: 200}\n    });\n    expect($.text()).toBe(\n      '−5051015200102030405060708090Reset ZoomLast Draw AreaTop: 11.083578425950623Right: 34.98Bottom: -0.5863163548405383Left: 13.2'\n    );\n  });\n\n  test('SelectionPlotExample', () => {\n    const $ = mount(<SelectionPlotExample />);\n\n    const initialText = '0.51.01.52.02.5681012There are 0 selected points';\n    expect($.find('g.selection-example').length).toBe(1);\n    expect($.text()).toBe(initialText);\n\n    $.find('.rv-mouse-target').simulate('mouseDown', {\n      nativeEvent: {offsetX: 100, offsetY: 100}\n    });\n    for (let i = 0; i < 100; i++) {\n      $.find('.rv-mouse-target').simulate('mouseMove', {\n        nativeEvent: {offsetX: 100, offsetY: 100 + i}\n      });\n    }\n    expect($.text()).toBe('0.51.01.52.02.5681012There are 4 selected points');\n    $.find('.rv-mouse-target').simulate('mouseUp', {\n      nativeEvent: {offsetX: 100, offsetY: 200}\n    });\n    expect($.text()).toBe('0.51.01.52.02.5681012There are 4 selected points');\n\n    // click to clear\n    $.find('.rv-mouse-target').simulate('mouseDown', {\n      nativeEvent: {offsetX: 0, offsetY: 0}\n    });\n    $.find('.rv-mouse-target').simulate('mouseUp', {\n      nativeEvent: {offsetX: 0, offsetY: 0}\n    });\n    expect($.text()).toBe(initialText);\n  });\n\n  test('BidirectionDragChart', () => {\n    const $ = mount(<BidirectionDragChart />);\n\n    // brush in a drag area\n    expect($.text()).toBe('12342468There are 0 selected points');\n\n    $.find('.rv-mouse-target').simulate('mouseDown', {\n      nativeEvent: {offsetX: 100, offsetY: 100}\n    });\n    for (let i = 0; i < 100; i++) {\n      $.find('.rv-mouse-target').simulate('mouseMove', {\n        nativeEvent: {offsetX: 100 + i, offsetY: 100 + i}\n      });\n    }\n    expect($.text()).toBe('12342468There are 5 selected points');\n\n    $.find('.rv-mouse-target').simulate('mouseUp', {\n      nativeEvent: {offsetX: 200, offsetY: 200}\n    });\n    expect($.text()).toBe('12342468There are 5 selected points');\n\n    // execute dragging\n    $.find('.rv-mouse-target').simulate('mouseDown', {\n      nativeEvent: {offsetX: 150, offsetY: 150}\n    });\n    for (let i = 0; i < 50; i++) {\n      $.find('.rv-mouse-target').simulate('mouseMove', {\n        nativeEvent: {offsetX: 150 + i, offsetY: 150 + i}\n      });\n    }\n    expect($.text()).toBe('12342468There are 6 selected points');\n    $.find('.rv-mouse-target').simulate('mouseUp', {\n      nativeEvent: {offsetX: 200, offsetY: 200}\n    });\n    expect($.text()).toBe('12342468There are 6 selected points');\n\n    // click to clear\n    $.find('.rv-mouse-target').simulate('mouseDown', {\n      nativeEvent: {offsetX: 75, offsetY: 75}\n    });\n    $.find('.rv-mouse-target').simulate('mouseUp', {\n      nativeEvent: {offsetX: 75, offsetY: 75}\n    });\n    expect($.text()).toBe('12342468There are 0 selected points');\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/hints.test.js",
    "content": "import React from 'react';\nimport {shallow} from 'enzyme';\nimport Hint from 'plot/hint';\n\ndescribe('Hint', () => {\n  test('Appends user-input class name to the class signatures list', () => {\n    const wrapper = shallow(\n      <Hint x={0} y={0} value={{test: 123}} className=\"test-class-name\" />\n    );\n\n    expect(wrapper.hasClass('test-class-name')).toBe(true);\n  });\n\n  test('Assigns only default class names when no custom class specified', () => {\n    const wrapper = shallow(<Hint x={0} y={0} value={{test: 123}} />);\n\n    expect(wrapper.hasClass('undefined')).toBe(false);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/interaction-article.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\n\nimport {\n  LinkedCharts,\n  LineChartMouseOverXY,\n  LineChartMouseOverSeries,\n  ScatterPlotOnNearestXY\n} from '../../../showcase/interaction/interaction-examples';\n\ndescribe('Interaction examples', () => {\n  test('LinkedCharts', () => {\n    const $ = mount(<LinkedCharts />);\n    expect($.find('.rv-xy-plot').length).toBe(3);\n  });\n\n  test('LineChartMouseOverXY', () => {\n    const $ = mount(<LineChartMouseOverXY />);\n    expect($.find('.rv-xy-plot').length).toBe(1);\n  });\n\n  test('LineChartMouseOverSeries', () => {\n    const $ = mount(<LineChartMouseOverSeries />);\n    expect($.find('.rv-xy-plot').length).toBe(1);\n  });\n\n  test('ScatterPlotOnNearestXY', () => {\n    const $ = mount(<ScatterPlotOnNearestXY />);\n    expect($.find('.rv-xy-plot').length).toBe(1);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/label-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport LabelSeries from 'plot/series/label-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport LabelSeriesExample from '../../../showcase/misc/label-series-example';\nimport LabeledStackedVerticalBarChart from '../../../showcase/plot/labeled-stacked-vertical-bar-chart';\n\ntestRenderWithProps(LabelSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\ndescribe('LabelSeries', () => {\n  test('Showcase Example - LabelSeriesExample', () => {\n    const $ = mount(\n      <svg>\n        <LabelSeriesExample />\n      </svg>\n    );\n    expect($.text()).toBe(\n      'UPDATE−101234505101520WigglytuffPsyduckGeodudeDittoSnorlax'\n    );\n    expect($.find('.rv-xy-plot__series--label text').length).toBe(5);\n\n    $.find('.showcase-button').simulate('click');\n    expect($.text()).toBe(\n      'UPDATE−101234505101520WigglytuffPsyduckGeoduderedblue'\n    );\n    $.find('.showcase-button').simulate('click');\n    expect($.text()).toBe(\n      'UPDATE−101234505101520WigglytuffPsyduckGeoduderedblue'\n    );\n  });\n\n  test('Showcase Example - LabeledStackedVerticalBarChart', () => {\n    const $ = mount(\n      <svg>\n        <LabeledStackedVerticalBarChart />\n      </svg>\n    );\n    expect($.find('.rv-xy-plot__series--label text').length).toBe(9);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/legends.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport ContinuousSizeLegend from '../../../showcase/legends/continuous-size';\nimport ContinuousColorLegend from '../../../showcase/legends/continuous-color';\n\nimport HorizontalDiscreteLegend from '../../../showcase/legends/horizontal-discrete-color';\nimport VerticalDiscreteLegend from '../../../showcase/legends/vertical-discrete-color';\nimport SearchableDiscreteLegend from '../../../showcase/legends/searchable-discrete-color';\nimport SearchableDiscreteColorLegendHoverExample from '../../../showcase/legends/searchable-discrete-color-hover';\nimport HorizontalDiscreteCustomPalette from '../../../showcase/legends/horizontal-discrete-custom-palette';\nimport ClusteredStackedVerticalBarChart from '../../../showcase/plot/clustered-stacked-bar-chart';\n\ndescribe('Legends', () => {\n  test('Discrete Legend has no clickable className while onItemClick is not passing', () => {\n    const withOnClick$ = mount(<VerticalDiscreteLegend />);\n    const withoutOnClick$ = mount(<SearchableDiscreteLegend />);\n\n    expect(\n      withOnClick$\n        .find('.rv-discrete-color-legend-item.vertical')\n        .first()\n        .props().onClick\n    ).toBe(null);\n    expect(\n      withoutOnClick$\n        .find('.rv-discrete-color-legend-item.vertical.clickable')\n        .first()\n        .props().onClick\n    ).not.toBe(Function);\n  });\n\n  test('Continuous Size Legend', () => {\n    const $ = mount(<ContinuousSizeLegend />);\n    expect($.text()).toBe('          100200');\n    expect($.find('.rv-bubble').length).toBe(10);\n  });\n\n  test('Continuous Color Legend', () => {\n    const $ = mount(<ContinuousColorLegend />);\n    expect($.text()).toBe('100200150');\n    const expectedStyle = {\n      background: 'linear-gradient(to right, #EF5D28,#FF9833)'\n    };\n    expect($.find('.rv-gradient').props().style).toEqual(expectedStyle);\n  });\n\n  test('Discrete Legends', () => {\n    const verticalLegend = mount(<VerticalDiscreteLegend />);\n    expect(verticalLegend.text()).toBe(\n      'OptionsButtonsSelect boxesDate inputsPassword inputsFormsOther'\n    );\n    expect(\n      verticalLegend.find('.rv-discrete-color-legend-item__color').length\n    ).toBe(7);\n\n    expect(\n      verticalLegend\n        .find('.rv-discrete-color-legend-item__color__path')\n        .first()\n        .props().style\n    ).toEqual({stroke: '#12939A'});\n\n    expect(\n      mount(<HorizontalDiscreteCustomPalette />)\n        .find('.rv-discrete-color-legend-item__color__path')\n        .first()\n        .props().style\n    ).toEqual({stroke: '#6588cd'});\n\n    const $ = mount(<SearchableDiscreteLegend />);\n    expect($.text()).toBe(\n      'ApplesBananasBlueberriesCarrotsEggplantsLimesPotatoes'\n    );\n    expect($.find('.rv-discrete-color-legend-item__color').length).toBe(7);\n    expect(\n      mount(<HorizontalDiscreteLegend />)\n        .find('.rv-discrete-color-legend-item__color__path')\n        .first()\n        .props().style\n    ).toEqual({strokeDasharray: '6, 2', stroke: '#45aeb1'});\n    expect(\n      mount(<HorizontalDiscreteLegend />)\n        .find('.rv-discrete-color-legend-item__color__path')\n        .at(4)\n        .props().style\n    ).toEqual({strokeWidth: 13, stroke: 'url(#stripes)'});\n    $.find('.rv-search-wrapper__form__input').simulate('change', {\n      target: {value: 'egg'}\n    });\n    expect($.text()).toBe('Eggplants');\n    const itemsFound = $.find('.rv-discrete-color-legend-item__color').length;\n    expect(itemsFound).toBe(1);\n\n    expect($.find('.disabled').length).toBe(0);\n    $.find('.clickable').simulate('click');\n    expect($.find('.disabled').length).toBe(1);\n\n    expect(\n      mount(<ClusteredStackedVerticalBarChart />)\n        .find('.rv-discrete-color-legend')\n        .first()\n        .props().style\n    ).toEqual({\n      width: undefined,\n      height: undefined,\n      position: 'absolute',\n      left: '50px',\n      top: '10px'\n    });\n  });\n\n  test('Discrete Legends Showcase: HorizontalDiscreteCustomPalette', () => {\n    const $ = mount(<HorizontalDiscreteCustomPalette />);\n    const colors = $.find('.rv-discrete-color-legend-item__color__path')\n      .map(colorBrick => {\n        return colorBrick.props().style.stroke;\n      })\n      .join(' ');\n\n    expect(colors).toBe(\n      '#6588cd #66b046 #a361c7 #ad953f #c75a87 #55a47b #cb6141'\n    );\n    expect($.text()).toBe(\n      'OptionsButtonsSelect boxesDate inputsPassword inputsFormsOther'\n    );\n\n    $.find('.rv-discrete-color-legend-item')\n      .first()\n      .simulate('mouseEnter');\n    expect($.text()).toBe(\n      'OptionsSELECTEDButtonsSelect boxesDate inputsPassword inputsFormsOther'\n    );\n  });\n\n  test('Discrete Legends Showcase: SearchableDiscreteLegendHover', () => {\n    const $ = mount(<SearchableDiscreteColorLegendHoverExample />);\n    $.find('.rv-discrete-color-legend-item')\n      .first()\n      .simulate('mouseEnter');\n    expect($.text()).toBe(\n      'Apples:SELECTEDBananasBlueberriesCarrotsEggplantsLimesPotatoes'\n    );\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/line-series-canvas.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport XYPlot from 'plot/xy-plot';\nimport LineSeriesCanvas from 'plot/series/line-series-canvas';\n\ndescribe('LineSeriesCanvas', () => {\n  test('should be rendered', () => {\n    const k = 7;\n\n    const $ = mount(\n      <XYPlot width={300} height={300}>\n        {Array(k)\n          .fill(0)\n          .map((_, index) => (\n            <LineSeriesCanvas\n              key={index.toString()}\n              color=\"#12939a\"\n              data={[\n                {x: 1, y: 5},\n                {x: 2, y: 20},\n                {x: 3, y: 10}\n              ]}\n            />\n          ))}\n      </XYPlot>\n    );\n\n    expect(\n      $.find('CanvasWrapper')\n        .children()\n        .find('LineSeriesCanvas').length\n    ).toBe(k);\n  });\n\n  test('on onNearestXY should be called and retur ncorrect values', () => {\n    const k = 7;\n    expect.assertions(k);\n\n    const $ = mount(\n      <XYPlot width={300} height={300}>\n        {[...Array(k).keys()].map(v => (\n          <LineSeriesCanvas\n            key={v}\n            color=\"#12939a\"\n            data={[\n              {x: -50, y: -50},\n              {x: v, y: v * v},\n              {x: 60, y: 60}\n            ]}\n            onNearestXY={value => {\n              expect({x: v, y: v * v}).toEqual(value);\n            }}\n          />\n        ))}\n      </XYPlot>\n    );\n\n    $.find('.rv-xy-plot__inner').simulate('mousemove', {\n      nativeEvent: {clientX: 150, clientY: 150}\n    });\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/line-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport XYPlot from 'plot/xy-plot';\nimport LineSeries from 'plot/series/line-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport LineChart from '../../../showcase/plot/line-chart';\nimport LineMarkSeries from '../../../showcase/plot/linemark-chart';\nimport LineChartManyColors from '../../../showcase/color/line-chart-many-colors';\nimport NullData from '../../../showcase/misc/null-data-example';\nimport TimeChart from '../../../showcase/misc/time-chart';\nimport SyncedCharts from '../../../showcase/misc/synced-charts';\n\ntestRenderWithProps(LineSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\nconst LINE_PROPS = {\n  className: 'line-chart-example',\n  color: '#12939a',\n  data: [\n    {x: 1, y: 5, y0: 6},\n    {x: 2, y: 20, y0: 11},\n    {x: 3, y: 10, y0: 9}\n  ]\n};\n\nconst LINE_WITH_MANY_COLORS_COLORS = [\n  'rgb(255, 255, 0)',\n  'rgb(255, 245, 0)',\n  'rgb(255, 235, 0)',\n  'rgb(255, 225, 0)',\n  'rgb(255, 215, 0)',\n  'rgb(255, 205, 0)',\n  'rgb(255, 195, 0)',\n  'rgb(255, 185, 0)',\n  'rgb(255, 175, 0)',\n  'rgb(255, 165, 0)',\n  'rgb(255, 155, 0)',\n  'rgb(255, 145, 0)',\n  'rgb(255, 135, 0)',\n  'rgb(255, 125, 0)',\n  'rgb(255, 115, 0)',\n  'rgb(255, 105, 0)',\n  'rgb(255, 95, 0)',\n  'rgb(255, 85, 0)',\n  'rgb(255, 75, 0)',\n  'rgb(255, 65, 0)'\n];\n\ndescribe('LineSeries', () => {\n  test('basic rendering', () => {\n    const $ = mount(\n      <XYPlot width={300} height={300}>\n        <LineSeries {...LINE_PROPS} />\n      </XYPlot>\n    );\n    expect($.find('.rv-xy-plot__series').length).toBe(1);\n    expect($.find('path.rv-xy-plot__series').length).toBe(1);\n    expect($.find('path.line-chart-example').length).toBe(1);\n\n    $.setProps({children: <LineSeries {...{...LINE_PROPS, data: null}} />});\n    expect($.find('.rv-xy-plot__series').length).toBe(0);\n    expect($.find('.rv-xy-plot__series path').length).toBe(0);\n    expect($.find('.line-chart-example').length).toBe(0);\n  });\n\n  test('Showcase Example - LineChart', () => {\n    const $ = mount(<LineChart />);\n    expect($.find('g.alt-x-label').length).toBe(1);\n\n    expect($.find('g.alt-y-label').length).toBe(1);\n    expect($.text()).toBe(\n      'TOGGLE TO CANVAS1.01.52.02.53.03.54.02468101214X AxisY Axis'\n    );\n    expect($.find('.rv-xy-plot__series--line').length).toBe(3);\n\n    ['first-series', 'third-series', 'fourth-series'].forEach(\n      customClassName => {\n        expect(\n          $.find(`.rv-xy-plot__series--line.${customClassName}`).length\n        ).toBe(1);\n      }\n    );\n\n    expect($.find('path.second-series').length).toBe(0);\n\n    $.find('button').simulate('click');\n    expect($.find('.rv-xy-plot__series--line').length).toBe(0);\n\n    $.find('button').simulate('click');\n    expect($.find('.rv-xy-plot__series--line').length).toBe(3);\n  });\n\n  test('Showcase Example - LineMarkSeries', () => {\n    const $ = mount(<LineMarkSeries />);\n    expect($.text()).toBe('1.01.52.02.53.0510152025');\n    expect($.find('.rv-xy-plot__series--linemark').length).toBe(2);\n    expect($.find('.rv-xy-plot__series circle').length).toBe(6);\n\n    ['linemark-series-example', 'linemark-series-example-2'].forEach(\n      customClassName => {\n        expect($.find(`MarkSeries.${customClassName}`).length).toBe(1);\n\n        expect($.find(`LineSeries.${customClassName}`).length).toBe(1);\n      }\n    );\n  });\n\n  test('Showcase Example - LineChartManyColors', () => {\n    const $ = mount(<LineChartManyColors />);\n    const lines = $.find('.rv-xy-plot__series');\n    expect(lines.length).toBe(20);\n    lines.forEach((node, i) =>\n      expect(node.props().style.stroke).toBe(LINE_WITH_MANY_COLORS_COLORS[i])\n    );\n  });\n\n  test('Showcase Example - TimeChart', () => {\n    const $ = mount(<TimeChart />);\n    expect($.find('.rv-xy-plot__series--line').length).toBe(2);\n    expect($.text()).toBe(\n      'Sep 1012 PMMon 1112 PMTue 1212 PMWed 13X Axis2468101214Y Axis'\n    );\n  });\n\n  test('Showcase Example - SyncedCharts', () => {\n    const $ = mount(<SyncedCharts />);\n    const tests = () => {\n      expect($.find('.rv-xy-plot').length).toBe(2);\n      expect($.find('.rv-xy-plot__series--line').length).toBe(4);\n      expect($.text()).toBe('1.01.52.02.53.024681012141.01.52.02.53.0246810');\n    };\n    tests();\n    $.find('.rv-xy-plot__series--line')\n      .at(0)\n      .simulate('mouseEnter');\n    tests();\n    $.find('.rv-xy-plot')\n      .at(0)\n      .simulate('mouseLeave');\n  });\n\n  test('Line Styling', () => {\n    const $ = mount(\n      <XYPlot width={300} height={300}>\n        <LineSeries\n          {...LINE_PROPS}\n          opacity={0.5}\n          strokeWidth=\"3px\"\n          stroke=\"rgb(255, 255, 255)\"\n          strokeDasharray=\"3, 1\"\n        />\n      </XYPlot>\n    );\n\n    const lineStyle = $.find('path.rv-xy-plot__series').prop('style');\n\n    expect(lineStyle.opacity).toBe(0.5);\n    expect(lineStyle.strokeWidth).toBe('3px');\n    expect(lineStyle.stroke).toBe('rgb(255, 255, 255)');\n    expect(lineStyle.strokeDasharray).toBe('3, 1');\n  });\n\n  test('getNull prop: Showcase Example - Null Data Example', () => {\n    const $ = mount(<NullData />);\n    expect($.find('path.rv-xy-plot__series').length).toBe(2);\n    expect($.find('.rv-xy-plot__series--mark circle').length).toBe(3);\n\n    simulateMouseMove(35);\n    expect($.find('.rv-crosshair__title').text()).toBe('x: 1');\n    expect(\n      $.find('.rv-crosshair__item')\n        .at(0)\n        .text()\n    ).toBe('0: 10');\n    expect(\n      $.find('.rv-crosshair__item')\n        .at(1)\n        .text()\n    ).toBe('1: 30');\n\n    $.find('.rv-xy-plot__inner').simulate('mouseleave');\n    expect($.find('.rv-crosshair').exists()).toBe(false);\n\n    simulateMouseMove(100);\n    expect($.find('.rv-crosshair__title').text()).toBe('x: 2');\n    expect(\n      $.find('.rv-crosshair__item')\n        .at(0)\n        .text()\n    ).toBe('0: 10');\n    expect(\n      $.find('.rv-crosshair__item')\n        .at(1)\n        .text()\n    ).toBe('1: 0');\n\n    simulateMouseMove(165);\n    expect($.find('.rv-crosshair__title').text()).toBe('x: 3');\n    expect(\n      $.find('.rv-crosshair__item')\n        .at(0)\n        .text()\n    ).toBe('0: 13');\n    expect(\n      $.find('.rv-crosshair__item')\n        .at(1)\n        .exists()\n    ).toBe(false);\n\n    simulateMouseMove(230);\n    expect($.find('.rv-crosshair__title').text()).toBe('x: 4');\n    expect(\n      $.find('.rv-crosshair__item')\n        .at(0)\n        .text()\n    ).toBe('0: 7');\n    expect(\n      $.find('.rv-crosshair__item')\n        .at(1)\n        .text()\n    ).toBe('1: 15');\n\n    simulateMouseMove(295);\n    expect($.find('.rv-crosshair').exists()).toBe(false);\n\n    function simulateMouseMove(x) {\n      $.find('.rv-xy-plot__inner').simulate('mousemove', {\n        nativeEvent: {clientX: x, clientY: 150}\n      });\n    }\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/make-vis-flexible.test.js",
    "content": "import {makeWidthFlexible} from 'make-vis-flexible';\n\ndescribe('makeWidthFlexible', () => {\n  test('displayName given', () => {\n    function ChildComponent() {}\n    ChildComponent.displayName = 'ChildComponentWithDisplayName';\n    const FlexibleComponent = makeWidthFlexible(ChildComponent);\n    expect(FlexibleComponent.displayName).toBe(\n      'FlexibleChildComponentWithDisplayName'\n    );\n  });\n\n  test('displayName not given', () => {\n    function ChildComponent() {}\n    const FlexibleComponent = makeWidthFlexible(ChildComponent);\n    expect(FlexibleComponent.displayName).toBe('FlexibleChildComponent');\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/mark-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport MarkSeries from 'plot/series/mark-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport Scatterplot from '../../../showcase/plot/scatterplot';\nimport DynamicCrosshairScatterplot from '../../../showcase/axes/dynamic-crosshair-scatterplot';\n\ndescribe('MarkSeries', () => {\n  testRenderWithProps(MarkSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\n  test('MShowcase Example - Scatterplot', () => {\n    const $ = mount(<Scatterplot />);\n    expect($.text()).toBe('1.01.52.02.53.068101214');\n    expect($.find('.rv-xy-plot__series--mark circle').length).toBe(5);\n    expect($.find('g.mark-series-example').length).toBe(1);\n  });\n\n  test('MShowcase Example - Dynamic Crosshair Scatterplot', () => {\n    const $ = mount(<DynamicCrosshairScatterplot />);\n    // NOTE: Point 0 (P0) and Point 1 (P1) are vertically aligned\n    const yDistanceBetweenP0andP1 = 2.5;\n    const chatTopPadding = 10;\n\n    const highlightedCircles1 = $.find(\n      '.rv-xy-plot__series--mark circle'\n    ).reduce(highlightedCircle, []);\n    expect(highlightedCircles1.length).toBe(0);\n\n    updateCursor(0, yDistanceBetweenP0andP1 / 2 - 0.01);\n    const highlightedCircles2 = $.find(\n      '.rv-xy-plot__series--mark circle'\n    ).reduce(highlightedCircle, []);\n    expect(highlightedCircles2.length).toBe(1);\n    expect(highlightedCircles2[0]).toEqual({cx: 0, cy: 0});\n\n    updateCursor(0, yDistanceBetweenP0andP1 / 2);\n    const highlightedCircles3 = $.find(\n      '.rv-xy-plot__series--mark circle'\n    ).reduce(highlightedCircle, []);\n    expect(highlightedCircles3.length).toBe(1);\n\n    expect(Math.abs(highlightedCircles3[0].cx - 0) < 0.005).toBeTruthy();\n    expect(Math.abs(highlightedCircles3[0].cy - 2.5) < 0.005).toBeTruthy();\n\n    function updateCursor(x, y) {\n      $.find('.rv-xy-plot__series--mark').simulate('mousemove', {\n        nativeEvent: {clientX: x, clientY: y + chatTopPadding}\n      });\n    }\n\n    function highlightedCircle(_highlightedCircle, circle) {\n      const isHighlighted = circle.prop('style').fill === '#FF9833';\n      const circlePosition = {cx: circle.prop('cx'), cy: circle.prop('cy')};\n      return isHighlighted\n        ? [..._highlightedCircle, circlePosition]\n        : _highlightedCircle;\n    }\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/parallel-coordinates.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport ParallelCoordinates from 'parallel-coordinates';\nimport BasicParallelCoordinates from '../../../showcase/parallel-coordinates/basic-parallel-coordinates';\nimport AnimatedParallelCoordinates from '../../../showcase/parallel-coordinates/animated-parallel-coordinates';\nimport BrushedParallelCoordinates from '../../../showcase/parallel-coordinates/brushed-parallel-coordinates';\n\nimport {testRenderWithProps} from '../test-utils';\n\nconst PARALLEL_COODINATES_PROPS = {\n  data: [\n    {\n      explosions: 7,\n      wow: 10,\n      dog: 8,\n      sickMoves: 9,\n      nice: 7\n    }\n  ],\n  domains: [\n    {name: 'nice', domain: [0, 100]},\n    {name: 'explosions', domain: [6.9, 7.1]},\n    {name: 'wow', domain: [0, 11]},\n    {name: 'dog', domain: [0, 16]},\n    {name: 'sickMoves', domain: [0, 20]}\n  ],\n  height: 300,\n  width: 400\n};\n\ndescribe('Parallel Coordinates', () => {\n  // make sure that the components render at all\n  testRenderWithProps(ParallelCoordinates, PARALLEL_COODINATES_PROPS);\n\n  test('Basic Parallel Coordinates', () => {\n    const $ = mount(<BasicParallelCoordinates />);\n    expect($.find('div.rv-parallel-coordinates-chart').length).toBe(1);\n    expect($.find('.rv-xy-manipulable-axis__ticks').length).toBe(6);\n    expect($.find('LineSeries.rv-parallel-coordinates-chart-line').length).toBe(\n      3\n    );\n    expect($.find('MarkSeries.rv-parallel-coordinates-chart-line').length).toBe(\n      3\n    );\n\n    expect($.find('circle').length).toBe(18);\n    expect($.find('div.rv-parallel-coordinates-chart').text()).toBe(\n      '0.002.004.006.008.0010.0$2.0$4.8$7.6$10$13$165.006.007.008.009.0010.00.002.004.006.008.0010.00.001.402.804.205.607.0010.08.406.805.203.602.00mileagepricesafetyperformanceinteriorwarranty'\n    );\n  });\n\n  test('Animated Parallel Coordinates ', () => {\n    const $ = mount(<AnimatedParallelCoordinates />);\n    expect($.find('div.rv-parallel-coordinates-chart').length).toBe(1);\n    expect($.find('.rv-xy-manipulable-axis__ticks').length).toBe(5);\n    expect($.find('path.rv-parallel-coordinates-chart-line').length).toBe(1);\n    // This relies on floating point\n    // t.equal(\n    //   $.find('div.rv-parallel-coordinates-chart').text(),\n    //   '020406080100niceexplosionswowdogsickMoves',\n    //   'should find the right text content'\n    // );\n\n    $.find('.showcase-button').simulate('click');\n    expect($.find('.rv-xy-manipulable-axis__ticks').length).toBe(5);\n    expect($.find('path.rv-parallel-coordinates-chart-line').length).toBe(1);\n  });\n\n  test('Brushed Parallel Coordinates', () => {\n    const $ = mount(<BrushedParallelCoordinates />);\n    expect($.find('path.rv-parallel-coordinates-chart-line').length).toBe(150);\n    expect($.find('div.rv-parallel-coordinates-chart').text()).toBe(\n      '4.35.05.76.57.27.92.02.53.03.43.94.41.02.23.44.55.76.90.100.581.11.52.02.5sepal lengthsepal widthpetal lengthpetal width'\n    );\n\n    // brush\n    $.find('.rv-mouse-target')\n      .at(0)\n      .simulate('mouseDown', {nativeEvent: {offsetX: 50, offsetY: 100}});\n    for (let i = 0; i < 100; i++) {\n      $.find('.rv-mouse-target')\n        .at(0)\n        .simulate('mouseMove', {nativeEvent: {offsetX: 50, offsetY: 100 + i}});\n    }\n    expect(\n      $.find('.rv-parallel-coordinates-chart-line-unselected').length\n    ).toBe(0);\n\n    $.find('.rv-mouse-target')\n      .at(0)\n      .simulate('mouseUp', {nativeEvent: {offsetX: 50, offsetY: 200}});\n\n    expect(\n      $.find('path.rv-parallel-coordinates-chart-line-unselected').length\n    ).toBe(102);\n\n    // click to clear\n    $.find('.rv-mouse-target')\n      .at(0)\n      .simulate('mouseDown', {nativeEvent: {offsetX: 50, offsetY: 95}});\n    $.find('.rv-mouse-target')\n      .at(0)\n      .simulate('mouseUp', {nativeEvent: {offsetX: 50, offsetY: 95}});\n\n    expect(\n      $.find('.rv-parallel-coordinates-chart-line-unselected').length\n    ).toBe(0);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/polygon-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport PolygonSeries from 'plot/series/mark-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport TriangleExample from '../../../showcase/misc/triangle-example';\n\ndescribe('PolygonSeries', () => {\n  testRenderWithProps(PolygonSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\n  test('Showcase Example - Triangle Example', () => {\n    const $ = mount(<TriangleExample />);\n    expect($.text()).toBe('024681012024681012');\n    expect($.find('.rv-xy-plot__series--polygon').length).toBe(121);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/radar-chart.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport RadialChart from 'radial-chart';\nimport BasicRadarChart from '../../../showcase/radar-chart/basic-radar-chart';\nimport AnimatedRadarChart from '../../../showcase/radar-chart/animated-radar-chart';\nimport FourQuadrantRadarChart from '../../../showcase/radar-chart/four-quadrant-radar-chart';\nimport RadarChartWithTooltips from '../../../showcase/radar-chart/radar-chart-with-tooltips';\nimport RadarChartSeriesTooltips from '../../../showcase/radar-chart/radar-chart-series-tooltips';\n\nimport {testRenderWithProps} from '../test-utils';\n\nconst RADAR_PROPS = {\n  data: [\n    {\n      explosions: 7,\n      wow: 10,\n      dog: 8,\n      sickMoves: 9,\n      nice: 7\n    }\n  ],\n  domains: [\n    {name: 'nice', domain: [0, 100]},\n    {name: 'explosions', domain: [6.9, 7.1]},\n    {name: 'wow', domain: [0, 11]},\n    {name: 'dog', domain: [0, 16]},\n    {name: 'sickMoves', domain: [0, 20]}\n  ],\n  height: 300,\n  width: 400\n};\n\ndescribe('Radar', () => {\n  // make sure that the components render at all\n  testRenderWithProps(RadialChart, RADAR_PROPS);\n\n  test('Radar: Showcase Example - Basic Radar Chart', () => {\n    const $ = mount(<BasicRadarChart />);\n    expect($.find('div.rv-radar-chart').length).toBe(1);\n    expect($.find('.rv-xy-manipulable-axis__ticks').length).toBe(6);\n    expect($.find('path.rv-radar-chart-polygon').length).toBe(3);\n    expect($.find('div.rv-radar-chart').text()).toBe(\n      '2.004.006.008.0010.0$4.8$7.6$10$13$166.007.008.009.0010.02.004.006.008.0010.01.402.804.205.607.008.406.805.203.602.00mileagepricesafetyperformanceinteriorwarranty'\n    );\n    expect($.find('.rv-xy-plot__series--custom-svg').length).toBe(0);\n  });\n\n  test('Radar: Showcase Example - Animated Radial ', () => {\n    const $ = mount(<AnimatedRadarChart />);\n    expect($.find('div.rv-radar-chart').length).toBe(1);\n    expect($.find('.rv-xy-manipulable-axis__ticks').length).toBe(5);\n    expect($.find('path.rv-radar-chart-polygon').length).toBe(1);\n    // Floating point\n    // t.equal(\n    //   $.find('div.rv-radar-chart').text(),\n    //   '20406080100niceexplosionswowdogsickMoves',\n    //   'should find the right text content'\n    // );\n    expect($.find('.rv-xy-plot__circular-grid-lines__line').length).toBe(10);\n\n    $.find('.showcase-button').simulate('click');\n    expect($.find('.rv-xy-manipulable-axis__ticks').length).toBe(5);\n\n    expect($.find('path.rv-radar-chart-polygon').length).toBe(1);\n    // Floating Point\n    // t.equal(\n    //   $.find('div.rv-radar-chart').text(),\n    //   '20406080100niceexplosionswowdogsickMoves',\n    //   'should find the right text content'\n    // );\n    expect($.find('.rv-xy-plot__series--custom-svg').length).toBe(0);\n  });\n\n  test('Radar: Showcase Example - Four Quadrant Radar Chart', () => {\n    const $ = mount(<FourQuadrantRadarChart />);\n    expect($.find('div.rv-radar-chart').length).toBe(1);\n    expect($.find('.rv-xy-manipulable-axis__ticks').length).toBe(4);\n    expect($.find('.rv-xy-manipulable-axis__ticks').children().length).toBe(24);\n    expect($.find('path.rv-radar-chart-polygon').length).toBe(1);\n    expect($.find('div.rv-radar-chart').text()).toBe(\n      '20406080100204060801002040608010020406080100CVisualBasicsExcelAccess'\n    );\n    expect($.find('.rv-xy-plot__series--custom-svg').length).toBe(0);\n  });\n\n  test('Radar: Showcase Example - Radar Chart with Tooltips', () => {\n    const $ = mount(<RadarChartWithTooltips />);\n    const chartText = 'mileagepricesafetyperformanceinteriorwarranty1234';\n    expect($.find('div.rv-radar-chart').length).toBe(1);\n    expect($.find('.rv-xy-manipulable-axis__ticks').length).toBe(6);\n    expect($.find('path.rv-radar-chart-polygon').length).toBe(7);\n    expect($.find('g.rv-radar-chart-polygonPoint').length).toBe(7);\n    expect($.find('div.rv-radar-chart').text()).toBe(chartText);\n\n    // Tooltips\n    const tooltipText = 'mileage: 3';\n    $.find('g.rv-radar-chart-polygonPoint')\n      .at(6)\n      .children()\n      .at(0)\n      .simulate('mouseOver');\n    expect($.text()).toBe(`${chartText}${tooltipText}`);\n  });\n\n  test('Radar: Showcase Example - series tooltips', () => {\n    const $ = mount(<RadarChartSeriesTooltips />);\n    const chartText =\n      '2.004.006.008.0010.0$4.8$7.6$10$13$166.007.008.009.0010.02.004.006.008.0010.01.402.804.205.607.008.406.805.203.602.00mileagepricesafetyperformanceinteriorwarranty';\n    const hoverText = 'Mercedes';\n\n    expect($.find('div.rv-radar-chart').length).toBe(1);\n    expect($.find('.rv-xy-manipulable-axis__ticks').length).toBe(6);\n    expect($.find('path.rv-radar-chart-polygon').length).toBe(3);\n    expect($.find('div.rv-radar-chart').text()).toBe(chartText);\n    expect($.find('.rv-xy-plot__series--custom-svg').length).toBe(0);\n    $.find('.rv-radar-chart-polygon')\n      .at(0)\n      .simulate('mouseOver');\n    expect($.find('div.rv-radar-chart').text()).toBe(\n      `${chartText}${hoverText}`\n    );\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/radial.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport RadialChart from 'radial-chart';\nimport SimpleRadialChart from '../../../showcase/radial-chart/simple-radial-chart';\nimport DonutChart from '../../../showcase/radial-chart/donut-chart';\nimport CustomRadiusRadialChart from '../../../showcase/radial-chart/custom-radius-radial-chart';\nimport GradientPie from '../../../showcase/radial-chart/gradient-pie';\n\nimport {testRenderWithProps} from '../test-utils';\n\nconst RADIAL_PROPS = {\n  data: [\n    {angle: 1, label: 'green'},\n    {angle: 2, label: 'yellow'},\n    {angle: 5, label: 'cyan'},\n    {angle: 3, label: 'magenta'},\n    {angle: 5, label: 'yellow again', className: 'custom-class'}\n  ],\n  height: 300,\n  showLabels: true,\n  width: 400,\n  padAngle: 0.3\n};\n\ndescribe('RadialChart', () => {\n  // make sure that the components render at all\n  testRenderWithProps(RadialChart, RADIAL_PROPS);\n\n  test('Basic rendering', () => {\n    const $ = mount(<RadialChart {...RADIAL_PROPS} />);\n    const pieSlices = $.find('.rv-radial-chart__series--pie__slice').length;\n    expect(pieSlices).toBe(RADIAL_PROPS.data.length);\n    expect(\n      $.find('.rv-radial-chart__series--pie__slice')\n        .at(0)\n        .prop('className')\n    ).toBe(\n      'rv-xy-plot__series rv-xy-plot__series--arc-path rv-radial-chart__series--pie__slice custom-class'\n    );\n\n    const labels = $.find('.rv-xy-plot__series--label-text').length;\n    expect(labels).toBe(RADIAL_PROPS.data.length);\n    expect($.text()).toBe('yellow againmagentacyanyellowgreen');\n\n    $.setProps({data: []});\n    expect($.find('.rv-radial-chart__series--pie__slice').length).toBe(0);\n    expect($.find('.rv-radial-chart__series--pie__slice-overlay').length).toBe(\n      0\n    );\n    expect($.find('.rv-xy-plot__series--label-text').length).toBe(0);\n    expect($.text()).toBe('');\n  });\n\n  test('Showcase Example - Simple Radial Chart Example', () => {\n    const $ = mount(<SimpleRadialChart />);\n    expect($.find('.rv-radial-chart__series--pie__slice').length).toBe(5);\n    expect($.find('.rv-xy-plot__series--label-text').length).toBe(5);\n    expect($.text()).toBe('yellow againmagentacyanyellowgreen');\n  });\n\n  test('Showcase Example - DonutChart', () => {\n    const $ = mount(<DonutChart />);\n    expect($.find('.rv-radial-chart__series--pie__slice').length).toBe(5);\n    expect($.find('.rv-xy-plot__series--label-text').length).toBe(0);\n    expect($.text()).toBe('');\n    $.find('.rv-radial-chart__series--pie__slice')\n      .at(1)\n      .simulate('mouseOver');\n    expect($.text()).toBe(\n      'theta: 3angle0: -2.9171931783333793angle: -4.263590029871862radius0: 0radius: 1color: 1x: -0.4338837391175583y: 0.900968867902419'\n    );\n  });\n\n  test('Showcase Example - Custom radius example', () => {\n    const $ = mount(<CustomRadiusRadialChart />);\n    $.find('.rv-radial-chart__series--pie__slice')\n      .at(1)\n      .simulate('mouseEnter');\n    $.find('.rv-radial-chart__series--pie__slice')\n      .at(1)\n      .simulate('mouseLeave');\n    // multiplied by two to account for the shadow listeners\n    expect($.find('.rv-radial-chart__series--pie__slice').length).toBe(2 * 5);\n    expect($.find('.rv-xy-plot__series--label-text').length).toBe(4);\n    expect($.text()).toBe(\n      'Sub Label onlyAlt LabelSuper Custom labelWith annotation'\n    );\n  });\n\n  test('Showcase Example - Gradient Pie Example', () => {\n    const $ = mount(<GradientPie />);\n    // multiplied by two to account for the shadow listeners\n    expect($.find('.rv-radial-chart__series--pie__slice').length).toBe(3);\n    expect($.find('.rv-xy-plot__series--label-text').length).toBe(0);\n    expect($.find('.rv-gradient-defs linearGradient').length).toBe(3);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/rect-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport HorizontalRectSeries from 'plot/series/horizontal-bar-series';\nimport VerticalRectSeries from 'plot/series/vertical-bar-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport Histogram from '../../../showcase/plot/histogram';\nimport StackedHistogram from '../../../showcase/plot/stacked-histogram';\n\ndescribe('RectSeries', () => {\n  testRenderWithProps(HorizontalRectSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\n  testRenderWithProps(VerticalRectSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\n  test('Showcase Example - StackedHistogram', () => {\n    const $ = mount(<StackedHistogram />);\n    expect($.text()).toBe('TOGGLE TO CANVAS01234567051015202530');\n    expect($.find('.rv-xy-plot__series--rect rect').length).toBe(6);\n\n    $.find('.showcase-button').simulate('click');\n    expect($.find('.rv-xy-plot__series--rect rect').length).toBe(0);\n    expect($.find('.rv-xy-canvas canvas').length).toBe(1);\n  });\n\n  test('Showcase Example - Histogram', () => {\n    const $ = mount(<Histogram />);\n    expect($.text()).toBe('May 21May 28Jun 04Jun 11Jun 180.51.01.52.0');\n    expect($.find('.rv-xy-plot__series--rect rect').length).toBe(8);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/sankey.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\n\nimport Sankey from 'sankey';\nimport Hint from 'plot/hint';\nimport BasicSankey from '../../../showcase/sankey/basic';\nimport VoronoiSankey from '../../../showcase/sankey/voronoi';\nimport EnergySankey from '../../../showcase/sankey/energy-sankey';\nimport LinkEventSankey from '../../../showcase/sankey/link-event';\nimport LinkHintSankey from '../../../showcase/sankey/link-hint';\n\nconst SANKEY_PROPS = {\n  nodes: [],\n  links: [],\n  width: 200,\n  height: 200,\n  strokeWidth: 1\n};\n\nimport {testRenderWithProps} from '../test-utils';\n\ndescribe('Sankey', () => {\n  // make sure that the components render at all\n  testRenderWithProps(Sankey, SANKEY_PROPS);\n\n  test('labels', () => {\n    const wrap = mount(\n      <Sankey\n        height={100}\n        width={100}\n        nodes={[{name: 'a'}, {name: 'b'}]}\n        links={[{source: 0, target: 1, value: 10}]}\n      />\n    );\n\n    expect(wrap.find('text').length).toBe(2);\n    wrap.setProps({hideLabels: true});\n    expect(wrap.find('text').length).toBe(0);\n  });\n\n  test('children', () => {\n    const $ = mount(\n      <Sankey\n        height={100}\n        width={100}\n        nodes={[{name: 'a'}, {name: 'b'}]}\n        links={[{source: 0, target: 1, value: 10}]}\n      >\n        <Hint x={0} y={0} value={{test: 123}} />\n      </Sankey>\n    );\n    expect($.find(Hint).length).toBe(1);\n  });\n\n  test('Showcase Example - BasicSankey', () => {\n    const $ = mount(<BasicSankey />);\n    expect($.find('.rv-sankey__link').length).toBe(3);\n    expect($.find('.rv-sankey__node rect').length).toBe(3);\n  });\n\n  test('Showcase Example - VoronoiSankey', () => {\n    const $ = mount(<VoronoiSankey />);\n\n    expect($.find('.rv-sankey__link').length).toBe(3);\n    expect($.find('.rv-sankey__node rect').length).toBe(3);\n    expect($.find('.rv-voronoi').length).toBe(1);\n    expect($.find('.rv-voronoi__cell').length).toBe(3);\n\n    expect($.text()).toBe('None selectedabc');\n    $.find('.rv-voronoi__cell')\n      .at(0)\n      .simulate('mouseOver');\n    expect($.text()).toBe('a selected!a!bc');\n    $.find('.rv-voronoi__cell')\n      .at(0)\n      .simulate('mouseLeave');\n  });\n\n  test('Showcase Example - LinkEventSankey', () => {\n    const $ = mount(<LinkEventSankey />);\n\n    expect($.find('.rv-sankey__link').length).toBe(3);\n    expect($.find('.rv-sankey__node rect').length).toBe(3);\n\n    expect($.text()).toBe('None selectedabc');\n    $.find('.rv-sankey__link')\n      .at(0)\n      .simulate('mouseOver');\n    expect($.text()).toBe('a -> b selectedabc');\n    $.find('.rv-sankey__link')\n      .at(0)\n      .simulate('mouseOut');\n    expect($.text()).toBe('None selectedabc');\n  });\n\n  test('Showcase Example - EnergySankey', () => {\n    const $ = mount(<EnergySankey />);\n\n    [\n      \"PREV MODE justify NEXT MODEAgricultural 'waste'Bio-conversionLiquidLossesSolidGasBiofuel importsBiomass importsCoal importsCoalCoal reservesDistrict heatingIndustryHeating and cooling - commercialHeating and cooling - homesElectricity gridOver generation / exportsH2 conversionRoad transportAgricultureRail transportLighting & appliances - commercialLighting & appliances - homesGas importsNgasGas reservesThermal generationGeothermalH2HydroInternational shippingDomestic aviationInternational aviationNational navigationMarine algaeNuclearOil importsOilOil reservesOther wastePumped heatSolar PVSolar ThermalSolarTidalUK land based bioenergyWaveWind\",\n      \"PREV MODE center NEXT MODEAgricultural 'waste'Bio-conversionLiquidLossesSolidGasBiofuel importsBiomass importsCoal importsCoalCoal reservesDistrict heatingIndustryHeating and cooling - commercialHeating and cooling - homesElectricity gridOver generation / exportsH2 conversionRoad transportAgricultureRail transportLighting & appliances - commercialLighting & appliances - homesGas importsNgasGas reservesThermal generationGeothermalH2HydroInternational shippingDomestic aviationInternational aviationNational navigationMarine algaeNuclearOil importsOilOil reservesOther wastePumped heatSolar PVSolar ThermalSolarTidalUK land based bioenergyWaveWind\",\n      \"PREV MODE left NEXT MODEAgricultural 'waste'Bio-conversionLiquidLossesSolidGasBiofuel importsBiomass importsCoal importsCoalCoal reservesDistrict heatingIndustryHeating and cooling - commercialHeating and cooling - homesElectricity gridOver generation / exportsH2 conversionRoad transportAgricultureRail transportLighting & appliances - commercialLighting & appliances - homesGas importsNgasGas reservesThermal generationGeothermalH2HydroInternational shippingDomestic aviationInternational aviationNational navigationMarine algaeNuclearOil importsOilOil reservesOther wastePumped heatSolar PVSolar ThermalSolarTidalUK land based bioenergyWaveWind\",\n      \"PREV MODE right NEXT MODEAgricultural 'waste'Bio-conversionLiquidLossesSolidGasBiofuel importsBiomass importsCoal importsCoalCoal reservesDistrict heatingIndustryHeating and cooling - commercialHeating and cooling - homesElectricity gridOver generation / exportsH2 conversionRoad transportAgricultureRail transportLighting & appliances - commercialLighting & appliances - homesGas importsNgasGas reservesThermal generationGeothermalH2HydroInternational shippingDomestic aviationInternational aviationNational navigationMarine algaeNuclearOil importsOilOil reservesOther wastePumped heatSolar PVSolar ThermalSolarTidalUK land based bioenergyWaveWind\"\n    ].forEach(testMessage => {\n      expect($.text()).toBe(testMessage);\n      $.find('.showcase-button')\n        .at(1)\n        .simulate('click');\n\n      expect($.find('.rv-sankey__link').length).toBe(68);\n      expect($.find('.rv-sankey__node rect').length).toBe(48);\n    });\n  });\n\n  test('Showcase Example - LinkHintSankey', () => {\n    const $ = mount(<LinkHintSankey />);\n\n    expect($.find('.rv-sankey__link').length).toBe(3);\n    expect($.find('.rv-sankey__node rect').length).toBe(3);\n\n    expect($.find(Hint).length).toBe(0);\n    $.find('.rv-sankey__link')\n      .at(0)\n      .simulate('mouseOver');\n    expect($.find(Hint).length).toBe(1);\n    $.find('.rv-sankey__link')\n      .at(0)\n      .simulate('mouseOut');\n    expect($.find(Hint).length).toBe(0);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/sunburst.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport Sunburst from 'sunburst';\nimport BasicSunburst from '../../../showcase/sunbursts/basic-sunburst';\nimport SunburstWithTooltips from '../../../showcase/sunbursts/sunburst-with-tooltips';\nimport AnimatedSunburst from '../../../showcase/sunbursts/animated-sunburst';\n\nimport {testRenderWithProps} from '../test-utils';\n\nconst INTERPOLATE_DATA = {\n  title: 'interpolate',\n  children: [\n    {title: 'ArrayInterpolator', color: '#12939A', size: 1983},\n    {title: 'ColorInterpolator', color: '#12939A', size: 2047},\n    {title: 'DateInterpolator', color: '#12939A', size: 1375},\n    {title: 'Interpolator', color: '#12939A', size: 8746},\n    {title: 'MatrixInterpolator', color: '#12939A', size: 2202},\n    {title: 'NumberInterpolator', color: '#12939A', size: 1382},\n    {title: 'ObjectInterpolator', color: '#12939A', size: 1629},\n    {title: 'PointInterpolator', color: '#12939A', size: 1675},\n    {title: 'RectangleInterpolator', color: '#12939A', size: 2042}\n  ]\n};\n\nconst SUNBURST_PROPS = {\n  height: 100,\n  width: 100,\n  className: 'little-nested-burst-example',\n  hideRootNode: true,\n  data: {\n    name: 'animate',\n    children: [\n      {title: 'Easing', color: '#12939A', size: 17010},\n      {title: 'FunctionSequence', color: '#12939A', size: 5842},\n      INTERPOLATE_DATA,\n      {title: 'ISchedulable', color: '#12939A', size: 1041},\n      {title: 'Parallel', color: '#12939A', size: 5176},\n      {title: 'Pause', color: '#12939A', size: 449},\n      {title: 'Scheduler', color: '#12939A', size: 5593},\n      {title: 'Sequence', color: '#12939A', size: 5534},\n      {title: 'Transition', color: '#12939A', size: 9201},\n      {title: 'Transitioner', color: '#12939A', size: 19975},\n      {title: 'TransitionEvent', color: '#12939A', size: 1116},\n      {title: 'Neonate', color: '#12939A', size: 6006}\n    ]\n  }\n};\n\ndescribe('Sunburst', () => {\n  // make sure that the components render at all\n  testRenderWithProps(Sunburst, SUNBURST_PROPS);\n\n  test('Basic rendering + data changes', () => {\n    const $ = mount(<Sunburst {...SUNBURST_PROPS} />);\n    expect(\n      $.find('.little-nested-burst-example.rv-xy-plot__series--arc path').length\n    ).toBe(21);\n\n    $.setProps({data: INTERPOLATE_DATA});\n    expect($.find('.rv-xy-plot__series--arc-path').length).toBe(9);\n  });\n\n  test('Empty', () => {\n    const $ = mount(<Sunburst {...{...SUNBURST_PROPS, data: {}}} />);\n    expect($.find('.rv-xy-plot__series--arc-path').length).toBe(0);\n  });\n\n  test('BasicSunburst', () => {\n    const $ = mount(<BasicSunburst />);\n    // multiplied by two to account for the shadow listeners\n    expect($.find('.rv-xy-plot__series--arc path').length).toBe(251 * 2);\n    expect($.text()).toBe('click to lock selectionSUNBURST');\n    // check hover state\n    expect($.state().pathValue).toEqual(false);\n    $.find('.rv-xy-plot__series--arc-path')\n      .at(200)\n      .simulate('mouseover');\n    expect($.state().pathValue).toEqual('root > vis > events > DataEvent');\n\n    $.find('.rv-xy-plot__series--arc-path')\n      .at(1)\n      .simulate('click');\n    expect($.text()).toBe(\n      'click to unlock selectionDataEventroot > vis > events > DataEvent'\n    );\n    $.find('.rv-xy-plot__series--arc-path')\n      .at(1)\n      .simulate('mouseLeave');\n    $.find('.rv-xy-plot__series--arc-path')\n      .at(10)\n      .simulate('mouseEnter');\n\n    expect($.text()).toBe(\n      'click to unlock selectionDataEventroot > vis > events > DataEvent'\n    );\n  });\n\n  test('SunburstWithTooltips', () => {\n    const $ = mount(<SunburstWithTooltips />);\n    expect($.text()).toBe('cooldogssunglassesexcellentchartgreatlabel');\n    expect($.find('.rv-xy-plot__series--arc path').length).toBe(10);\n    $.find('.rv-xy-plot__series--arc-path')\n      .at(1)\n      .simulate('mouseOver');\n    expect($.text()).toBe('cooldogssunglassesexcellentchartgreatlabel#FF991F');\n  });\n\n  test('AnimatedSunburst', () => {\n    const $ = mount(<AnimatedSunburst />);\n    expect($.text()).toBe('UPDATENOT HOVERED');\n    expect($.find('.rv-xy-plot__series--arc path').length > 2).toBeTruthy();\n    $.find('.rv-xy-plot__series--arc-path')\n      .at(1)\n      .simulate('mouseOver');\n    expect($.text()).toBe('UPDATECURRENTLY HOVERING');\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/treemap.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport Treemap from 'treemap';\n\nimport SimpleTreemap from '../../../showcase/treemap/simple-treemap';\nimport DynamicTreemap from '../../../showcase/treemap/dynamic-treemap';\n\nimport {testRenderWithProps} from '../test-utils';\n\nconst INTERPOLATE_DATA = {\n  title: 'interpolate',\n  children: [\n    {title: 'ArrayInterpolator', color: '#12939A', size: 1983},\n    {title: 'ColorInterpolator', color: '#12939A', size: 2047},\n    {title: 'DateInterpolator', color: '#12939A', size: 1375},\n    {title: 'Interpolator', color: '#12939A', size: 8746},\n    {title: 'MatrixInterpolator', color: '#12939A', size: 2202},\n    {title: 'NumberInterpolator', color: '#12939A', size: 1382},\n    {title: 'ObjectInterpolator', color: '#12939A', size: 1629},\n    {title: 'PointInterpolator', color: '#12939A', size: 1675},\n    {title: 'RectangleInterpolator', color: '#12939A', size: 2042}\n  ]\n};\n\nconst TREEMAP_PROPS = {\n  height: 100,\n  width: 100,\n  className: 'little-nested-tree-example',\n  data: {\n    name: 'animate',\n    children: [\n      {title: 'Easing', color: '#12939A', size: 17010},\n      {title: 'FunctionSequence', color: '#12939A', size: 5842},\n      INTERPOLATE_DATA,\n      {title: 'ISchedulable', color: '#12939A', size: 1041},\n      {title: 'Parallel', color: '#12939A', size: 5176},\n      {title: 'Pause', color: '#12939A', size: 449},\n      {title: 'Scheduler', color: '#12939A', size: 5593},\n      {title: 'Sequence', color: '#12939A', size: 5534},\n      {title: 'Transition', color: '#12939A', size: 9201},\n      {title: 'Transitioner', color: '#12939A', size: 19975},\n      {title: 'TransitionEvent', color: '#12939A', size: 1116},\n      {title: 'Neonate', color: '#12939A', size: 6006}\n    ]\n  }\n};\n\ndescribe('Treemap', () => {\n  // make sure that the components render at all\n  testRenderWithProps(Treemap, TREEMAP_PROPS);\n\n  test('Basic rendering', () => {\n    const $ = mount(<Treemap {...TREEMAP_PROPS} />);\n    expect($.find('.rv-treemap__leaf').length).toBe(22);\n    const expectedText =\n      'EasingFunctionSequenceinterpolateISchedulableParallelPauseSchedulerSequenceTransitionTransitionerTransitionEventNeonateArrayInterpolatorColorInterpolatorDateInterpolatorInterpolatorMatrixInterpolatorNumberInterpolatorObjectInterpolatorPointInterpolatorRectangleInterpolator';\n    expect($.find('.rv-treemap').text()).toBe(expectedText);\n    expect($.find('div.little-nested-tree-example').length).toBe(1);\n\n    $.setProps({data: INTERPOLATE_DATA});\n    expect($.find('.rv-treemap__leaf').length).toBe(10);\n    const newText =\n      'interpolateArrayInterpolatorColorInterpolatorDateInterpolatorInterpolatorMatrixInterpolatorNumberInterpolatorObjectInterpolatorPointInterpolatorRectangleInterpolator';\n    expect($.find('.rv-treemap').text()).toBe(newText);\n    expect($.find('div.little-nested-tree-example').length).toBe(1);\n  });\n\n  test('Custom Sorting', () => {\n    const $ = mount(<Treemap {...TREEMAP_PROPS} />);\n    const expectedText =\n      'interpolateTransitionerEasingTransitionNeonateFunctionSequenceSchedulerSequenceParallelTransitionEventISchedulablePauseInterpolatorMatrixInterpolatorColorInterpolatorRectangleInterpolatorArrayInterpolatorPointInterpolatorObjectInterpolatorNumberInterpolatorDateInterpolator';\n    const expectedReverseText =\n      'PauseISchedulableTransitionEventParallelSequenceSchedulerFunctionSequenceNeonateTransitionEasingTransitionerinterpolateDateInterpolatorNumberInterpolatorObjectInterpolatorPointInterpolatorArrayInterpolatorRectangleInterpolatorColorInterpolatorMatrixInterpolatorInterpolator';\n    const expectedNewText =\n      'interpolateInterpolatorMatrixInterpolatorColorInterpolatorRectangleInterpolatorArrayInterpolatorPointInterpolatorObjectInterpolatorNumberInterpolatorDateInterpolator';\n    const expectedReverseNewText =\n      'interpolateDateInterpolatorNumberInterpolatorObjectInterpolatorPointInterpolatorArrayInterpolatorRectangleInterpolatorColorInterpolatorMatrixInterpolatorInterpolator';\n\n    [\n      'circlePack',\n      'partition',\n      'partition-pivot',\n      'squarify',\n      'resquarify',\n      'slice',\n      'dice',\n      'slicedice',\n      'binary'\n    ].forEach(mode => {\n      $.setProps({\n        mode,\n        sortFunction: (a, b) => b.value - a.value,\n        ...TREEMAP_PROPS\n      });\n      expect($.find('.rv-treemap').text()).toBe(expectedText);\n      $.setProps({sortFunction: (a, b) => a.value - b.value});\n      expect($.find('.rv-treemap').text()).toBe(expectedReverseText);\n\n      // circle pack includes the root node, while the other modes do not. The root of INTERPOLATE_DATA has a title, but the root of the default data does not\n      $.setProps({\n        data: INTERPOLATE_DATA,\n        sortFunction: (a, b) => b.value - a.value\n      });\n      expect($.find('.rv-treemap').text()).toBe(expectedNewText);\n      $.setProps({sortFunction: (a, b) => a.value - b.value});\n      expect($.find('.rv-treemap').text()).toBe(expectedReverseNewText);\n    });\n  });\n\n  test('Empty treemap', () => {\n    const $ = mount(<Treemap {...{...TREEMAP_PROPS, data: {}}} />);\n    // 1 is the empty root node\n    expect($.find('.rv-treemap__leaf').length).toBe(1);\n    expect($.find('.rv-treemap').text()).toBe('');\n    expect($.find('div.little-nested-tree-example').length).toBe(1);\n  });\n\n  test('Hide Root Node', () => {\n    const $ = mount(<Treemap {...TREEMAP_PROPS} />);\n    // the tree from TREEMAP_PROPS doesn't have a title so its text is the same with ot without the root\n    const expectedText =\n      'EasingFunctionSequenceinterpolateISchedulableParallelPauseSchedulerSequenceTransitionTransitionerTransitionEventNeonateArrayInterpolatorColorInterpolatorDateInterpolatorInterpolatorMatrixInterpolatorNumberInterpolatorObjectInterpolatorPointInterpolatorRectangleInterpolator';\n    const numberOfElements = 21;\n    const numberOfElementsWithRoot = numberOfElements + 1;\n    const expectedNewText =\n      'ArrayInterpolatorColorInterpolatorDateInterpolatorInterpolatorMatrixInterpolatorNumberInterpolatorObjectInterpolatorPointInterpolatorRectangleInterpolator';\n    const expectedNewTextWithRoot = `interpolate${expectedNewText}`;\n    const numberOfNewElements = 9;\n    const numberOfNewElementsWithRoot = numberOfNewElements + 1;\n    [\n      'circlePack',\n      'partition',\n      'partition-pivot',\n      'squarify',\n      'resquarify',\n      'slice',\n      'dice',\n      'slicedice',\n      'binary'\n    ].forEach(mode => {\n      $.setProps({mode, ...TREEMAP_PROPS, hideRootNode: false});\n      expect($.find('.rv-treemap').text()).toBe(expectedText);\n      expect($.find('.rv-treemap__leaf').length).toBe(numberOfElementsWithRoot);\n      $.setProps({hideRootNode: true});\n      expect($.find('.rv-treemap').text()).toBe(expectedText);\n      expect($.find('.rv-treemap__leaf').length).toBe(numberOfElements);\n\n      $.setProps({data: INTERPOLATE_DATA, hideRootNode: false});\n      expect($.find('.rv-treemap').text()).toBe(expectedNewTextWithRoot);\n      expect($.find('.rv-treemap__leaf').length).toBe(\n        numberOfNewElementsWithRoot\n      );\n      $.setProps({hideRootNode: true});\n      expect($.find('.rv-treemap').text()).toBe(expectedNewText);\n      expect($.find('.rv-treemap__leaf').length).toBe(numberOfNewElements);\n    });\n  });\n\n  test('SimpleTreemap', () => {\n    const $ = mount(<SimpleTreemap />);\n    [\n      'circlePack',\n      'partition',\n      'partition-pivot',\n      'squarify',\n      'resquarify',\n      'slice',\n      'dice',\n      'slicedice',\n      'binary'\n    ].forEach(mode => {\n      const selector =\n        mode === 'circlePack'\n          ? '.rv-treemap__leaf circle'\n          : 'path.rv-treemap__leaf';\n      // circle pack includes the root node, while the other modes do not\n      const numberOfElements = 252;\n      expect($.find(selector).length).toBe(numberOfElements);\n      expect($.text()).toBe(`USE DOMPREV MODE ${mode} NEXT MODE`);\n      // switch to svg\n      $.find('.showcase-button')\n        .at(0)\n        .simulate('click');\n      expect($.find('.rv-treemap__leaf').length).toBe(numberOfElements);\n      expect($.text()).toBe(`USE SVGPREV MODE ${mode} NEXT MODE`);\n\n      // switch back to dom and go to next mode\n      $.find('.showcase-button')\n        .at(0)\n        .simulate('click');\n      $.find('.showcase-button')\n        .at(2)\n        .simulate('click');\n    });\n  });\n\n  test('DynamicTreemap', () => {\n    const $ = mount(<DynamicTreemap />);\n    expect($.find('.rv-treemap__leaf').length).toBe(21);\n    expect($.find('.rv-treemap').text()).toBe(\n      '2020202020202020202020202020202020202020'\n    );\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/voronoi.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport Voronoi from '../../src/plot/voronoi.js';\nimport XYPlot from 'plot/xy-plot';\n\nimport VoronoiLineChart from '../../../showcase/misc/voronoi-line-chart';\n\nconst StatelessVoronoiWrapper = () => (\n  <XYPlot\n    height={300}\n    width={300}\n    dontCheckIfEmpty\n    xDomain={[-50, 250]}\n    yDomain={[-50, 250]}\n  >\n    <Voronoi\n      extent={[\n        [0, 0],\n        [200, 200]\n      ]}\n      nodes={Array(100)\n        .fill()\n        .map((e, x) => ({\n          x,\n          y: 10,\n          className: `my-class-${x}`,\n          style: {color: 'red'}\n        }))}\n    />\n  </XYPlot>\n);\n\ndescribe('Voronoi', () => {\n  test('Basic Chart', () => {\n    const $ = mount(<StatelessVoronoiWrapper />);\n\n    expect(\n      $.find('.rv-voronoi__cell')\n        .at(30)\n        .prop('style').color\n    ).toBe('red');\n    expect(\n      $.find('.rv-voronoi__cell')\n        .at(30)\n        .hasClass('my-class-30')\n    ).toBe(true);\n    expect(\n      $.find('.rv-voronoi__cell')\n        .at(50)\n        .hasClass('my-class-50')\n    ).toBe(true);\n  });\n\n  test('VoronoiLineChart', () => {\n    const $ = mount(<VoronoiLineChart />);\n\n    expect($.text()).toBe(\n      'Show Voronoi1.01.52.02.53.03.54.0X Axis2468101214Y Axis'\n    );\n    expect($.find('.rv-voronoi__cell').length).toBe(12);\n    expect($.find('.rv-xy-plot__series--line').length).toBe(3);\n    expect($.find('circle').length).toBe(0);\n\n    $.find('input').simulate('click');\n    $.find('.rv-voronoi__cell')\n      .at(0)\n      .simulate('mouseOver');\n\n    expect($.find('circle').length).toBe(1);\n\n    $.find('.rv-voronoi__cell')\n      .at(0)\n      .simulate('mouseOut');\n\n    expect($.find('circle').length).toBe(0);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/whisker-series.test.js",
    "content": "import React from 'react';\nimport {mount} from 'enzyme';\nimport WhiskerSeries from 'plot/series/whisker-series';\nimport {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';\nimport WhiskerChart from '../../../showcase/plot/whisker-chart';\n\ntestRenderWithProps(WhiskerSeries, GENERIC_XYPLOT_SERIES_PROPS, true);\n\ndescribe('WhiskerSeries', () => {\n  test('Showcase Example - Whisker Scatterplot', () => {\n    const $ = mount(\n      <svg>\n        <WhiskerChart />\n      </svg>\n    );\n    expect($.text()).toBe('1.01.52.02.53.068101214');\n    expect($.find('g.whisker-series-example').length).toBe(1);\n    // 8 lines each per 5 (double) whiskers\n    expect($.find('.rv-xy-plot__series--whisker line').length).toBe(40);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components/xy-plot.test.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {mount, shallow} from 'enzyme';\n\nimport AbstractSeries from 'plot/series/abstract-series';\nimport VerticalBarSeries from 'plot/series/vertical-bar-series';\nimport BarSeries from 'plot/series/bar-series';\nimport LineSeries from 'plot/series/line-series';\nimport XAxis from 'plot/axis/x-axis';\nimport XYPlot from 'plot/xy-plot';\nimport HorizontalGridLines from 'plot/horizontal-grid-lines';\n\nimport MixedStackedChart from '../../../showcase/plot/mixed-stacked-chart';\nimport {FlexibleCharts} from '../../../showcase/flexible/flexible-examples';\nimport EmptyChart from '../../../showcase/axes/empty-chart';\nimport {testRenderWithProps} from '../test-utils';\n\nconst XYPLOT_PROPS = {width: 10, height: 10};\n\ntestRenderWithProps(XYPlot, XYPLOT_PROPS, false);\n\ndescribe('XYPlot', () => {\n  test('Render a stacked bar chart', () => {\n    const wrapper = shallow(\n      <XYPlot width={300} height={300} stackBy=\"y\">\n        <VerticalBarSeries\n          data={[\n            {x: 1, y: 0},\n            {x: 2, y: 1},\n            {x: 3, y: 2}\n          ]}\n        />\n        <VerticalBarSeries\n          data={[\n            {x: 1, y: 2},\n            {x: 2, y: 1},\n            {x: 3, y: 0}\n          ]}\n        />\n      </XYPlot>\n    );\n\n    const renderedVerticalBarsWrapper = wrapper.find(VerticalBarSeries);\n\n    expect(renderedVerticalBarsWrapper.at(0).prop('data')).toEqual([\n      {x: 1, y: 0},\n      {x: 2, y: 1},\n      {x: 3, y: 2}\n    ]);\n\n    expect(renderedVerticalBarsWrapper.at(1).prop('data')).toEqual([\n      {x: 1, y: 2, y0: 0},\n      {x: 2, y: 2, y0: 1},\n      {x: 3, y: 2, y0: 2}\n    ]);\n  });\n\n  test('Render a stacked bar chart with other children', () => {\n    const wrapper = shallow(\n      <XYPlot width={300} height={300} stackBy=\"y\">\n        <XAxis />\n        <VerticalBarSeries data={[{x: 1, y: 0}]} />\n        <VerticalBarSeries data={[{x: 1, y: 2}]} />\n        {\n          // Empty div here is intentional, to test series children handling\n        }\n        <div />\n      </XYPlot>\n    );\n\n    const renderedVerticalBarsWrapper = wrapper.find(VerticalBarSeries);\n\n    expect(renderedVerticalBarsWrapper.at(0).prop('data')).toEqual([\n      {x: 1, y: 0}\n    ]);\n\n    expect(renderedVerticalBarsWrapper.at(1).prop('data')).toEqual([\n      {x: 1, y: 2, y0: 0}\n    ]);\n  });\n\n  test('Render a bar chart with some nonAnimatedProps', () => {\n    const wrapper = shallow(\n      <XYPlot\n        width={300}\n        height={300}\n        animation={{nonAnimatedProps: ['xDomain']}}\n      >\n        <VerticalBarSeries data={[{x: 1, y: 0}]} />\n        <XAxis />\n      </XYPlot>\n    );\n\n    const renderedXAxisWrapper = wrapper.find(XAxis);\n    const renderedVerticalBarsWrapper = wrapper.find(VerticalBarSeries);\n\n    expect(renderedXAxisWrapper.at(0).prop('animation')).toEqual({\n      nonAnimatedProps: ['xDomain']\n    });\n\n    expect(renderedVerticalBarsWrapper.at(0).prop('animation')).toEqual({\n      nonAnimatedProps: ['xDomain']\n    });\n  });\n\n  test('testing flexible charts', () => {\n    const $ = mount(FlexibleCharts({height: 200, width: 400}));\n    const w = $.find('.flexible-width .rv-xy-plot').prop('style');\n    const h = $.find('.flexible-height .rv-xy-plot').prop('style');\n    const v = $.find('.flexible-vis .rv-xy-plot').prop('style');\n\n    expect(w.width).not.toBe('100px');\n    expect(w.height).toEqual('100px');\n    expect(h.width).toEqual('100px');\n    expect(h.height).not.toBe('100px');\n    expect(v.width).not.toBe('100px');\n    expect(v.height).not.toBe('100px');\n  });\n\n  test('Render two stacked bar series with a non-stacked line series chart', () => {\n    const $ = mount(<MixedStackedChart />);\n\n    const renderedBarsWrapper = $.find(BarSeries);\n    const renderedLineWrapper = $.find(LineSeries);\n    expect(renderedBarsWrapper.at(0).prop('data')).toEqual([\n      {x: 2, y: 10},\n      {x: 4, y: 5},\n      {x: 5, y: 15}\n    ]);\n\n    expect(renderedBarsWrapper.at(1).prop('data')).toEqual([\n      {x: 2, y: 22, y0: 10},\n      {x: 4, y: 7, y0: 5},\n      {x: 5, y: 26, y0: 15}\n    ]);\n\n    expect(renderedLineWrapper.at(0).prop('data')).toEqual([\n      {x: 2, y: 26},\n      {x: 4, y: 8},\n      {x: 5, y: 30}\n    ]);\n  });\n\n  test('Render a line series with data accessors', () => {\n    const $ = mount(\n      <XYPlot width={300} height={300} getX={d => d[0]} getY={d => d[1]}>\n        <LineSeries\n          data={[\n            [1, 0],\n            [2, 1],\n            [3, 2]\n          ]}\n        />\n      </XYPlot>\n    );\n\n    const renderedLineWrapper = $.find(LineSeries);\n    const dataProp = renderedLineWrapper.at(0).prop('data');\n    const getXProp = renderedLineWrapper.at(0).prop('getX');\n    const getYProp = renderedLineWrapper.at(0).prop('getY');\n    expect(dataProp.map(getXProp)).toEqual([1, 2, 3]);\n    expect(dataProp.map(getYProp)).toEqual([0, 1, 2]);\n  });\n\n  test('Trigger all onParentMouse handlers on Series components', () => {\n    const onParentMouseHandler = jest.fn();\n\n    class ExtendedSeries extends AbstractSeries {\n      onParentMouseUp = onParentMouseHandler;\n      onParentMouseDown = onParentMouseHandler;\n      onParentMouseMove = onParentMouseHandler;\n      onParentMouseLeave = onParentMouseHandler;\n      onParentMouseEnter = onParentMouseHandler;\n      onParentTouchStart = onParentMouseHandler;\n      onParentTouchMove = onParentMouseHandler;\n      render() {\n        return null;\n      }\n    }\n    const $ = mount(\n      <XYPlot width={300} height={300} getX={d => d[0]} getY={d => d[1]}>\n        <ExtendedSeries\n          name=\"series-1\"\n          data={[\n            [1, 0],\n            [2, 1],\n            [3, 2]\n          ]}\n        />\n        <ExtendedSeries\n          name=\"series-2\"\n          data={[\n            [1, 0],\n            [2, 1],\n            [3, 2]\n          ]}\n        />\n      </XYPlot>\n    );\n    $.find('svg')\n      .at(0)\n      .simulate('mouseenter');\n    $.find('svg')\n      .at(0)\n      .simulate('mousedown');\n    $.find('svg')\n      .at(0)\n      .simulate('mousemove');\n    $.find('svg')\n      .at(0)\n      .simulate('mouseup');\n    $.find('svg')\n      .at(0)\n      .simulate('mouseleave');\n    $.find('svg')\n      .at(0)\n      .simulate('touchstart');\n    $.find('svg')\n      .at(0)\n      .simulate('touchmove');\n\n    expect(onParentMouseHandler).toHaveBeenCalledTimes(14);\n  });\n\n  test('dontCheckIfEmpty - Showcase example EmptyChart', () => {\n    const $ = mount(<EmptyChart />);\n    expect($.find('.rv-xy-plot__series').length).toBe(0);\n    expect($.text()).toBe('1!1.5!2!3!Empty Chart Right Here');\n  });\n\n  test('attach ref only to series components', () => {\n    const Stateless = () => {\n      return <div>stateless</div>;\n    };\n    const $ = mount(\n      <XYPlot width={300} height={300}>\n        <HorizontalGridLines />\n        <XAxis />\n        <LineSeries\n          data={[\n            {x: 1, y: 3},\n            {x: 2, y: 5},\n            {x: 3, y: 15},\n            {x: 4, y: 12}\n          ]}\n        />\n        <Stateless />\n      </XYPlot>\n    );\n\n    const clonedChilds = $.instance()._getClonedChildComponents();\n    const horizontalGridLinesChild = clonedChilds.find(\n      element => element.type === HorizontalGridLines\n    );\n    const axisChild = clonedChilds.find(element => element.type === XAxis);\n    const lineSeriesChild = clonedChilds.find(\n      element => element.type === LineSeries\n    );\n    const statelessChild = clonedChilds.find(\n      element => element.type === Stateless\n    );\n    expect(horizontalGridLinesChild.ref === null).toBeTruthy();\n    expect(axisChild.ref === null).toBeTruthy();\n    expect(typeof lineSeriesChild.ref === 'function').toBeTruthy();\n    expect(statelessChild.ref === null).toBeTruthy();\n  });\n\n  test('with wheel event callback', () => {\n    const onWheel = jest.fn();\n\n    const $ = mount(\n      <XYPlot onWheel={onWheel} width={300} height={300}>\n        <VerticalBarSeries\n          data={[\n            {x: 1, y: 0},\n            {x: 2, y: 1},\n            {x: 3, y: 2}\n          ]}\n        />\n      </XYPlot>\n    );\n\n    $.find('svg')\n      .at(0)\n      .simulate('wheel');\n\n    expect(onWheel).toHaveBeenCalledTimes(1);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/components.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport HorizontalGrid from 'plot/horizontal-grid-lines';\nimport VerticalGrid from 'plot/vertical-grid-lines';\nimport XAxisBottom from 'plot/axis/x-axis';\nimport YAxisLeft from 'plot/axis/y-axis';\n\nimport {testRenderWithProps} from './test-utils';\n\nconst XYPLOT_XAXIS_PROPS = {\n  xRange: [0, 1],\n  xDomain: [0, 1],\n  xType: 'linear',\n  width: 100,\n  height: 100,\n  top: 0,\n  left: 0\n};\n\nconst XYPLOT_YAXIS_PROPS = {\n  yRange: [0, 1],\n  yDomain: [0, 1],\n  yType: 'linear',\n  width: 100,\n  height: 100,\n  top: 0,\n  left: 0\n};\n\ntestRenderWithProps(HorizontalGrid, XYPLOT_YAXIS_PROPS);\ntestRenderWithProps(VerticalGrid, XYPLOT_XAXIS_PROPS);\ntestRenderWithProps(XAxisBottom, XYPLOT_XAXIS_PROPS);\ntestRenderWithProps(YAxisLeft, XYPLOT_YAXIS_PROPS);\n"
  },
  {
    "path": "packages/react-vis/tests/index.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport './setup';\n\nimport './utils/axis-utils-tests';\nimport './utils/chart-utils-tests';\nimport './utils/data-utils-tests';\nimport './utils/react-utils-tests';\nimport './utils/scales-utils-tests';\nimport './utils/series-utils-tests';\nimport './utils/styling-utils-tests';\n\nimport './components';\nimport './components/line-series-canvas-test';\nimport './components/animation-tests';\nimport './components/area-series-tests';\nimport './components/arc-series-tests';\nimport './components/axes-tests';\nimport './components/axis-tick-format-tests';\nimport './components/axis-title-tests';\nimport './components/bar-series-tests';\nimport './components/borders-tests';\nimport './components/canvas-component-tests';\nimport './components/circular-grid-lines-tests';\nimport './components/color-article-tests';\nimport './components/contour-series-tests';\nimport './components/crosshair-tests';\nimport './components/custom-svg-series-tests';\nimport './components/data-article-tests';\nimport './components/decorative-axis-tests';\nimport './components/gradient-tests';\nimport './components/grid-lines-tests';\nimport './components/heatmap-tests';\nimport './components/hexbin-series-tests';\nimport './components/highlight-tests';\nimport './components/hints-tests';\nimport './components/interaction-article-tests';\nimport './components/legends-tests';\nimport './components/label-series-tests';\nimport './components/line-series-tests';\nimport './components/make-vis-flexible-tests';\nimport './components/mark-series-tests';\nimport './components/whisker-series-tests';\nimport './components/parallel-coordinates-tests';\nimport './components/polygon-series-tests';\nimport './components/radial-tests';\nimport './components/radar-chart-tests';\nimport './components/rect-series-tests';\nimport './components/treemap-tests';\nimport './components/sankey-tests';\nimport './components/showcase-example-tests';\nimport './components/sunburst-tests';\nimport './components/voronoi-tests';\nimport './components/xy-plot-tests';\n"
  },
  {
    "path": "packages/react-vis/tests/jsconfig.json",
    "content": "{\n  \"typeAcquisition\": {\n    \"enable\": true,\n    \"include\": [\n      \"jest\"\n    ]\n  }\n}"
  },
  {
    "path": "packages/react-vis/tests/plot/__snapshots__/content-clip-path.test.js.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`content-clip-path should render 1`] = `\n<defs>\n  <clipPath\n    id=\"foo\"\n  >\n    <rect\n      height={200}\n      width={300}\n      x={0}\n      y={0}\n    />\n  </clipPath>\n</defs>\n`;\n"
  },
  {
    "path": "packages/react-vis/tests/plot/content-clip-path.test.js",
    "content": "import React from 'react';\nimport {shallow} from 'enzyme';\nimport ContentClipPath from '../../src/plot/content-clip-path';\n\ndescribe('content-clip-path', () => {\n  it('should render', () => {\n    const wrapper = shallow(\n      <ContentClipPath id=\"foo\" innerWidth={300} innerHeight={200} />\n    );\n    expect(wrapper).toMatchSnapshot();\n  });\n\n  it('should default id to content-area', () => {\n    const wrapper = shallow(\n      <ContentClipPath innerWidth={300} innerHeight={200} />\n    );\n    const clip = wrapper.find('clipPath');\n    expect(clip.prop('id')).toEqual('content-area');\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/setup.js",
    "content": "/* eslint-disable no-undef */\nimport jsdom from 'jsdom';\nimport Enzyme from 'enzyme';\n\nimport Adapter from 'enzyme-adapter-react-16';\nEnzyme.configure({adapter: new Adapter()});\n\nglobal.document = jsdom.jsdom('<body></body>');\nglobal.window = document.defaultView;\nObject.keys(document.defaultView).forEach(function mapProperties(property) {\n  if (typeof global[property] === 'undefined') {\n    global[property] = document.defaultView[property];\n  }\n});\n\nglobal.navigator = {\n  userAgent: 'node.js'\n};\n\n/* eslint-enable no-undef */\n"
  },
  {
    "path": "packages/react-vis/tests/test-utils.js",
    "content": "/* eslint-disable jest/no-export */\nimport React from 'react';\nimport {mount} from 'enzyme';\n\nconst NOOP = f => f;\n\nexport const GENERIC_XYPLOT_SERIES_PROPS = {\n  xDomain: [0, 1],\n  xRange: [0, 1],\n  xType: 'linear',\n  xDistance: 1,\n  yDomain: [0, 1],\n  yRange: [0, 1],\n  yDistance: 1,\n  yType: 'linear',\n  data: [\n    {x: 1, y: 1},\n    {x: 2, y: 2}\n  ],\n  _allData: [\n    [\n      {x: 1, y: 1},\n      {x: 2, y: 2}\n    ]\n  ],\n  onSeriesMouseOver: NOOP,\n  onSeriesMouseOut: NOOP,\n  onSeriesClick: NOOP,\n  onSeriesRightClick: NOOP,\n  onValueMouseOver: NOOP,\n  onValueMouseOut: NOOP,\n  onValueClick: NOOP,\n  onValueRightClick: NOOP\n};\n\nexport const testRenderWithProps = (Component, props, wrapWithSvg = false) =>\n  // eslint-disable-next-line jest/require-top-level-describe\n  test(`Rendering ${Component.displayName}`, () => {\n    const wrapper = mount(\n      wrapWithSvg ? (\n        <svg>\n          <Component {...props} />\n        </svg>\n      ) : (\n        <Component {...props} />\n      )\n    );\n\n    const component = wrapper.find(Component);\n    expect(component).toHaveLength(1);\n\n    const componentProps = component.props();\n    Object.keys(props).forEach(propName => {\n      expect(componentProps[propName]).toEqual(props[propName]);\n    });\n  });\n"
  },
  {
    "path": "packages/react-vis/tests/utils/axis-utils.test.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport {scaleLinear} from 'd3-scale';\nimport {range} from 'd3-array';\n\nimport {\n  getTicksTotalFromSize,\n  getTickValues,\n  getAxisAngle,\n  generateFit,\n  generatePoints\n} from 'utils/axis-utils';\n\ndescribe('axis-utils', () => {\n  test('getTicksTotalFromSize', () => {\n    expect(getTicksTotalFromSize(0) === 5).toBeTruthy();\n    expect(getTicksTotalFromSize(301) === 10).toBeTruthy();\n    expect(getTicksTotalFromSize(701) === 20).toBeTruthy();\n  });\n\n  test('getTickValues', () => {\n    const scale = scaleLinear()\n      .domain([0, 1])\n      .range(['red', 'blue']);\n    expect(\n      getTickValues(scale, 10, false).map(d => Math.round(d * 1000) / 1000)\n    ).toEqual([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]);\n\n    const predefinedVals = ['got dang', 1, undefined, 'lolz'];\n    expect(getTickValues(scale, 10, predefinedVals)).toEqual(predefinedVals);\n  });\n\n  test('getAxisAngle', () => {\n    expect(getAxisAngle({x: 0, y: 0}, {x: 1, y: 1})).toBe(Math.PI / 4);\n    expect(getAxisAngle({x: 0, y: 0}, {x: 0, y: 1})).toBe(Math.PI / 2);\n    expect(getAxisAngle({x: 0, y: 0}, {x: 0, y: -1})).toBe((3 * Math.PI) / 2);\n  });\n\n  test('generateFit', () => {\n    expect(generateFit({x: 0, y: 0}, {x: 1, y: 1})).toEqual({\n      left: 0,\n      offset: 0,\n      right: 1,\n      slope: 1\n    });\n    expect(generateFit({x: 0, y: 0}, {x: 0, y: 1})).toEqual({\n      left: 0,\n      offset: 0,\n      right: 1,\n      slope: 0\n    });\n    expect(generateFit({x: 0, y: 0}, {x: 0, y: -1})).toEqual({\n      left: 0,\n      offset: 0,\n      right: -1,\n      slope: 0\n    });\n    const result = generateFit(\n      {x: 175, y: 125},\n      {x: 17.33044811707665, y: 179.23546738969475}\n    );\n    const numberOfTicks = 5;\n    const left = result.left;\n    const right = result.right;\n    const pointSlope = (right - left) / numberOfTicks;\n    const lengthOfGeneratedPoints = range(left, right + pointSlope, pointSlope)\n      .length;\n    expect(lengthOfGeneratedPoints).toBe(7);\n  });\n\n  test('generatePoints', () => {\n    const result = generatePoints({\n      axisStart: {x: 0, y: 1},\n      axisEnd: {x: 1, y: 1},\n      numberOfTicks: 5,\n      axisDomain: [10, 100]\n    });\n    const expectedResult = {\n      points: [\n        {text: 10, y: 1, x: 0},\n        {text: 28, y: 1, x: 0.2},\n        {text: 46, y: 1, x: 0.4},\n        {text: 64, y: 1, x: 0.6000000000000001},\n        {text: 82, y: 1, x: 0.8},\n        {text: 100, y: 1, x: 1}\n      ],\n      slope: -0\n    };\n    // const result2 = generatePoints({\n    //   axisStart: {x: 175, y: 125},\n    //   axisEnd: {x: 17.33044811707665, y: 179.23546738969475},\n    //   numberOfTicks: 5,\n    //   axisDomain: [0, 100]\n    // });\n    const expectedResult2 = {\n      points: [\n        {text: 0, y: 125.00000000000001, x: 175},\n        {text: 20, y: 135.84709347793896, x: 143.46608962341534},\n        {text: 40, y: 146.6941869558779, x: 111.93217924683066},\n        {text: 59.99999999999999, y: 157.54128043381687, x: 80.398268870246},\n        {text: 80, y: 168.38837391175582, x: 48.86435849366133},\n        {text: 100, y: 179.23546738969478, x: 17.330448117076656}\n      ],\n      slope: -0.34398187057680607\n    };\n    const result3 = generatePoints({\n      axisStart: {x: 175, y: 125},\n      axisEnd: {x: 175, y: 250},\n      numberOfTicks: 5,\n      axisDomain: [0, 100]\n    });\n    const expectedResult3 = {\n      points: [\n        {text: 0, y: 125, x: 175},\n        {text: 20, y: 150, x: 175},\n        {text: 40, y: 175, x: 175},\n        {text: 60, y: 200, x: 175},\n        {text: 80, y: 225, x: 175},\n        {text: 100, y: 250, x: 175}\n      ],\n      slope: Infinity\n    };\n    const result4 = generatePoints({\n      axisStart: {x: 175, y: 125},\n      axisEnd: {x: 174.99999999999997, y: 250},\n      numberOfTicks: 5,\n      axisDomain: [0, 100]\n    });\n    const expectedResult4 = {\n      points: [\n        {text: 0, y: 128, x: 175},\n        {text: 0, y: 128, x: 175},\n        {text: 0, y: 128, x: 175},\n        {text: 100, y: 256, x: 174.99999999999997},\n        {text: 100, y: 256, x: 174.99999999999997}\n      ],\n      slope: -4398046511104000\n    };\n    expect(result).toEqual(expectedResult);\n\n    // Relies on testing library to handle differences in floating point numbers.\n    // t.deepEqual(result2, expectedResult2);\n    expect(expectedResult2.points.length).toBe(6);\n    expect(result3).toEqual(expectedResult3);\n    expect(result4).toEqual(expectedResult4);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/utils/chart-utils.test.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport {getRadialLayoutMargin} from 'utils/chart-utils';\n\ndescribe('chart-utils', () => {\n  test('getRadialLayoutMargin', () => {\n    expect(getRadialLayoutMargin(500, 300, 120)).toEqual({\n      bottom: 30,\n      left: 130,\n      right: 130,\n      top: 30\n    });\n\n    expect(getRadialLayoutMargin(300, 500, 120)).toEqual({\n      bottom: 130,\n      left: 30,\n      right: 30,\n      top: 130\n    });\n\n    expect(getRadialLayoutMargin(300, 300, 120)).toEqual({\n      bottom: 30,\n      left: 30,\n      right: 30,\n      top: 30\n    });\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/utils/data-utils.test.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport {\n  getUniquePropertyValues,\n  addValueToArray,\n  transformValueToString\n} from 'utils/data-utils';\n\nconst arr = [{a: 1}, {b: 3, a: 2}, {a: 2}];\n\ndescribe('data-utils', () => {\n  test('getUniquePropertyValues', () => {\n    const result = getUniquePropertyValues(arr, d => d.a);\n    expect(result.length === 2).toBeTruthy();\n    expect(result.indexOf(1) !== -1 && result.indexOf(2) !== -1).toBeTruthy();\n  });\n\n  test('addValueToArray', () => {\n    expect(addValueToArray([-10, 10], 1)).toEqual([-10, 10]);\n    expect(addValueToArray([-10, 0], 1)).toEqual([-10, 1]);\n    expect(addValueToArray([0, 10], -1)).toEqual([-1, 10]);\n  });\n\n  test('transformValueToString', () => {\n    expect(transformValueToString(0)).toEqual(0);\n\n    // 43200000 - this is the timestamp for 12PM on 1970-01-01\n    // This plays much nicer when running tests locally for different timezones.\n    expect(transformValueToString(new Date(43200000))).toEqual(\n      'Thu Jan 01 1970'\n    );\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/utils/react-utils.test.js",
    "content": "import {isReactDOMSupported} from 'utils/react-utils';\n\ndescribe('react-utils', () => {\n  test('isReactDOMSupported', () => {\n    expect(isReactDOMSupported()).toBeTruthy();\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/utils/scales-utils.test.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport {\n  _adjustCategoricalScale,\n  getScaleObjectFromProps,\n  getScalePropTypesByAttribute,\n  getAttributeFunctor,\n  getAttr0Functor,\n  getAttributeScale,\n  getAttributeValue,\n  getFontColorFromBackground,\n  getOptionalScaleProps,\n  getXYPlotValues,\n  _getSmallestDistanceIndex,\n  getScaleFnFromScaleObject,\n  _getScaleDistanceAndAdjustedDomain,\n  extractScalePropsFromProps,\n  getMissingScaleProps,\n  literalScale\n} from 'utils/scales-utils';\n\nconst isScaleConsistent = (scaleObject, attr) => {\n  return (\n    scaleObject &&\n    scaleObject.range &&\n    scaleObject.domain &&\n    scaleObject.type &&\n    scaleObject.attr === attr\n  );\n};\n\nconst _allData = [[{x: 1}, {x: 2}, {x: 3}, {x: 2}]];\nconst _xValue = 20;\nconst xRange = [0, 100];\nconst xDomain = [1, 5];\nconst xType = 'ordinal';\nconst xDistance = 10;\n\ndescribe('scales-utils', () => {\n  test('getScaleObjectFromProps ', () => {\n    // with empty props\n    const nullResult = getScaleObjectFromProps({}, 'x');\n    expect(nullResult).toBe(null);\n    // with empty domain\n    const noRangeResult = getScaleObjectFromProps({xDomain}, 'x');\n    expect(noRangeResult).toBe(null);\n    // with empty range\n    const noDomainResult = getScaleObjectFromProps({xRange}, 'x');\n    expect(noDomainResult).toBe(null);\n\n    // with all props\n    const completeResult = getScaleObjectFromProps(\n      {xRange, _allData, xDomain, xType, xDistance},\n      'x'\n    );\n    expect(isScaleConsistent(completeResult, 'x')).toBeTruthy();\n    expect(completeResult.type).toBe(xType);\n    // does not mutate passed domain\n    const tXDomain = [1, 5];\n    const scaleObj = getScaleObjectFromProps(\n      {\n        xRange,\n        _adjustBy: ['x'],\n        _adjustWhat: [0],\n        _allData,\n        xDomain: tXDomain,\n        xDistance\n      },\n      'x'\n    );\n\n    expect(scaleObj.domain).toEqual([0.5, 5.5]);\n    expect(tXDomain).toEqual([1, 5]);\n\n    // with the value that overrides props\n    const valueResult = getScaleObjectFromProps({x: 10, _allData}, 'x');\n    expect(isScaleConsistent(valueResult, 'x')).toBeTruthy();\n    expect(valueResult.isValue).toBe(true);\n  });\n\n  test('getScalePropTypesByAttribute', () => {\n    const result = Object.keys(getScalePropTypesByAttribute('size'));\n    const expectedResult = [\n      '_sizeValue',\n      'sizeDomain',\n      'getSize',\n      'getSize0',\n      'sizeRange',\n      'sizeType',\n      'sizeDistance',\n      'sizeBaseValue'\n    ];\n    expect(result).toEqual(expectedResult);\n  });\n\n  test('getAttributeFunctor', () => {\n    // without props\n    let result = getAttributeFunctor({_xValue}, 'x');\n    expect(result({x: Math.random()}) === _xValue).toBeTruthy();\n    expect(result({})).toBe(_xValue);\n    // with props\n    result = getAttributeFunctor({xRange, xDomain}, 'x');\n    const isFunction = typeof result === 'function';\n    expect(isFunction).toBeTruthy();\n    expect(result(_allData[0][0])).toBe(xRange[0]);\n\n    expect(result({data: {x: 10}})).toBe(225);\n\n    // with custom accessor\n    result = getAttributeFunctor({xRange, xDomain, getX: d => d.value}, 'x');\n    expect(typeof result === 'function').toBeTruthy();\n\n    expect(result({data: {x: 10, value: 1}})).toBe(0);\n  });\n\n  test('getAttr0Functor', () => {\n    // without props\n    let result = getAttr0Functor({}, 'x');\n    expect(null).toBe(null);\n\n    // using a literal scale to check that the fall back is working correctly\n    const exNaughtData = [\n      [{x: 1, x0: 1}, {x: 0}, {x: 3, x0: 3}, {x: 2, x0: 4}]\n    ];\n    result = getAttr0Functor(\n      {\n        xRange,\n        _allData: exNaughtData,\n        xDomain,\n        xType: 'literal',\n        xDistance\n      },\n      'x'\n    );\n    expect(typeof result === 'function').toBeTruthy();\n    expect(result(exNaughtData[0][0])).toBe(1);\n    expect(result(exNaughtData[0][1])).toBe(1);\n\n    expect(result({data: {x: 10, x0: 5}})).toBe(5);\n\n    // with custom accessor\n    result = getAttr0Functor(\n      {\n        xRange,\n        _allData: exNaughtData,\n        getX0: d => d.z,\n        xDomain,\n        xType: 'literal',\n        xDistance\n      },\n      'x'\n    );\n    expect(typeof result === 'function').toBeTruthy();\n    expect(result({data: {x: 10, x0: 5, z: 1}})).toBe(1);\n\n    // now with a linear scale\n    result = getAttr0Functor(\n      {\n        xRange,\n        _allData: exNaughtData,\n        xDomain,\n        xType: 'linear',\n        xDistance\n      },\n      'x'\n    );\n\n    expect(typeof result === 'function').toBeTruthy();\n    expect(result(exNaughtData[0][0])).toBe(xRange[0]);\n    expect(result(exNaughtData[0][1])).toBe(0);\n\n    expect(result({data: {x: 10, x0: 5}})).toBe(100);\n  });\n\n  test('getAttributeScale', () => {\n    // without props\n    let result = getAttributeScale({}, 'x');\n    expect(result === null).toBeTruthy();\n    // with props\n    result = getAttributeScale({xRange, xDomain}, 'x');\n    const isFunction = typeof result === 'function';\n    expect(isFunction).toBeTruthy();\n    expect(result(_allData[0][0].x)).toBe(xRange[0]);\n  });\n\n  test('getAttributeValue ', () => {\n    // without props\n    let result = getAttributeValue({_xValue}, 'x');\n    expect(result === _xValue).toBeTruthy();\n    // with props\n    result = getAttributeValue({x: 10}, 'x');\n    expect(result).toBe(10);\n    // with props including a scale type\n    result = getAttributeValue(\n      {opacity: 0.5, opacityType: 'literal'},\n      'opacity'\n    );\n    expect(result).toBe(0.5);\n  });\n\n  test('_getSmallestDistanceIndex', () => {\n    const scaleObj = {type: 'linear', domain: [0, 1], range: [0, 1]};\n    const runTest = arg => _getSmallestDistanceIndex(arg, scaleObj);\n\n    expect(runTest([0, 0, 2])).toBe(1);\n    expect(runTest([0, 1, 2])).toBe(1);\n    expect(runTest([0, 2, 2])).toBe(2);\n    expect(runTest([0, 2, 2])).toBe(2);\n    expect(runTest([1, 2, 2])).toBe(2);\n    expect(runTest([2, 2, 2])).toBe(1);\n  });\n\n  test('extractScalePropsFromProps', () => {\n    expect(\n      Object.keys(extractScalePropsFromProps({}, [])).length === 0\n    ).toBeTruthy();\n\n    const props = {\n      aType: 'linear',\n      aRange: [1, 2],\n      _aValue: 10,\n      somethingElse: [],\n      bDomain: [1, 2, 3],\n      getA: d => d.a\n    };\n\n    const result = extractScalePropsFromProps(props, ['a', 'b']);\n    expect(\n      Object.keys(result).length === 5 &&\n        result.aType === props.aType &&\n        result.aRange === props.aRange &&\n        result._aValue === props._aValue &&\n        result.bDomain === props.bDomain &&\n        result.getA === props.getA\n    ).toBeTruthy();\n  });\n\n  test('getMissingScaleProps', () => {\n    const fakeDataInteger = [\n      {x: 10, y: 10},\n      {x: 15, y: 15},\n      {x: 20, y: 20}\n    ];\n    const fakeDataIntegerDomain = [9, 21];\n    const fakeDataString = [{x: 'React'}, {x: 'Vis'}];\n    const fakeDataStringDomain = ['React', 'Vis'];\n    const dayOne = 971136000;\n    const dayTen = 972000000;\n    const fakeDomain = [0, 100];\n    const fakeDataUnixTime = [{x: dayOne}, {x: dayTen}];\n    const paddedDayOne = dayOne - (dayTen - dayOne) * 0.1;\n    const paddedDayTen = dayTen + (dayTen - dayOne) * 0.1;\n    const fakePadding = 10;\n\n    expect(Object.keys(getMissingScaleProps({}, [], [])).length).toBe(0);\n    const result = getMissingScaleProps({}, _allData[0], ['x']);\n    expect(\n      Boolean(result.xDomain) &&\n        result.xDomain.length === 2 &&\n        result.xDomain[0] === 1 &&\n        result.xDomain[1] === 3\n    ).toBeTruthy();\n\n    expect(\n      getMissingScaleProps(\n        {\n          xPadding: fakePadding\n        },\n        fakeDataInteger,\n        ['x']\n      ).xDomain\n    ).toEqual(fakeDataIntegerDomain);\n    // need to use json stringify to peel off the functions\n    expect(\n      JSON.stringify(\n        getMissingScaleProps(\n          {\n            xPadding: fakePadding,\n            xDomain: fakeDomain\n          },\n          fakeDataInteger,\n          ['x']\n        )\n      )\n    ).toEqual('{}');\n    expect(\n      Object.keys(\n        getMissingScaleProps(\n          {\n            xPadding: fakePadding,\n            xDomain: fakeDomain\n          },\n          fakeDataInteger,\n          ['x']\n        )\n      )\n    ).toEqual(['getX', 'getX0']);\n    expect(\n      getMissingScaleProps(\n        {\n          yPadding: fakePadding\n        },\n        fakeDataInteger,\n        ['y']\n      ).yDomain\n    ).toEqual(fakeDataIntegerDomain);\n    expect(\n      getMissingScaleProps(\n        {\n          xPadding: fakePadding\n        },\n        fakeDataString,\n        ['x']\n      ).xDomain\n    ).toEqual(fakeDataStringDomain);\n    expect(\n      getMissingScaleProps(\n        {\n          xPadding: fakePadding\n        },\n        fakeDataUnixTime,\n        ['x']\n      ).xDomain\n    ).toEqual([paddedDayOne, paddedDayTen]);\n  });\n\n  test('literalScale', () => {\n    const s = literalScale(5);\n\n    expect(s(0.5)).toBe(0.5);\n    expect(s(1)).toBe(1);\n    expect(s(1.5)).toBe(1.5);\n    expect(s(2)).toBe(2);\n    expect(s(2.5)).toBe(2.5);\n    expect(s()).toBe(5);\n    expect(s('2')).toBe('2');\n  });\n\n  test('getFontColorFromBackground', () => {\n    expect(getFontColorFromBackground('#fff')).toBe('#222');\n    expect(getFontColorFromBackground('#000')).toBe('#fff');\n    expect(getFontColorFromBackground(null)).toBe(null);\n  });\n\n  test('getScaleFnFromScaleObject', () => {\n    expect(getScaleFnFromScaleObject()).toBe(null);\n    const linearScale = getScaleFnFromScaleObject({\n      type: 'linear',\n      domain: [0, 1],\n      range: [1, 0]\n    });\n\n    const literalScaleWithDefaultValue = getScaleFnFromScaleObject({\n      type: 'literal',\n      domain: [],\n      range: [5]\n    });\n\n    expect(linearScale.domain()).toEqual([0, 1]);\n    expect(linearScale.range()).toEqual([1, 0]);\n\n    expect(literalScaleWithDefaultValue()).toEqual(5);\n    expect(literalScaleWithDefaultValue(2)).toEqual(2);\n\n    const modScaleWithZero = getScaleFnFromScaleObject({\n      type: 'linear',\n      domain: [0, 0],\n      range: [1, 0]\n    });\n    expect(modScaleWithZero.domain()).toEqual([-1, 0]);\n\n    const modScale = getScaleFnFromScaleObject({\n      type: 'linear',\n      domain: [1, 1],\n      range: [1, 0]\n    });\n    expect(modScale.domain()).toEqual([-1, 1]);\n\n    const ordinalScale = getScaleFnFromScaleObject({\n      type: 'ordinal',\n      domain: ['a', 'b', 'c', 'd', 'e'],\n      range: [20, 120]\n    });\n\n    expect(ordinalScale.invert(-10)).toBe('a');\n    expect(ordinalScale.invert(25)).toBe('a');\n    expect(ordinalScale.invert(40)).toBe('a');\n    expect(ordinalScale.invert(60)).toBe('b');\n    expect(ordinalScale.invert(80)).toBe('c');\n    expect(ordinalScale.invert(100)).toBe('d');\n    expect(ordinalScale.invert(115)).toBe('e');\n    expect(ordinalScale.invert(130)).toBe('e');\n  });\n\n  function generateFakeData() {\n    return new Array(100).fill(0).map((zero, i) => ({xxxx: i}));\n  }\n\n  test('_getScaleDistanceAndAdjustedDomain', () => {\n    const FAKE_DATA = generateFakeData();\n    const scaleObject = {\n      attr: 'x',\n      domain: [0, 100],\n      range: [0, 1],\n      type: 'linear',\n      // the extra x's are here to test the accessor behaviour\n      accessor: d => d.xxxx\n    };\n    const resultObject = _getScaleDistanceAndAdjustedDomain(\n      FAKE_DATA,\n      scaleObject\n    );\n    const expectedResults = {\n      distance: 0.009900990099009799,\n      domain0: -0.5,\n      domainN: 100.5\n    };\n    expect(resultObject).toEqual(expectedResults);\n\n    const FAKE_TIME_DATA_WITH_ONE_VALUE_AND_X0 = [\n      {\n        x: 1422774000000,\n        x0: 1420095600000,\n        y: 16\n      }\n    ];\n\n    const FAKE_TIME_DATA_WITH_ONE_VALUE_AND_Y0 = [\n      {\n        x: 16,\n        y0: 1420095600000,\n        y: 1422774000000\n      }\n    ];\n\n    const timeScaleObjectX = {\n      attr: 'x',\n      domain: [1417546800000, 1430420400000],\n      range: [0, 550],\n      type: 'time',\n      accessor: d => d.x,\n      accessor0: d => d.x0\n    };\n    const timeResultWithOneValueAndX0 = _getScaleDistanceAndAdjustedDomain(\n      FAKE_TIME_DATA_WITH_ONE_VALUE_AND_X0,\n      timeScaleObjectX\n    );\n    const expectedTimeResultsWithOneValueAndX0 = {\n      distance: 94.72222222222223,\n      domain0: 1416207600000,\n      domainN: 1431759600000\n    };\n    expect(timeResultWithOneValueAndX0).toEqual(\n      expectedTimeResultsWithOneValueAndX0\n    );\n\n    const timeScaleObjectY = {\n      attr: 'y',\n      domain: [1417546800000, 1430420400000],\n      range: [0, 550],\n      type: 'time',\n      accessor: d => d.y,\n      accessor0: d => d.y0\n    };\n    const timeResultWithOneValueAndY0 = _getScaleDistanceAndAdjustedDomain(\n      FAKE_TIME_DATA_WITH_ONE_VALUE_AND_Y0,\n      timeScaleObjectY\n    );\n    const expectedTimeResultsWithOneValueAndY0 = {\n      distance: 94.72222222222223,\n      domain0: 1416207600000,\n      domainN: 1431759600000\n    };\n    expect(timeResultWithOneValueAndY0).toEqual(\n      expectedTimeResultsWithOneValueAndY0\n    );\n\n    const timeResult = _getScaleDistanceAndAdjustedDomain(FAKE_DATA, {\n      ...timeScaleObjectX,\n      accessor: d => d.xxxx\n    });\n    const expectedTimeResults = {\n      distance: 4.272442311048508e-8,\n      domain0: 1417546799999.5,\n      domainN: 1430420400000.5\n    };\n    expect(timeResult).toEqual(expectedTimeResults);\n\n    const logScaleObject = {\n      attr: 'x',\n      domain: [-0.5, 1],\n      range: [1, 10],\n      type: 'log',\n      accessor: d => d.xxxx\n    };\n    const logResult = _getScaleDistanceAndAdjustedDomain(\n      FAKE_DATA,\n      logScaleObject\n    );\n    const expectedLogResults = {distance: NaN, domain0: 0.1, domainN: 1.5};\n    expect(logResult).toEqual(expectedLogResults);\n  });\n\n  test('getXYPlotValues', () => {\n    const XYPlotProps = {\n      colorType: 'linear',\n      colorRange: ['#000', '#fff'],\n      colorDomain: [0, 1]\n    };\n    const children = [\n      {props: {color: 0}},\n      {props: {color: 0.5, opacity: '0.5'}},\n      {props: {color: 1}}\n    ];\n    const result = getXYPlotValues(XYPlotProps, children);\n    expect(result[2]._colorValue).toBe('rgb(255, 255, 255)');\n    expect(result[1]._opacityValue).toBe('0.5');\n  });\n\n  test('_adjustCategoricalScale', () => {\n    [\n      {\n        scale: {type: 'category', domain: ['a', 'b', 'c'], range: [0, 10]},\n        distance: 10\n      },\n      {\n        scale: {type: 'category', domain: ['a'], range: [1, 10]},\n        distance: 9\n      },\n      {\n        scale: {type: 'ordinal', domain: ['a', 'b', 'c', 'd'], range: [10, 0]},\n        distance: 2.5\n      },\n      {\n        scale: {type: 'ordinal', domain: ['a'], range: [10, 1]},\n        distance: 9\n      }\n    ].forEach(({scale, distance}) => {\n      expect(_adjustCategoricalScale(scale)).toEqual({...scale, distance});\n    });\n  });\n\n  test('getOptionalScaleProps', () => {\n    const foundProps = getOptionalScaleProps({node: 1, x: 2, margins: 4});\n    expect(foundProps).toEqual({});\n\n    const paddingProps = getOptionalScaleProps({\n      node: 1,\n      x: 2,\n      margins: 4,\n      coolDogExplosionPadding: 10\n    });\n    expect(paddingProps).toEqual({coolDogExplosionPadding: 10});\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/utils/series-utils.test.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {mount} from 'enzyme';\n\nimport {\n  isSeriesChild,\n  getSeriesPropsFromChildren,\n  getSeriesChildren,\n  getStackedData\n} from 'utils/series-utils';\nimport LineSeries from 'plot/series/line-series';\nimport XAxis from 'plot/axis/x-axis';\nimport HorizontalBarSeries from 'plot/series/horizontal-rect-series';\nimport VerticalBarSeries from 'plot/series/vertical-rect-series';\nimport LabelSeries from 'plot/series/label-series';\n\ndescribe('series-utils', () => {\n  test('isSeriesChild', () => {\n    const series = <LineSeries data={[]} />;\n    expect(isSeriesChild(series)).toBeTruthy();\n    const axis = (\n      <XAxis\n        xRange={[0, 1]}\n        xDomain={[0, 1]}\n        xType=\"linear\"\n        width={100}\n        height={100}\n        top={0}\n        left={0}\n      />\n    );\n    expect(isSeriesChild(axis)).toBeFalsy();\n  });\n\n  test('getSeriesChildren', () => {\n    const children = [\n      <text key=\"wild\"> This squid is heavy </text>,\n      <circle key=\"wacky\" cx=\"50\" cy=\"50\" r=\"50\" />,\n      <LineSeries key=\"woah\" data={[]} />\n    ];\n    const $ = mount(\n      <svg width={300} height={300}>\n        {children}\n      </svg>\n    );\n    const expectedChildren = [{...children[2], key: '.$woah'}];\n    expect(getSeriesChildren($.props().children)).toEqual(expectedChildren);\n  });\n\n  const arePropsValid = seriesProps => {\n    return (\n      typeof seriesProps._colorValue !== 'undefined' &&\n      typeof seriesProps._opacityValue !== 'undefined' &&\n      typeof seriesProps.sameTypeIndex === 'number' &&\n      typeof seriesProps.sameTypeTotal === 'number' &&\n      typeof seriesProps.seriesIndex === 'number'\n    );\n  };\n\n  test('collectSeriesTypesInfo', () => {\n    const result = getSeriesPropsFromChildren([\n      <LineSeries data={[]} />,\n      <LineSeries data={[]} />\n    ]);\n    expect(result.length === 2).toBeTruthy();\n    result.forEach(props => expect(arePropsValid(props)).toBeTruthy());\n  });\n\n  test('seriesClusterProps', () => {\n    const result = getSeriesPropsFromChildren([\n      <HorizontalBarSeries cluster=\"alpha\" data={[]} />,\n      <HorizontalBarSeries cluster=\"beta\" data={[]} />,\n      <HorizontalBarSeries cluster=\"alpha\" data={[]} />,\n      <HorizontalBarSeries cluster=\"gamma\" data={[]} />\n    ]);\n    const expectedClusters = ['alpha', 'beta', 'gamma'];\n    expect(result.length === 4).toBeTruthy();\n    result.forEach(props => {\n      expect(\n        props.sameTypeIndex === expectedClusters.indexOf(props.cluster)\n      ).toBeTruthy();\n      expect(props.sameTypeTotal === props.clusters.length).toBeTruthy();\n      expect(props.clusters.length === 3).toBeTruthy();\n    });\n  });\n\n  // eslint-disable-next-line max-statements\n  test('getStackedData', () => {\n    const yData = [\n      [\n        {y: 2, x: 10},\n        {y: 4, x: 5},\n        {y: 5, x: 15}\n      ],\n      [\n        {y: 2, x: 12},\n        {y: 4, x: 2},\n        {y: 5, x: 11}\n      ]\n    ];\n\n    const stackByYExpected = [\n      [\n        {x: 2, y: 10},\n        {x: 4, y: 5},\n        {x: 5, y: 15}\n      ],\n      [\n        {x: 2, y: 22, y0: 10},\n        {x: 4, y: 7, y0: 5},\n        {x: 5, y: 26, y0: 15}\n      ],\n      undefined\n    ];\n\n    const stackByXExpected = [\n      [\n        {y: 2, x: 10},\n        {y: 4, x: 5},\n        {y: 5, x: 15}\n      ],\n      [\n        {y: 2, x: 22, x0: 10},\n        {y: 4, x: 7, x0: 5},\n        {y: 5, x: 26, x0: 15}\n      ],\n      null\n    ];\n\n    const stackByYExpectedPartial = [\n      [\n        {x: 2, y: 10},\n        {x: 4, y: 5}\n      ],\n      [\n        {x: 4, y: 7, y0: 5},\n        {x: 5, y: 11}\n      ]\n    ];\n\n    const stackByXExpectedPartial = [\n      [\n        {y: 2, x: 10},\n        {y: 4, x: 5}\n      ],\n      [\n        {y: 4, x: 7, x0: 5},\n        {y: 5, x: 11}\n      ]\n    ];\n\n    // Transpose data to flip stacking\n    const xData = yData.map(arr => arr.map(d => ({x: d.y, y: d.x})));\n\n    const partialYData = [yData[0].slice(0, 2), yData[1].slice(1)];\n    const partialXData = partialYData.map(arr =>\n      arr.map(d => ({x: d.y, y: d.x}))\n    );\n\n    let children = [\n      <VerticalBarSeries data={xData[0]} />,\n      <VerticalBarSeries data={xData[1]} />,\n      <div> i think i will by that lamp </div>\n    ];\n\n    let results = getStackedData(children, 'y');\n    expect(results).toEqual(stackByYExpected);\n\n    children = [\n      <HorizontalBarSeries data={yData[0]} />,\n      <HorizontalBarSeries data={yData[1]} />,\n      null\n    ];\n    results = getStackedData(children, 'x');\n\n    expect(results).toEqual(stackByXExpected);\n\n    children = [\n      <HorizontalBarSeries cluster=\"alpha\" data={yData[0]} />,\n      <HorizontalBarSeries cluster=\"alpha\" data={yData[1]} />,\n      <HorizontalBarSeries cluster=\"beta\" data={yData[0]} />,\n      <HorizontalBarSeries cluster=\"beta\" data={yData[1]} />\n    ];\n    results = getStackedData(children, 'x');\n    let expectedResults = [\n      ...stackByXExpected.slice(0, 2),\n      ...stackByXExpected.slice(0, 2)\n    ];\n\n    expect(results).toEqual(expectedResults);\n\n    children = [\n      <VerticalBarSeries cluster=\"alpha\" data={xData[0]} />,\n      <VerticalBarSeries cluster=\"alpha\" data={xData[1]} />,\n      <VerticalBarSeries cluster=\"beta\" data={xData[0]} />,\n      <VerticalBarSeries cluster=\"beta\" data={xData[1]} />\n    ];\n    results = getStackedData(children, 'y');\n    expectedResults = [\n      ...stackByYExpected.slice(0, 2),\n      ...stackByYExpected.slice(0, 2)\n    ];\n    expect(results).toEqual(expectedResults);\n\n    children = [\n      <HorizontalBarSeries cluster=\"alpha\" data={partialYData[0]} />,\n      <HorizontalBarSeries cluster=\"alpha\" data={partialYData[1]} />,\n      <HorizontalBarSeries cluster=\"beta\" data={partialYData[0]} />,\n      <HorizontalBarSeries cluster=\"beta\" data={partialYData[1]} />\n    ];\n    results = getStackedData(children, 'x');\n    expectedResults = [...stackByXExpectedPartial, ...stackByXExpectedPartial];\n    expect(results).toEqual(expectedResults);\n\n    children = [\n      <VerticalBarSeries cluster=\"alpha\" data={partialXData[0]} />,\n      <VerticalBarSeries cluster=\"alpha\" data={partialXData[1]} />,\n      <VerticalBarSeries cluster=\"beta\" data={partialXData[0]} />,\n      <VerticalBarSeries cluster=\"beta\" data={partialXData[1]} />\n    ];\n    results = getStackedData(children, 'y');\n    expectedResults = [...stackByYExpectedPartial, ...stackByYExpectedPartial];\n\n    expect(results).toEqual(expectedResults);\n\n    children = [\n      <VerticalBarSeries data={yData[0]} stack />,\n      <VerticalBarSeries\n        data={[\n          {x: 10, y: 3},\n          {x: 5, y: 6},\n          {x: 15, y: 7}\n        ]}\n        stack\n      />,\n      <LineSeries data={yData[1]} />\n    ];\n    results = getStackedData(children, 'y');\n    expectedResults = [\n      yData[0],\n      [\n        {x: 10, y: 5, y0: 2},\n        {x: 5, y: 10, y0: 4},\n        {x: 15, y: 12, y0: 5}\n      ],\n      yData[1]\n    ];\n    expect(results).toEqual(expectedResults);\n\n    children = [\n      <VerticalBarSeries cluster=\"alpha\" data={xData[0]} stack />,\n      <VerticalBarSeries cluster=\"alpha\" data={xData[1]} stack />,\n      <VerticalBarSeries cluster=\"beta\" data={xData[0]} stack />,\n      <VerticalBarSeries cluster=\"beta\" data={xData[1]} stack />,\n      <LineSeries data={xData[1]} />\n    ];\n    results = getStackedData(children, 'y');\n    expectedResults = [\n      ...stackByYExpected.slice(0, 2),\n      ...stackByYExpected.slice(0, 2),\n      xData[1]\n    ];\n    expect(results).toEqual(expectedResults);\n\n    children = [\n      <VerticalBarSeries data={xData[0]} />,\n      <VerticalBarSeries data={xData[1]} />,\n      <LabelSeries data={xData[0]} />,\n      <LabelSeries data={xData[1]} />\n    ];\n    results = getStackedData(children, 'y');\n    expectedResults = [\n      ...stackByYExpected.slice(0, 2),\n      ...stackByYExpected.slice(0, 2)\n    ];\n\n    expect(results).toEqual(expectedResults);\n  });\n});\n"
  },
  {
    "path": "packages/react-vis/tests/utils/styling-utils.test.js",
    "content": "// Copyright (c) 2016 - 2019 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport {getCombinedClassName} from 'utils/styling-utils';\n\ndescribe('styling-utils', () => {\n  test('getCombinedClassName', () => {\n    const allValidStringParams = [\n      'test_class--1',\n      'test_class--2',\n      'test_class--3'\n    ];\n    const expectedAllValidStringParamsCombined =\n      'test_class--1 test_class--2 test_class--3';\n    const falsyValues = [null, undefined, false, '', 0, NaN];\n    const nonStringValues = [\n      ['invalid_class--1', 'invalid_class--2'],\n      {foo: 'bar'},\n      123,\n      () => {\n        return 'invalid_class--3';\n      }\n    ];\n\n    expect(getCombinedClassName(...allValidStringParams)).toBe(\n      expectedAllValidStringParamsCombined\n    );\n\n    expect(getCombinedClassName(...allValidStringParams, ...falsyValues)).toBe(\n      expectedAllValidStringParamsCombined\n    );\n\n    expect(\n      getCombinedClassName(...allValidStringParams, ...nonStringValues)\n    ).toBe(expectedAllValidStringParamsCombined);\n  });\n});\n"
  },
  {
    "path": "packages/showcase/.babelrc.json",
    "content": "{\n  \"plugins\": [\n    [\"module-resolver\", {\n      \"root\": [\".\"],\n      \"alias\": {\n        \"react-vis/*\": \"../react-vis/src/*\",\n        \"react-vis\": \"../react-vis/src\"\n      }\n    }]\n  ]\n}\n"
  },
  {
    "path": "packages/showcase/app.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport ReactDOM from 'react-dom';\nimport React from 'react';\nimport document from 'global/document';\n\nimport {BrowserRouter, Route} from 'react-router-dom';\n\nimport ShowcaseApp from './showcase-app';\nimport '../react-vis/src/styles/examples.scss';\n\nexport default function App() {\n  // using react-router to trigger react updates on url change\n  return (\n    <BrowserRouter>\n      <Route path=\"/\" component={ShowcaseApp} />\n    </BrowserRouter>\n  );\n}\n\nconst el = document.createElement('div');\ndocument.body.appendChild(el);\n\nReactDOM.render(<App />, el);\n"
  },
  {
    "path": "packages/showcase/axes/axis-on-0.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries\n} from 'react-vis';\n\nexport default function AxisOn0({\n  xDomain = [-1, 3],\n  yDomain = [-5, 15],\n  xAxisOn0 = true,\n  yAxisOn0 = true,\n  verticalTickValues = [],\n  horizontalTickValues = [0]\n}) {\n  return (\n    <XYPlot width={300} height={300} {...{xDomain, yDomain}}>\n      {!verticalTickValues || verticalTickValues.length ? (\n        <VerticalGridLines tickValues={verticalTickValues} />\n      ) : null}\n      {!horizontalTickValues || horizontalTickValues.length ? (\n        <HorizontalGridLines tickValues={horizontalTickValues} />\n      ) : null}\n      <XAxis on0={xAxisOn0} />\n      <YAxis on0={yAxisOn0} />\n      <LineSeries\n        data={[\n          {x: -1, y: 10},\n          {x: 0, y: 5},\n          {x: 1, y: 3},\n          {x: 2, y: -5},\n          {x: 3, y: 15}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/axes/custom-axes-orientation.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  HorizontalGridLines,\n  VerticalGridLines,\n  LineSeries\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot\n      margin={{top: 40, right: 40, left: 10, bottom: 10}}\n      width={300}\n      height={300}\n    >\n      <HorizontalGridLines />\n      <VerticalGridLines />\n      <XAxis orientation=\"top\" title=\"X Axis\" />\n      <YAxis orientation=\"right\" title=\"Y Axis\" />\n      <LineSeries\n        data={[\n          {x: 1, y: 3, z: 10},\n          {x: 2, y: 4, z: 10},\n          {x: 3, y: 8, z: 10},\n          {x: 4, y: 11, z: 10}\n        ]}\n      />\n      <LineSeries data={null} />\n      <LineSeries\n        data={[\n          {x: 1, y: 3, z: 10},\n          {x: 2, y: 9, z: 10},\n          {x: 3, y: 2, z: 10},\n          {x: 4, y: 11, z: 10}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/axes/custom-axes.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {XYPlot, XAxis, YAxis, MarkSeries} from 'react-vis';\n\nconst MARGIN = {\n  left: 10,\n  right: 10,\n  bottom: 80,\n  top: 20\n};\n\nconst WORDS = [\n  'cool',\n  'dog',\n  'skateboard',\n  'wow',\n  'such',\n  <tspan key=\"tspan\">\n    <tspan x=\"0\" dy=\"1em\">\n      Multiline\n    </tspan>\n    <tspan x=\"0\" dy=\"1em\">\n      dogs\n    </tspan>\n  </tspan>\n];\nexport default function Example() {\n  return (\n    <XYPlot margin={MARGIN} width={300} height={300}>\n      <XAxis top={0} hideLine tickValues={[0, 1, 3, 4, 5]} title=\"X\" />\n      <XAxis tickFormat={v => `Value is ${v}`} tickLabelAngle={-90} />\n      <YAxis hideTicks />\n      <YAxis left={50} tickFormat={v => v * v} />\n      <YAxis hideLine left={150} tickFormat={v => WORDS[v]} />\n      <MarkSeries\n        data={[\n          {x: 0, y: 0},\n          {x: 5, y: 5}\n        ]}\n        opacity={0}\n        opacityType=\"linear\"\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/axes/custom-axis-tick-element.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  state = {\n    data: [\n      {x: 0, y: 100, label: <circle cx={0} cy={10} r={5} fill=\"darksalmon\" />},\n      {\n        x: 1,\n        y: 200,\n        label: <rect x={-5} y={5} width={10} height={10} fill=\"slateblue\" />\n      },\n      {x: 2, y: 500, label: <tspan>Label</tspan>},\n      {x: 3, y: 900, label: <path d=\"M0 5 L5 15 L-5 15 Z\" fill=\"sandybrown\" />},\n      {x: 4, y: 1000, label: 'Label'}\n    ]\n  };\n\n  formatX = (v, i) => {\n    if (i < this.state.data.length) {\n      return this.state.data[i].label;\n    }\n    return null;\n  };\n\n  render() {\n    return (\n      <XYPlot\n        width={300}\n        height={300}\n        xDomain={[0, 4]}\n        yDomain={[0, 1000]}\n        margin={{top: 10, right: 10, left: 60, bottom: 40}}\n      >\n        <VerticalGridLines />\n        <HorizontalGridLines />\n        <XAxis tickTotal={this.state.data.length} tickFormat={this.formatX} />\n        <YAxis />\n        <LineSeries data={this.state.data} />\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/axes/custom-axis-tick-format.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  static _xTickFormatValue(v, i, scale, tickTotal) {\n    // format axis tick with SI prefix (e.g. ms, µs)\n    // see https://github.com/d3/d3-scale#continuous_tickFormat\n    // and https://github.com/d3/d3-format#locale_format\n    return `${scale.tickFormat(tickTotal, 's')(v)}s`;\n  }\n\n  static _yTickFormatValue(v, i, scale, tickTotal) {\n    // format axis tick with SI prefix (e.g. kWh, MWh)\n    return `${scale.tickFormat(tickTotal, 's')(v)}Wh`;\n  }\n\n  render() {\n    const data = [\n      {x: 0.042, y: 100},\n      {x: 0.051, y: 1200},\n      {x: 0.063, y: 1600},\n      {x: 0.07, y: 1300},\n      {x: 0.073, y: 1220}\n    ];\n    const xMin = Math.min(...data.map(e => e.x));\n    const xMax = Math.max(...data.map(e => e.x));\n    const yMin = 0;\n    const yMax = Math.max(...data.map(e => e.y));\n\n    return (\n      <XYPlot\n        width={300}\n        height={300}\n        xType=\"linear\"\n        xDomain={[xMin, xMax]}\n        yType=\"linear\"\n        yDomain={[yMin, yMax]}\n        margin={{top: 10, right: 10, left: 60, bottom: 40}}\n      >\n        <VerticalGridLines />\n        <HorizontalGridLines />\n        <XAxis tickFormat={Example._xTickFormatValue} />\n        <YAxis tickFormat={Example._yTickFormatValue} />\n        <LineSeries data={data} />\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/axes/custom-axis.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries\n} from 'react-vis';\n\nexport default function Example() {\n  const axisStyle = {\n    ticks: {\n      fontSize: '14px',\n      color: '#333'\n    },\n    title: {\n      fontSize: '16px',\n      color: '#333'\n    }\n  };\n\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis\n        hideLine\n        title=\"X\"\n        labelFormat={v => `Value is ${v}`}\n        labelValues={[2]}\n        tickValues={[1, 1.5, 2, 3]}\n        style={axisStyle}\n      />\n      <YAxis hideTicks />\n      <LineSeries\n        data={[\n          {x: 1, y: 10},\n          {x: 2, y: 5},\n          {x: 3, y: 15}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/axes/decorative-axes-criss-cross.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {XYPlot, DecorativeAxis} from 'react-vis';\n\nconst MARGIN = {\n  left: 30,\n  right: 30,\n  top: 30,\n  bottom: 30\n};\n\nexport default function Example() {\n  return (\n    <XYPlot\n      dontCheckIfEmpty\n      margin={MARGIN}\n      xDomain={[0, 1]}\n      yDomain={[0, 1]}\n      width={300}\n      height={300}\n    >\n      <DecorativeAxis\n        axisStart={{x: 0, y: 0}}\n        axisEnd={{x: 1, y: 1}}\n        axisDomain={[-10, 100]}\n      />\n      <DecorativeAxis\n        axisStart={{x: 1, y: 0}}\n        axisEnd={{x: 0, y: 1}}\n        axisDomain={[1000, 900]}\n        tickSize={-10}\n        tickValue={t => `¡${t}!`}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/axes/dynamic-complex-edge-hints.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries,\n  MarkSeries,\n  Hint\n} from 'react-vis';\n\nconst {LEFT, TOP, BOTTOM_EDGE, LEFT_EDGE, RIGHT_EDGE, TOP_EDGE} = Hint.ALIGN;\n\nconst CHART_MARGINS = {left: 30, right: 10, top: 10, bottom: 25};\nconst XMIN = 1;\nconst XMAX = 4;\nconst YMIN = 5;\nconst YMAX = 15;\nconst DATA = [\n  {x: 1, y: 5},\n  {x: 2, y: 8},\n  {x: 3, y: 12},\n  {x: 4, y: 15}\n];\nconst POLE = [\n  [\n    {x: XMIN, y: DATA[0].y},\n    {x: XMAX, y: DATA[0].y}\n  ],\n  [\n    {x: DATA[1].x, y: DATA[1].y},\n    {x: DATA[1].x, y: YMAX}\n  ],\n  [\n    {x: DATA[2].x, y: YMIN},\n    {x: DATA[2].x, y: DATA[2].y}\n  ],\n  [\n    {x: XMIN, y: DATA[3].y},\n    {x: DATA[3].x, y: DATA[3].y}\n  ]\n];\nconst DATA_HINT_ALIGN = [\n  {\n    horizontal: RIGHT_EDGE,\n    vertical: TOP\n  },\n  {\n    horizontal: LEFT,\n    vertical: TOP_EDGE\n  },\n  {\n    horizontal: LEFT,\n    vertical: BOTTOM_EDGE\n  },\n  {\n    horizontal: LEFT_EDGE,\n    vertical: TOP\n  }\n];\n\nexport default class Example extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      value: null\n    };\n  }\n\n  _rememberValue = value => {\n    this.setState({value});\n  };\n\n  render() {\n    const {value} = this.state;\n    return (\n      <div className=\"complex-hint\">\n        <XYPlot width={300} height={300} margin={CHART_MARGINS}>\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <MarkSeries onNearestX={this._rememberValue} data={DATA} />\n          {value ? (\n            <LineSeries data={POLE[value.x - 1]} stroke=\"black\" />\n          ) : null}\n          {value ? (\n            <Hint value={value} align={DATA_HINT_ALIGN[value.x - 1]}>\n              <div\n                className={`hint--text-container ${\n                  DATA_HINT_ALIGN[value.x - 1].horizontal\n                }-${DATA_HINT_ALIGN[value.x - 1].vertical}`}\n              >\n                <div className=\"hint--text\">{`(${value.x}, ${value.y})`}</div>\n              </div>\n              <div\n                className={`hint--pole ${\n                  DATA_HINT_ALIGN[value.x - 1].horizontal\n                }-${DATA_HINT_ALIGN[value.x - 1].vertical}`}\n              />\n            </Hint>\n          ) : null}\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/axes/dynamic-crosshair-scatterplot.js",
    "content": "// Copyright (c) 2016-2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {scaleLinear} from 'd3-scale';\n\nimport {\n  Crosshair,\n  HorizontalGridLines,\n  MarkSeries,\n  VerticalGridLines,\n  XAxis,\n  XYPlot,\n  YAxis,\n  Voronoi\n} from 'react-vis';\n\nconst DATA = [\n  {x: 1, y: 4, size: 9},\n  {x: 1, y: 5, size: 18},\n  {x: 1, y: 10, size: 5},\n  {x: 1, y: 11, size: 29},\n  {x: 1, y: 13.9, size: 5},\n  {x: 1, y: 14, size: 8},\n  {x: 1.5, y: 11.8, size: 25},\n  {x: 1.7, y: 9, size: 30},\n  {x: 2, y: 5, size: 11},\n  {x: 2.1, y: 11.8, size: 28},\n  {x: 2.4, y: 7.9, size: 14},\n  {x: 2.4, y: 13.5, size: 20},\n  {x: 2.7, y: 13.7, size: 14},\n  {x: 2.9, y: 7.7, size: 26},\n  {x: 3, y: 5.4, size: 6}\n].map((d, id) => ({...d, id}));\n\nconst getDomain = (data, key) => {\n  const {min, max} = data.reduce(\n    (acc, row) => ({\n      min: Math.min(acc.min, row[key]),\n      max: Math.max(acc.max, row[key])\n    }),\n    {min: Infinity, max: -Infinity}\n  );\n  return [min, max];\n};\n\n// magic numbers chosen for design\nconst sizeRange = [5, 13];\nconst margin = {top: 10, left: 40, bottom: 40, right: 10};\nconst width = 300;\nconst height = 300;\n\n// Intentionally using explicit sales here to show another way of using the voronoi\nconst x = scaleLinear()\n  .domain(getDomain(DATA, 'x'))\n  .range([0, width]);\nconst y = scaleLinear()\n  .domain(getDomain(DATA, 'y'))\n  .range([height, 0]);\n\nexport default class Example extends React.Component {\n  state = {\n    selectedPointId: null,\n    showVoronoi: true\n  };\n\n  render() {\n    const {crosshairValues, selectedPointId, showVoronoi} = this.state;\n\n    return (\n      <div>\n        <label style={{display: 'block'}}>\n          <input\n            type=\"checkbox\"\n            checked={showVoronoi}\n            onChange={() => this.setState({showVoronoi: !showVoronoi})}\n          />\n          Show Voronoi\n        </label>\n        <XYPlot\n          onMouseLeave={() =>\n            this.setState({selectedPointId: null, crosshairValues: null})\n          }\n          width={width}\n          height={height}\n        >\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <MarkSeries\n            className=\"mark-series-example\"\n            colorType=\"literal\"\n            data={DATA}\n            onNearestXY={(value, {index}) =>\n              this.setState({\n                selectedPointId: index,\n                crosshairValues: [value]\n              })\n            }\n            getColor={({id}) =>\n              selectedPointId === id ? '#FF9833' : '#12939A'\n            }\n            sizeRange={sizeRange}\n          />\n          {crosshairValues && <Crosshair values={crosshairValues} />}\n          {showVoronoi && (\n            <Voronoi\n              extent={[\n                [margin.left, margin.top],\n                [width - margin.right, height - margin.bottom]\n              ]}\n              nodes={DATA}\n              polygonStyle={{stroke: 'rgba(0, 0, 0, .2)'}}\n              x={d => x(d.x)}\n              y={d => y(d.y)}\n            />\n          )}\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/axes/dynamic-crosshair.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries,\n  Crosshair\n} from 'react-vis';\n\nconst DATA = [\n  [\n    {x: 1, y: 10},\n    {x: 2, y: 7},\n    {x: 3, y: 15}\n  ],\n  [\n    {x: 1, y: 20},\n    {x: 2, y: 5},\n    {x: 3, y: 15}\n  ]\n];\n\nexport default class DynamicCrosshair extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      crosshairValues: []\n    };\n  }\n\n  /**\n   * Event handler for onMouseLeave.\n   * @private\n   */\n  _onMouseLeave = () => {\n    this.setState({crosshairValues: []});\n  };\n\n  /**\n   * Event handler for onNearestX.\n   * @param {Object} value Selected value.\n   * @param {index} index Index of the value in the data array.\n   * @private\n   */\n  _onNearestX = (value, {index}) => {\n    this.setState({crosshairValues: DATA.map(d => d[index])});\n  };\n\n  render() {\n    return (\n      <XYPlot onMouseLeave={this._onMouseLeave} width={300} height={300}>\n        <VerticalGridLines />\n        <HorizontalGridLines />\n        <XAxis />\n        <YAxis />\n        <LineSeries onNearestX={this._onNearestX} data={DATA[0]} />\n        <LineSeries data={DATA[1]} />\n        <Crosshair\n          values={this.state.crosshairValues}\n          className={'test-class-name'}\n        />\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/axes/dynamic-hints.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  MarkSeries,\n  Hint\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      value: null\n    };\n  }\n\n  _forgetValue = () => {\n    this.setState({\n      value: null\n    });\n  };\n\n  _rememberValue = value => {\n    this.setState({value});\n  };\n\n  render() {\n    const {value} = this.state;\n    return (\n      <XYPlot width={300} height={300}>\n        <VerticalGridLines />\n        <HorizontalGridLines />\n        <XAxis />\n        <YAxis />\n        <MarkSeries\n          onValueMouseOver={this._rememberValue}\n          onValueMouseOut={this._forgetValue}\n          data={[\n            {x: 1, y: 10},\n            {x: 2, y: 5},\n            {x: 3, y: 15}\n          ]}\n        />\n        {value ? <Hint value={value} /> : null}\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/axes/dynamic-programmatic-rightedge-hints.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries,\n  MarkSeries,\n  Hint\n} from 'react-vis';\n\nconst CHART_MARGINS = {left: 50, right: 10, top: 10, bottom: 25};\nconst DATA = [\n  {x: 1, y: 5},\n  {x: 2, y: 12},\n  {x: 3, y: 8},\n  {x: 4, y: 15}\n];\nconst XMAX = 4;\n\nfunction getAlignStyle(align, x, y) {\n  return {\n    right: 0,\n    top: CHART_MARGINS.top + y\n  };\n}\n\nexport default class Example extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      value: null\n    };\n  }\n\n  _rememberValue = value => {\n    this.setState({value});\n  };\n\n  render() {\n    const {value} = this.state;\n    return (\n      <XYPlot width={300} height={300} margin={CHART_MARGINS}>\n        <VerticalGridLines />\n        <HorizontalGridLines />\n        <XAxis />\n        <YAxis />\n        <MarkSeries onNearestX={this._rememberValue} data={DATA} />\n        {value ? (\n          <LineSeries\n            data={[\n              {x: value.x, y: value.y},\n              {x: XMAX, y: value.y}\n            ]}\n            stroke=\"black\"\n          />\n        ) : null}\n        {value ? (\n          <Hint value={value} getAlignStyle={getAlignStyle}>\n            <div className=\"rv-hint__content\">{`(${value.x}, ${value.y})`}</div>\n          </Hint>\n        ) : null}\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/axes/dynamic-simple-edge-hints.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  MarkSeries,\n  Hint\n} from 'react-vis';\n\nconst {LEFT, RIGHT, TOP, BOTTOM_EDGE, RIGHT_EDGE, TOP_EDGE} = Hint.ALIGN;\nconst CHART_MARGINS = {left: 50, right: 10, top: 10, bottom: 25};\nconst DATA = [\n  {x: 1, y: 5},\n  {x: 2, y: 10},\n  {x: 3, y: 10},\n  {x: 4, y: 15}\n];\nconst DATA_HINT_ALIGN = [\n  {\n    horizontal: RIGHT_EDGE,\n    vertical: TOP\n  },\n  {\n    horizontal: RIGHT,\n    vertical: BOTTOM_EDGE\n  },\n  {\n    horizontal: LEFT,\n    vertical: TOP_EDGE\n  },\n  {\n    horizontal: LEFT,\n    vertical: BOTTOM_EDGE\n  }\n];\n\nexport default class Example extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      value: null\n    };\n  }\n\n  _rememberValue = value => {\n    this.setState({value});\n  };\n\n  render() {\n    const {value} = this.state;\n    return (\n      <XYPlot width={300} height={300} margin={CHART_MARGINS}>\n        <VerticalGridLines />\n        <HorizontalGridLines />\n        <XAxis />\n        <YAxis />\n        <MarkSeries onNearestX={this._rememberValue} data={DATA} />\n        {value ? (\n          <Hint value={value} align={DATA_HINT_ALIGN[value.x - 1]}>\n            <div className=\"rv-hint__content\">\n              {`(${value.x}, ${value.y})`}\n              <br />\n              {`${DATA_HINT_ALIGN[value.x - 1].horizontal}-${\n                DATA_HINT_ALIGN[value.x - 1].vertical\n              }`}\n            </div>\n          </Hint>\n        ) : null}\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/axes/dynamic-simple-topedge-hints.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries,\n  MarkSeries,\n  Hint\n} from 'react-vis';\n\nconst CHART_MARGINS = {left: 50, right: 10, top: 10, bottom: 25};\nconst DATA = [\n  {x: 1, y: 5},\n  {x: 2, y: 10},\n  {x: 3, y: 10},\n  {x: 4, y: 15}\n];\nconst YMAX = 15;\n\nexport default class Example extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      value: null\n    };\n  }\n\n  _rememberValue = value => {\n    this.setState({value});\n  };\n\n  render() {\n    const {value} = this.state;\n    return (\n      <XYPlot width={300} height={300} margin={CHART_MARGINS}>\n        <VerticalGridLines />\n        <HorizontalGridLines />\n        <XAxis />\n        <YAxis />\n        <MarkSeries onNearestX={this._rememberValue} data={DATA} />\n        {value ? (\n          <LineSeries\n            data={[\n              {x: value.x, y: value.y},\n              {x: value.x, y: YMAX}\n            ]}\n            stroke=\"black\"\n          />\n        ) : null}\n        {value ? (\n          <Hint\n            value={value}\n            align={{horizontal: Hint.ALIGN.AUTO, vertical: Hint.ALIGN.TOP_EDGE}}\n          >\n            <div className=\"rv-hint__content\">{`(${value.x}, ${value.y})`}</div>\n          </Hint>\n        ) : null}\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/axes/empty-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines\n} from 'react-vis';\n\nexport default function EmptyChart() {\n  return (\n    <XYPlot\n      dontCheckIfEmpty\n      xDomain={[0, 3]}\n      yDomain={[10, 3]}\n      width={300}\n      height={300}\n    >\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis\n        hideLine\n        title=\"Empty Chart Right Here\"\n        tickFormat={v => `${v}!`}\n        tickValues={[1, 1.5, 2, 3]}\n      />\n      <YAxis hideTicks />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/axes/padded-axis.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  HorizontalGridLines,\n  VerticalGridLines,\n  LineSeries\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  getRandomData() {\n    const randomYData = [...new Array(100)].map(() =>\n      Math.round(Math.random() * 40)\n    );\n    return randomYData.map((val, idx) => {\n      return {x: idx, y: val};\n    });\n  }\n\n  render() {\n    const firstData = this.getRandomData();\n    const secondData = this.getRandomData();\n    return (\n      <div style={{display: 'flex'}}>\n        <XYPlot width={300} height={300}>\n          <HorizontalGridLines />\n          <VerticalGridLines />\n          <XAxis title=\"X Axis\" />\n          <YAxis title=\"Y Axis\" />\n          <LineSeries className=\"first-series\" data={firstData} />\n          <LineSeries className=\"second-series\" data={secondData} />\n        </XYPlot>\n        <XYPlot yPadding={60} width={300} height={300}>\n          <HorizontalGridLines />\n          <VerticalGridLines />\n          <XAxis title=\"X Axis\" />\n          <YAxis title=\"Y Axis\" />\n          <LineSeries className=\"first-series\" data={firstData} />\n          <LineSeries className=\"second-series\" data={secondData} />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/axes/parallel-coordinates-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {scaleLinear} from 'd3-scale';\n\nimport CarData from '../datasets/car-data.json';\n\nimport {XYPlot, DecorativeAxis, LineSeries} from 'react-vis';\n\nconst DEFAULT_DOMAIN = {min: Infinity, max: -Infinity};\n// begin by figuring out the domain of each of the columns\nconst domains = CarData.reduce((res, row) => {\n  Object.keys(row).forEach(key => {\n    if (!res[key]) {\n      res[key] = {...DEFAULT_DOMAIN};\n    }\n    res[key] = {\n      min: Math.min(res[key].min, row[key]),\n      max: Math.max(res[key].max, row[key])\n    };\n  });\n  return res;\n}, {});\n// use that to generate columns that map the data to a unit scale\nconst scales = Object.keys(domains).reduce((res, key) => {\n  const domain = domains[key];\n  res[key] = scaleLinear()\n    .domain([domain.min, domain.max])\n    .range([0, 1]);\n  return res;\n}, {});\n\n// break each object into an array and rescale it\nconst mappedData = CarData.map(row => {\n  return Object.keys(row)\n    .filter(key => key !== 'name')\n    .map(key => ({\n      x: key,\n      y: scales[key](Number(row[key]))\n    }));\n});\n\nconst MARGIN = {\n  left: 10,\n  right: 10,\n  top: 10,\n  bottom: 10\n};\n\nfunction ParallelCoordinatesExample() {\n  return (\n    <XYPlot\n      width={500}\n      height={300}\n      xType=\"ordinal\"\n      margin={MARGIN}\n      className=\"parallel-coordinates-example\"\n    >\n      {mappedData.map((series, index) => {\n        return <LineSeries data={series} key={`series-${index}`} />;\n      })}\n      {mappedData[0].map((cell, index) => {\n        return (\n          <DecorativeAxis\n            key={`${index}-axis`}\n            axisStart={{x: cell.x, y: 0}}\n            axisEnd={{x: cell.x, y: 1}}\n            axisDomain={[domains[cell.x].min, domains[cell.x].max]}\n          />\n        );\n      })}\n    </XYPlot>\n  );\n}\n\nexport default ParallelCoordinatesExample;\n"
  },
  {
    "path": "packages/showcase/axes/static-crosshair.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries,\n  Crosshair\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis />\n      <YAxis />\n      <LineSeries\n        data={[\n          {x: 1, y: 10},\n          {x: 2, y: 7},\n          {x: 3, y: 15}\n        ]}\n      />\n      <LineSeries\n        data={[\n          {x: 1, y: 20},\n          {x: 2, y: 5},\n          {x: 3, y: 15}\n        ]}\n      />\n      <Crosshair\n        values={[\n          {x: 2, y: 5},\n          {x: 2, y: 7}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/axes/static-hints.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries,\n  Hint\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis />\n      <YAxis />\n      <LineSeries\n        data={[\n          {x: 0, y: 1},\n          {x: 1, y: 10},\n          {x: 2, y: 5},\n          {x: 3, y: 15}\n        ]}\n      />\n      <Hint value={{x: 1, y: 10}} />\n      <Hint\n        value={{x: 0.4, y: 14}}\n        horizontalAlign={Hint.ALIGN.RIGHT}\n        verticalAlign={Hint.ALIGN.BOTTOM}\n      >\n        <div className=\"custom-hint\">\n          This is a custom hint\n          <br />\n          for a non-existent value\n        </div>\n      </Hint>\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/color/line-chart-many-colors.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  HorizontalGridLines,\n  VerticalGridLines,\n  LineSeries\n} from 'react-vis';\n\nconst data = [];\n\nfor (let i = 0; i < 20; i++) {\n  const series = [];\n  for (let j = 0; j < 100; j++) {\n    series.push({x: j, y: (i / 10 + 1) * Math.sin((Math.PI * (i + j)) / 50)});\n  }\n  data.push({color: i, key: i, data: series, opacity: 0.8});\n}\n\nexport default function Example() {\n  return (\n    <XYPlot\n      width={300}\n      height={300}\n      colorType=\"linear\"\n      colorDomain={[0, 9]}\n      colorRange={['yellow', 'orange']}\n    >\n      <HorizontalGridLines />\n      <VerticalGridLines />\n      <XAxis />\n      <YAxis />\n      {data.map(({key, ...props}) => (\n        <LineSeries key={key} {...props} />\n      ))}\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/color/mini-color-examples.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the 'Software'), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  GradientDefs,\n  XYPlot,\n  LineSeries,\n  MarkSeries,\n  VerticalBarSeries\n} from 'react-vis';\n\nimport {\n  DISCRETE_COLOR_RANGE,\n  EXTENDED_DISCRETE_COLOR_RANGE,\n  CONTINUOUS_COLOR_RANGE\n} from '../../react-vis/src/theme';\n\nconst colors = [\n  '#cd3b54',\n  '#59b953',\n  '#ba4fb9',\n  '#99b53e',\n  '#7f61d3',\n  '#c9a83a',\n  '#626dbc',\n  '#e08b39',\n  '#5ea0d8',\n  '#cf4d2a',\n  '#4fb79b',\n  '#d24691',\n  '#528240',\n  '#c388d2',\n  '#80742b',\n  '#9c4a6d',\n  '#caaa70',\n  '#e0829f',\n  '#9d5d30',\n  '#dc7666'\n];\n\nconst data = {\n  noColor: [],\n  categoryColorAtSeriesLevel: [],\n  literalColorAtSeriesLevel: [],\n  linearColorAtSeriesLevel: [],\n  literalColorAtMarkLevel: [],\n  linearColorAtMarkLevel: [],\n  categoryColorAtMarkLevel: []\n};\n\nfor (let i = 0; i < 3; i++) {\n  const noColorSeries = [];\n  const categoryColorSeries = [];\n  const literalColorSeries = [];\n  const linearColorSeries = [];\n\n  for (let j = 0; j < 10; j++) {\n    const datapoint = {x: j, y: Math.random() * 10};\n    const categoryDatapoint = {\n      ...datapoint,\n      color: Math.floor(Math.random() * 20)\n    };\n    const linearDatapoint = {...datapoint, color: Math.random() * 10};\n    const literalDatapoint = {\n      ...datapoint,\n      color: colors[Math.floor(Math.random() * 20)]\n    };\n    noColorSeries.push(datapoint);\n    categoryColorSeries.push(categoryDatapoint);\n    literalColorSeries.push(literalDatapoint);\n    linearColorSeries.push(linearDatapoint);\n  }\n  data.noColor.push({key: i, data: noColorSeries});\n  data.categoryColorAtSeriesLevel.push({key: i, data: noColorSeries, color: i});\n  data.literalColorAtSeriesLevel.push({\n    key: i,\n    data: noColorSeries,\n    color: colors[i]\n  });\n  data.linearColorAtSeriesLevel.push({\n    key: i,\n    data: noColorSeries,\n    color: Math.floor(Math.random() * 20)\n  });\n  data.literalColorAtMarkLevel.push({key: i, data: literalColorSeries});\n  data.linearColorAtMarkLevel.push({key: i, data: linearColorSeries});\n  data.categoryColorAtMarkLevel.push({key: i, data: categoryColorSeries});\n}\n\nconst defaultXYPlotProps = {\n  width: 200,\n  height: 200,\n  xDomain: [-0.5, 9.5],\n  yDomain: [-0.5, 10.5],\n  margin: {top: 5, bottom: 5, left: 5, right: 5}\n};\n\nexport function SensibleDefaults() {\n  return generateCharts(data.noColor);\n}\n\nexport function ColorInXYPlot() {\n  return generateCharts(data.noColor, {color: 'red', stroke: 'red'});\n}\n\nexport function LiteralColorAtSeriesLevel() {\n  return generateCharts(data.literalColorAtSeriesLevel);\n}\n\nexport function LinearColorAtSeriesLevel() {\n  return generateCharts(data.linearColorAtSeriesLevel, {\n    colorType: 'linear',\n    colorDomain: [0, 9],\n    colorRange: CONTINUOUS_COLOR_RANGE\n  });\n}\n\nexport function CategoryColorAtSeriesLevel() {\n  return generateCharts(data.categoryColorAtSeriesLevel, {\n    colorType: 'category',\n    colorDomain: [0, 1, 2],\n    colorRange: EXTENDED_DISCRETE_COLOR_RANGE\n  });\n}\n\nexport function LiteralColorAtMarkLevel() {\n  return generateCharts(data.literalColorAtMarkLevel, {colorType: 'literal'});\n}\n\nexport function CategoryColorAtMarkLevel() {\n  return generateCharts(data.categoryColorAtMarkLevel, {colorType: 'category'});\n}\n\nexport function CategoryColorAtMarkLevelCustomPalette() {\n  return generateCharts(data.categoryColorAtMarkLevel, {\n    colorType: 'category',\n    colorRange: colors\n  });\n}\n\nexport function CategoryColorAtMarkLevelFixedStroke() {\n  return generateCharts(data.categoryColorAtMarkLevel, {\n    colorType: 'category',\n    stroke: '#f70'\n  });\n}\n\nexport function LinearColorAtMarkLevelNoPalette() {\n  return generateCharts(data.linearColorAtMarkLevel);\n}\n\nexport function LinearColorAtMarkLevel() {\n  return generateCharts(data.linearColorAtMarkLevel, {\n    colorRange: ['#c7e9c0', '#00441b']\n  });\n}\n\nexport function LineSeriesMarkSeries() {\n  return (\n    <XYPlot {...defaultXYPlotProps} width={600}>\n      {data.noColor.map((d, i) => (\n        <LineSeries {...d} key={i} color={DISCRETE_COLOR_RANGE[i]} />\n      ))}\n      {data.noColor.map((d, i) => (\n        <MarkSeries\n          {...d}\n          key={i}\n          color={DISCRETE_COLOR_RANGE[i]}\n          stroke=\"white\"\n        />\n      ))}\n    </XYPlot>\n  );\n}\n\nexport function GradientCharts() {\n  const gradient = (\n    <GradientDefs>\n      <linearGradient\n        id=\"myGradient\"\n        gradientUnits=\"userSpaceOnUse\"\n        x1=\"0\"\n        y1=\"0\"\n        x2=\"200\"\n        y2=\"200\"\n      >\n        <stop offset=\"10%\" stopColor=\"#c6e48b\" />\n        <stop offset=\"33%\" stopColor=\"#7bc96f\" />\n        <stop offset=\"66%\" stopColor=\"#239a3b\" />\n        <stop offset=\"90%\" stopColor=\"#196127\" />\n      </linearGradient>\n    </GradientDefs>\n  );\n  return (\n    <div style={{display: 'flex'}}>\n      <XYPlot {...defaultXYPlotProps}>\n        {gradient}\n        <VerticalBarSeries {...data.noColor[0]} color={'url(#myGradient)'} />\n      </XYPlot>\n      <XYPlot {...defaultXYPlotProps}>\n        {gradient}\n        <LineSeries {...data.noColor[0]} color={'url(#myGradient)'} />\n      </XYPlot>\n      <XYPlot {...defaultXYPlotProps}>\n        {gradient}\n        <MarkSeries {...data.noColor[0]} color={'url(#myGradient)'} />\n      </XYPlot>\n    </div>\n  );\n}\n\nexport function ColorSpecificity() {\n  const accentColor = '#FF9833';\n  const seventhElementColored = [...data.noColor[2].data];\n  seventhElementColored[6].color = accentColor;\n\n  return (\n    <div style={{display: 'flex'}}>\n      <XYPlot {...defaultXYPlotProps} color=\"#12939A\" colorType=\"literal\">\n        <VerticalBarSeries data={seventhElementColored} />\n      </XYPlot>\n      <XYPlot {...defaultXYPlotProps} stroke=\"#e5e5e5\" strokeType=\"literal\">\n        <LineSeries {...data.noColor[0]} />\n        <LineSeries {...data.noColor[1]} />\n        <LineSeries {...data.noColor[2]} stroke={accentColor} />\n      </XYPlot>\n      <XYPlot\n        {...defaultXYPlotProps}\n        color=\"#12939A\"\n        colorType=\"literal\"\n        stroke=\"white\"\n      >\n        <MarkSeries {...data.noColor[0]} />\n        <MarkSeries {...data.noColor[1]} />\n        <MarkSeries data={seventhElementColored} color=\"#4fb79b\" />\n      </XYPlot>\n    </div>\n  );\n}\n\nexport function ReactVis5() {\n  return generatePalette(DISCRETE_COLOR_RANGE);\n}\n\nexport function ReactVis20() {\n  return generatePalette(EXTENDED_DISCRETE_COLOR_RANGE);\n}\n\nexport function Continuous() {\n  return generatePalette(CONTINUOUS_COLOR_RANGE);\n}\n\nexport function CustomPalette() {\n  return generatePalette(colors);\n}\n\nfunction generatePalette(range) {\n  return (\n    <div style={{display: 'flex', maxWidth: 700, flexWrap: 'wrap'}}>\n      {range.map((d, i) => (\n        <div\n          key={i.toString()}\n          style={{\n            background: d,\n            width: 80,\n            height: 80,\n            borderRadius: 5,\n            margin: 10,\n            position: 'relative'\n          }}\n        >\n          <div\n            className=\"color-box\"\n            style={{\n              position: 'absolute',\n              top: '50%',\n              left: '50%',\n              textShadow: 'white 1px 1px',\n              transform: 'translate(-50%, -50%)'\n            }}\n          >\n            {d}\n          </div>\n        </div>\n      ))}\n    </div>\n  );\n}\n\nfunction generateCharts(seriesData, props) {\n  return (\n    <div style={{display: 'flex'}}>\n      {[VerticalBarSeries, LineSeries, MarkSeries].map((Type, key) => (\n        <XYPlot key={key} {...defaultXYPlotProps} {...props}>\n          {seriesData.map((d, i) => (\n            <Type key={i} {...d} />\n          ))}\n        </XYPlot>\n      ))}\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/data/mini-data-examples.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the 'Software'), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {XYPlot, LineSeries, MarkSeries, VerticalBarSeries} from 'react-vis';\n\nconst data = [\n  {x: 0, y: 8},\n  {x: 1, y: 5},\n  {x: 2, y: 4},\n  {x: 3, y: 9},\n  {x: 4, y: 1},\n  {x: 5, y: 7},\n  {x: 6, y: 6},\n  {x: 7, y: 3},\n  {x: 8, y: 2},\n  {x: 9, y: 0}\n];\n\nconst defaultProps = {\n  width: 200,\n  height: 200,\n  margin: {top: 5, left: 5, right: 5, bottom: 5}\n};\n\nexport function MiniCharts() {\n  return (\n    <div style={{display: 'flex'}}>\n      <XYPlot {...defaultProps}>\n        <VerticalBarSeries data={data} />\n      </XYPlot>\n      <XYPlot {...defaultProps}>\n        <LineSeries data={data} />\n      </XYPlot>\n      <XYPlot {...defaultProps}>\n        <MarkSeries data={data} />\n      </XYPlot>\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/datasets/car-data.json",
    "content": "[\n    {\n        \"name\": \"AMC Ambassador Brougham\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"360\",\n        \"power (hp)\": \"175\",\n        \"weight (lb)\": \"3821\",\n        \"0-60 mph (s)\": \"11\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"AMC Ambassador DPL\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"390\",\n        \"power (hp)\": \"190\",\n        \"weight (lb)\": \"3850\",\n        \"0-60 mph (s)\": \"8.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"AMC Ambassador SST\",\n        \"economy (mpg)\": \"17\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"304\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3672\",\n        \"0-60 mph (s)\": \"11.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"AMC Concord DL 6\",\n        \"economy (mpg)\": \"20.2\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"3265\",\n        \"0-60 mph (s)\": \"18.2\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"AMC Concord DL\",\n        \"economy (mpg)\": \"18.1\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"258\",\n        \"power (hp)\": \"120\",\n        \"weight (lb)\": \"3410\",\n        \"0-60 mph (s)\": \"15.1\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"AMC Concord DL\",\n        \"economy (mpg)\": \"23\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"151\",\n        \"power (hp)\": \"\",\n        \"weight (lb)\": \"3035\",\n        \"0-60 mph (s)\": \"20.5\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"AMC Concord\",\n        \"economy (mpg)\": \"19.4\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"3210\",\n        \"0-60 mph (s)\": \"17.2\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"AMC Concord\",\n        \"economy (mpg)\": \"24.3\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"151\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"3003\",\n        \"0-60 mph (s)\": \"20.1\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"AMC Gremlin\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"2789\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"AMC Gremlin\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"2634\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"AMC Gremlin\",\n        \"economy (mpg)\": \"20\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"2914\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"AMC Gremlin\",\n        \"economy (mpg)\": \"21\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"199\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2648\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"AMC Hornet Sportabout (Wagon)\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"258\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"2962\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"AMC Hornet\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"199\",\n        \"power (hp)\": \"97\",\n        \"weight (lb)\": \"2774\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"AMC Hornet\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"2945\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"AMC Hornet\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"2901\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"AMC Hornet\",\n        \"economy (mpg)\": \"22.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"3085\",\n        \"0-60 mph (s)\": \"17.6\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"AMC Matador (Wagon)\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"304\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4257\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"AMC Matador (Wagon)\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"304\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3892\",\n        \"0-60 mph (s)\": \"12.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"AMC Matador\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"304\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3672\",\n        \"0-60 mph (s)\": \"11.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"AMC Matador\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"258\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3730\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"AMC Matador\",\n        \"economy (mpg)\": \"15.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"304\",\n        \"power (hp)\": \"120\",\n        \"weight (lb)\": \"3962\",\n        \"0-60 mph (s)\": \"13.9\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"AMC Matador\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"258\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3632\",\n        \"0-60 mph (s)\": \"18\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"AMC Matador\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"3288\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"AMC Pacer D/L\",\n        \"economy (mpg)\": \"17.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"258\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"3193\",\n        \"0-60 mph (s)\": \"17.8\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"AMC Pacer\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"3211\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"AMC Rebel SST (Wagon)\",\n        \"economy (mpg)\": \"\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"360\",\n        \"power (hp)\": \"175\",\n        \"weight (lb)\": \"3850\",\n        \"0-60 mph (s)\": \"11\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"AMC Rebel SST\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"304\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3433\",\n        \"0-60 mph (s)\": \"12\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"AMC Spirit DL\",\n        \"economy (mpg)\": \"27.4\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"80\",\n        \"weight (lb)\": \"2670\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Audi 100 LS\",\n        \"economy (mpg)\": \"20\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"114\",\n        \"power (hp)\": \"91\",\n        \"weight (lb)\": \"2582\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Audi 100 LS\",\n        \"economy (mpg)\": \"23\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"115\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"2694\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Audi 100 LS\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"107\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2430\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Audi 4000\",\n        \"economy (mpg)\": \"34.3\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"78\",\n        \"weight (lb)\": \"2188\",\n        \"0-60 mph (s)\": \"15.8\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Audi 5000\",\n        \"economy (mpg)\": \"20.3\",\n        \"cylinders\": \"5\",\n        \"displacement (cc)\": \"131\",\n        \"power (hp)\": \"103\",\n        \"weight (lb)\": \"2830\",\n        \"0-60 mph (s)\": \"15.9\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Audi 5000S (Diesel)\",\n        \"economy (mpg)\": \"36.4\",\n        \"cylinders\": \"5\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"2950\",\n        \"0-60 mph (s)\": \"19.9\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Audi Fox\",\n        \"economy (mpg)\": \"29\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"83\",\n        \"weight (lb)\": \"2219\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"BMW 2002\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"113\",\n        \"weight (lb)\": \"2234\",\n        \"0-60 mph (s)\": \"12.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"BMW 320i\",\n        \"economy (mpg)\": \"21.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"2600\",\n        \"0-60 mph (s)\": \"12.8\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Buick Century 350\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"175\",\n        \"weight (lb)\": \"4100\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Buick Century Limited\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"181\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"2945\",\n        \"0-60 mph (s)\": \"16.4\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Buick Century Luxus (Wagon)\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4699\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Buick Century Special\",\n        \"economy (mpg)\": \"20.6\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"231\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"3380\",\n        \"0-60 mph (s)\": \"15.8\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Buick Century\",\n        \"economy (mpg)\": \"17\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"231\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3907\",\n        \"0-60 mph (s)\": \"21\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Buick Century\",\n        \"economy (mpg)\": \"22.4\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"231\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3415\",\n        \"0-60 mph (s)\": \"15.8\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Buick Electra 225 Custom\",\n        \"economy (mpg)\": \"12\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"455\",\n        \"power (hp)\": \"225\",\n        \"weight (lb)\": \"4951\",\n        \"0-60 mph (s)\": \"11\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Buick Estate Wagon (Wagon)\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"455\",\n        \"power (hp)\": \"225\",\n        \"weight (lb)\": \"3086\",\n        \"0-60 mph (s)\": \"10\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Buick Estate Wagon (Wagon)\",\n        \"economy (mpg)\": \"16.9\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"155\",\n        \"weight (lb)\": \"4360\",\n        \"0-60 mph (s)\": \"14.9\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Buick Lesabre Custom\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"155\",\n        \"weight (lb)\": \"4502\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Buick Opel Isuzu Deluxe\",\n        \"economy (mpg)\": \"30\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"111\",\n        \"power (hp)\": \"80\",\n        \"weight (lb)\": \"2155\",\n        \"0-60 mph (s)\": \"14.8\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Buick Regal Sport Coupe (Turbo)\",\n        \"economy (mpg)\": \"17.7\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"231\",\n        \"power (hp)\": \"165\",\n        \"weight (lb)\": \"3445\",\n        \"0-60 mph (s)\": \"13.4\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Buick Skyhawk\",\n        \"economy (mpg)\": \"21\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"231\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3039\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Buick Skylark 320\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"165\",\n        \"weight (lb)\": \"3693\",\n        \"0-60 mph (s)\": \"11.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Buick Skylark Limited\",\n        \"economy (mpg)\": \"28.4\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"151\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2670\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Buick Skylark\",\n        \"economy (mpg)\": \"20.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"231\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"3425\",\n        \"0-60 mph (s)\": \"16.9\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Buick Skylark\",\n        \"economy (mpg)\": \"26.6\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"151\",\n        \"power (hp)\": \"84\",\n        \"weight (lb)\": \"2635\",\n        \"0-60 mph (s)\": \"16.4\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Cadillac Eldorado\",\n        \"economy (mpg)\": \"23\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"125\",\n        \"weight (lb)\": \"3900\",\n        \"0-60 mph (s)\": \"17.4\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Cadillac Seville\",\n        \"economy (mpg)\": \"16.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"180\",\n        \"weight (lb)\": \"4380\",\n        \"0-60 mph (s)\": \"12.1\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Chevroelt Chevelle Malibu\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"3897\",\n        \"0-60 mph (s)\": \"18.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Chevrolet Bel Air\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"145\",\n        \"weight (lb)\": \"4440\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Chevrolet Camaro\",\n        \"economy (mpg)\": \"27\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"151\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2950\",\n        \"0-60 mph (s)\": \"17.3\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Chevrolet Caprice Classic\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4464\",\n        \"0-60 mph (s)\": \"12\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Chevrolet Caprice Classic\",\n        \"economy (mpg)\": \"17\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"305\",\n        \"power (hp)\": \"130\",\n        \"weight (lb)\": \"3840\",\n        \"0-60 mph (s)\": \"15.4\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Chevrolet Caprice Classic\",\n        \"economy (mpg)\": \"17.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"305\",\n        \"power (hp)\": \"145\",\n        \"weight (lb)\": \"3880\",\n        \"0-60 mph (s)\": \"12.5\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Chevrolet Cavalier 2-Door\",\n        \"economy (mpg)\": \"34\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"112\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2395\",\n        \"0-60 mph (s)\": \"18\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Chevrolet Cavalier Wagon\",\n        \"economy (mpg)\": \"27\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"112\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2640\",\n        \"0-60 mph (s)\": \"18.6\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Chevrolet Cavalier\",\n        \"economy (mpg)\": \"28\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"112\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2605\",\n        \"0-60 mph (s)\": \"19.6\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Chevrolet Chevelle Concours (Wagon)\",\n        \"economy (mpg)\": \"\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"165\",\n        \"weight (lb)\": \"4142\",\n        \"0-60 mph (s)\": \"11.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Chevrolet Chevelle Concours (Wagon)\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"307\",\n        \"power (hp)\": \"130\",\n        \"weight (lb)\": \"4098\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Chevrolet Chevelle Malibu Classic\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"3781\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Chevrolet Chevelle Malibu Classic\",\n        \"economy (mpg)\": \"17.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"305\",\n        \"power (hp)\": \"140\",\n        \"weight (lb)\": \"4215\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Chevrolet Chevelle Malibu\",\n        \"economy (mpg)\": \"17\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"3329\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Chevrolet Chevelle Malibu\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"307\",\n        \"power (hp)\": \"130\",\n        \"weight (lb)\": \"3504\",\n        \"0-60 mph (s)\": \"12\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Chevrolet Chevette\",\n        \"economy (mpg)\": \"29\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"85\",\n        \"power (hp)\": \"52\",\n        \"weight (lb)\": \"2035\",\n        \"0-60 mph (s)\": \"22.2\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Chevrolet Chevette\",\n        \"economy (mpg)\": \"30\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"68\",\n        \"weight (lb)\": \"2155\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Chevrolet Chevette\",\n        \"economy (mpg)\": \"30.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"63\",\n        \"weight (lb)\": \"2051\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Chevrolet Chevette\",\n        \"economy (mpg)\": \"32.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"2120\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Chevrolet Citation\",\n        \"economy (mpg)\": \"23.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"173\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"2725\",\n        \"0-60 mph (s)\": \"12.6\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Chevrolet Citation\",\n        \"economy (mpg)\": \"28\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"151\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2678\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Chevrolet Citation\",\n        \"economy (mpg)\": \"28.8\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"173\",\n        \"power (hp)\": \"115\",\n        \"weight (lb)\": \"2595\",\n        \"0-60 mph (s)\": \"11.3\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Chevrolet Concours\",\n        \"economy (mpg)\": \"17.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3520\",\n        \"0-60 mph (s)\": \"16.4\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Chevrolet Impala\",\n        \"economy (mpg)\": \"11\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4997\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Chevrolet Impala\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"165\",\n        \"weight (lb)\": \"4274\",\n        \"0-60 mph (s)\": \"12\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Chevrolet Impala\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"165\",\n        \"weight (lb)\": \"4209\",\n        \"0-60 mph (s)\": \"12\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Chevrolet Impala\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"454\",\n        \"power (hp)\": \"220\",\n        \"weight (lb)\": \"4354\",\n        \"0-60 mph (s)\": \"9\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Chevrolet Malibu Classic (Wagon)\",\n        \"economy (mpg)\": \"19.2\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"267\",\n        \"power (hp)\": \"125\",\n        \"weight (lb)\": \"3605\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Chevrolet Malibu\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"145\",\n        \"weight (lb)\": \"3988\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Chevrolet Malibu\",\n        \"economy (mpg)\": \"20.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"200\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"3155\",\n        \"0-60 mph (s)\": \"18.2\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Chevrolet Monte Carlo Landau\",\n        \"economy (mpg)\": \"15.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"170\",\n        \"weight (lb)\": \"4165\",\n        \"0-60 mph (s)\": \"11.4\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Chevrolet Monte Carlo Landau\",\n        \"economy (mpg)\": \"19.2\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"305\",\n        \"power (hp)\": \"145\",\n        \"weight (lb)\": \"3425\",\n        \"0-60 mph (s)\": \"13.2\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Chevrolet Monte Carlo S\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"145\",\n        \"weight (lb)\": \"4082\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Chevrolet Monte Carlo\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3761\",\n        \"0-60 mph (s)\": \"9.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Chevrolet Monza 2+2\",\n        \"economy (mpg)\": \"20\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"262\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3221\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Chevrolet Nova Custom\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"3278\",\n        \"0-60 mph (s)\": \"18\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Chevrolet Nova\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"3336\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Chevrolet Nova\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"3459\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Chevrolet Nova\",\n        \"economy (mpg)\": \"22\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"3353\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Chevrolet Vega (Wagon)\",\n        \"economy (mpg)\": \"22\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"72\",\n        \"weight (lb)\": \"2408\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Chevrolet Vega 2300\",\n        \"economy (mpg)\": \"28\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2264\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Chevrolet Vega\",\n        \"economy (mpg)\": \"20\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2408\",\n        \"0-60 mph (s)\": \"19.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Chevrolet Vega\",\n        \"economy (mpg)\": \"21\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"72\",\n        \"weight (lb)\": \"2401\",\n        \"0-60 mph (s)\": \"19.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Chevrolet Vega\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2542\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Chevrolet Woody\",\n        \"economy (mpg)\": \"24.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"60\",\n        \"weight (lb)\": \"2164\",\n        \"0-60 mph (s)\": \"22.1\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Chevy C10\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"145\",\n        \"weight (lb)\": \"4055\",\n        \"0-60 mph (s)\": \"12\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Chevy C20\",\n        \"economy (mpg)\": \"10\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"307\",\n        \"power (hp)\": \"200\",\n        \"weight (lb)\": \"4376\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Chevy S-10\",\n        \"economy (mpg)\": \"31\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"119\",\n        \"power (hp)\": \"82\",\n        \"weight (lb)\": \"2720\",\n        \"0-60 mph (s)\": \"19.4\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Chrysler Cordoba\",\n        \"economy (mpg)\": \"15.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"190\",\n        \"weight (lb)\": \"4325\",\n        \"0-60 mph (s)\": \"12.2\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Chrysler Lebaron Medallion\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"156\",\n        \"power (hp)\": \"92\",\n        \"weight (lb)\": \"2585\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Chrysler Lebaron Salon\",\n        \"economy (mpg)\": \"17.6\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"85\",\n        \"weight (lb)\": \"3465\",\n        \"0-60 mph (s)\": \"16.6\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Chrysler Lebaron Town & Country (Wagon)\",\n        \"economy (mpg)\": \"18.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"360\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3940\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Chrysler New Yorker Brougham\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"440\",\n        \"power (hp)\": \"215\",\n        \"weight (lb)\": \"4735\",\n        \"0-60 mph (s)\": \"11\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Chrysler Newport Royal\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"190\",\n        \"weight (lb)\": \"4422\",\n        \"0-60 mph (s)\": \"12.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Citroen DS-21 Pallas\",\n        \"economy (mpg)\": \"\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"133\",\n        \"power (hp)\": \"115\",\n        \"weight (lb)\": \"3090\",\n        \"0-60 mph (s)\": \"17.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Datsun 1200\",\n        \"economy (mpg)\": \"35\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"72\",\n        \"power (hp)\": \"69\",\n        \"weight (lb)\": \"1613\",\n        \"0-60 mph (s)\": \"18\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Datsun 200SX\",\n        \"economy (mpg)\": \"23.9\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"119\",\n        \"power (hp)\": \"97\",\n        \"weight (lb)\": \"2405\",\n        \"0-60 mph (s)\": \"14.9\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Datsun 200SX\",\n        \"economy (mpg)\": \"32.9\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"119\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"2615\",\n        \"0-60 mph (s)\": \"14.8\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Datsun 210\",\n        \"economy (mpg)\": \"31.8\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"85\",\n        \"power (hp)\": \"65\",\n        \"weight (lb)\": \"2020\",\n        \"0-60 mph (s)\": \"19.2\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Datsun 210\",\n        \"economy (mpg)\": \"37\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"85\",\n        \"power (hp)\": \"65\",\n        \"weight (lb)\": \"1975\",\n        \"0-60 mph (s)\": \"19.4\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Datsun 210\",\n        \"economy (mpg)\": \"40.8\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"85\",\n        \"power (hp)\": \"65\",\n        \"weight (lb)\": \"2110\",\n        \"0-60 mph (s)\": \"19.2\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Datsun 280ZX\",\n        \"economy (mpg)\": \"32.7\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"168\",\n        \"power (hp)\": \"132\",\n        \"weight (lb)\": \"2910\",\n        \"0-60 mph (s)\": \"11.4\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Datsun 310 GX\",\n        \"economy (mpg)\": \"38\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"1995\",\n        \"0-60 mph (s)\": \"16.2\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Datsun 310\",\n        \"economy (mpg)\": \"37.2\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"86\",\n        \"power (hp)\": \"65\",\n        \"weight (lb)\": \"2019\",\n        \"0-60 mph (s)\": \"16.4\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Datsun 510 (Wagon)\",\n        \"economy (mpg)\": \"28\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"92\",\n        \"weight (lb)\": \"2288\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Datsun 510 Hatchback\",\n        \"economy (mpg)\": \"37\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"119\",\n        \"power (hp)\": \"92\",\n        \"weight (lb)\": \"2434\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Datsun 510\",\n        \"economy (mpg)\": \"27.2\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"119\",\n        \"power (hp)\": \"97\",\n        \"weight (lb)\": \"2300\",\n        \"0-60 mph (s)\": \"14.7\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Datsun 610\",\n        \"economy (mpg)\": \"22\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"108\",\n        \"power (hp)\": \"94\",\n        \"weight (lb)\": \"2379\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Datsun 710\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"119\",\n        \"power (hp)\": \"97\",\n        \"weight (lb)\": \"2545\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Datsun 710\",\n        \"economy (mpg)\": \"32\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"83\",\n        \"power (hp)\": \"61\",\n        \"weight (lb)\": \"2003\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Datsun 810 Maxima\",\n        \"economy (mpg)\": \"24.2\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"146\",\n        \"power (hp)\": \"120\",\n        \"weight (lb)\": \"2930\",\n        \"0-60 mph (s)\": \"13.8\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Datsun 810\",\n        \"economy (mpg)\": \"22\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"146\",\n        \"power (hp)\": \"97\",\n        \"weight (lb)\": \"2815\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Datsun B-210\",\n        \"economy (mpg)\": \"32\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"85\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"1990\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Datsun B210 GX\",\n        \"economy (mpg)\": \"39.4\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"85\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"2070\",\n        \"0-60 mph (s)\": \"18.6\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Datsun B210\",\n        \"economy (mpg)\": \"31\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"79\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"1950\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Datsun F-10 Hatchback\",\n        \"economy (mpg)\": \"33.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"85\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"1945\",\n        \"0-60 mph (s)\": \"16.8\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Datsun PL510\",\n        \"economy (mpg)\": \"27\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2130\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Datsun PL510\",\n        \"economy (mpg)\": \"27\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2130\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Dodge Aries SE\",\n        \"economy (mpg)\": \"29\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"135\",\n        \"power (hp)\": \"84\",\n        \"weight (lb)\": \"2525\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Dodge Aries Wagon (Wagon)\",\n        \"economy (mpg)\": \"25.8\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"156\",\n        \"power (hp)\": \"92\",\n        \"weight (lb)\": \"2620\",\n        \"0-60 mph (s)\": \"14.4\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Dodge Aspen 6\",\n        \"economy (mpg)\": \"20.6\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3360\",\n        \"0-60 mph (s)\": \"16.6\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Dodge Aspen SE\",\n        \"economy (mpg)\": \"20\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"3651\",\n        \"0-60 mph (s)\": \"17.7\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Dodge Aspen\",\n        \"economy (mpg)\": \"18.6\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3620\",\n        \"0-60 mph (s)\": \"18.7\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Dodge Aspen\",\n        \"economy (mpg)\": \"19.1\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"3381\",\n        \"0-60 mph (s)\": \"18.7\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Dodge Challenger SE\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"383\",\n        \"power (hp)\": \"170\",\n        \"weight (lb)\": \"3563\",\n        \"0-60 mph (s)\": \"10\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Dodge Charger 2.2\",\n        \"economy (mpg)\": \"36\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"135\",\n        \"power (hp)\": \"84\",\n        \"weight (lb)\": \"2370\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Dodge Colt (Wagon)\",\n        \"economy (mpg)\": \"28\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"80\",\n        \"weight (lb)\": \"2164\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Dodge Colt Hardtop\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97.5\",\n        \"power (hp)\": \"80\",\n        \"weight (lb)\": \"2126\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Dodge Colt Hatchback Custom\",\n        \"economy (mpg)\": \"35.7\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"80\",\n        \"weight (lb)\": \"1915\",\n        \"0-60 mph (s)\": \"14.4\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Dodge Colt M/M\",\n        \"economy (mpg)\": \"33.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"83\",\n        \"weight (lb)\": \"2075\",\n        \"0-60 mph (s)\": \"15.9\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Dodge Colt\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"79\",\n        \"weight (lb)\": \"2255\",\n        \"0-60 mph (s)\": \"17.7\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Dodge Colt\",\n        \"economy (mpg)\": \"27.9\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"156\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"2800\",\n        \"0-60 mph (s)\": \"14.4\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Dodge Colt\",\n        \"economy (mpg)\": \"28\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"90\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2125\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Dodge Coronet Brougham\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4190\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Dodge Coronet Custom (Wagon)\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4457\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Dodge Coronet Custom\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3777\",\n        \"0-60 mph (s)\": \"12.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Dodge D100\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3755\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Dodge D200\",\n        \"economy (mpg)\": \"11\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"210\",\n        \"weight (lb)\": \"4382\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Dodge Dart Custom\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3399\",\n        \"0-60 mph (s)\": \"11\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Dodge Diplomat\",\n        \"economy (mpg)\": \"19.4\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"140\",\n        \"weight (lb)\": \"3735\",\n        \"0-60 mph (s)\": \"13.2\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Dodge Magnum XE\",\n        \"economy (mpg)\": \"17.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"140\",\n        \"weight (lb)\": \"4080\",\n        \"0-60 mph (s)\": \"13.7\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Dodge Monaco (Wagon)\",\n        \"economy (mpg)\": \"12\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"383\",\n        \"power (hp)\": \"180\",\n        \"weight (lb)\": \"4955\",\n        \"0-60 mph (s)\": \"11.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Dodge Monaco Brougham\",\n        \"economy (mpg)\": \"15.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"145\",\n        \"weight (lb)\": \"4140\",\n        \"0-60 mph (s)\": \"13.7\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Dodge Omni\",\n        \"economy (mpg)\": \"30.9\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"105\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2230\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Dodge Rampage\",\n        \"economy (mpg)\": \"32\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"135\",\n        \"power (hp)\": \"84\",\n        \"weight (lb)\": \"2295\",\n        \"0-60 mph (s)\": \"11.6\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Dodge St. Regis\",\n        \"economy (mpg)\": \"18.2\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"135\",\n        \"weight (lb)\": \"3830\",\n        \"0-60 mph (s)\": \"15.2\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Fiat 124 Sport Coupe\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2265\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Fiat 124 TC\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"116\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2246\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Fiat 124B\",\n        \"economy (mpg)\": \"30\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"88\",\n        \"power (hp)\": \"76\",\n        \"weight (lb)\": \"2065\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Fiat 128\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"90\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2108\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Fiat 128\",\n        \"economy (mpg)\": \"29\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"68\",\n        \"power (hp)\": \"49\",\n        \"weight (lb)\": \"1867\",\n        \"0-60 mph (s)\": \"19.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Fiat 131\",\n        \"economy (mpg)\": \"28\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"107\",\n        \"power (hp)\": \"86\",\n        \"weight (lb)\": \"2464\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Fiat Strada Custom\",\n        \"economy (mpg)\": \"37.3\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"69\",\n        \"weight (lb)\": \"2130\",\n        \"0-60 mph (s)\": \"14.7\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Fiat X1.9\",\n        \"economy (mpg)\": \"31\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"79\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"2000\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Ford Capri II\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"92\",\n        \"weight (lb)\": \"2572\",\n        \"0-60 mph (s)\": \"14.9\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Ford Country Squire (Wagon)\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"170\",\n        \"weight (lb)\": \"4746\",\n        \"0-60 mph (s)\": \"12\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Ford Country Squire (Wagon)\",\n        \"economy (mpg)\": \"15.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"351\",\n        \"power (hp)\": \"142\",\n        \"weight (lb)\": \"4054\",\n        \"0-60 mph (s)\": \"14.3\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Ford Country\",\n        \"economy (mpg)\": \"12\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"167\",\n        \"weight (lb)\": \"4906\",\n        \"0-60 mph (s)\": \"12.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Ford Escort 2H\",\n        \"economy (mpg)\": \"29.9\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"65\",\n        \"weight (lb)\": \"2380\",\n        \"0-60 mph (s)\": \"20.7\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Ford Escort 4W\",\n        \"economy (mpg)\": \"34.4\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"65\",\n        \"weight (lb)\": \"2045\",\n        \"0-60 mph (s)\": \"16.2\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Ford F108\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"130\",\n        \"weight (lb)\": \"3870\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Ford F250\",\n        \"economy (mpg)\": \"10\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"360\",\n        \"power (hp)\": \"215\",\n        \"weight (lb)\": \"4615\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Ford Fairmont (Auto)\",\n        \"economy (mpg)\": \"20.2\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"200\",\n        \"power (hp)\": \"85\",\n        \"weight (lb)\": \"2965\",\n        \"0-60 mph (s)\": \"15.8\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Ford Fairmont (Man)\",\n        \"economy (mpg)\": \"25.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2720\",\n        \"0-60 mph (s)\": \"15.4\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Ford Fairmont 4\",\n        \"economy (mpg)\": \"22.3\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2890\",\n        \"0-60 mph (s)\": \"17.3\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Ford Fairmont Futura\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"92\",\n        \"weight (lb)\": \"2865\",\n        \"0-60 mph (s)\": \"16.4\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Ford Fairmont\",\n        \"economy (mpg)\": \"26.4\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2870\",\n        \"0-60 mph (s)\": \"18.1\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Ford Fiesta\",\n        \"economy (mpg)\": \"36.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"66\",\n        \"weight (lb)\": \"1800\",\n        \"0-60 mph (s)\": \"14.4\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Ford Futura\",\n        \"economy (mpg)\": \"18.1\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"139\",\n        \"weight (lb)\": \"3205\",\n        \"0-60 mph (s)\": \"11.2\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Ford Galaxie 500\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"351\",\n        \"power (hp)\": \"153\",\n        \"weight (lb)\": \"4129\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Ford Galaxie 500\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"351\",\n        \"power (hp)\": \"153\",\n        \"weight (lb)\": \"4154\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Ford Galaxie 500\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"429\",\n        \"power (hp)\": \"198\",\n        \"weight (lb)\": \"4341\",\n        \"0-60 mph (s)\": \"10\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Ford Gran Torino (Wagon)\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"140\",\n        \"weight (lb)\": \"4294\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Ford Gran Torino (Wagon)\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"140\",\n        \"weight (lb)\": \"4638\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Ford Gran Torino\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"137\",\n        \"weight (lb)\": \"4042\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Ford Gran Torino\",\n        \"economy (mpg)\": \"14.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"351\",\n        \"power (hp)\": \"152\",\n        \"weight (lb)\": \"4215\",\n        \"0-60 mph (s)\": \"12.8\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Ford Gran Torino\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"140\",\n        \"weight (lb)\": \"4141\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Ford Granada Ghia\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"78\",\n        \"weight (lb)\": \"3574\",\n        \"0-60 mph (s)\": \"21\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Ford Granada GL\",\n        \"economy (mpg)\": \"20.2\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"200\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"3060\",\n        \"0-60 mph (s)\": \"17.1\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Ford Granada L\",\n        \"economy (mpg)\": \"22\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"232\",\n        \"power (hp)\": \"112\",\n        \"weight (lb)\": \"2835\",\n        \"0-60 mph (s)\": \"14.7\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Ford Granada\",\n        \"economy (mpg)\": \"18.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"98\",\n        \"weight (lb)\": \"3525\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Ford LTD Landau\",\n        \"economy (mpg)\": \"17.6\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"129\",\n        \"weight (lb)\": \"3725\",\n        \"0-60 mph (s)\": \"13.4\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Ford LTD\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"351\",\n        \"power (hp)\": \"158\",\n        \"weight (lb)\": \"4363\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Ford LTD\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"351\",\n        \"power (hp)\": \"148\",\n        \"weight (lb)\": \"4657\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Ford Maverick\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"72\",\n        \"weight (lb)\": \"3158\",\n        \"0-60 mph (s)\": \"19.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Ford Maverick\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"3021\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Ford Maverick\",\n        \"economy (mpg)\": \"21\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"200\",\n        \"power (hp)\": \"\",\n        \"weight (lb)\": \"2875\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Ford Maverick\",\n        \"economy (mpg)\": \"21\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"200\",\n        \"power (hp)\": \"85\",\n        \"weight (lb)\": \"2587\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Ford Maverick\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"200\",\n        \"power (hp)\": \"81\",\n        \"weight (lb)\": \"3012\",\n        \"0-60 mph (s)\": \"17.6\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Ford Mustang Boss 302\",\n        \"economy (mpg)\": \"\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"140\",\n        \"weight (lb)\": \"3353\",\n        \"0-60 mph (s)\": \"8\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Ford Mustang Cobra\",\n        \"economy (mpg)\": \"23.6\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"\",\n        \"weight (lb)\": \"2905\",\n        \"0-60 mph (s)\": \"14.3\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Ford Mustang GL\",\n        \"economy (mpg)\": \"27\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"86\",\n        \"weight (lb)\": \"2790\",\n        \"0-60 mph (s)\": \"15.6\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Ford Mustang II 2+2\",\n        \"economy (mpg)\": \"25.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"89\",\n        \"weight (lb)\": \"2755\",\n        \"0-60 mph (s)\": \"15.8\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Ford Mustang II\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"129\",\n        \"weight (lb)\": \"3169\",\n        \"0-60 mph (s)\": \"12\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Ford Mustang\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"3139\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Ford Pinto (Wagon)\",\n        \"economy (mpg)\": \"22\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"122\",\n        \"power (hp)\": \"86\",\n        \"weight (lb)\": \"2395\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Ford Pinto Runabout\",\n        \"economy (mpg)\": \"21\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"122\",\n        \"power (hp)\": \"86\",\n        \"weight (lb)\": \"2226\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Ford Pinto\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"171\",\n        \"power (hp)\": \"97\",\n        \"weight (lb)\": \"2984\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Ford Pinto\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"122\",\n        \"power (hp)\": \"85\",\n        \"weight (lb)\": \"2310\",\n        \"0-60 mph (s)\": \"18.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Ford Pinto\",\n        \"economy (mpg)\": \"23\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"83\",\n        \"weight (lb)\": \"2639\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Ford Pinto\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"\",\n        \"weight (lb)\": \"2046\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Ford Pinto\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"122\",\n        \"power (hp)\": \"80\",\n        \"weight (lb)\": \"2451\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Ford Pinto\",\n        \"economy (mpg)\": \"26.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"72\",\n        \"weight (lb)\": \"2565\",\n        \"0-60 mph (s)\": \"13.6\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Ford Ranger\",\n        \"economy (mpg)\": \"28\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"120\",\n        \"power (hp)\": \"79\",\n        \"weight (lb)\": \"2625\",\n        \"0-60 mph (s)\": \"18.6\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Ford Thunderbird\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"351\",\n        \"power (hp)\": \"149\",\n        \"weight (lb)\": \"4335\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Ford Torino (Wagon)\",\n        \"economy (mpg)\": \"\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"351\",\n        \"power (hp)\": \"153\",\n        \"weight (lb)\": \"4034\",\n        \"0-60 mph (s)\": \"11\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Ford Torino 500\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"3302\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Ford Torino\",\n        \"economy (mpg)\": \"17\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"140\",\n        \"weight (lb)\": \"3449\",\n        \"0-60 mph (s)\": \"10.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Hi 1200D\",\n        \"economy (mpg)\": \"9\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"304\",\n        \"power (hp)\": \"193\",\n        \"weight (lb)\": \"4732\",\n        \"0-60 mph (s)\": \"18.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Honda Accord CVCC\",\n        \"economy (mpg)\": \"31.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"68\",\n        \"weight (lb)\": \"2045\",\n        \"0-60 mph (s)\": \"18.5\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Honda Accord LX\",\n        \"economy (mpg)\": \"29.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"68\",\n        \"weight (lb)\": \"2135\",\n        \"0-60 mph (s)\": \"16.6\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Honda Accord\",\n        \"economy (mpg)\": \"32.4\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"107\",\n        \"power (hp)\": \"72\",\n        \"weight (lb)\": \"2290\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Honda Accord\",\n        \"economy (mpg)\": \"36\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"107\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2205\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Honda Civic (Auto)\",\n        \"economy (mpg)\": \"32\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"1965\",\n        \"0-60 mph (s)\": \"15.7\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Honda Civic 1300\",\n        \"economy (mpg)\": \"35.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"81\",\n        \"power (hp)\": \"60\",\n        \"weight (lb)\": \"1760\",\n        \"0-60 mph (s)\": \"16.1\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Honda Civic 1500 GL\",\n        \"economy (mpg)\": \"44.6\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"1850\",\n        \"0-60 mph (s)\": \"13.8\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Honda Civic CVCC\",\n        \"economy (mpg)\": \"33\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"53\",\n        \"weight (lb)\": \"1795\",\n        \"0-60 mph (s)\": \"17.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Honda Civic CVCC\",\n        \"economy (mpg)\": \"36.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"60\",\n        \"weight (lb)\": \"1800\",\n        \"0-60 mph (s)\": \"16.4\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Honda Civic\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"120\",\n        \"power (hp)\": \"97\",\n        \"weight (lb)\": \"2489\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Honda Civic\",\n        \"economy (mpg)\": \"33\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"53\",\n        \"weight (lb)\": \"1795\",\n        \"0-60 mph (s)\": \"17.4\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Honda Civic\",\n        \"economy (mpg)\": \"38\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"1965\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Honda Prelude\",\n        \"economy (mpg)\": \"33.7\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"107\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2210\",\n        \"0-60 mph (s)\": \"14.4\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Maxda GLC Deluxe\",\n        \"economy (mpg)\": \"34.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"86\",\n        \"power (hp)\": \"65\",\n        \"weight (lb)\": \"1975\",\n        \"0-60 mph (s)\": \"15.2\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Maxda RX-3\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"3\",\n        \"displacement (cc)\": \"70\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2124\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Mazda 626\",\n        \"economy (mpg)\": \"31.3\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"120\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2542\",\n        \"0-60 mph (s)\": \"17.5\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Mazda 626\",\n        \"economy (mpg)\": \"31.6\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"120\",\n        \"power (hp)\": \"74\",\n        \"weight (lb)\": \"2635\",\n        \"0-60 mph (s)\": \"18.3\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Mazda GLC 4\",\n        \"economy (mpg)\": \"34.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"68\",\n        \"weight (lb)\": \"1985\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Mazda GLC Custom L\",\n        \"economy (mpg)\": \"37\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"68\",\n        \"weight (lb)\": \"2025\",\n        \"0-60 mph (s)\": \"18.2\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Mazda GLC Custom\",\n        \"economy (mpg)\": \"31\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"68\",\n        \"weight (lb)\": \"1970\",\n        \"0-60 mph (s)\": \"17.6\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Mazda GLC Deluxe\",\n        \"economy (mpg)\": \"32.8\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"78\",\n        \"power (hp)\": \"52\",\n        \"weight (lb)\": \"1985\",\n        \"0-60 mph (s)\": \"19.4\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Mazda GLC\",\n        \"economy (mpg)\": \"46.6\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"86\",\n        \"power (hp)\": \"65\",\n        \"weight (lb)\": \"2110\",\n        \"0-60 mph (s)\": \"17.9\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Mazda RX-2 Coupe\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"3\",\n        \"displacement (cc)\": \"70\",\n        \"power (hp)\": \"97\",\n        \"weight (lb)\": \"2330\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Mazda RX-4\",\n        \"economy (mpg)\": \"21.5\",\n        \"cylinders\": \"3\",\n        \"displacement (cc)\": \"80\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"2720\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Mazda RX-7 Gs\",\n        \"economy (mpg)\": \"23.7\",\n        \"cylinders\": \"3\",\n        \"displacement (cc)\": \"70\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"2420\",\n        \"0-60 mph (s)\": \"12.5\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Mercedes-Benz 240D\",\n        \"economy (mpg)\": \"30\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"146\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"3250\",\n        \"0-60 mph (s)\": \"21.8\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Mercedes-Benz 280S\",\n        \"economy (mpg)\": \"16.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"168\",\n        \"power (hp)\": \"120\",\n        \"weight (lb)\": \"3820\",\n        \"0-60 mph (s)\": \"16.7\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Mercedes-Benz 300D\",\n        \"economy (mpg)\": \"25.4\",\n        \"cylinders\": \"5\",\n        \"displacement (cc)\": \"183\",\n        \"power (hp)\": \"77\",\n        \"weight (lb)\": \"3530\",\n        \"0-60 mph (s)\": \"20.1\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Mercury Capri 2000\",\n        \"economy (mpg)\": \"23\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"122\",\n        \"power (hp)\": \"86\",\n        \"weight (lb)\": \"2220\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Mercury Capri V6\",\n        \"economy (mpg)\": \"21\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"155\",\n        \"power (hp)\": \"107\",\n        \"weight (lb)\": \"2472\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Mercury Cougar Brougham\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"130\",\n        \"weight (lb)\": \"4295\",\n        \"0-60 mph (s)\": \"14.9\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Mercury Grand Marquis\",\n        \"economy (mpg)\": \"16.5\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"351\",\n        \"power (hp)\": \"138\",\n        \"weight (lb)\": \"3955\",\n        \"0-60 mph (s)\": \"13.2\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Mercury Lynx L\",\n        \"economy (mpg)\": \"36\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"2125\",\n        \"0-60 mph (s)\": \"17.3\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Mercury Marquis Brougham\",\n        \"economy (mpg)\": \"12\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"429\",\n        \"power (hp)\": \"198\",\n        \"weight (lb)\": \"4952\",\n        \"0-60 mph (s)\": \"11.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Mercury Marquis\",\n        \"economy (mpg)\": \"11\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"429\",\n        \"power (hp)\": \"208\",\n        \"weight (lb)\": \"4633\",\n        \"0-60 mph (s)\": \"11\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Mercury Monarch Ghia\",\n        \"economy (mpg)\": \"20.2\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"302\",\n        \"power (hp)\": \"139\",\n        \"weight (lb)\": \"3570\",\n        \"0-60 mph (s)\": \"12.8\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Mercury Monarch\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"72\",\n        \"weight (lb)\": \"3432\",\n        \"0-60 mph (s)\": \"21\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Mercury Zephyr 6\",\n        \"economy (mpg)\": \"19.8\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"200\",\n        \"power (hp)\": \"85\",\n        \"weight (lb)\": \"2990\",\n        \"0-60 mph (s)\": \"18.2\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Mercury Zephyr\",\n        \"economy (mpg)\": \"20.8\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"200\",\n        \"power (hp)\": \"85\",\n        \"weight (lb)\": \"3070\",\n        \"0-60 mph (s)\": \"16.7\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Nissan Stanza XE\",\n        \"economy (mpg)\": \"36\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"120\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2160\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Oldsmobile Cutlass Ciera (Diesel)\",\n        \"economy (mpg)\": \"38\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"262\",\n        \"power (hp)\": \"85\",\n        \"weight (lb)\": \"3015\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Oldsmobile Cutlass LS\",\n        \"economy (mpg)\": \"26.6\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"3725\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Oldsmobile Cutlass Salon Brougham\",\n        \"economy (mpg)\": \"19.9\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"260\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3365\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Oldsmobile Cutlass Salon Brougham\",\n        \"economy (mpg)\": \"23.9\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"260\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"3420\",\n        \"0-60 mph (s)\": \"22.2\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Oldsmobile Cutlass Supreme\",\n        \"economy (mpg)\": \"17\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"260\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"4060\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Oldsmobile Delta 88 Royale\",\n        \"economy (mpg)\": \"12\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"160\",\n        \"weight (lb)\": \"4456\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Oldsmobile Omega Brougham\",\n        \"economy (mpg)\": \"26.8\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"173\",\n        \"power (hp)\": \"115\",\n        \"weight (lb)\": \"2700\",\n        \"0-60 mph (s)\": \"12.9\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Oldsmobile Omega\",\n        \"economy (mpg)\": \"11\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"180\",\n        \"weight (lb)\": \"3664\",\n        \"0-60 mph (s)\": \"11\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Oldsmobile Starfire SX\",\n        \"economy (mpg)\": \"23.8\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"151\",\n        \"power (hp)\": \"85\",\n        \"weight (lb)\": \"2855\",\n        \"0-60 mph (s)\": \"17.6\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Oldsmobile Vista Cruiser\",\n        \"economy (mpg)\": \"12\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"350\",\n        \"power (hp)\": \"180\",\n        \"weight (lb)\": \"4499\",\n        \"0-60 mph (s)\": \"12.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Opel 1900\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"116\",\n        \"power (hp)\": \"81\",\n        \"weight (lb)\": \"2220\",\n        \"0-60 mph (s)\": \"16.9\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Opel 1900\",\n        \"economy (mpg)\": \"28\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"116\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2123\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Opel Manta\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"116\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2158\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Opel Manta\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"78\",\n        \"weight (lb)\": \"2300\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Peugeot 304\",\n        \"economy (mpg)\": \"30\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"79\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"2074\",\n        \"0-60 mph (s)\": \"19.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Peugeot 504 (Wagon)\",\n        \"economy (mpg)\": \"21\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"120\",\n        \"power (hp)\": \"87\",\n        \"weight (lb)\": \"2979\",\n        \"0-60 mph (s)\": \"19.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Peugeot 504\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"120\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"3270\",\n        \"0-60 mph (s)\": \"21.9\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Peugeot 504\",\n        \"economy (mpg)\": \"23\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"120\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2957\",\n        \"0-60 mph (s)\": \"17\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Peugeot 504\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"110\",\n        \"power (hp)\": \"87\",\n        \"weight (lb)\": \"2672\",\n        \"0-60 mph (s)\": \"17.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Peugeot 504\",\n        \"economy (mpg)\": \"27.2\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"141\",\n        \"power (hp)\": \"71\",\n        \"weight (lb)\": \"3190\",\n        \"0-60 mph (s)\": \"24.8\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Peugeot 505S Turbo Diesel\",\n        \"economy (mpg)\": \"28.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"141\",\n        \"power (hp)\": \"80\",\n        \"weight (lb)\": \"3230\",\n        \"0-60 mph (s)\": \"20.4\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Peugeot 604SL\",\n        \"economy (mpg)\": \"16.2\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"163\",\n        \"power (hp)\": \"133\",\n        \"weight (lb)\": \"3410\",\n        \"0-60 mph (s)\": \"15.8\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Plymouth Arrow GS\",\n        \"economy (mpg)\": \"25.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"122\",\n        \"power (hp)\": \"96\",\n        \"weight (lb)\": \"2300\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Plymouth Barracuda 340\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"340\",\n        \"power (hp)\": \"160\",\n        \"weight (lb)\": \"3609\",\n        \"0-60 mph (s)\": \"8\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Plymouth Champ\",\n        \"economy (mpg)\": \"39\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"86\",\n        \"power (hp)\": \"64\",\n        \"weight (lb)\": \"1875\",\n        \"0-60 mph (s)\": \"16.4\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Plymouth Cricket\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"91\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"1955\",\n        \"0-60 mph (s)\": \"20.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Plymouth Custom Suburb\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"360\",\n        \"power (hp)\": \"170\",\n        \"weight (lb)\": \"4654\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Plymouth Duster\",\n        \"economy (mpg)\": \"20\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"198\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"3102\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Plymouth Duster\",\n        \"economy (mpg)\": \"22\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"198\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"2833\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Plymouth Duster\",\n        \"economy (mpg)\": \"23\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"198\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"2904\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Plymouth Fury Gran Sedan\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4237\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Plymouth Fury III\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4096\",\n        \"0-60 mph (s)\": \"13\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Plymouth Fury III\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"440\",\n        \"power (hp)\": \"215\",\n        \"weight (lb)\": \"4312\",\n        \"0-60 mph (s)\": \"8.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Plymouth Fury III\",\n        \"economy (mpg)\": \"15\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4135\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Plymouth Fury\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"3785\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Plymouth Grand Fury\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4498\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Plymouth Horizon 4\",\n        \"economy (mpg)\": \"34.7\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"105\",\n        \"power (hp)\": \"63\",\n        \"weight (lb)\": \"2215\",\n        \"0-60 mph (s)\": \"14.9\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Plymouth Horizon Miser\",\n        \"economy (mpg)\": \"38\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"105\",\n        \"power (hp)\": \"63\",\n        \"weight (lb)\": \"2125\",\n        \"0-60 mph (s)\": \"14.7\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Plymouth Horizon TC3\",\n        \"economy (mpg)\": \"34.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"105\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"2150\",\n        \"0-60 mph (s)\": \"14.9\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Plymouth Horizon\",\n        \"economy (mpg)\": \"34.2\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"105\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"2200\",\n        \"0-60 mph (s)\": \"13.2\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Plymouth Reliant\",\n        \"economy (mpg)\": \"27.2\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"135\",\n        \"power (hp)\": \"84\",\n        \"weight (lb)\": \"2490\",\n        \"0-60 mph (s)\": \"15.7\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Plymouth Reliant\",\n        \"economy (mpg)\": \"30\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"135\",\n        \"power (hp)\": \"84\",\n        \"weight (lb)\": \"2385\",\n        \"0-60 mph (s)\": \"12.9\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Plymouth Sapporo\",\n        \"economy (mpg)\": \"23.2\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"156\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"2745\",\n        \"0-60 mph (s)\": \"16.7\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Plymouth Satellite (Wagon)\",\n        \"economy (mpg)\": \"\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"383\",\n        \"power (hp)\": \"175\",\n        \"weight (lb)\": \"4166\",\n        \"0-60 mph (s)\": \"10.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Plymouth Satellite Custom (Wagon)\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"4077\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Plymouth Satellite Custom\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"3439\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Plymouth Satellite Sebring\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"3613\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Plymouth Satellite\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3436\",\n        \"0-60 mph (s)\": \"11\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Plymouth Valiant Custom\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"3264\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Plymouth Valiant\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"3121\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Plymouth Valiant\",\n        \"economy (mpg)\": \"22\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"3233\",\n        \"0-60 mph (s)\": \"15.4\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Plymouth Volare Custom\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"3630\",\n        \"0-60 mph (s)\": \"17.7\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Plymouth Volare Premier V8\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"318\",\n        \"power (hp)\": \"150\",\n        \"weight (lb)\": \"3940\",\n        \"0-60 mph (s)\": \"13.2\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Plymouth Volare\",\n        \"economy (mpg)\": \"20.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"225\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"3430\",\n        \"0-60 mph (s)\": \"17.2\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Pontiac Astro\",\n        \"economy (mpg)\": \"23\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"140\",\n        \"power (hp)\": \"78\",\n        \"weight (lb)\": \"2592\",\n        \"0-60 mph (s)\": \"18.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Pontiac Catalina Brougham\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"175\",\n        \"weight (lb)\": \"4464\",\n        \"0-60 mph (s)\": \"11.5\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Pontiac Catalina\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"175\",\n        \"weight (lb)\": \"4385\",\n        \"0-60 mph (s)\": \"12\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Pontiac Catalina\",\n        \"economy (mpg)\": \"14\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"455\",\n        \"power (hp)\": \"225\",\n        \"weight (lb)\": \"4425\",\n        \"0-60 mph (s)\": \"10\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Pontiac Catalina\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"170\",\n        \"weight (lb)\": \"4668\",\n        \"0-60 mph (s)\": \"11.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Pontiac Firebird\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"100\",\n        \"weight (lb)\": \"3282\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Pontiac Grand Prix Lj\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"180\",\n        \"weight (lb)\": \"4220\",\n        \"0-60 mph (s)\": \"11.1\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Pontiac Grand Prix\",\n        \"economy (mpg)\": \"16\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"230\",\n        \"weight (lb)\": \"4278\",\n        \"0-60 mph (s)\": \"9.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Pontiac J2000 Se Hatchback\",\n        \"economy (mpg)\": \"31\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"112\",\n        \"power (hp)\": \"85\",\n        \"weight (lb)\": \"2575\",\n        \"0-60 mph (s)\": \"16.2\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Pontiac Lemans V6\",\n        \"economy (mpg)\": \"21.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"231\",\n        \"power (hp)\": \"115\",\n        \"weight (lb)\": \"3245\",\n        \"0-60 mph (s)\": \"15.4\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Pontiac Phoenix LJ\",\n        \"economy (mpg)\": \"19.2\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"231\",\n        \"power (hp)\": \"105\",\n        \"weight (lb)\": \"3535\",\n        \"0-60 mph (s)\": \"19.2\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Pontiac Phoenix\",\n        \"economy (mpg)\": \"27\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"151\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2735\",\n        \"0-60 mph (s)\": \"18\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Pontiac Phoenix\",\n        \"economy (mpg)\": \"33.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"151\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2556\",\n        \"0-60 mph (s)\": \"13.2\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Pontiac Safari (Wagon)\",\n        \"economy (mpg)\": \"13\",\n        \"cylinders\": \"8\",\n        \"displacement (cc)\": \"400\",\n        \"power (hp)\": \"175\",\n        \"weight (lb)\": \"5140\",\n        \"0-60 mph (s)\": \"12\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Pontiac Sunbird Coupe\",\n        \"economy (mpg)\": \"24.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"151\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2740\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Pontiac Ventura Sj\",\n        \"economy (mpg)\": \"18.5\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"250\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"3645\",\n        \"0-60 mph (s)\": \"16.2\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Renault 12 (Wagon)\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"96\",\n        \"power (hp)\": \"69\",\n        \"weight (lb)\": \"2189\",\n        \"0-60 mph (s)\": \"18\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Renault 12TL\",\n        \"economy (mpg)\": \"27\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"101\",\n        \"power (hp)\": \"83\",\n        \"weight (lb)\": \"2202\",\n        \"0-60 mph (s)\": \"15.3\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Renault 18I\",\n        \"economy (mpg)\": \"34.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"100\",\n        \"power (hp)\": \"\",\n        \"weight (lb)\": \"2320\",\n        \"0-60 mph (s)\": \"15.8\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Renault 5 Gtl\",\n        \"economy (mpg)\": \"36\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"79\",\n        \"power (hp)\": \"58\",\n        \"weight (lb)\": \"1825\",\n        \"0-60 mph (s)\": \"18.6\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Renault Lecar Deluxe\",\n        \"economy (mpg)\": \"40.9\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"85\",\n        \"power (hp)\": \"\",\n        \"weight (lb)\": \"1835\",\n        \"0-60 mph (s)\": \"17.3\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Saab 900S\",\n        \"economy (mpg)\": \"\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"2800\",\n        \"0-60 mph (s)\": \"15.4\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Saab 99E\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"104\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"2375\",\n        \"0-60 mph (s)\": \"17.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Saab 99GLE\",\n        \"economy (mpg)\": \"21.6\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"115\",\n        \"weight (lb)\": \"2795\",\n        \"0-60 mph (s)\": \"15.7\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Saab 99LE\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"110\",\n        \"weight (lb)\": \"2660\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Saab 99LE\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"115\",\n        \"weight (lb)\": \"2671\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Subaru DL\",\n        \"economy (mpg)\": \"30\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"1985\",\n        \"0-60 mph (s)\": \"16.4\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Subaru DL\",\n        \"economy (mpg)\": \"33.8\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"2145\",\n        \"0-60 mph (s)\": \"18\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Subaru\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"108\",\n        \"power (hp)\": \"93\",\n        \"weight (lb)\": \"2391\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Subaru\",\n        \"economy (mpg)\": \"32.3\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"2065\",\n        \"0-60 mph (s)\": \"17.8\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Toyota Carina\",\n        \"economy (mpg)\": \"20\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2279\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Toyota Celica GT Liftback\",\n        \"economy (mpg)\": \"21.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"134\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"2515\",\n        \"0-60 mph (s)\": \"14.8\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Toyota Celica GT\",\n        \"economy (mpg)\": \"32\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"144\",\n        \"power (hp)\": \"96\",\n        \"weight (lb)\": \"2665\",\n        \"0-60 mph (s)\": \"13.9\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Toyota Corolla 1200\",\n        \"economy (mpg)\": \"31\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"71\",\n        \"power (hp)\": \"65\",\n        \"weight (lb)\": \"1773\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Toyota Corolla 1200\",\n        \"economy (mpg)\": \"32\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"71\",\n        \"power (hp)\": \"65\",\n        \"weight (lb)\": \"1836\",\n        \"0-60 mph (s)\": \"21\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Toyota Corolla 1600 (Wagon)\",\n        \"economy (mpg)\": \"27\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2100\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Toyota Corolla Liftback\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2265\",\n        \"0-60 mph (s)\": \"18.2\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Toyota Corolla Tercel\",\n        \"economy (mpg)\": \"38.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"89\",\n        \"power (hp)\": \"60\",\n        \"weight (lb)\": \"1968\",\n        \"0-60 mph (s)\": \"18.8\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Toyota Corolla\",\n        \"economy (mpg)\": \"28\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2155\",\n        \"0-60 mph (s)\": \"16.4\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Toyota Corolla\",\n        \"economy (mpg)\": \"29\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2171\",\n        \"0-60 mph (s)\": \"16\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Toyota Corolla\",\n        \"economy (mpg)\": \"32.2\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"108\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2265\",\n        \"0-60 mph (s)\": \"15.2\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Toyota Corolla\",\n        \"economy (mpg)\": \"32.4\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"108\",\n        \"power (hp)\": \"75\",\n        \"weight (lb)\": \"2350\",\n        \"0-60 mph (s)\": \"16.8\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Toyota Corolla\",\n        \"economy (mpg)\": \"34\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"108\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"2245\",\n        \"0-60 mph (s)\": \"16.9\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Toyota Corona Hardtop\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"113\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"2278\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Toyota Corona Liftback\",\n        \"economy (mpg)\": \"29.8\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"134\",\n        \"power (hp)\": \"90\",\n        \"weight (lb)\": \"2711\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Toyota Corona Mark II\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"113\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"2372\",\n        \"0-60 mph (s)\": \"15\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Toyota Corona\",\n        \"economy (mpg)\": \"24\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"134\",\n        \"power (hp)\": \"96\",\n        \"weight (lb)\": \"2702\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Toyota Corona\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"113\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"2228\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Toyota Corona\",\n        \"economy (mpg)\": \"27.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"134\",\n        \"power (hp)\": \"95\",\n        \"weight (lb)\": \"2560\",\n        \"0-60 mph (s)\": \"14.2\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Toyota Corona\",\n        \"economy (mpg)\": \"31\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"76\",\n        \"power (hp)\": \"52\",\n        \"weight (lb)\": \"1649\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Toyota Cressida\",\n        \"economy (mpg)\": \"25.4\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"168\",\n        \"power (hp)\": \"116\",\n        \"weight (lb)\": \"2900\",\n        \"0-60 mph (s)\": \"12.6\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Toyota Mark II\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"156\",\n        \"power (hp)\": \"108\",\n        \"weight (lb)\": \"2930\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Toyota Mark II\",\n        \"economy (mpg)\": \"20\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"156\",\n        \"power (hp)\": \"122\",\n        \"weight (lb)\": \"2807\",\n        \"0-60 mph (s)\": \"13.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Toyota Starlet\",\n        \"economy (mpg)\": \"39.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"79\",\n        \"power (hp)\": \"58\",\n        \"weight (lb)\": \"1755\",\n        \"0-60 mph (s)\": \"16.9\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Toyota Tercel\",\n        \"economy (mpg)\": \"37.7\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"89\",\n        \"power (hp)\": \"62\",\n        \"weight (lb)\": \"2050\",\n        \"0-60 mph (s)\": \"17.3\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Toyouta Corona Mark II (Wagon)\",\n        \"economy (mpg)\": \"23\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"120\",\n        \"power (hp)\": \"97\",\n        \"weight (lb)\": \"2506\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Triumph TR7 Coupe\",\n        \"economy (mpg)\": \"35\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"122\",\n        \"power (hp)\": \"88\",\n        \"weight (lb)\": \"2500\",\n        \"0-60 mph (s)\": \"15.1\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Vokswagen Rabbit\",\n        \"economy (mpg)\": \"29.8\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"89\",\n        \"power (hp)\": \"62\",\n        \"weight (lb)\": \"1845\",\n        \"0-60 mph (s)\": \"15.3\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Volkswagen 1131 Deluxe Sedan\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"46\",\n        \"weight (lb)\": \"1835\",\n        \"0-60 mph (s)\": \"20.5\",\n        \"year\": \"70\"\n    },\n    {\n        \"name\": \"Volkswagen 411 (Wagon)\",\n        \"economy (mpg)\": \"22\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"76\",\n        \"weight (lb)\": \"2511\",\n        \"0-60 mph (s)\": \"18\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Volkswagen Dasher (Diesel)\",\n        \"economy (mpg)\": \"43.4\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"90\",\n        \"power (hp)\": \"48\",\n        \"weight (lb)\": \"2335\",\n        \"0-60 mph (s)\": \"23.7\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Volkswagen Dasher\",\n        \"economy (mpg)\": \"25\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"90\",\n        \"power (hp)\": \"71\",\n        \"weight (lb)\": \"2223\",\n        \"0-60 mph (s)\": \"16.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Volkswagen Dasher\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"79\",\n        \"power (hp)\": \"67\",\n        \"weight (lb)\": \"1963\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"74\"\n    },\n    {\n        \"name\": \"Volkswagen Dasher\",\n        \"economy (mpg)\": \"30.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"78\",\n        \"weight (lb)\": \"2190\",\n        \"0-60 mph (s)\": \"14.1\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Volkswagen Jetta\",\n        \"economy (mpg)\": \"33\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"105\",\n        \"power (hp)\": \"74\",\n        \"weight (lb)\": \"2190\",\n        \"0-60 mph (s)\": \"14.2\",\n        \"year\": \"81\"\n    },\n    {\n        \"name\": \"Volkswagen Model 111\",\n        \"economy (mpg)\": \"27\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"60\",\n        \"weight (lb)\": \"1834\",\n        \"0-60 mph (s)\": \"19\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Volkswagen Pickup\",\n        \"economy (mpg)\": \"44\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"52\",\n        \"weight (lb)\": \"2130\",\n        \"0-60 mph (s)\": \"24.6\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Volkswagen Rabbit C (Diesel)\",\n        \"economy (mpg)\": \"44.3\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"90\",\n        \"power (hp)\": \"48\",\n        \"weight (lb)\": \"2085\",\n        \"0-60 mph (s)\": \"21.7\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Volkswagen Rabbit Custom Diesel\",\n        \"economy (mpg)\": \"43.1\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"90\",\n        \"power (hp)\": \"48\",\n        \"weight (lb)\": \"1985\",\n        \"0-60 mph (s)\": \"21.5\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Volkswagen Rabbit Custom\",\n        \"economy (mpg)\": \"29\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"78\",\n        \"weight (lb)\": \"1940\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"77\"\n    },\n    {\n        \"name\": \"Volkswagen Rabbit Custom\",\n        \"economy (mpg)\": \"31.9\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"89\",\n        \"power (hp)\": \"71\",\n        \"weight (lb)\": \"1925\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"79\"\n    },\n    {\n        \"name\": \"Volkswagen Rabbit L\",\n        \"economy (mpg)\": \"36\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"105\",\n        \"power (hp)\": \"74\",\n        \"weight (lb)\": \"1980\",\n        \"0-60 mph (s)\": \"15.3\",\n        \"year\": \"82\"\n    },\n    {\n        \"name\": \"Volkswagen Rabbit\",\n        \"economy (mpg)\": \"29\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"90\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"1937\",\n        \"0-60 mph (s)\": \"14\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Volkswagen Rabbit\",\n        \"economy (mpg)\": \"29\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"90\",\n        \"power (hp)\": \"70\",\n        \"weight (lb)\": \"1937\",\n        \"0-60 mph (s)\": \"14.2\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Volkswagen Rabbit\",\n        \"economy (mpg)\": \"29.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"71\",\n        \"weight (lb)\": \"1825\",\n        \"0-60 mph (s)\": \"12.2\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Volkswagen Rabbit\",\n        \"economy (mpg)\": \"41.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"98\",\n        \"power (hp)\": \"76\",\n        \"weight (lb)\": \"2144\",\n        \"0-60 mph (s)\": \"14.7\",\n        \"year\": \"80\"\n    },\n    {\n        \"name\": \"Volkswagen Scirocco\",\n        \"economy (mpg)\": \"31.5\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"89\",\n        \"power (hp)\": \"71\",\n        \"weight (lb)\": \"1990\",\n        \"0-60 mph (s)\": \"14.9\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Volkswagen Super Beetle 117\",\n        \"economy (mpg)\": \"\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"48\",\n        \"weight (lb)\": \"1978\",\n        \"0-60 mph (s)\": \"20\",\n        \"year\": \"71\"\n    },\n    {\n        \"name\": \"Volkswagen Super Beetle\",\n        \"economy (mpg)\": \"26\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"46\",\n        \"weight (lb)\": \"1950\",\n        \"0-60 mph (s)\": \"21\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Volkswagen Type 3\",\n        \"economy (mpg)\": \"23\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"97\",\n        \"power (hp)\": \"54\",\n        \"weight (lb)\": \"2254\",\n        \"0-60 mph (s)\": \"23.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Volvo 144EA\",\n        \"economy (mpg)\": \"19\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"112\",\n        \"weight (lb)\": \"2868\",\n        \"0-60 mph (s)\": \"15.5\",\n        \"year\": \"73\"\n    },\n    {\n        \"name\": \"Volvo 145E (Wagon)\",\n        \"economy (mpg)\": \"18\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"112\",\n        \"weight (lb)\": \"2933\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"72\"\n    },\n    {\n        \"name\": \"Volvo 244DL\",\n        \"economy (mpg)\": \"22\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"121\",\n        \"power (hp)\": \"98\",\n        \"weight (lb)\": \"2945\",\n        \"0-60 mph (s)\": \"14.5\",\n        \"year\": \"75\"\n    },\n    {\n        \"name\": \"Volvo 245\",\n        \"economy (mpg)\": \"20\",\n        \"cylinders\": \"4\",\n        \"displacement (cc)\": \"130\",\n        \"power (hp)\": \"102\",\n        \"weight (lb)\": \"3150\",\n        \"0-60 mph (s)\": \"15.7\",\n        \"year\": \"76\"\n    },\n    {\n        \"name\": \"Volvo 264GL\",\n        \"economy (mpg)\": \"17\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"163\",\n        \"power (hp)\": \"125\",\n        \"weight (lb)\": \"3140\",\n        \"0-60 mph (s)\": \"13.6\",\n        \"year\": \"78\"\n    },\n    {\n        \"name\": \"Volvo Diesel\",\n        \"economy (mpg)\": \"30.7\",\n        \"cylinders\": \"6\",\n        \"displacement (cc)\": \"145\",\n        \"power (hp)\": \"76\",\n        \"weight (lb)\": \"3160\",\n        \"0-60 mph (s)\": \"19.6\",\n        \"year\": \"81\"\n    }\n]\n"
  },
  {
    "path": "packages/showcase/datasets/d3-flare-example.json",
    "content": "{\n \"children\": [\n  {\n   \"name\": \"analytics\",\n   \"hex\": \"#12939A\",\n   \"children\": [\n    {\n     \"name\": \"cluster\",\n     \"children\": [\n      {\"name\": \"AgglomerativeCluster\", \"hex\": \"#12939A\", \"value\": 3938},\n      {\"name\": \"CommunityStructure\", \"hex\": \"#12939A\", \"value\": 3812},\n      {\"name\": \"HierarchicalCluster\", \"hex\": \"#12939A\", \"value\": 6714},\n      {\"name\": \"MergeEdge\", \"hex\": \"#12939A\", \"value\": 743}\n     ]\n    },\n    {\n     \"name\": \"graph\",\n     \"children\": [\n      {\"name\": \"BetweennessCentrality\", \"hex\": \"#12939A\", \"value\": 3534},\n      {\"name\": \"LinkDistance\", \"hex\": \"#12939A\", \"value\": 5731},\n      {\"name\": \"MaxFlowMinCut\", \"hex\": \"#12939A\", \"value\": 7840},\n      {\"name\": \"ShortestPaths\", \"hex\": \"#12939A\", \"value\": 5914},\n      {\"name\": \"SpanningTree\", \"hex\": \"#12939A\", \"value\": 3416}\n     ]\n    },\n    {\n     \"name\": \"optimization\",\n     \"children\": [\n      {\"name\": \"AspectRatioBanker\", \"hex\": \"#12939A\", \"value\": 7074}\n     ]\n    }\n   ]\n  },\n  {\n   \"name\": \"animate\",\n   \"children\": [\n    {\"name\": \"Easing\", \"hex\": \"#12939A\", \"value\": 17010},\n    {\"name\": \"FunctionSequence\", \"hex\": \"#12939A\", \"value\": 5842},\n    {\n     \"name\": \"interpolate\",\n     \"children\": [\n      {\"name\": \"ArrayInterpolator\", \"hex\": \"#12939A\", \"value\": 1983},\n      {\"name\": \"hexInterpolator\", \"hex\": \"#12939A\", \"value\": 2047},\n      {\"name\": \"DateInterpolator\", \"hex\": \"#12939A\", \"value\": 1375},\n      {\"name\": \"Interpolator\", \"hex\": \"#12939A\", \"value\": 8746},\n      {\"name\": \"MatrixInterpolator\", \"hex\": \"#12939A\", \"value\": 2202},\n      {\"name\": \"NumberInterpolator\", \"hex\": \"#12939A\", \"value\": 1382},\n      {\"name\": \"ObjectInterpolator\", \"hex\": \"#12939A\", \"value\": 1629},\n      {\"name\": \"PointInterpolator\", \"hex\": \"#12939A\", \"value\": 1675},\n      {\"name\": \"RectangleInterpolator\", \"hex\": \"#12939A\", \"value\": 2042}\n     ]\n    },\n    {\"name\": \"ISchedulable\", \"hex\": \"#12939A\", \"value\": 1041},\n    {\"name\": \"Parallel\", \"hex\": \"#12939A\", \"value\": 5176},\n    {\"name\": \"Pause\", \"hex\": \"#12939A\", \"value\": 449},\n    {\"name\": \"Scheduler\", \"hex\": \"#12939A\", \"value\": 5593},\n    {\"name\": \"Sequence\", \"hex\": \"#12939A\", \"value\": 5534},\n    {\"name\": \"Transition\", \"hex\": \"#12939A\", \"value\": 9201},\n    {\"name\": \"Transitioner\", \"hex\": \"#12939A\", \"value\": 19975},\n    {\"name\": \"TransitionEvent\", \"hex\": \"#12939A\", \"value\": 1116},\n    {\"name\": \"Neonate\", \"hex\": \"#12939A\", \"value\": 6006}\n   ]\n  },\n  {\n   \"name\": \"data\",\n   \"children\": [\n    {\n     \"name\": \"converters\",\n     \"children\": [\n      {\"name\": \"Converters\", \"hex\": \"#12939A\", \"value\": 721},\n      {\"name\": \"DelimitedTextConverter\", \"hex\": \"#12939A\", \"value\": 4294},\n      {\"name\": \"GraphMLConverter\", \"hex\": \"#12939A\", \"value\": 9800},\n      {\"name\": \"IDataConverter\", \"hex\": \"#12939A\", \"value\": 1314},\n      {\"name\": \"JSONConverter\", \"hex\": \"#12939A\", \"value\": 2220}\n     ]\n    },\n    {\"name\": \"DataField\", \"hex\": \"#12939A\", \"value\": 1759},\n    {\"name\": \"DataSchema\", \"hex\": \"#12939A\", \"value\": 2165},\n    {\"name\": \"DataSet\", \"hex\": \"#12939A\", \"value\": 586},\n    {\"name\": \"DataSource\", \"hex\": \"#12939A\", \"value\": 3331},\n    {\"name\": \"DataTable\", \"hex\": \"#12939A\", \"value\": 772},\n    {\"name\": \"DataUtil\", \"hex\": \"#12939A\", \"value\": 3322}\n   ]\n  },\n  {\n   \"name\": \"display\",\n   \"children\": [\n    {\"name\": \"DirtySprite\", \"hex\": \"#12939A\", \"value\": 8833},\n    {\"name\": \"LineSprite\", \"hex\": \"#12939A\", \"value\": 1732},\n    {\"name\": \"RectSprite\", \"hex\": \"#12939A\", \"value\": 3623},\n    {\"name\": \"TextSprite\", \"hex\": \"#12939A\", \"value\": 10066}\n   ]\n  },\n  {\n   \"name\": \"flex\",\n   \"children\": [\n    {\"name\": \"FlareVis\", \"hex\": \"#12939A\", \"value\": 4116}\n   ]\n  },\n  {\n   \"name\": \"physics\",\n   \"children\": [\n    {\"name\": \"DragForce\", \"hex\": \"#12939A\", \"value\": 1082},\n    {\"name\": \"GravityForce\", \"hex\": \"#12939A\", \"value\": 1336},\n    {\"name\": \"IForce\", \"hex\": \"#12939A\", \"value\": 319},\n    {\"name\": \"NBodyForce\", \"hex\": \"#12939A\", \"value\": 10498},\n    {\"name\": \"Particle\", \"hex\": \"#12939A\", \"value\": 2822},\n    {\"name\": \"Simulation\", \"hex\": \"#12939A\", \"value\": 9983},\n    {\"name\": \"Spring\", \"hex\": \"#12939A\", \"value\": 2213},\n    {\"name\": \"SpringForce\", \"hex\": \"#12939A\", \"value\": 1681}\n   ]\n  },\n  {\n   \"name\": \"query\",\n   \"children\": [\n    {\"name\": \"AggregateExpression\", \"hex\": \"#12939A\", \"value\": 1616},\n    {\"name\": \"And\", \"hex\": \"#12939A\", \"value\": 1027},\n    {\"name\": \"Arithmetic\", \"hex\": \"#12939A\", \"value\": 3891},\n    {\"name\": \"Average\", \"hex\": \"#12939A\", \"value\": 891},\n    {\"name\": \"BinaryExpression\", \"hex\": \"#12939A\", \"value\": 2893},\n    {\"name\": \"Comparison\", \"hex\": \"#12939A\", \"value\": 5103},\n    {\"name\": \"CompositeExpression\", \"hex\": \"#12939A\", \"value\": 3677},\n    {\"name\": \"Count\", \"hex\": \"#12939A\", \"value\": 781},\n    {\"name\": \"DateUtil\", \"hex\": \"#12939A\", \"value\": 4141},\n    {\"name\": \"Distinct\", \"hex\": \"#12939A\", \"value\": 933},\n    {\"name\": \"Expression\", \"hex\": \"#12939A\", \"value\": 5130},\n    {\"name\": \"ExpressionIterator\", \"hex\": \"#12939A\", \"value\": 3617},\n    {\"name\": \"Fn\", \"hex\": \"#12939A\", \"value\": 3240},\n    {\"name\": \"If\", \"hex\": \"#12939A\", \"value\": 2732},\n    {\"name\": \"IsA\", \"hex\": \"#12939A\", \"value\": 2039},\n    {\"name\": \"Literal\", \"hex\": \"#12939A\", \"value\": 1214},\n    {\"name\": \"Match\", \"hex\": \"#12939A\", \"value\": 3748},\n    {\"name\": \"Maximum\", \"hex\": \"#12939A\", \"value\": 843},\n    {\n     \"name\": \"methods\",\n     \"children\": [\n      {\"name\": \"add\", \"hex\": \"#12939A\", \"value\": 593},\n      {\"name\": \"and\", \"hex\": \"#12939A\", \"value\": 330},\n      {\"name\": \"average\", \"hex\": \"#12939A\", \"value\": 287},\n      {\"name\": \"count\", \"hex\": \"#12939A\", \"value\": 277},\n      {\"name\": \"distinct\", \"hex\": \"#12939A\", \"value\": 292},\n      {\"name\": \"div\", \"hex\": \"#12939A\", \"value\": 595},\n      {\"name\": \"eq\", \"hex\": \"#12939A\", \"value\": 594},\n      {\"name\": \"fn\", \"hex\": \"#12939A\", \"value\": 460},\n      {\"name\": \"gt\", \"hex\": \"#12939A\", \"value\": 603},\n      {\"name\": \"gte\", \"hex\": \"#12939A\", \"value\": 625},\n      {\"name\": \"iff\", \"hex\": \"#12939A\", \"value\": 748},\n      {\"name\": \"isa\", \"hex\": \"#12939A\", \"value\": 461},\n      {\"name\": \"lt\", \"hex\": \"#12939A\", \"value\": 597},\n      {\"name\": \"lte\", \"hex\": \"#12939A\", \"value\": 619},\n      {\"name\": \"max\", \"hex\": \"#12939A\", \"value\": 283},\n      {\"name\": \"min\", \"hex\": \"#12939A\", \"value\": 283},\n      {\"name\": \"mod\", \"hex\": \"#12939A\", \"value\": 591},\n      {\"name\": \"mul\", \"hex\": \"#12939A\", \"value\": 603},\n      {\"name\": \"neq\", \"hex\": \"#12939A\", \"value\": 599},\n      {\"name\": \"not\", \"hex\": \"#12939A\", \"value\": 386},\n      {\"name\": \"or\", \"hex\": \"#12939A\", \"value\": 323},\n      {\"name\": \"orderby\", \"hex\": \"#12939A\", \"value\": 307},\n      {\"name\": \"range\", \"hex\": \"#12939A\", \"value\": 772},\n      {\"name\": \"select\", \"hex\": \"#12939A\", \"value\": 296},\n      {\"name\": \"stddev\", \"hex\": \"#12939A\", \"value\": 363},\n      {\"name\": \"sub\", \"hex\": \"#12939A\", \"value\": 600},\n      {\"name\": \"sum\", \"hex\": \"#12939A\", \"value\": 280},\n      {\"name\": \"update\", \"hex\": \"#12939A\", \"value\": 307},\n      {\"name\": \"variance\", \"hex\": \"#12939A\", \"value\": 335},\n      {\"name\": \"where\", \"hex\": \"#12939A\", \"value\": 299},\n      {\"name\": \"xor\", \"hex\": \"#12939A\", \"value\": 354},\n      {\"name\": \"_\", \"hex\": \"#12939A\", \"value\": 264}\n     ]\n    },\n    {\"name\": \"Minimum\", \"hex\": \"#12939A\", \"value\": 843},\n    {\"name\": \"Not\", \"hex\": \"#12939A\", \"value\": 1554},\n    {\"name\": \"Or\", \"hex\": \"#12939A\", \"value\": 970},\n    {\"name\": \"Query\", \"hex\": \"#12939A\", \"value\": 13896},\n    {\"name\": \"Range\", \"hex\": \"#12939A\", \"value\": 1594},\n    {\"name\": \"StringUtil\", \"hex\": \"#12939A\", \"value\": 4130},\n    {\"name\": \"Sum\", \"hex\": \"#12939A\", \"value\": 791},\n    {\"name\": \"Variable\", \"hex\": \"#12939A\", \"value\": 1124},\n    {\"name\": \"Variance\", \"hex\": \"#12939A\", \"value\": 1876},\n    {\"name\": \"Xor\", \"hex\": \"#12939A\", \"value\": 1101}\n   ]\n  },\n  {\n   \"name\": \"scale\",\n   \"children\": [\n    {\"name\": \"IScaleMap\", \"hex\": \"#FF9833\", \"value\": 2105},\n    {\"name\": \"LinearScale\", \"hex\": \"#FF9833\", \"value\": 1316},\n    {\"name\": \"LogScale\", \"hex\": \"#FF9833\", \"value\": 3151},\n    {\"name\": \"OrdinalScale\", \"hex\": \"#FF9833\", \"value\": 3770},\n    {\"name\": \"QuantileScale\", \"hex\": \"#1A3177\", \"value\": 2435},\n    {\"name\": \"QuantitativeScale\", \"hex\": \"#FF9833\", \"value\": 4839},\n    {\"name\": \"RootScale\", \"hex\": \"#FF9833\", \"value\": 1756},\n    {\"name\": \"Scale\", \"hex\": \"#FF9833\", \"value\": 4268},\n    {\"name\": \"ScaleType\", \"hex\": \"#FF9833\", \"value\": 1821},\n    {\"name\": \"TimeScale\", \"hex\": \"#FF9833\", \"value\": 5833}\n   ]\n  },\n  {\n   \"name\": \"util\",\n   \"children\": [\n    {\"name\": \"Arrays\", \"hex\": \"#12939A\", \"value\": 8258},\n    {\"name\": \"hexs\", \"hex\": \"#12939A\", \"value\": 10001},\n    {\"name\": \"Dates\", \"hex\": \"#12939A\", \"value\": 8217},\n    {\"name\": \"Displays\", \"hex\": \"#12939A\", \"value\": 12555},\n    {\"name\": \"Filter\", \"hex\": \"#12939A\", \"value\": 2324},\n    {\"name\": \"Geometry\", \"hex\": \"#12939A\", \"value\": 10993},\n    {\n     \"name\": \"heap\",\n     \"children\": [\n      {\"name\": \"FibonacciHeap\", \"hex\": \"#12939A\", \"value\": 9354},\n      {\"name\": \"HeapNode\", \"hex\": \"#12939A\", \"value\": 1233}\n     ]\n    },\n    {\"name\": \"IEvaluable\", \"hex\": \"#12939A\", \"value\": 335},\n    {\"name\": \"IPredicate\", \"hex\": \"#12939A\", \"value\": 383},\n    {\"name\": \"IValueProxy\", \"hex\": \"#12939A\", \"value\": 874},\n    {\n     \"name\": \"math\",\n     \"children\": [\n      {\"name\": \"DenseMatrix\", \"hex\": \"#12939A\", \"value\": 3165},\n      {\"name\": \"IMatrix\", \"hex\": \"#12939A\", \"value\": 2815},\n      {\"name\": \"SparseMatrix\", \"hex\": \"#12939A\", \"value\": 3366}\n     ]\n    },\n    {\"name\": \"Maths\", \"hex\": \"#12939A\", \"value\": 17705},\n    {\"name\": \"Orientation\", \"hex\": \"#12939A\", \"value\": 1486},\n    {\n     \"name\": \"palette\",\n     \"children\": [\n      {\"name\": \"hexPalette\", \"hex\": \"#12939A\", \"value\": 6367},\n      {\"name\": \"Palette\", \"hex\": \"#12939A\", \"value\": 1229},\n      {\"name\": \"ShapePalette\", \"hex\": \"#12939A\", \"value\": 2059},\n      {\"name\": \"valuePalette\", \"hex\": \"#12939A\", \"value\": 2291}\n     ]\n    },\n    {\"name\": \"Property\", \"hex\": \"#12939A\", \"value\": 5559},\n    {\"name\": \"Shapes\", \"hex\": \"#12939A\", \"value\": 19118},\n    {\"name\": \"Sort\", \"hex\": \"#12939A\", \"value\": 6887},\n    {\"name\": \"Stats\", \"hex\": \"#12939A\", \"value\": 6557},\n    {\"name\": \"Strings\", \"hex\": \"#12939A\", \"value\": 22026}\n   ]\n  },\n  {\n   \"name\": \"vis\",\n   \"children\": [\n    {\n     \"name\": \"axis\",\n     \"children\": [\n      {\"name\": \"Axes\", \"hex\": \"#12939A\", \"value\": 1302},\n      {\"name\": \"Axis\", \"hex\": \"#12939A\", \"value\": 24593},\n      {\"name\": \"AxisGridLine\", \"hex\": \"#12939A\", \"value\": 652},\n      {\"name\": \"AxisLabel\", \"hex\": \"#12939A\", \"value\": 636},\n      {\"name\": \"CartesianAxes\", \"hex\": \"#12939A\", \"value\": 6703}\n     ]\n    },\n    {\n     \"name\": \"controls\",\n     \"children\": [\n      {\"name\": \"AnchorControl\", \"hex\": \"#12939A\", \"value\": 2138},\n      {\"name\": \"ClickControl\", \"hex\": \"#12939A\", \"value\": 3824},\n      {\"name\": \"Control\", \"hex\": \"#12939A\", \"value\": 1353},\n      {\"name\": \"ControlList\", \"hex\": \"#12939A\", \"value\": 4665},\n      {\"name\": \"DragControl\", \"hex\": \"#12939A\", \"value\": 2649},\n      {\"name\": \"ExpandControl\", \"hex\": \"#12939A\", \"value\": 2832},\n      {\"name\": \"HoverControl\", \"hex\": \"#12939A\", \"value\": 4896},\n      {\"name\": \"IControl\", \"hex\": \"#12939A\", \"value\": 763},\n      {\"name\": \"PanZoomControl\", \"hex\": \"#12939A\", \"value\": 5222},\n      {\"name\": \"SelectionControl\", \"hex\": \"#12939A\", \"value\": 7862},\n      {\"name\": \"TooltipControl\", \"hex\": \"#12939A\", \"value\": 8435}\n     ]\n    },\n    {\n     \"name\": \"data\",\n     \"children\": [\n      {\"name\": \"Data\", \"hex\": \"#12939A\", \"value\": 20544},\n      {\"name\": \"DataList\", \"hex\": \"#12939A\", \"value\": 19788},\n      {\"name\": \"DataSprite\", \"hex\": \"#12939A\", \"value\": 10349},\n      {\"name\": \"EdgeSprite\", \"hex\": \"#12939A\", \"value\": 3301},\n      {\"name\": \"NodeSprite\", \"hex\": \"#12939A\", \"value\": 19382},\n      {\n       \"name\": \"render\",\n       \"children\": [\n        {\"name\": \"ArrowType\", \"hex\": \"#12939A\", \"value\": 698},\n        {\"name\": \"EdgeRenderer\", \"hex\": \"#12939A\", \"value\": 5569},\n        {\"name\": \"IRenderer\", \"hex\": \"#12939A\", \"value\": 353},\n        {\"name\": \"ShapeRenderer\", \"hex\": \"#12939A\", \"value\": 2247}\n       ]\n      },\n      {\"name\": \"ScaleBinding\", \"hex\": \"#12939A\", \"value\": 11275},\n      {\"name\": \"Tree\", \"hex\": \"#12939A\", \"value\": 7147},\n      {\"name\": \"TreeBuilder\", \"hex\": \"#12939A\", \"value\": 9930}\n     ]\n    },\n    {\n     \"name\": \"events\",\n     \"children\": [\n      {\"name\": \"DataEvent\", \"hex\": \"#12939A\", \"value\": 2313},\n      {\"name\": \"SelectionEvent\", \"hex\": \"#12939A\", \"value\": 1880},\n      {\"name\": \"TooltipEvent\", \"hex\": \"#12939A\", \"value\": 1701},\n      {\"name\": \"VisualizationEvent\", \"hex\": \"#12939A\", \"value\": 1117}\n     ]\n    },\n    {\n     \"name\": \"legend\",\n     \"children\": [\n      {\"name\": \"Legend\", \"hex\": \"#12939A\", \"value\": 20859},\n      {\"name\": \"LegendItem\", \"hex\": \"#12939A\", \"value\": 4614},\n      {\"name\": \"LegendRange\", \"hex\": \"#12939A\", \"value\": 10530}\n     ]\n    },\n    {\n     \"name\": \"operator\",\n     \"children\": [\n      {\n       \"name\": \"distortion\",\n       \"children\": [\n        {\"name\": \"BifocalDistortion\", \"hex\": \"#12939A\", \"value\": 4461},\n        {\"name\": \"Distortion\", \"hex\": \"#12939A\", \"value\": 6314},\n        {\"name\": \"FisheyeDistortion\", \"hex\": \"#12939A\", \"value\": 3444}\n       ]\n      },\n      {\n       \"name\": \"encoder\",\n       \"children\": [\n        {\"name\": \"hexEncoder\", \"hex\": \"#12939A\", \"value\": 3179},\n        {\"name\": \"Encoder\", \"hex\": \"#12939A\", \"value\": 4060},\n        {\"name\": \"PropertyEncoder\", \"hex\": \"#12939A\", \"value\": 4138},\n        {\"name\": \"ShapeEncoder\", \"hex\": \"#12939A\", \"value\": 1690},\n        {\"name\": \"valueEncoder\", \"hex\": \"#12939A\", \"value\": 1830}\n       ]\n      },\n      {\n       \"name\": \"filter\",\n       \"children\": [\n        {\"name\": \"FisheyeTreeFilter\", \"hex\": \"#12939A\", \"value\": 5219},\n        {\"name\": \"GraphDistanceFilter\", \"hex\": \"#12939A\", \"value\": 3165},\n        {\"name\": \"VisibilityFilter\", \"hex\": \"#12939A\", \"value\": 3509}\n       ]\n      },\n      {\"name\": \"IOperator\", \"hex\": \"#12939A\", \"value\": 1286},\n      {\n       \"name\": \"label\",\n       \"children\": [\n        {\"name\": \"Labeler\", \"hex\": \"#12939A\", \"value\": 9956},\n        {\"name\": \"RadialLabeler\", \"hex\": \"#12939A\", \"value\": 3899},\n        {\"name\": \"StackedAreaLabeler\", \"hex\": \"#12939A\", \"value\": 3202}\n       ]\n      },\n      {\n       \"name\": \"layout\",\n       \"children\": [\n        {\"name\": \"AxisLayout\", \"hex\": \"#12939A\", \"value\": 6725},\n        {\"name\": \"BundledEdgeRouter\", \"hex\": \"#12939A\", \"value\": 3727},\n        {\"name\": \"CircleLayout\", \"hex\": \"#12939A\", \"value\": 9317},\n        {\"name\": \"CirclePackingLayout\", \"hex\": \"#12939A\", \"value\": 12003},\n        {\"name\": \"DendrogramLayout\", \"hex\": \"#12939A\", \"value\": 4853},\n        {\"name\": \"ForceDirectedLayout\", \"hex\": \"#12939A\", \"value\": 8411},\n        {\"name\": \"IcicleTreeLayout\", \"hex\": \"#12939A\", \"value\": 4864},\n        {\"name\": \"IndentedTreeLayout\", \"hex\": \"#12939A\", \"value\": 3174},\n        {\"name\": \"Layout\", \"hex\": \"#12939A\", \"value\": 7881},\n        {\"name\": \"NodeLinkTreeLayout\", \"hex\": \"#12939A\", \"value\": 12870},\n        {\"name\": \"PieLayout\", \"hex\": \"#12939A\", \"value\": 2728},\n        {\"name\": \"RadialTreeLayout\", \"hex\": \"#12939A\", \"value\": 12348},\n        {\"name\": \"RandomLayout\", \"hex\": \"#12939A\", \"value\": 870},\n        {\"name\": \"StackedAreaLayout\", \"hex\": \"#12939A\", \"value\": 9121},\n        {\"name\": \"TreeMapLayout\", \"hex\": \"#12939A\", \"value\": 9191}\n       ]\n      },\n      {\"name\": \"Operator\", \"hex\": \"#12939A\", \"value\": 2490},\n      {\"name\": \"OperatorList\", \"hex\": \"#12939A\", \"value\": 5248},\n      {\"name\": \"OperatorSequence\", \"hex\": \"#12939A\", \"value\": 4190},\n      {\"name\": \"OperatorSwitch\", \"hex\": \"#12939A\", \"value\": 2581},\n      {\"name\": \"SortOperator\", \"hex\": \"#12939A\", \"value\": 2023}\n     ]\n    },\n    {\"name\": \"Visualization\", \"hex\": \"#12939A\", \"value\": 16540}\n   ]\n  }\n ]\n}\n"
  },
  {
    "path": "packages/showcase/datasets/energy.json",
    "content": "{\n  \"nodes\":  [\n    {\"name\": \"Agricultural 'waste'\"},\n    {\"name\": \"Bio-conversion\"},\n    {\"name\": \"Liquid\"},\n    {\"name\": \"Losses\"},\n    {\"name\": \"Solid\"},\n    {\"name\": \"Gas\"},\n    {\"name\": \"Biofuel imports\"},\n    {\"name\": \"Biomass imports\"},\n    {\"name\": \"Coal imports\"},\n    {\"name\": \"Coal\"},\n    {\"name\": \"Coal reserves\"},\n    {\"name\": \"District heating\"},\n    {\"name\": \"Industry\"},\n    {\"name\": \"Heating and cooling - commercial\"},\n    {\"name\": \"Heating and cooling - homes\"},\n    {\"name\": \"Electricity grid\"},\n    {\"name\": \"Over generation / exports\"},\n    {\"name\": \"H2 conversion\"},\n    {\"name\": \"Road transport\"},\n    {\"name\": \"Agriculture\"},\n    {\"name\": \"Rail transport\"},\n    {\"name\": \"Lighting & appliances - commercial\"},\n    {\"name\": \"Lighting & appliances - homes\"},\n    {\"name\": \"Gas imports\"},\n    {\"name\": \"Ngas\"},\n    {\"name\": \"Gas reserves\"},\n    {\"name\": \"Thermal generation\"},\n    {\"name\": \"Geothermal\"},\n    {\"name\": \"H2\"},\n    {\"name\": \"Hydro\"},\n    {\"name\": \"International shipping\"},\n    {\"name\": \"Domestic aviation\"},\n    {\"name\": \"International aviation\"},\n    {\"name\": \"National navigation\"},\n    {\"name\": \"Marine algae\"},\n    {\"name\": \"Nuclear\"},\n    {\"name\": \"Oil imports\"},\n    {\"name\": \"Oil\"},\n    {\"name\": \"Oil reserves\"},\n    {\"name\": \"Other waste\"},\n    {\"name\": \"Pumped heat\"},\n    {\"name\": \"Solar PV\"},\n    {\"name\": \"Solar Thermal\"},\n    {\"name\": \"Solar\"},\n    {\"name\": \"Tidal\"},\n    {\"name\": \"UK land based bioenergy\"},\n    {\"name\": \"Wave\"},\n    {\"name\": \"Wind\"}\n  ],\n  \"links\":  [\n    {\"source\": 0,\"target\": 1,\"value\": 124.729},\n    {\"source\": 1,\"target\": 2,\"value\": 0.597},\n    {\"source\": 1,\"target\": 3,\"value\": 26.862},\n    {\"source\": 1,\"target\": 4,\"value\": 280.322},\n    {\"source\": 1,\"target\": 5,\"value\": 81.144},\n    {\"source\": 6,\"target\": 2,\"value\": 35},\n    {\"source\": 7,\"target\": 4,\"value\": 35},\n    {\"source\": 8,\"target\": 9,\"value\": 11.606},\n    {\"source\": 10,\"target\": 9,\"value\": 63.965},\n    {\"source\": 9,\"target\": 4,\"value\": 75.571},\n    {\"source\": 11,\"target\": 12,\"value\": 10.639},\n    {\"source\": 11,\"target\": 13,\"value\": 22.505},\n    {\"source\": 11,\"target\": 14,\"value\": 46.184},\n    {\"source\": 15,\"target\": 16,\"value\": 104.453},\n    {\"source\": 15,\"target\": 14,\"value\": 113.726},\n    {\"source\": 15,\"target\": 17,\"value\": 27.14},\n    {\"source\": 15,\"target\": 12,\"value\": 342.165},\n    {\"source\": 15,\"target\": 18,\"value\": 37.797},\n    {\"source\": 15,\"target\": 19,\"value\": 4.412},\n    {\"source\": 15,\"target\": 13,\"value\": 40.858},\n    {\"source\": 15,\"target\": 3,\"value\": 56.691},\n    {\"source\": 15,\"target\": 20,\"value\": 7.863},\n    {\"source\": 15,\"target\": 21,\"value\": 90.008},\n    {\"source\": 15,\"target\": 22,\"value\": 93.494},\n    {\"source\": 23,\"target\": 24,\"value\": 40.719},\n    {\"source\": 25,\"target\": 24,\"value\": 82.233},\n    {\"source\": 5,\"target\": 13,\"value\": 0.129},\n    {\"source\": 5,\"target\": 3,\"value\": 1.401},\n    {\"source\": 5,\"target\": 26,\"value\": 151.891},\n    {\"source\": 5,\"target\": 19,\"value\": 2.096},\n    {\"source\": 5,\"target\": 12,\"value\": 48.58},\n    {\"source\": 27,\"target\": 15,\"value\": 7.013},\n    {\"source\": 17,\"target\": 28,\"value\": 20.897},\n    {\"source\": 17,\"target\": 3,\"value\": 6.242},\n    {\"source\": 28,\"target\": 18,\"value\": 20.897},\n    {\"source\": 29,\"target\": 15,\"value\": 6.995},\n    {\"source\": 2,\"target\": 12,\"value\": 121.066},\n    {\"source\": 2,\"target\": 30,\"value\": 128.69},\n    {\"source\": 2,\"target\": 18,\"value\": 135.835},\n    {\"source\": 2,\"target\": 31,\"value\": 14.458},\n    {\"source\": 2,\"target\": 32,\"value\": 206.267},\n    {\"source\": 2,\"target\": 19,\"value\": 3.64},\n    {\"source\": 2,\"target\": 33,\"value\": 33.218},\n    {\"source\": 2,\"target\": 20,\"value\": 4.413},\n    {\"source\": 34,\"target\": 1,\"value\": 4.375},\n    {\"source\": 24,\"target\": 5,\"value\": 122.952},\n    {\"source\": 35,\"target\": 26,\"value\": 839.978},\n    {\"source\": 36,\"target\": 37,\"value\": 504.287},\n    {\"source\": 38,\"target\": 37,\"value\": 107.703},\n    {\"source\": 37,\"target\": 2,\"value\": 611.99},\n    {\"source\": 39,\"target\": 4,\"value\": 56.587},\n    {\"source\": 39,\"target\": 1,\"value\": 77.81},\n    {\"source\": 40,\"target\": 14,\"value\": 193.026},\n    {\"source\": 40,\"target\": 13,\"value\": 70.672},\n    {\"source\": 41,\"target\": 15,\"value\": 59.901},\n    {\"source\": 42,\"target\": 14,\"value\": 19.263},\n    {\"source\": 43,\"target\": 42,\"value\": 19.263},\n    {\"source\": 43,\"target\": 41,\"value\": 59.901},\n    {\"source\": 4,\"target\": 19,\"value\": 0.882},\n    {\"source\": 4,\"target\": 26,\"value\": 400.12},\n    {\"source\": 4,\"target\": 12,\"value\": 46.477},\n    {\"source\": 26,\"target\": 15,\"value\": 525.531},\n    {\"source\": 26,\"target\": 3,\"value\": 787.129},\n    {\"source\": 26,\"target\": 11,\"value\": 79.329},\n    {\"source\": 44,\"target\": 15,\"value\": 9.452},\n    {\"source\": 45,\"target\": 1,\"value\": 182.01},\n    {\"source\": 46,\"target\": 15,\"value\": 19.013},\n    {\"source\": 47,\"target\": 15,\"value\": 289.366}\n  ]\n}\n"
  },
  {
    "path": "packages/showcase/datasets/iris.json",
    "content": "[\n  {\n    \"sepal length\": 5.1,\n    \"sepal width\": 3.5,\n    \"petal length\": 1.4,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.9,\n    \"sepal width\": 3.0,\n    \"petal length\": 1.4,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.7,\n    \"sepal width\": 3.2,\n    \"petal length\": 1.3,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.6,\n    \"sepal width\": 3.1,\n    \"petal length\": 1.5,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.0,\n    \"sepal width\": 3.6,\n    \"petal length\": 1.4,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.4,\n    \"sepal width\": 3.9,\n    \"petal length\": 1.7,\n    \"petal width\": 0.4,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.6,\n    \"sepal width\": 3.4,\n    \"petal length\": 1.4,\n    \"petal width\": 0.3,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.0,\n    \"sepal width\": 3.4,\n    \"petal length\": 1.5,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.4,\n    \"sepal width\": 2.9,\n    \"petal length\": 1.4,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.9,\n    \"sepal width\": 3.1,\n    \"petal length\": 1.5,\n    \"petal width\": 0.1,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.4,\n    \"sepal width\": 3.7,\n    \"petal length\": 1.5,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.8,\n    \"sepal width\": 3.4,\n    \"petal length\": 1.6,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.8,\n    \"sepal width\": 3.0,\n    \"petal length\": 1.4,\n    \"petal width\": 0.1,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.3,\n    \"sepal width\": 3.0,\n    \"petal length\": 1.1,\n    \"petal width\": 0.1,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.8,\n    \"sepal width\": 4.0,\n    \"petal length\": 1.2,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.7,\n    \"sepal width\": 4.4,\n    \"petal length\": 1.5,\n    \"petal width\": 0.4,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.4,\n    \"sepal width\": 3.9,\n    \"petal length\": 1.3,\n    \"petal width\": 0.4,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.1,\n    \"sepal width\": 3.5,\n    \"petal length\": 1.4,\n    \"petal width\": 0.3,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.7,\n    \"sepal width\": 3.8,\n    \"petal length\": 1.7,\n    \"petal width\": 0.3,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.1,\n    \"sepal width\": 3.8,\n    \"petal length\": 1.5,\n    \"petal width\": 0.3,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.4,\n    \"sepal width\": 3.4,\n    \"petal length\": 1.7,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.1,\n    \"sepal width\": 3.7,\n    \"petal length\": 1.5,\n    \"petal width\": 0.4,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.6,\n    \"sepal width\": 3.6,\n    \"petal length\": 1.0,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.1,\n    \"sepal width\": 3.3,\n    \"petal length\": 1.7,\n    \"petal width\": 0.5,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.8,\n    \"sepal width\": 3.4,\n    \"petal length\": 1.9,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.0,\n    \"sepal width\": 3.0,\n    \"petal length\": 1.6,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.0,\n    \"sepal width\": 3.4,\n    \"petal length\": 1.6,\n    \"petal width\": 0.4,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.2,\n    \"sepal width\": 3.5,\n    \"petal length\": 1.5,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.2,\n    \"sepal width\": 3.4,\n    \"petal length\": 1.4,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.7,\n    \"sepal width\": 3.2,\n    \"petal length\": 1.6,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.8,\n    \"sepal width\": 3.1,\n    \"petal length\": 1.6,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.4,\n    \"sepal width\": 3.4,\n    \"petal length\": 1.5,\n    \"petal width\": 0.4,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.2,\n    \"sepal width\": 4.1,\n    \"petal length\": 1.5,\n    \"petal width\": 0.1,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.5,\n    \"sepal width\": 4.2,\n    \"petal length\": 1.4,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.9,\n    \"sepal width\": 3.1,\n    \"petal length\": 1.5,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.0,\n    \"sepal width\": 3.2,\n    \"petal length\": 1.2,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.5,\n    \"sepal width\": 3.5,\n    \"petal length\": 1.3,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.9,\n    \"sepal width\": 3.6,\n    \"petal length\": 1.4,\n    \"petal width\": 0.1,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.4,\n    \"sepal width\": 3.0,\n    \"petal length\": 1.3,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.1,\n    \"sepal width\": 3.4,\n    \"petal length\": 1.5,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.0,\n    \"sepal width\": 3.5,\n    \"petal length\": 1.3,\n    \"petal width\": 0.3,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.5,\n    \"sepal width\": 2.3,\n    \"petal length\": 1.3,\n    \"petal width\": 0.3,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.4,\n    \"sepal width\": 3.2,\n    \"petal length\": 1.3,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.0,\n    \"sepal width\": 3.5,\n    \"petal length\": 1.6,\n    \"petal width\": 0.6,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.1,\n    \"sepal width\": 3.8,\n    \"petal length\": 1.9,\n    \"petal width\": 0.4,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.8,\n    \"sepal width\": 3.0,\n    \"petal length\": 1.4,\n    \"petal width\": 0.3,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.1,\n    \"sepal width\": 3.8,\n    \"petal length\": 1.6,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 4.6,\n    \"sepal width\": 3.2,\n    \"petal length\": 1.4,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.3,\n    \"sepal width\": 3.7,\n    \"petal length\": 1.5,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 5.0,\n    \"sepal width\": 3.3,\n    \"petal length\": 1.4,\n    \"petal width\": 0.2,\n    \"species\": \"setosa\"\n  },\n  {\n    \"sepal length\": 7.0,\n    \"sepal width\": 3.2,\n    \"petal length\": 4.7,\n    \"petal width\": 1.4,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.4,\n    \"sepal width\": 3.2,\n    \"petal length\": 4.5,\n    \"petal width\": 1.5,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.9,\n    \"sepal width\": 3.1,\n    \"petal length\": 4.9,\n    \"petal width\": 1.5,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.5,\n    \"sepal width\": 2.3,\n    \"petal length\": 4.0,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.5,\n    \"sepal width\": 2.8,\n    \"petal length\": 4.6,\n    \"petal width\": 1.5,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.7,\n    \"sepal width\": 2.8,\n    \"petal length\": 4.5,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.3,\n    \"sepal width\": 3.3,\n    \"petal length\": 4.7,\n    \"petal width\": 1.6,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 4.9,\n    \"sepal width\": 2.4,\n    \"petal length\": 3.3,\n    \"petal width\": 1.0,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.6,\n    \"sepal width\": 2.9,\n    \"petal length\": 4.6,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.2,\n    \"sepal width\": 2.7,\n    \"petal length\": 3.9,\n    \"petal width\": 1.4,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.0,\n    \"sepal width\": 2.0,\n    \"petal length\": 3.5,\n    \"petal width\": 1.0,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.9,\n    \"sepal width\": 3.0,\n    \"petal length\": 4.2,\n    \"petal width\": 1.5,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.0,\n    \"sepal width\": 2.2,\n    \"petal length\": 4.0,\n    \"petal width\": 1.0,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.1,\n    \"sepal width\": 2.9,\n    \"petal length\": 4.7,\n    \"petal width\": 1.4,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.6,\n    \"sepal width\": 2.9,\n    \"petal length\": 3.6,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.7,\n    \"sepal width\": 3.1,\n    \"petal length\": 4.4,\n    \"petal width\": 1.4,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.6,\n    \"sepal width\": 3.0,\n    \"petal length\": 4.5,\n    \"petal width\": 1.5,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.8,\n    \"sepal width\": 2.7,\n    \"petal length\": 4.1,\n    \"petal width\": 1.0,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.2,\n    \"sepal width\": 2.2,\n    \"petal length\": 4.5,\n    \"petal width\": 1.5,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.6,\n    \"sepal width\": 2.5,\n    \"petal length\": 3.9,\n    \"petal width\": 1.1,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.9,\n    \"sepal width\": 3.2,\n    \"petal length\": 4.8,\n    \"petal width\": 1.8,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.1,\n    \"sepal width\": 2.8,\n    \"petal length\": 4.0,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.3,\n    \"sepal width\": 2.5,\n    \"petal length\": 4.9,\n    \"petal width\": 1.5,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.1,\n    \"sepal width\": 2.8,\n    \"petal length\": 4.7,\n    \"petal width\": 1.2,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.4,\n    \"sepal width\": 2.9,\n    \"petal length\": 4.3,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.6,\n    \"sepal width\": 3.0,\n    \"petal length\": 4.4,\n    \"petal width\": 1.4,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.8,\n    \"sepal width\": 2.8,\n    \"petal length\": 4.8,\n    \"petal width\": 1.4,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.7,\n    \"sepal width\": 3.0,\n    \"petal length\": 5.0,\n    \"petal width\": 1.7,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.0,\n    \"sepal width\": 2.9,\n    \"petal length\": 4.5,\n    \"petal width\": 1.5,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.7,\n    \"sepal width\": 2.6,\n    \"petal length\": 3.5,\n    \"petal width\": 1.0,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.5,\n    \"sepal width\": 2.4,\n    \"petal length\": 3.8,\n    \"petal width\": 1.1,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.5,\n    \"sepal width\": 2.4,\n    \"petal length\": 3.7,\n    \"petal width\": 1.0,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.8,\n    \"sepal width\": 2.7,\n    \"petal length\": 3.9,\n    \"petal width\": 1.2,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.0,\n    \"sepal width\": 2.7,\n    \"petal length\": 5.1,\n    \"petal width\": 1.6,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.4,\n    \"sepal width\": 3.0,\n    \"petal length\": 4.5,\n    \"petal width\": 1.5,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.0,\n    \"sepal width\": 3.4,\n    \"petal length\": 4.5,\n    \"petal width\": 1.6,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.7,\n    \"sepal width\": 3.1,\n    \"petal length\": 4.7,\n    \"petal width\": 1.5,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.3,\n    \"sepal width\": 2.3,\n    \"petal length\": 4.4,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.6,\n    \"sepal width\": 3.0,\n    \"petal length\": 4.1,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.5,\n    \"sepal width\": 2.5,\n    \"petal length\": 4.0,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.5,\n    \"sepal width\": 2.6,\n    \"petal length\": 4.4,\n    \"petal width\": 1.2,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.1,\n    \"sepal width\": 3.0,\n    \"petal length\": 4.6,\n    \"petal width\": 1.4,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.8,\n    \"sepal width\": 2.6,\n    \"petal length\": 4.0,\n    \"petal width\": 1.2,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.0,\n    \"sepal width\": 2.3,\n    \"petal length\": 3.3,\n    \"petal width\": 1.0,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.6,\n    \"sepal width\": 2.7,\n    \"petal length\": 4.2,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.7,\n    \"sepal width\": 3.0,\n    \"petal length\": 4.2,\n    \"petal width\": 1.2,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.7,\n    \"sepal width\": 2.9,\n    \"petal length\": 4.2,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.2,\n    \"sepal width\": 2.9,\n    \"petal length\": 4.3,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.1,\n    \"sepal width\": 2.5,\n    \"petal length\": 3.0,\n    \"petal width\": 1.1,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 5.7,\n    \"sepal width\": 2.8,\n    \"petal length\": 4.1,\n    \"petal width\": 1.3,\n    \"species\": \"versicolor\"\n  },\n  {\n    \"sepal length\": 6.3,\n    \"sepal width\": 3.3,\n    \"petal length\": 6.0,\n    \"petal width\": 2.5,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 5.8,\n    \"sepal width\": 2.7,\n    \"petal length\": 5.1,\n    \"petal width\": 1.9,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.1,\n    \"sepal width\": 3.0,\n    \"petal length\": 5.9,\n    \"petal width\": 2.1,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.3,\n    \"sepal width\": 2.9,\n    \"petal length\": 5.6,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.5,\n    \"sepal width\": 3.0,\n    \"petal length\": 5.8,\n    \"petal width\": 2.2,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.6,\n    \"sepal width\": 3.0,\n    \"petal length\": 6.6,\n    \"petal width\": 2.1,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 4.9,\n    \"sepal width\": 2.5,\n    \"petal length\": 4.5,\n    \"petal width\": 1.7,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.3,\n    \"sepal width\": 2.9,\n    \"petal length\": 6.3,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.7,\n    \"sepal width\": 2.5,\n    \"petal length\": 5.8,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.2,\n    \"sepal width\": 3.6,\n    \"petal length\": 6.1,\n    \"petal width\": 2.5,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.5,\n    \"sepal width\": 3.2,\n    \"petal length\": 5.1,\n    \"petal width\": 2.0,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.4,\n    \"sepal width\": 2.7,\n    \"petal length\": 5.3,\n    \"petal width\": 1.9,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.8,\n    \"sepal width\": 3.0,\n    \"petal length\": 5.5,\n    \"petal width\": 2.1,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 5.7,\n    \"sepal width\": 2.5,\n    \"petal length\": 5.0,\n    \"petal width\": 2.0,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 5.8,\n    \"sepal width\": 2.8,\n    \"petal length\": 5.1,\n    \"petal width\": 2.4,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.4,\n    \"sepal width\": 3.2,\n    \"petal length\": 5.3,\n    \"petal width\": 2.3,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.5,\n    \"sepal width\": 3.0,\n    \"petal length\": 5.5,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.7,\n    \"sepal width\": 3.8,\n    \"petal length\": 6.7,\n    \"petal width\": 2.2,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.7,\n    \"sepal width\": 2.6,\n    \"petal length\": 6.9,\n    \"petal width\": 2.3,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.0,\n    \"sepal width\": 2.2,\n    \"petal length\": 5.0,\n    \"petal width\": 1.5,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.9,\n    \"sepal width\": 3.2,\n    \"petal length\": 5.7,\n    \"petal width\": 2.3,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 5.6,\n    \"sepal width\": 2.8,\n    \"petal length\": 4.9,\n    \"petal width\": 2.0,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.7,\n    \"sepal width\": 2.8,\n    \"petal length\": 6.7,\n    \"petal width\": 2.0,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.3,\n    \"sepal width\": 2.7,\n    \"petal length\": 4.9,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.7,\n    \"sepal width\": 3.3,\n    \"petal length\": 5.7,\n    \"petal width\": 2.1,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.2,\n    \"sepal width\": 3.2,\n    \"petal length\": 6.0,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.2,\n    \"sepal width\": 2.8,\n    \"petal length\": 4.8,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.1,\n    \"sepal width\": 3.0,\n    \"petal length\": 4.9,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.4,\n    \"sepal width\": 2.8,\n    \"petal length\": 5.6,\n    \"petal width\": 2.1,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.2,\n    \"sepal width\": 3.0,\n    \"petal length\": 5.8,\n    \"petal width\": 1.6,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.4,\n    \"sepal width\": 2.8,\n    \"petal length\": 6.1,\n    \"petal width\": 1.9,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.9,\n    \"sepal width\": 3.8,\n    \"petal length\": 6.4,\n    \"petal width\": 2.0,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.4,\n    \"sepal width\": 2.8,\n    \"petal length\": 5.6,\n    \"petal width\": 2.2,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.3,\n    \"sepal width\": 2.8,\n    \"petal length\": 5.1,\n    \"petal width\": 1.5,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.1,\n    \"sepal width\": 2.6,\n    \"petal length\": 5.6,\n    \"petal width\": 1.4,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 7.7,\n    \"sepal width\": 3.0,\n    \"petal length\": 6.1,\n    \"petal width\": 2.3,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.3,\n    \"sepal width\": 3.4,\n    \"petal length\": 5.6,\n    \"petal width\": 2.4,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.4,\n    \"sepal width\": 3.1,\n    \"petal length\": 5.5,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.0,\n    \"sepal width\": 3.0,\n    \"petal length\": 4.8,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.9,\n    \"sepal width\": 3.1,\n    \"petal length\": 5.4,\n    \"petal width\": 2.1,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.7,\n    \"sepal width\": 3.1,\n    \"petal length\": 5.6,\n    \"petal width\": 2.4,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.9,\n    \"sepal width\": 3.1,\n    \"petal length\": 5.1,\n    \"petal width\": 2.3,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 5.8,\n    \"sepal width\": 2.7,\n    \"petal length\": 5.1,\n    \"petal width\": 1.9,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.8,\n    \"sepal width\": 3.2,\n    \"petal length\": 5.9,\n    \"petal width\": 2.3,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.7,\n    \"sepal width\": 3.3,\n    \"petal length\": 5.7,\n    \"petal width\": 2.5,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.7,\n    \"sepal width\": 3.0,\n    \"petal length\": 5.2,\n    \"petal width\": 2.3,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.3,\n    \"sepal width\": 2.5,\n    \"petal length\": 5.0,\n    \"petal width\": 1.9,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.5,\n    \"sepal width\": 3.0,\n    \"petal length\": 5.2,\n    \"petal width\": 2.0,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 6.2,\n    \"sepal width\": 3.4,\n    \"petal length\": 5.4,\n    \"petal width\": 2.3,\n    \"species\": \"virginica\"\n  },\n  {\n    \"sepal length\": 5.9,\n    \"sepal width\": 3.0,\n    \"petal length\": 5.1,\n    \"petal width\": 1.8,\n    \"species\": \"virginica\"\n  }\n]\n"
  },
  {
    "path": "packages/showcase/datasets/old-faithful.json",
    "content": "[\n  {\"eruptions\": 3.6, \"waiting\": 79},\n  {\"eruptions\": 1.8, \"waiting\": 54},\n  {\"eruptions\": 3.333, \"waiting\": 74},\n  {\"eruptions\": 2.283, \"waiting\": 62},\n  {\"eruptions\": 4.533, \"waiting\": 85},\n  {\"eruptions\": 2.883, \"waiting\": 55},\n  {\"eruptions\": 4.7, \"waiting\": 88},\n  {\"eruptions\": 3.6, \"waiting\": 85},\n  {\"eruptions\": 1.95, \"waiting\": 51},\n  {\"eruptions\": 4.35, \"waiting\": 85},\n  {\"eruptions\": 1.833, \"waiting\": 54},\n  {\"eruptions\": 3.917, \"waiting\": 84},\n  {\"eruptions\": 4.2, \"waiting\": 78},\n  {\"eruptions\": 1.75, \"waiting\": 47},\n  {\"eruptions\": 4.7, \"waiting\": 83},\n  {\"eruptions\": 2.167, \"waiting\": 52},\n  {\"eruptions\": 1.75, \"waiting\": 62},\n  {\"eruptions\": 4.8, \"waiting\": 84},\n  {\"eruptions\": 1.6, \"waiting\": 52},\n  {\"eruptions\": 4.25, \"waiting\": 79},\n  {\"eruptions\": 1.8, \"waiting\": 51},\n  {\"eruptions\": 1.75, \"waiting\": 47},\n  {\"eruptions\": 3.45, \"waiting\": 78},\n  {\"eruptions\": 3.067, \"waiting\": 69},\n  {\"eruptions\": 4.533, \"waiting\": 74},\n  {\"eruptions\": 3.6, \"waiting\": 83},\n  {\"eruptions\": 1.967, \"waiting\": 55},\n  {\"eruptions\": 4.083, \"waiting\": 76},\n  {\"eruptions\": 3.85, \"waiting\": 78},\n  {\"eruptions\": 4.433, \"waiting\": 79},\n  {\"eruptions\": 4.3, \"waiting\": 73},\n  {\"eruptions\": 4.467, \"waiting\": 77},\n  {\"eruptions\": 3.367, \"waiting\": 66},\n  {\"eruptions\": 4.033, \"waiting\": 80},\n  {\"eruptions\": 3.833, \"waiting\": 74},\n  {\"eruptions\": 2.017, \"waiting\": 52},\n  {\"eruptions\": 1.867, \"waiting\": 48},\n  {\"eruptions\": 4.833, \"waiting\": 80},\n  {\"eruptions\": 1.833, \"waiting\": 59},\n  {\"eruptions\": 4.783, \"waiting\": 90},\n  {\"eruptions\": 4.35, \"waiting\": 80},\n  {\"eruptions\": 1.883, \"waiting\": 58},\n  {\"eruptions\": 4.567, \"waiting\": 84},\n  {\"eruptions\": 1.75, \"waiting\": 58},\n  {\"eruptions\": 4.533, \"waiting\": 73},\n  {\"eruptions\": 3.317, \"waiting\": 83},\n  {\"eruptions\": 3.833, \"waiting\": 64},\n  {\"eruptions\": 2.1, \"waiting\": 53},\n  {\"eruptions\": 4.633, \"waiting\": 82},\n  {\"eruptions\": 2, \"waiting\": 59},\n  {\"eruptions\": 4.8, \"waiting\": 75},\n  {\"eruptions\": 4.716, \"waiting\": 90},\n  {\"eruptions\": 1.833, \"waiting\": 54},\n  {\"eruptions\": 4.833, \"waiting\": 80},\n  {\"eruptions\": 1.733, \"waiting\": 54},\n  {\"eruptions\": 4.883, \"waiting\": 83},\n  {\"eruptions\": 3.717, \"waiting\": 71},\n  {\"eruptions\": 1.667, \"waiting\": 64},\n  {\"eruptions\": 4.567, \"waiting\": 77},\n  {\"eruptions\": 4.317, \"waiting\": 81},\n  {\"eruptions\": 2.233, \"waiting\": 59},\n  {\"eruptions\": 4.5, \"waiting\": 84},\n  {\"eruptions\": 1.75, \"waiting\": 48},\n  {\"eruptions\": 4.8, \"waiting\": 82},\n  {\"eruptions\": 1.817, \"waiting\": 60},\n  {\"eruptions\": 4.4, \"waiting\": 92},\n  {\"eruptions\": 4.167, \"waiting\": 78},\n  {\"eruptions\": 4.7, \"waiting\": 78},\n  {\"eruptions\": 2.067, \"waiting\": 65},\n  {\"eruptions\": 4.7, \"waiting\": 73},\n  {\"eruptions\": 4.033, \"waiting\": 82},\n  {\"eruptions\": 1.967, \"waiting\": 56},\n  {\"eruptions\": 4.5, \"waiting\": 79},\n  {\"eruptions\": 4, \"waiting\": 71},\n  {\"eruptions\": 1.983, \"waiting\": 62},\n  {\"eruptions\": 5.067, \"waiting\": 76},\n  {\"eruptions\": 2.017, \"waiting\": 60},\n  {\"eruptions\": 4.567, \"waiting\": 78},\n  {\"eruptions\": 3.883, \"waiting\": 76},\n  {\"eruptions\": 3.6, \"waiting\": 83},\n  {\"eruptions\": 4.133, \"waiting\": 75},\n  {\"eruptions\": 4.333, \"waiting\": 82},\n  {\"eruptions\": 4.1, \"waiting\": 70},\n  {\"eruptions\": 2.633, \"waiting\": 65},\n  {\"eruptions\": 4.067, \"waiting\": 73},\n  {\"eruptions\": 4.933, \"waiting\": 88},\n  {\"eruptions\": 3.95, \"waiting\": 76},\n  {\"eruptions\": 4.517, \"waiting\": 80},\n  {\"eruptions\": 2.167, \"waiting\": 48},\n  {\"eruptions\": 4, \"waiting\": 86},\n  {\"eruptions\": 2.2, \"waiting\": 60},\n  {\"eruptions\": 4.333, \"waiting\": 90},\n  {\"eruptions\": 1.867, \"waiting\": 50},\n  {\"eruptions\": 4.817, \"waiting\": 78},\n  {\"eruptions\": 1.833, \"waiting\": 63},\n  {\"eruptions\": 4.3, \"waiting\": 72},\n  {\"eruptions\": 4.667, \"waiting\": 84},\n  {\"eruptions\": 3.75, \"waiting\": 75},\n  {\"eruptions\": 1.867, \"waiting\": 51},\n  {\"eruptions\": 4.9, \"waiting\": 82},\n  {\"eruptions\": 2.483, \"waiting\": 62},\n  {\"eruptions\": 4.367, \"waiting\": 88},\n  {\"eruptions\": 2.1, \"waiting\": 49},\n  {\"eruptions\": 4.5, \"waiting\": 83},\n  {\"eruptions\": 4.05, \"waiting\": 81},\n  {\"eruptions\": 1.867, \"waiting\": 47},\n  {\"eruptions\": 4.7, \"waiting\": 84},\n  {\"eruptions\": 1.783, \"waiting\": 52},\n  {\"eruptions\": 4.85, \"waiting\": 86},\n  {\"eruptions\": 3.683, \"waiting\": 81},\n  {\"eruptions\": 4.733, \"waiting\": 75},\n  {\"eruptions\": 2.3, \"waiting\": 59},\n  {\"eruptions\": 4.9, \"waiting\": 89},\n  {\"eruptions\": 4.417, \"waiting\": 79},\n  {\"eruptions\": 1.7, \"waiting\": 59},\n  {\"eruptions\": 4.633, \"waiting\": 81},\n  {\"eruptions\": 2.317, \"waiting\": 50},\n  {\"eruptions\": 4.6, \"waiting\": 85},\n  {\"eruptions\": 1.817, \"waiting\": 59},\n  {\"eruptions\": 4.417, \"waiting\": 87},\n  {\"eruptions\": 2.617, \"waiting\": 53},\n  {\"eruptions\": 4.067, \"waiting\": 69},\n  {\"eruptions\": 4.25, \"waiting\": 77},\n  {\"eruptions\": 1.967, \"waiting\": 56},\n  {\"eruptions\": 4.6, \"waiting\": 88},\n  {\"eruptions\": 3.767, \"waiting\": 81},\n  {\"eruptions\": 1.917, \"waiting\": 45},\n  {\"eruptions\": 4.5, \"waiting\": 82},\n  {\"eruptions\": 2.267, \"waiting\": 55},\n  {\"eruptions\": 4.65, \"waiting\": 90},\n  {\"eruptions\": 1.867, \"waiting\": 45},\n  {\"eruptions\": 4.167, \"waiting\": 83},\n  {\"eruptions\": 2.8, \"waiting\": 56},\n  {\"eruptions\": 4.333, \"waiting\": 89},\n  {\"eruptions\": 1.833, \"waiting\": 46},\n  {\"eruptions\": 4.383, \"waiting\": 82},\n  {\"eruptions\": 1.883, \"waiting\": 51},\n  {\"eruptions\": 4.933, \"waiting\": 86},\n  {\"eruptions\": 2.033, \"waiting\": 53},\n  {\"eruptions\": 3.733, \"waiting\": 79},\n  {\"eruptions\": 4.233, \"waiting\": 81},\n  {\"eruptions\": 2.233, \"waiting\": 60},\n  {\"eruptions\": 4.533, \"waiting\": 82},\n  {\"eruptions\": 4.817, \"waiting\": 77},\n  {\"eruptions\": 4.333, \"waiting\": 76},\n  {\"eruptions\": 1.983, \"waiting\": 59},\n  {\"eruptions\": 4.633, \"waiting\": 80},\n  {\"eruptions\": 2.017, \"waiting\": 49},\n  {\"eruptions\": 5.1, \"waiting\": 96},\n  {\"eruptions\": 1.8, \"waiting\": 53},\n  {\"eruptions\": 5.033, \"waiting\": 77},\n  {\"eruptions\": 4, \"waiting\": 77},\n  {\"eruptions\": 2.4, \"waiting\": 65},\n  {\"eruptions\": 4.6, \"waiting\": 81},\n  {\"eruptions\": 3.567, \"waiting\": 71},\n  {\"eruptions\": 4, \"waiting\": 70},\n  {\"eruptions\": 4.5, \"waiting\": 81},\n  {\"eruptions\": 4.083, \"waiting\": 93},\n  {\"eruptions\": 1.8, \"waiting\": 53},\n  {\"eruptions\": 3.967, \"waiting\": 89},\n  {\"eruptions\": 2.2, \"waiting\": 45},\n  {\"eruptions\": 4.15, \"waiting\": 86},\n  {\"eruptions\": 2, \"waiting\": 58},\n  {\"eruptions\": 3.833, \"waiting\": 78},\n  {\"eruptions\": 3.5, \"waiting\": 66},\n  {\"eruptions\": 4.583, \"waiting\": 76},\n  {\"eruptions\": 2.367, \"waiting\": 63},\n  {\"eruptions\": 5, \"waiting\": 88},\n  {\"eruptions\": 1.933, \"waiting\": 52},\n  {\"eruptions\": 4.617, \"waiting\": 93},\n  {\"eruptions\": 1.917, \"waiting\": 49},\n  {\"eruptions\": 2.083, \"waiting\": 57},\n  {\"eruptions\": 4.583, \"waiting\": 77},\n  {\"eruptions\": 3.333, \"waiting\": 68},\n  {\"eruptions\": 4.167, \"waiting\": 81},\n  {\"eruptions\": 4.333, \"waiting\": 81},\n  {\"eruptions\": 4.5, \"waiting\": 73},\n  {\"eruptions\": 2.417, \"waiting\": 50},\n  {\"eruptions\": 4, \"waiting\": 85},\n  {\"eruptions\": 4.167, \"waiting\": 74},\n  {\"eruptions\": 1.883, \"waiting\": 55},\n  {\"eruptions\": 4.583, \"waiting\": 77},\n  {\"eruptions\": 4.25, \"waiting\": 83},\n  {\"eruptions\": 3.767, \"waiting\": 83},\n  {\"eruptions\": 2.033, \"waiting\": 51},\n  {\"eruptions\": 4.433, \"waiting\": 78},\n  {\"eruptions\": 4.083, \"waiting\": 84},\n  {\"eruptions\": 1.833, \"waiting\": 46},\n  {\"eruptions\": 4.417, \"waiting\": 83},\n  {\"eruptions\": 2.183, \"waiting\": 55},\n  {\"eruptions\": 4.8, \"waiting\": 81},\n  {\"eruptions\": 1.833, \"waiting\": 57},\n  {\"eruptions\": 4.8, \"waiting\": 76},\n  {\"eruptions\": 4.1, \"waiting\": 84},\n  {\"eruptions\": 3.966, \"waiting\": 77},\n  {\"eruptions\": 4.233, \"waiting\": 81},\n  {\"eruptions\": 3.5, \"waiting\": 87},\n  {\"eruptions\": 4.366, \"waiting\": 77},\n  {\"eruptions\": 2.25, \"waiting\": 51},\n  {\"eruptions\": 4.667, \"waiting\": 78},\n  {\"eruptions\": 2.1, \"waiting\": 60},\n  {\"eruptions\": 4.35, \"waiting\": 82},\n  {\"eruptions\": 4.133, \"waiting\": 91},\n  {\"eruptions\": 1.867, \"waiting\": 53},\n  {\"eruptions\": 4.6, \"waiting\": 78},\n  {\"eruptions\": 1.783, \"waiting\": 46},\n  {\"eruptions\": 4.367, \"waiting\": 77},\n  {\"eruptions\": 3.85, \"waiting\": 84},\n  {\"eruptions\": 1.933, \"waiting\": 49},\n  {\"eruptions\": 4.5, \"waiting\": 83},\n  {\"eruptions\": 2.383, \"waiting\": 71},\n  {\"eruptions\": 4.7, \"waiting\": 80},\n  {\"eruptions\": 1.867, \"waiting\": 49},\n  {\"eruptions\": 3.833, \"waiting\": 75},\n  {\"eruptions\": 3.417, \"waiting\": 64},\n  {\"eruptions\": 4.233, \"waiting\": 76},\n  {\"eruptions\": 2.4, \"waiting\": 53},\n  {\"eruptions\": 4.8, \"waiting\": 94},\n  {\"eruptions\": 2, \"waiting\": 55},\n  {\"eruptions\": 4.15, \"waiting\": 76},\n  {\"eruptions\": 1.867, \"waiting\": 50},\n  {\"eruptions\": 4.267, \"waiting\": 82},\n  {\"eruptions\": 1.75, \"waiting\": 54},\n  {\"eruptions\": 4.483, \"waiting\": 75},\n  {\"eruptions\": 4, \"waiting\": 78},\n  {\"eruptions\": 4.117, \"waiting\": 79},\n  {\"eruptions\": 4.083, \"waiting\": 78},\n  {\"eruptions\": 4.267, \"waiting\": 78},\n  {\"eruptions\": 3.917, \"waiting\": 70},\n  {\"eruptions\": 4.55, \"waiting\": 79},\n  {\"eruptions\": 4.083, \"waiting\": 70},\n  {\"eruptions\": 2.417, \"waiting\": 54},\n  {\"eruptions\": 4.183, \"waiting\": 86},\n  {\"eruptions\": 2.217, \"waiting\": 50},\n  {\"eruptions\": 4.45, \"waiting\": 90},\n  {\"eruptions\": 1.883, \"waiting\": 54},\n  {\"eruptions\": 1.85, \"waiting\": 54},\n  {\"eruptions\": 4.283, \"waiting\": 77},\n  {\"eruptions\": 3.95, \"waiting\": 79},\n  {\"eruptions\": 2.333, \"waiting\": 64},\n  {\"eruptions\": 4.15, \"waiting\": 75},\n  {\"eruptions\": 2.35, \"waiting\": 47},\n  {\"eruptions\": 4.933, \"waiting\": 86},\n  {\"eruptions\": 2.9, \"waiting\": 63},\n  {\"eruptions\": 4.583, \"waiting\": 85},\n  {\"eruptions\": 3.833, \"waiting\": 82},\n  {\"eruptions\": 2.083, \"waiting\": 57},\n  {\"eruptions\": 4.367, \"waiting\": 82},\n  {\"eruptions\": 2.133, \"waiting\": 67},\n  {\"eruptions\": 4.35, \"waiting\": 74},\n  {\"eruptions\": 2.2, \"waiting\": 54},\n  {\"eruptions\": 4.45, \"waiting\": 83},\n  {\"eruptions\": 3.567, \"waiting\": 73},\n  {\"eruptions\": 4.5, \"waiting\": 73},\n  {\"eruptions\": 4.15, \"waiting\": 88},\n  {\"eruptions\": 3.817, \"waiting\": 80},\n  {\"eruptions\": 3.917, \"waiting\": 71},\n  {\"eruptions\": 4.45, \"waiting\": 83},\n  {\"eruptions\": 2, \"waiting\": 56},\n  {\"eruptions\": 4.283, \"waiting\": 79},\n  {\"eruptions\": 4.767, \"waiting\": 78},\n  {\"eruptions\": 4.533, \"waiting\": 84},\n  {\"eruptions\": 1.85, \"waiting\": 58},\n  {\"eruptions\": 4.25, \"waiting\": 83},\n  {\"eruptions\": 1.983, \"waiting\": 43},\n  {\"eruptions\": 2.25, \"waiting\": 60},\n  {\"eruptions\": 4.75, \"waiting\": 75},\n  {\"eruptions\": 4.117, \"waiting\": 81},\n  {\"eruptions\": 2.15, \"waiting\": 46},\n  {\"eruptions\": 4.417, \"waiting\": 90},\n  {\"eruptions\": 1.817, \"waiting\": 46},\n  {\"eruptions\": 4.467, \"waiting\": 74}\n]\n"
  },
  {
    "path": "packages/showcase/examples/candlestick/candlestick-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {XAxis, YAxis, LineSeries, FlexibleWidthXYPlot} from 'react-vis';\nimport Candlestick from './candlestick';\n\nimport './candlestick.scss';\n\n/**\n * Generate random random for candle stick chart\n * @param {number} total - Total number of values.\n * @returns {Array} Array of data.\n */\nfunction buildRandomBinnedData(total) {\n  const result = Array(total)\n    .fill(0)\n    .map((x, i) => {\n      const values = [\n        Math.random(),\n        Math.random(),\n        Math.random(),\n        Math.random()\n      ]\n        .sort()\n        .map(d => Math.floor(d * 100));\n      const y = (values[2] + values[1]) / 2;\n      return {\n        x: i,\n        y,\n        yHigh: values[3],\n        yOpen: values[2],\n        yClose: values[1],\n        yLow: values[0],\n        color: y < 25 ? '#EF5D28' : '#12939A',\n        opacity: y > 75 ? 0.7 : 1\n      };\n    });\n  return result;\n}\n\nexport default class CandlestickExample extends React.Component {\n  state = {\n    data: buildRandomBinnedData(30)\n  };\n\n  render() {\n    const {data} = this.state;\n    return (\n      <div className=\"candlestick-example\">\n        <div className=\"chart\">\n          <FlexibleWidthXYPlot animation yDomain={[0, 100]} height={300}>\n            <XAxis />\n            <YAxis />\n            <LineSeries color=\"#12939A\" data={data} />\n            <LineSeries\n              color=\"#FF9833\"\n              className=\"dashed-example-line\"\n              data={[\n                {x: 0, y: 25},\n                {x: 30, y: 25}\n              ]}\n            />\n            <LineSeries\n              color=\"#1A3177\"\n              className=\"dashed-example-line\"\n              opacity={0.3}\n              data={[\n                {x: 0, y: 75},\n                {x: 30, y: 75}\n              ]}\n            />\n            <Candlestick\n              colorType=\"literal\"\n              opacityType=\"literal\"\n              stroke=\"#79C7E3\"\n              data={data}\n            />\n          </FlexibleWidthXYPlot>\n        </div>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/examples/candlestick/candlestick.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {AbstractSeries} from 'react-vis';\n\nconst predefinedClassName =\n  'rv-xy-plot__series rv-xy-plot__series--candlestick';\n\nclass CandlestickSeries extends AbstractSeries {\n  render() {\n    const {className, data, marginLeft, marginTop} = this.props;\n    if (!data) {\n      return null;\n    }\n\n    const xFunctor = this._getAttributeFunctor('x');\n    const yFunctor = this._getAttributeFunctor('y');\n    const strokeFunctor =\n      this._getAttributeFunctor('stroke') || this._getAttributeFunctor('color');\n    const fillFunctor =\n      this._getAttributeFunctor('fill') || this._getAttributeFunctor('color');\n    const opacityFunctor = this._getAttributeFunctor('opacity');\n\n    const distance = Math.abs(xFunctor(data[1]) - xFunctor(data[0])) * 0.2;\n\n    return (\n      <g\n        className={`${predefinedClassName} ${className}`}\n        transform={`translate(${marginLeft},${marginTop})`}\n      >\n        {data.map((d, i) => {\n          const xTrans = xFunctor(d);\n          // Names of values borrowed from here https://en.wikipedia.org/wiki/Candlestick_chart\n          const yHigh = yFunctor({...d, y: d.yHigh});\n          const yOpen = yFunctor({...d, y: d.yOpen});\n          const yClose = yFunctor({...d, y: d.yClose});\n          const yLow = yFunctor({...d, y: d.yLow});\n\n          const lineAttrs = {\n            stroke: strokeFunctor && strokeFunctor(d)\n          };\n\n          const xWidth = distance * 2;\n          return (\n            <g\n              transform={`translate(${xTrans})`}\n              opacity={opacityFunctor ? opacityFunctor(d) : 1}\n              key={i}\n              onClick={e => this._valueClickHandler(d, e)}\n              onMouseOver={e => this._valueMouseOverHandler(d, e)}\n              onMouseOut={e => this._valueMouseOutHandler(d, e)}\n            >\n              <line\n                x1={-xWidth}\n                x2={xWidth}\n                y1={yHigh}\n                y2={yHigh}\n                {...lineAttrs}\n              />\n              <line x1={0} x2={0} y1={yHigh} y2={yLow} {...lineAttrs} />\n              <line\n                x1={-xWidth}\n                x2={xWidth}\n                y1={yLow}\n                y2={yLow}\n                {...lineAttrs}\n              />\n              <rect\n                x={-xWidth}\n                width={Math.max(xWidth * 2, 0)}\n                y={yOpen}\n                height={Math.abs(yOpen - yClose)}\n                fill={fillFunctor && fillFunctor(d)}\n              />\n            </g>\n          );\n        })}\n      </g>\n    );\n  }\n}\n\nCandlestickSeries.displayName = 'CandlestickSeries';\n\nexport default CandlestickSeries;\n"
  },
  {
    "path": "packages/showcase/examples/candlestick/candlestick.scss",
    "content": ".candlestick-example {\n  width: 100%;\n\n  .chart {\n    width: 100%;\n  }\n\n  .dashed-example-line {\n    stroke-dasharray: 2, 2;\n  }\n}\n"
  },
  {
    "path": "packages/showcase/examples/force-directed-graph/force-directed-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {useState} from 'react';\nimport LesMisData from './les-mis-data.json';\n\nimport './force-directed.scss';\nimport ForceDirectedGraph from './force-directed-graph';\n\nconst makeStrength = () => Math.random() * 60 - 30;\nexport default function ForceDirectedExample() {\n  const [strength, setStrength] = useState(makeStrength);\n  return (\n    <div className=\"force-directed-example\">\n      <button\n        className=\"showcase-button\"\n        onClick={() => setStrength(makeStrength())}\n      >\n        REWEIGHT\n      </button>\n      <ForceDirectedGraph\n        data={LesMisData}\n        height={500}\n        width={500}\n        animation\n        strength={strength}\n      />\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/examples/force-directed-graph/force-directed-graph.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {useState, useEffect} from 'react';\nimport {forceSimulation, forceLink, forceManyBody, forceCenter} from 'd3-force';\n\nimport {XYPlot, MarkSeriesCanvas, LineSeriesCanvas} from 'react-vis';\n\nconst colors = [\n  '#19CDD7',\n  '#DDB27C',\n  '#88572C',\n  '#FF991F',\n  '#F15C17',\n  '#223F9A',\n  '#DA70BF',\n  '#4DC19C',\n  '#12939A',\n  '#B7885E',\n  '#FFCB99',\n  '#F89570',\n  '#E79FD5',\n  '#89DAC1'\n];\n\n/**\n * Create the list of nodes to render.\n * @returns {Array} Array of nodes.\n */\nfunction generateSimulation(props) {\n  const {data, height, width, maxSteps, strength} = props;\n  if (!data) {\n    return {nodes: [], links: []};\n  }\n  // copy the data\n  const nodes = data.nodes.map(d => ({...d}));\n  const links = data.links.map(d => ({...d}));\n  // build the simulation\n  const simulation = forceSimulation(nodes)\n    .force(\n      'link',\n      forceLink().id(d => d.id)\n    )\n    .force('charge', forceManyBody().strength(strength))\n    .force('center', forceCenter(width / 2, height / 2))\n    .stop();\n\n  simulation.force('link').links(links);\n\n  const upperBound = Math.ceil(\n    Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())\n  );\n  for (let i = 0; i < Math.min(maxSteps, upperBound); ++i) {\n    simulation.tick();\n  }\n\n  return {nodes, links};\n}\n\nexport default function ForceDirectedGraph(props) {\n  const {\n    className = '',\n    height,\n    width,\n    animation,\n    data = {\n      nodes: [],\n      links: []\n    },\n    maxSteps = 50,\n    strength\n  } = props;\n  const [{nodes, links}, setData] = useState({\n    nodes: [],\n    links: []\n  });\n  useEffect(() => {\n    setData(generateSimulation({data, height, width, maxSteps, strength}));\n  }, [data, height, width, maxSteps, strength]);\n\n  return (\n    <XYPlot width={width} height={height} className={className}>\n      {links.map(({source, target}, index) => {\n        return (\n          <LineSeriesCanvas\n            animation={animation}\n            color={'#B3AD9E'}\n            key={`link-${index}`}\n            opacity={0.3}\n            data={[\n              {...source, color: null},\n              {...target, color: null}\n            ]}\n          />\n        );\n      })}\n      <MarkSeriesCanvas\n        data={nodes}\n        animation={animation}\n        colorType={'category'}\n        stroke={'#ddd'}\n        strokeWidth={2}\n        colorRange={colors}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/examples/force-directed-graph/force-directed.scss",
    "content": ".candlestick-example {\n  width: 100%;\n\n  .chart {\n    width: 100%;\n  }\n\n  .dashed-example-line {\n    stroke-dasharray: 2, 2;\n  }\n}\n"
  },
  {
    "path": "packages/showcase/examples/force-directed-graph/les-mis-data.json",
    "content": "{\n  \"nodes\": [\n    {\"id\": \"Myriel\", \"group\": 1, \"color\": 1},\n    {\"id\": \"Napoleon\", \"group\": 1, \"color\": 1},\n    {\"id\": \"Mlle.Baptistine\", \"group\": 1, \"color\": 1},\n    {\"id\": \"Mme.Magloire\", \"group\": 1, \"color\": 1},\n    {\"id\": \"CountessdeLo\", \"group\": 1, \"color\": 1},\n    {\"id\": \"Geborand\", \"group\": 1, \"color\": 1},\n    {\"id\": \"Champtercier\", \"group\": 1, \"color\": 1},\n    {\"id\": \"Cravatte\", \"group\": 1, \"color\": 1},\n    {\"id\": \"Count\", \"group\": 1, \"color\": 1},\n    {\"id\": \"OldMan\", \"group\": 1, \"color\": 1},\n    {\"id\": \"Labarre\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Valjean\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Marguerite\", \"group\": 3, \"color\": 3},\n    {\"id\": \"Mme.deR\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Isabeau\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Gervais\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Tholomyes\", \"group\": 3, \"color\": 3},\n    {\"id\": \"Listolier\", \"group\": 3, \"color\": 3},\n    {\"id\": \"Fameuil\", \"group\": 3, \"color\": 3},\n    {\"id\": \"Blacheville\", \"group\": 3, \"color\": 3},\n    {\"id\": \"Favourite\", \"group\": 3, \"color\": 3},\n    {\"id\": \"Dahlia\", \"group\": 3, \"color\": 3},\n    {\"id\": \"Zephine\", \"group\": 3, \"color\": 3},\n    {\"id\": \"Fantine\", \"group\": 3, \"color\": 3},\n    {\"id\": \"Mme.Thenardier\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Thenardier\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Cosette\", \"group\": 5, \"color\": 5},\n    {\"id\": \"Javert\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Fauchelevent\", \"group\": 0, \"color\": 0},\n    {\"id\": \"Bamatabois\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Perpetue\", \"group\": 3, \"color\": 3},\n    {\"id\": \"Simplice\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Scaufflaire\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Woman1\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Judge\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Champmathieu\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Brevet\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Chenildieu\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Cochepaille\", \"group\": 2, \"color\": 2},\n    {\"id\": \"Pontmercy\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Boulatruelle\", \"group\": 6, \"color\": 6},\n    {\"id\": \"Eponine\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Anzelma\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Woman2\", \"group\": 5, \"color\": 5},\n    {\"id\": \"MotherInnocent\", \"group\": 0, \"color\": 0},\n    {\"id\": \"Gribier\", \"group\": 0, \"color\": 0},\n    {\"id\": \"Jondrette\", \"group\": 7, \"color\": 7},\n    {\"id\": \"Mme.Burgon\", \"group\": 7, \"color\": 7},\n    {\"id\": \"Gavroche\", \"group\": 8, \"color\": 8},\n    {\"id\": \"Gillenormand\", \"group\": 5, \"color\": 5},\n    {\"id\": \"Magnon\", \"group\": 5, \"color\": 5},\n    {\"id\": \"Mlle.Gillenormand\", \"group\": 5, \"color\": 5},\n    {\"id\": \"Mme.Pontmercy\", \"group\": 5, \"color\": 5},\n    {\"id\": \"Mlle.Vaubois\", \"group\": 5, \"color\": 5},\n    {\"id\": \"Lt.Gillenormand\", \"group\": 5, \"color\": 5},\n    {\"id\": \"Marius\", \"group\": 8, \"color\": 8},\n    {\"id\": \"BaronessT\", \"group\": 5, \"color\": 5},\n    {\"id\": \"Mabeuf\", \"group\": 8, \"color\": 8},\n    {\"id\": \"Enjolras\", \"group\": 8, \"color\": 8},\n    {\"id\": \"Combeferre\", \"group\": 8, \"color\": 8},\n    {\"id\": \"Prouvaire\", \"group\": 8, \"color\": 8},\n    {\"id\": \"Feuilly\", \"group\": 8, \"color\": 8},\n    {\"id\": \"Courfeyrac\", \"group\": 8, \"color\": 8},\n    {\"id\": \"Bahorel\", \"group\": 8, \"color\": 8},\n    {\"id\": \"Bossuet\", \"group\": 8, \"color\": 8},\n    {\"id\": \"Joly\", \"group\": 8, \"color\": 8},\n    {\"id\": \"Grantaire\", \"group\": 8, \"color\": 8},\n    {\"id\": \"MotherPlutarch\", \"group\": 9, \"color\": 9},\n    {\"id\": \"Gueulemer\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Babet\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Claquesous\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Montparnasse\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Toussaint\", \"group\": 5, \"color\": 5},\n    {\"id\": \"Child1\", \"group\": 10, \"color\": 10},\n    {\"id\": \"Child2\", \"group\": 10, \"color\": 10},\n    {\"id\": \"Brujon\", \"group\": 4, \"color\": 4},\n    {\"id\": \"Mme.Hucheloup\", \"group\": 8, \"color\": 8}\n  ],\n  \"links\": [\n    {\"source\": \"Napoleon\", \"target\": \"Myriel\", \"value\": 1},\n    {\"source\": \"Mlle.Baptistine\", \"target\": \"Myriel\", \"value\": 8},\n    {\"source\": \"Mme.Magloire\", \"target\": \"Myriel\", \"value\": 10},\n    {\"source\": \"Mme.Magloire\", \"target\": \"Mlle.Baptistine\", \"value\": 6},\n    {\"source\": \"CountessdeLo\", \"target\": \"Myriel\", \"value\": 1},\n    {\"source\": \"Geborand\", \"target\": \"Myriel\", \"value\": 1},\n    {\"source\": \"Champtercier\", \"target\": \"Myriel\", \"value\": 1},\n    {\"source\": \"Cravatte\", \"target\": \"Myriel\", \"value\": 1},\n    {\"source\": \"Count\", \"target\": \"Myriel\", \"value\": 2},\n    {\"source\": \"OldMan\", \"target\": \"Myriel\", \"value\": 1},\n    {\"source\": \"Valjean\", \"target\": \"Labarre\", \"value\": 1},\n    {\"source\": \"Valjean\", \"target\": \"Mme.Magloire\", \"value\": 3},\n    {\"source\": \"Valjean\", \"target\": \"Mlle.Baptistine\", \"value\": 3},\n    {\"source\": \"Valjean\", \"target\": \"Myriel\", \"value\": 5},\n    {\"source\": \"Marguerite\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Mme.deR\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Isabeau\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Gervais\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Listolier\", \"target\": \"Tholomyes\", \"value\": 4},\n    {\"source\": \"Fameuil\", \"target\": \"Tholomyes\", \"value\": 4},\n    {\"source\": \"Fameuil\", \"target\": \"Listolier\", \"value\": 4},\n    {\"source\": \"Blacheville\", \"target\": \"Tholomyes\", \"value\": 4},\n    {\"source\": \"Blacheville\", \"target\": \"Listolier\", \"value\": 4},\n    {\"source\": \"Blacheville\", \"target\": \"Fameuil\", \"value\": 4},\n    {\"source\": \"Favourite\", \"target\": \"Tholomyes\", \"value\": 3},\n    {\"source\": \"Favourite\", \"target\": \"Listolier\", \"value\": 3},\n    {\"source\": \"Favourite\", \"target\": \"Fameuil\", \"value\": 3},\n    {\"source\": \"Favourite\", \"target\": \"Blacheville\", \"value\": 4},\n    {\"source\": \"Dahlia\", \"target\": \"Tholomyes\", \"value\": 3},\n    {\"source\": \"Dahlia\", \"target\": \"Listolier\", \"value\": 3},\n    {\"source\": \"Dahlia\", \"target\": \"Fameuil\", \"value\": 3},\n    {\"source\": \"Dahlia\", \"target\": \"Blacheville\", \"value\": 3},\n    {\"source\": \"Dahlia\", \"target\": \"Favourite\", \"value\": 5},\n    {\"source\": \"Zephine\", \"target\": \"Tholomyes\", \"value\": 3},\n    {\"source\": \"Zephine\", \"target\": \"Listolier\", \"value\": 3},\n    {\"source\": \"Zephine\", \"target\": \"Fameuil\", \"value\": 3},\n    {\"source\": \"Zephine\", \"target\": \"Blacheville\", \"value\": 3},\n    {\"source\": \"Zephine\", \"target\": \"Favourite\", \"value\": 4},\n    {\"source\": \"Zephine\", \"target\": \"Dahlia\", \"value\": 4},\n    {\"source\": \"Fantine\", \"target\": \"Tholomyes\", \"value\": 3},\n    {\"source\": \"Fantine\", \"target\": \"Listolier\", \"value\": 3},\n    {\"source\": \"Fantine\", \"target\": \"Fameuil\", \"value\": 3},\n    {\"source\": \"Fantine\", \"target\": \"Blacheville\", \"value\": 3},\n    {\"source\": \"Fantine\", \"target\": \"Favourite\", \"value\": 4},\n    {\"source\": \"Fantine\", \"target\": \"Dahlia\", \"value\": 4},\n    {\"source\": \"Fantine\", \"target\": \"Zephine\", \"value\": 4},\n    {\"source\": \"Fantine\", \"target\": \"Marguerite\", \"value\": 2},\n    {\"source\": \"Fantine\", \"target\": \"Valjean\", \"value\": 9},\n    {\"source\": \"Mme.Thenardier\", \"target\": \"Fantine\", \"value\": 2},\n    {\"source\": \"Mme.Thenardier\", \"target\": \"Valjean\", \"value\": 7},\n    {\"source\": \"Thenardier\", \"target\": \"Mme.Thenardier\", \"value\": 13},\n    {\"source\": \"Thenardier\", \"target\": \"Fantine\", \"value\": 1},\n    {\"source\": \"Thenardier\", \"target\": \"Valjean\", \"value\": 12},\n    {\"source\": \"Cosette\", \"target\": \"Mme.Thenardier\", \"value\": 4},\n    {\"source\": \"Cosette\", \"target\": \"Valjean\", \"value\": 31},\n    {\"source\": \"Cosette\", \"target\": \"Tholomyes\", \"value\": 1},\n    {\"source\": \"Cosette\", \"target\": \"Thenardier\", \"value\": 1},\n    {\"source\": \"Javert\", \"target\": \"Valjean\", \"value\": 17},\n    {\"source\": \"Javert\", \"target\": \"Fantine\", \"value\": 5},\n    {\"source\": \"Javert\", \"target\": \"Thenardier\", \"value\": 5},\n    {\"source\": \"Javert\", \"target\": \"Mme.Thenardier\", \"value\": 1},\n    {\"source\": \"Javert\", \"target\": \"Cosette\", \"value\": 1},\n    {\"source\": \"Fauchelevent\", \"target\": \"Valjean\", \"value\": 8},\n    {\"source\": \"Fauchelevent\", \"target\": \"Javert\", \"value\": 1},\n    {\"source\": \"Bamatabois\", \"target\": \"Fantine\", \"value\": 1},\n    {\"source\": \"Bamatabois\", \"target\": \"Javert\", \"value\": 1},\n    {\"source\": \"Bamatabois\", \"target\": \"Valjean\", \"value\": 2},\n    {\"source\": \"Perpetue\", \"target\": \"Fantine\", \"value\": 1},\n    {\"source\": \"Simplice\", \"target\": \"Perpetue\", \"value\": 2},\n    {\"source\": \"Simplice\", \"target\": \"Valjean\", \"value\": 3},\n    {\"source\": \"Simplice\", \"target\": \"Fantine\", \"value\": 2},\n    {\"source\": \"Simplice\", \"target\": \"Javert\", \"value\": 1},\n    {\"source\": \"Scaufflaire\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Woman1\", \"target\": \"Valjean\", \"value\": 2},\n    {\"source\": \"Woman1\", \"target\": \"Javert\", \"value\": 1},\n    {\"source\": \"Judge\", \"target\": \"Valjean\", \"value\": 3},\n    {\"source\": \"Judge\", \"target\": \"Bamatabois\", \"value\": 2},\n    {\"source\": \"Champmathieu\", \"target\": \"Valjean\", \"value\": 3},\n    {\"source\": \"Champmathieu\", \"target\": \"Judge\", \"value\": 3},\n    {\"source\": \"Champmathieu\", \"target\": \"Bamatabois\", \"value\": 2},\n    {\"source\": \"Brevet\", \"target\": \"Judge\", \"value\": 2},\n    {\"source\": \"Brevet\", \"target\": \"Champmathieu\", \"value\": 2},\n    {\"source\": \"Brevet\", \"target\": \"Valjean\", \"value\": 2},\n    {\"source\": \"Brevet\", \"target\": \"Bamatabois\", \"value\": 1},\n    {\"source\": \"Chenildieu\", \"target\": \"Judge\", \"value\": 2},\n    {\"source\": \"Chenildieu\", \"target\": \"Champmathieu\", \"value\": 2},\n    {\"source\": \"Chenildieu\", \"target\": \"Brevet\", \"value\": 2},\n    {\"source\": \"Chenildieu\", \"target\": \"Valjean\", \"value\": 2},\n    {\"source\": \"Chenildieu\", \"target\": \"Bamatabois\", \"value\": 1},\n    {\"source\": \"Cochepaille\", \"target\": \"Judge\", \"value\": 2},\n    {\"source\": \"Cochepaille\", \"target\": \"Champmathieu\", \"value\": 2},\n    {\"source\": \"Cochepaille\", \"target\": \"Brevet\", \"value\": 2},\n    {\"source\": \"Cochepaille\", \"target\": \"Chenildieu\", \"value\": 2},\n    {\"source\": \"Cochepaille\", \"target\": \"Valjean\", \"value\": 2},\n    {\"source\": \"Cochepaille\", \"target\": \"Bamatabois\", \"value\": 1},\n    {\"source\": \"Pontmercy\", \"target\": \"Thenardier\", \"value\": 1},\n    {\"source\": \"Boulatruelle\", \"target\": \"Thenardier\", \"value\": 1},\n    {\"source\": \"Eponine\", \"target\": \"Mme.Thenardier\", \"value\": 2},\n    {\"source\": \"Eponine\", \"target\": \"Thenardier\", \"value\": 3},\n    {\"source\": \"Anzelma\", \"target\": \"Eponine\", \"value\": 2},\n    {\"source\": \"Anzelma\", \"target\": \"Thenardier\", \"value\": 2},\n    {\"source\": \"Anzelma\", \"target\": \"Mme.Thenardier\", \"value\": 1},\n    {\"source\": \"Woman2\", \"target\": \"Valjean\", \"value\": 3},\n    {\"source\": \"Woman2\", \"target\": \"Cosette\", \"value\": 1},\n    {\"source\": \"Woman2\", \"target\": \"Javert\", \"value\": 1},\n    {\"source\": \"MotherInnocent\", \"target\": \"Fauchelevent\", \"value\": 3},\n    {\"source\": \"MotherInnocent\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Gribier\", \"target\": \"Fauchelevent\", \"value\": 2},\n    {\"source\": \"Mme.Burgon\", \"target\": \"Jondrette\", \"value\": 1},\n    {\"source\": \"Gavroche\", \"target\": \"Mme.Burgon\", \"value\": 2},\n    {\"source\": \"Gavroche\", \"target\": \"Thenardier\", \"value\": 1},\n    {\"source\": \"Gavroche\", \"target\": \"Javert\", \"value\": 1},\n    {\"source\": \"Gavroche\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Gillenormand\", \"target\": \"Cosette\", \"value\": 3},\n    {\"source\": \"Gillenormand\", \"target\": \"Valjean\", \"value\": 2},\n    {\"source\": \"Magnon\", \"target\": \"Gillenormand\", \"value\": 1},\n    {\"source\": \"Magnon\", \"target\": \"Mme.Thenardier\", \"value\": 1},\n    {\"source\": \"Mlle.Gillenormand\", \"target\": \"Gillenormand\", \"value\": 9},\n    {\"source\": \"Mlle.Gillenormand\", \"target\": \"Cosette\", \"value\": 2},\n    {\"source\": \"Mlle.Gillenormand\", \"target\": \"Valjean\", \"value\": 2},\n    {\"source\": \"Mme.Pontmercy\", \"target\": \"Mlle.Gillenormand\", \"value\": 1},\n    {\"source\": \"Mme.Pontmercy\", \"target\": \"Pontmercy\", \"value\": 1},\n    {\"source\": \"Mlle.Vaubois\", \"target\": \"Mlle.Gillenormand\", \"value\": 1},\n    {\"source\": \"Lt.Gillenormand\", \"target\": \"Mlle.Gillenormand\", \"value\": 2},\n    {\"source\": \"Lt.Gillenormand\", \"target\": \"Gillenormand\", \"value\": 1},\n    {\"source\": \"Lt.Gillenormand\", \"target\": \"Cosette\", \"value\": 1},\n    {\"source\": \"Marius\", \"target\": \"Mlle.Gillenormand\", \"value\": 6},\n    {\"source\": \"Marius\", \"target\": \"Gillenormand\", \"value\": 12},\n    {\"source\": \"Marius\", \"target\": \"Pontmercy\", \"value\": 1},\n    {\"source\": \"Marius\", \"target\": \"Lt.Gillenormand\", \"value\": 1},\n    {\"source\": \"Marius\", \"target\": \"Cosette\", \"value\": 21},\n    {\"source\": \"Marius\", \"target\": \"Valjean\", \"value\": 19},\n    {\"source\": \"Marius\", \"target\": \"Tholomyes\", \"value\": 1},\n    {\"source\": \"Marius\", \"target\": \"Thenardier\", \"value\": 2},\n    {\"source\": \"Marius\", \"target\": \"Eponine\", \"value\": 5},\n    {\"source\": \"Marius\", \"target\": \"Gavroche\", \"value\": 4},\n    {\"source\": \"BaronessT\", \"target\": \"Gillenormand\", \"value\": 1},\n    {\"source\": \"BaronessT\", \"target\": \"Marius\", \"value\": 1},\n    {\"source\": \"Mabeuf\", \"target\": \"Marius\", \"value\": 1},\n    {\"source\": \"Mabeuf\", \"target\": \"Eponine\", \"value\": 1},\n    {\"source\": \"Mabeuf\", \"target\": \"Gavroche\", \"value\": 1},\n    {\"source\": \"Enjolras\", \"target\": \"Marius\", \"value\": 7},\n    {\"source\": \"Enjolras\", \"target\": \"Gavroche\", \"value\": 7},\n    {\"source\": \"Enjolras\", \"target\": \"Javert\", \"value\": 6},\n    {\"source\": \"Enjolras\", \"target\": \"Mabeuf\", \"value\": 1},\n    {\"source\": \"Enjolras\", \"target\": \"Valjean\", \"value\": 4},\n    {\"source\": \"Combeferre\", \"target\": \"Enjolras\", \"value\": 15},\n    {\"source\": \"Combeferre\", \"target\": \"Marius\", \"value\": 5},\n    {\"source\": \"Combeferre\", \"target\": \"Gavroche\", \"value\": 6},\n    {\"source\": \"Combeferre\", \"target\": \"Mabeuf\", \"value\": 2},\n    {\"source\": \"Prouvaire\", \"target\": \"Gavroche\", \"value\": 1},\n    {\"source\": \"Prouvaire\", \"target\": \"Enjolras\", \"value\": 4},\n    {\"source\": \"Prouvaire\", \"target\": \"Combeferre\", \"value\": 2},\n    {\"source\": \"Feuilly\", \"target\": \"Gavroche\", \"value\": 2},\n    {\"source\": \"Feuilly\", \"target\": \"Enjolras\", \"value\": 6},\n    {\"source\": \"Feuilly\", \"target\": \"Prouvaire\", \"value\": 2},\n    {\"source\": \"Feuilly\", \"target\": \"Combeferre\", \"value\": 5},\n    {\"source\": \"Feuilly\", \"target\": \"Mabeuf\", \"value\": 1},\n    {\"source\": \"Feuilly\", \"target\": \"Marius\", \"value\": 1},\n    {\"source\": \"Courfeyrac\", \"target\": \"Marius\", \"value\": 9},\n    {\"source\": \"Courfeyrac\", \"target\": \"Enjolras\", \"value\": 17},\n    {\"source\": \"Courfeyrac\", \"target\": \"Combeferre\", \"value\": 13},\n    {\"source\": \"Courfeyrac\", \"target\": \"Gavroche\", \"value\": 7},\n    {\"source\": \"Courfeyrac\", \"target\": \"Mabeuf\", \"value\": 2},\n    {\"source\": \"Courfeyrac\", \"target\": \"Eponine\", \"value\": 1},\n    {\"source\": \"Courfeyrac\", \"target\": \"Feuilly\", \"value\": 6},\n    {\"source\": \"Courfeyrac\", \"target\": \"Prouvaire\", \"value\": 3},\n    {\"source\": \"Bahorel\", \"target\": \"Combeferre\", \"value\": 5},\n    {\"source\": \"Bahorel\", \"target\": \"Gavroche\", \"value\": 5},\n    {\"source\": \"Bahorel\", \"target\": \"Courfeyrac\", \"value\": 6},\n    {\"source\": \"Bahorel\", \"target\": \"Mabeuf\", \"value\": 2},\n    {\"source\": \"Bahorel\", \"target\": \"Enjolras\", \"value\": 4},\n    {\"source\": \"Bahorel\", \"target\": \"Feuilly\", \"value\": 3},\n    {\"source\": \"Bahorel\", \"target\": \"Prouvaire\", \"value\": 2},\n    {\"source\": \"Bahorel\", \"target\": \"Marius\", \"value\": 1},\n    {\"source\": \"Bossuet\", \"target\": \"Marius\", \"value\": 5},\n    {\"source\": \"Bossuet\", \"target\": \"Courfeyrac\", \"value\": 12},\n    {\"source\": \"Bossuet\", \"target\": \"Gavroche\", \"value\": 5},\n    {\"source\": \"Bossuet\", \"target\": \"Bahorel\", \"value\": 4},\n    {\"source\": \"Bossuet\", \"target\": \"Enjolras\", \"value\": 10},\n    {\"source\": \"Bossuet\", \"target\": \"Feuilly\", \"value\": 6},\n    {\"source\": \"Bossuet\", \"target\": \"Prouvaire\", \"value\": 2},\n    {\"source\": \"Bossuet\", \"target\": \"Combeferre\", \"value\": 9},\n    {\"source\": \"Bossuet\", \"target\": \"Mabeuf\", \"value\": 1},\n    {\"source\": \"Bossuet\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Joly\", \"target\": \"Bahorel\", \"value\": 5},\n    {\"source\": \"Joly\", \"target\": \"Bossuet\", \"value\": 7},\n    {\"source\": \"Joly\", \"target\": \"Gavroche\", \"value\": 3},\n    {\"source\": \"Joly\", \"target\": \"Courfeyrac\", \"value\": 5},\n    {\"source\": \"Joly\", \"target\": \"Enjolras\", \"value\": 5},\n    {\"source\": \"Joly\", \"target\": \"Feuilly\", \"value\": 5},\n    {\"source\": \"Joly\", \"target\": \"Prouvaire\", \"value\": 2},\n    {\"source\": \"Joly\", \"target\": \"Combeferre\", \"value\": 5},\n    {\"source\": \"Joly\", \"target\": \"Mabeuf\", \"value\": 1},\n    {\"source\": \"Joly\", \"target\": \"Marius\", \"value\": 2},\n    {\"source\": \"Grantaire\", \"target\": \"Bossuet\", \"value\": 3},\n    {\"source\": \"Grantaire\", \"target\": \"Enjolras\", \"value\": 3},\n    {\"source\": \"Grantaire\", \"target\": \"Combeferre\", \"value\": 1},\n    {\"source\": \"Grantaire\", \"target\": \"Courfeyrac\", \"value\": 2},\n    {\"source\": \"Grantaire\", \"target\": \"Joly\", \"value\": 2},\n    {\"source\": \"Grantaire\", \"target\": \"Gavroche\", \"value\": 1},\n    {\"source\": \"Grantaire\", \"target\": \"Bahorel\", \"value\": 1},\n    {\"source\": \"Grantaire\", \"target\": \"Feuilly\", \"value\": 1},\n    {\"source\": \"Grantaire\", \"target\": \"Prouvaire\", \"value\": 1},\n    {\"source\": \"MotherPlutarch\", \"target\": \"Mabeuf\", \"value\": 3},\n    {\"source\": \"Gueulemer\", \"target\": \"Thenardier\", \"value\": 5},\n    {\"source\": \"Gueulemer\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Gueulemer\", \"target\": \"Mme.Thenardier\", \"value\": 1},\n    {\"source\": \"Gueulemer\", \"target\": \"Javert\", \"value\": 1},\n    {\"source\": \"Gueulemer\", \"target\": \"Gavroche\", \"value\": 1},\n    {\"source\": \"Gueulemer\", \"target\": \"Eponine\", \"value\": 1},\n    {\"source\": \"Babet\", \"target\": \"Thenardier\", \"value\": 6},\n    {\"source\": \"Babet\", \"target\": \"Gueulemer\", \"value\": 6},\n    {\"source\": \"Babet\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Babet\", \"target\": \"Mme.Thenardier\", \"value\": 1},\n    {\"source\": \"Babet\", \"target\": \"Javert\", \"value\": 2},\n    {\"source\": \"Babet\", \"target\": \"Gavroche\", \"value\": 1},\n    {\"source\": \"Babet\", \"target\": \"Eponine\", \"value\": 1},\n    {\"source\": \"Claquesous\", \"target\": \"Thenardier\", \"value\": 4},\n    {\"source\": \"Claquesous\", \"target\": \"Babet\", \"value\": 4},\n    {\"source\": \"Claquesous\", \"target\": \"Gueulemer\", \"value\": 4},\n    {\"source\": \"Claquesous\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Claquesous\", \"target\": \"Mme.Thenardier\", \"value\": 1},\n    {\"source\": \"Claquesous\", \"target\": \"Javert\", \"value\": 1},\n    {\"source\": \"Claquesous\", \"target\": \"Eponine\", \"value\": 1},\n    {\"source\": \"Claquesous\", \"target\": \"Enjolras\", \"value\": 1},\n    {\"source\": \"Montparnasse\", \"target\": \"Javert\", \"value\": 1},\n    {\"source\": \"Montparnasse\", \"target\": \"Babet\", \"value\": 2},\n    {\"source\": \"Montparnasse\", \"target\": \"Gueulemer\", \"value\": 2},\n    {\"source\": \"Montparnasse\", \"target\": \"Claquesous\", \"value\": 2},\n    {\"source\": \"Montparnasse\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Montparnasse\", \"target\": \"Gavroche\", \"value\": 1},\n    {\"source\": \"Montparnasse\", \"target\": \"Eponine\", \"value\": 1},\n    {\"source\": \"Montparnasse\", \"target\": \"Thenardier\", \"value\": 1},\n    {\"source\": \"Toussaint\", \"target\": \"Cosette\", \"value\": 2},\n    {\"source\": \"Toussaint\", \"target\": \"Javert\", \"value\": 1},\n    {\"source\": \"Toussaint\", \"target\": \"Valjean\", \"value\": 1},\n    {\"source\": \"Child1\", \"target\": \"Gavroche\", \"value\": 2},\n    {\"source\": \"Child2\", \"target\": \"Gavroche\", \"value\": 2},\n    {\"source\": \"Child2\", \"target\": \"Child1\", \"value\": 3},\n    {\"source\": \"Brujon\", \"target\": \"Babet\", \"value\": 3},\n    {\"source\": \"Brujon\", \"target\": \"Gueulemer\", \"value\": 3},\n    {\"source\": \"Brujon\", \"target\": \"Thenardier\", \"value\": 3},\n    {\"source\": \"Brujon\", \"target\": \"Gavroche\", \"value\": 1},\n    {\"source\": \"Brujon\", \"target\": \"Eponine\", \"value\": 1},\n    {\"source\": \"Brujon\", \"target\": \"Claquesous\", \"value\": 1},\n    {\"source\": \"Brujon\", \"target\": \"Montparnasse\", \"value\": 1},\n    {\"source\": \"Mme.Hucheloup\", \"target\": \"Bossuet\", \"value\": 1},\n    {\"source\": \"Mme.Hucheloup\", \"target\": \"Joly\", \"value\": 1},\n    {\"source\": \"Mme.Hucheloup\", \"target\": \"Grantaire\", \"value\": 1},\n    {\"source\": \"Mme.Hucheloup\", \"target\": \"Bahorel\", \"value\": 1},\n    {\"source\": \"Mme.Hucheloup\", \"target\": \"Courfeyrac\", \"value\": 1},\n    {\"source\": \"Mme.Hucheloup\", \"target\": \"Gavroche\", \"value\": 1},\n    {\"source\": \"Mme.Hucheloup\", \"target\": \"Enjolras\", \"value\": 1}\n  ]\n}\n"
  },
  {
    "path": "packages/showcase/examples/iris-dashboard/iris-dashboard.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {\n  XAxis,\n  YAxis,\n  XYPlot,\n  MarkSeriesCanvas,\n  Borders,\n  Highlight\n} from 'react-vis';\n\nimport Iris from '../../datasets/iris.json';\n\nimport './iris-dashboard.scss';\nconst AXES = ['sepal length', 'sepal width', 'petal length', 'petal width'];\n\nconst SPECIES = ['setosa', 'versicolor', 'virginica'];\n\nconst SIZE = 200;\n\nexport default class IrisDashboard extends React.Component {\n  state = {\n    filters: AXES.reduce((acc, axis) => {\n      acc[axis] = {min: null, max: null};\n      return acc;\n    }, {})\n  };\n\n  render() {\n    const {filters} = this.state;\n\n    const data = Iris.map(d => {\n      const unselected = AXES.some(key => {\n        const filter = filters[key];\n        return (\n          filter.min !== filter.max &&\n          (filter.min > d[key] || filter.max < d[key])\n        );\n      });\n      return {...d, selected: !unselected};\n    });\n    return (\n      <div className=\"iris-dasboard-example\">\n        <div className=\"chart-container\">\n          {AXES.map(yAxis => {\n            return (\n              <div key={yAxis} className=\"chart-row\">\n                {AXES.map(xAxis => {\n                  if (xAxis === yAxis) {\n                    return (\n                      <div\n                        key={`${xAxis}-${yAxis}`}\n                        className=\"axis-label\"\n                        style={{height: SIZE, width: SIZE}}\n                      >\n                        <h3>{xAxis}</h3>\n                      </div>\n                    );\n                  }\n                  const updateFilter = area => {\n                    if (!area) {\n                      filters[xAxis] = {min: null, max: null};\n                      filters[yAxis] = {min: null, max: null};\n                      this.setState({filters});\n                    } else {\n                      const {left, right, top, bottom} = area;\n                      filters[xAxis] = {min: left, max: right};\n                      filters[yAxis] = {min: bottom, max: top};\n                    }\n                    this.setState({filters});\n                  };\n                  return (\n                    <XYPlot\n                      height={SIZE}\n                      width={SIZE}\n                      key={`${xAxis}-${yAxis}`}\n                    >\n                      <MarkSeriesCanvas\n                        data={data.map(d => ({\n                          x: Number(d[xAxis]),\n                          y: Number(d[yAxis]),\n                          color: d.species,\n                          selected: d.selected\n                        }))}\n                        colorType=\"category\"\n                        colorDomain={SPECIES}\n                        colorRange={['#19CDD7', 'red', '#88572C']}\n                        getOpacity={d => (d.selected ? 1 : 0.1)}\n                        size={2}\n                      />\n                      <Borders style={{all: {fill: '#fff'}}} />\n                      <XAxis title={xAxis} />\n                      <YAxis title={yAxis} />\n                      <Highlight\n                        drag\n                        onBrush={updateFilter}\n                        onDrag={updateFilter}\n                        onBrushEnd={updateFilter}\n                      />\n                    </XYPlot>\n                  );\n                })}\n              </div>\n            );\n          })}\n        </div>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/examples/iris-dashboard/iris-dashboard.scss",
    "content": ".iris-dasboard-example {\n  align-items: center;\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n\n  .chart-row {\n    display: flex;\n  }\n\n  .rv-xy-plot__axis__title text {\n    font-size: 8px;\n  }\n\n  .axis-label {\n    align-items: center;\n    display: flex;\n    justify-content: center;\n  }\n}\n"
  },
  {
    "path": "packages/showcase/examples/responsive-vis/responsive-bar-chart.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {AreaSeries, HorizontalBarSeries, XAxis, XYPlot, YAxis} from 'react-vis';\n\nimport {filterFeatures, getPPP} from './responsive-vis-utils';\n\n// range constants\nconst VERY_LOW_RANGE = [0, 0.08];\nconst LOW_RANGE = [0, 0.7];\nconst HIGH_RANGE = [0.7, Infinity];\n\nexport const BARCHART_FEATURES = [\n  {min: -Infinity, max: Infinity, name: 'xaxis', group: 0},\n  {min: VERY_LOW_RANGE[0], max: VERY_LOW_RANGE[1], name: 'yaxis', group: 1},\n  {min: LOW_RANGE[0], max: LOW_RANGE[1], name: 'bars', group: 2},\n  {min: HIGH_RANGE[0], max: HIGH_RANGE[1], name: 'area', group: 2}\n];\n\nfunction updateDataForArea(data, ppp) {\n  // Use the PPP ratio as the step to sample the data\n  const step = Math.round(ppp);\n  const sample = [];\n  let index = data.length - 1;\n  while (index >= 0) {\n    const dataPoint = data[index];\n    sample.unshift({...dataPoint, y: sample.length - 1});\n    index -= step;\n  }\n  return sample;\n}\n\nexport function getFeatures(props) {\n  const {data, height, margin, width} = props;\n  const innerWidth = width - margin.left - margin.right;\n  const innerHeight = height - margin.top - margin.bottom;\n  const ppp = getPPP(innerWidth, innerHeight, data, 'HEIGHT');\n  return filterFeatures(BARCHART_FEATURES, ppp);\n}\n\nexport default function ResponsiveBarChart(props) {\n  const {data, height, margin, width} = props;\n\n  const innerWidth = width - margin.left - margin.right;\n  const innerHeight = height - margin.top - margin.bottom;\n  const ppp = getPPP(innerWidth, innerHeight, data, 'HEIGHT');\n  const featuresToRender = filterFeatures(BARCHART_FEATURES, ppp);\n  const updatedData = featuresToRender.area\n    ? updateDataForArea(data, ppp)\n    : data;\n\n  return (\n    <div className=\"responsive-bar-chart\">\n      <XYPlot\n        yType=\"ordinal\"\n        xType=\"linear\"\n        margin={margin}\n        height={height}\n        width={width}\n      >\n        {featuresToRender.xaxis && <XAxis orientation=\"top\" />}\n        {featuresToRender.yaxis && <YAxis />}\n        {featuresToRender.bars && (\n          <HorizontalBarSeries\n            colorType=\"literal\"\n            yRange={[0, innerHeight]}\n            xRange={[0, innerWidth]}\n            data={updatedData}\n          />\n        )}\n        {featuresToRender.area && (\n          <AreaSeries\n            colorType=\"literal\"\n            color=\"#12939A\"\n            yType=\"linear\"\n            yDomain={[0, updatedData.length]}\n            yRange={[0, innerHeight]}\n            xRange={[innerWidth, 0]}\n            data={updatedData}\n          />\n        )}\n      </XYPlot>\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/examples/responsive-vis/responsive-scatterplot.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {useState, useEffect} from 'react';\nimport {\n  XYPlot,\n  MarkSeries,\n  HeatmapSeries,\n  XAxis,\n  YAxis,\n  Hint,\n  LabelSeries\n} from 'react-vis';\n\nimport {\n  filterFeatures,\n  computeRadius,\n  getPPP,\n  transformToBinData,\n  manicureData\n} from './responsive-vis-utils';\n\n// range constants\nconst SUPER_LOW_RANGE = [0, 1e-4];\nconst VERY_LOW_RANGE = [0, 8e-4];\nconst LOW_RANGE = [0, 5e-3];\nconst MED_LOW_RANGE = [1e-4, 5e-3];\nconst MED_RANGE = [5e-3, 1e-2];\nconst HIGH_RANGE = [1e-2, Infinity];\nconst MED_HIGH_RANGE = [MED_RANGE[0], HIGH_RANGE[1]];\n\nexport const SCATTERPLOT_FEATURES = [\n  {min: -Infinity, max: Infinity, name: 'axes', group: 0},\n  {min: SUPER_LOW_RANGE[0], max: SUPER_LOW_RANGE[1], name: 'labels', group: 1},\n  {\n    min: VERY_LOW_RANGE[0],\n    max: VERY_LOW_RANGE[1],\n    name: 'pointSelection',\n    group: 1\n  },\n  {min: LOW_RANGE[0], max: LOW_RANGE[1], name: 'points', group: 3},\n  {min: MED_LOW_RANGE[0], max: MED_LOW_RANGE[1], name: 'tooltips', group: 2},\n  {min: MED_HIGH_RANGE[0], max: MED_HIGH_RANGE[1], name: 'bins', group: 3},\n  {min: MED_HIGH_RANGE[0], max: MED_HIGH_RANGE[1], name: 'bintips', group: 2},\n  {\n    min: MED_HIGH_RANGE[0],\n    max: MED_HIGH_RANGE[1],\n    name: 'binSelection',\n    group: 1\n  }\n];\n\nexport function getFeatures(props) {\n  const {data, height, margin, width} = props;\n  const innerWidth = width - margin.left - margin.right;\n  const innerHeight = height - margin.top - margin.bottom;\n  const ppp = getPPP(innerWidth, innerHeight, data, 'HEIGHT');\n  return filterFeatures(SCATTERPLOT_FEATURES, ppp);\n}\n\nexport default function ResponsiveScatterplot(props) {\n  const {data, height, margin, width} = props;\n  const [binData, setBinData] = useState([]);\n  const [hoveredPoint, setHoveredPoint] = useState(false);\n  const [selectedPoints, setSelectedPoints] = useState([]);\n  useEffect(() => {\n    setBinData(transformToBinData(data, width, height));\n  }, [data, width, height]);\n  // const {binData, hoveredPoint, selectedPoints} = this.state;\n  function select(accessor) {\n    return (value, e) => {\n      e.event.stopPropagation();\n      let foundValue = false;\n\n      const updatedSelectedPoints = selectedPoints.filter(row => {\n        if (accessor(row) === accessor(value)) {\n          foundValue = true;\n        }\n        return accessor(row) !== accessor(value);\n      });\n\n      if (!foundValue) {\n        updatedSelectedPoints.push(value);\n      }\n      setSelectedPoints(updatedSelectedPoints);\n    };\n  }\n\n  const innerWidth = width - margin.left - margin.right;\n  const innerHeight = height - margin.top - margin.bottom;\n\n  const ppp = getPPP(innerWidth, innerHeight, data, 'TWOD');\n  const featuresToRender = filterFeatures(SCATTERPLOT_FEATURES, ppp);\n  const rememberVal =\n    featuresToRender.pointSelection || featuresToRender.tooltips;\n  const rememberBin = featuresToRender.bintips || featuresToRender.binSelection;\n\n  const pointRadii = computeRadius(data, innerWidth, innerHeight);\n\n  const showHint =\n    (featuresToRender.tooltips || featuresToRender.bintips) && hoveredPoint;\n  return (\n    <div className=\"responsive-vis\">\n      <XYPlot height={height} margin={margin} width={width}>\n        {featuresToRender.axes && <XAxis />}\n        {featuresToRender.axes && <YAxis />}\n        {featuresToRender.bins && (\n          <HeatmapSeries\n            className=\"responsive-vis-heatmap\"\n            colorType=\"literal\"\n            onValueMouseOver={\n              rememberBin ? value => setHoveredPoint(value) : null\n            }\n            onValueMouseOut={rememberBin ? () => setHoveredPoint(null) : null}\n            onValueClick={\n              featuresToRender.binSelection\n                ? select(d => `${d.x}-${d.y}`)\n                : null\n            }\n            data={manicureData(binData, hoveredPoint, selectedPoints, true)}\n          />\n        )}\n        {featuresToRender.points && (\n          <MarkSeries\n            className=\"responsive-vis-scatterplot\"\n            colorType=\"literal\"\n            size={pointRadii}\n            onValueMouseOver={\n              rememberVal ? value => setHoveredPoint(value) : null\n            }\n            onValueMouseOut={rememberVal ? () => setHoveredPoint(null) : null}\n            onValueClick={\n              featuresToRender.pointSelection ? select(d => d.label) : null\n            }\n            data={manicureData(data, hoveredPoint, selectedPoints, false)}\n          />\n        )}\n        {showHint && <Hint value={hoveredPoint} />}\n        {featuresToRender.labels && (\n          <LabelSeries\n            allowOffsetToBeReversed\n            data={data}\n            yOffset={-1 * pointRadii}\n          />\n        )}\n      </XYPlot>\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/examples/responsive-vis/responsive-vis-example.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {useState} from 'react';\n\nimport {createData, getPPP} from './responsive-vis-utils';\nimport ResponsiveScatterplot, {\n  getFeatures as getScatterplotFeatures\n} from './responsive-scatterplot';\nimport ResponsiveBarChart, {\n  getFeatures as getBarFeatures\n} from './responsive-bar-chart';\n\nimport 'styles/examples.scss';\nimport './responsive-vis.scss';\n\nconst ASPECT_RATIO = 1.2;\nconst EXAMPLE_MARGIN = {left: 60, top: 60, bottom: 50, right: 50};\n\nexport default function ResponsiveVisDemo() {\n  const [chartType, setChartType] = useState('barChart');\n  const [data, setData] = useState(() => createData(5, true));\n  const [visSize, setVisSize] = useState(400);\n  const [dataSize, setDataSize] = useState(1);\n\n  const ResponsiveChartType =\n    chartType === 'barChart' ? ResponsiveBarChart : ResponsiveScatterplot;\n\n  const handleTypeClick = chartType => () => {\n    setChartType(chartType);\n    setData(createData(~~Math.pow(10, dataSize), chartType === 'barChart'));\n  };\n\n  const width = visSize;\n  const height = visSize * ASPECT_RATIO;\n  const ppp = getPPP(width, height, data, 'TWOD');\n  const featuresProps = {width, height, data, margin: EXAMPLE_MARGIN};\n  const featuresToRender = (chartType === 'barChart'\n    ? getBarFeatures\n    : getScatterplotFeatures)(featuresProps);\n\n  return (\n    <div className=\"responsive-vis-example\">\n      <div className=\"controls-wrapper\">\n        <div className=\"responsive-controls\">\n          <div className=\"points-per-pixel-label\">{`Points Per Pixel: ${ppp}`}</div>\n          <div className=\"features-label\">\n            {`Features: ${Object.keys(featuresToRender).join(', ')}`}\n          </div>\n          <div className=\"chart-type-selector\">\n            <div\n              className={\n                chartType === 'scatterplot'\n                  ? 'selected-chart-type'\n                  : 'unselected-chart-type'\n              }\n              onClick={handleTypeClick('scatterplot')}\n            >\n              Scatterplot\n            </div>\n            <div\n              className={\n                chartType === 'barChart'\n                  ? 'selected-chart-type'\n                  : 'unselected-chart-type'\n              }\n              onClick={handleTypeClick('barChart')}\n            >\n              BarChart\n            </div>\n          </div>\n          {`Data Size: ${~~Math.pow(10, dataSize)}`}\n          <input\n            onChange={e => {\n              setDataSize(e.target.value);\n              setData(\n                createData(\n                  ~~Math.pow(10, e.target.value),\n                  chartType === 'barChart'\n                )\n              );\n            }}\n            type=\"range\"\n            min={1}\n            max={6}\n            step={0.1}\n            value={dataSize}\n          />\n\n          {`Visualization size: ${visSize}`}\n          <input\n            onChange={e => setVisSize(~~e.target.value)}\n            type=\"range\"\n            min={100}\n            max={1000}\n            value={visSize}\n          />\n        </div>\n      </div>\n      <ResponsiveChartType\n        data={data}\n        margin={EXAMPLE_MARGIN}\n        height={height}\n        width={width}\n      />\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/examples/responsive-vis/responsive-vis-utils.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport {randomNormal} from 'd3-random';\nimport {scaleLinear, scaleQuantize, scaleSqrt} from 'd3-scale';\nimport {max, range} from 'd3-array';\n\n// create fake data\nexport const createData = (dataSize, barChart = true) => {\n  const gen1 = randomNormal(70, 15);\n  const gen2 = randomNormal(50, 8);\n  const gen = i => (i % 3 ? gen1() : gen2());\n\n  const data = new Array(dataSize).fill(0).map((d, index) => ({\n    x: gen(index),\n    y: barChart ? `Point-${index}` : gen(index),\n    label: `Point ${index}`,\n    color: '#12939A'\n  }));\n\n  if (barChart) {\n    data.sort((a, b) => b.x - a.x);\n  }\n  return data;\n};\n\nexport function filterFeatures(features, ppp) {\n  return features.reduce((res, feature) => {\n    if (ppp < feature.min || ppp > feature.max) {\n      return res;\n    }\n    res[feature.name] = true;\n    return res;\n  }, {});\n}\n\nexport function computeRadius(data, width, height) {\n  const targetPPP = 2e-2;\n  const radiusDomain = [2, 12];\n  const r = Math.sqrt((targetPPP * width * height) / data.length);\n  return Math.min(radiusDomain[1], Math.max(radiusDomain[0], r));\n}\n\nexport function getPPP(w, h, data, dimensionality) {\n  // what is TWOD?\n  const pixels =\n    dimensionality === 'TWOD' ? w * h : dimensionality === 'WIDTH' ? w : h;\n  return data.length / pixels;\n}\n\nfunction generateDomain(data) {\n  return data.reduce(\n    (res, row) => ({\n      xMin: Math.min(res.xMin, row.x),\n      xMax: Math.max(res.xMax, row.x),\n      yMin: Math.min(res.yMin, row.y),\n      yMax: Math.max(res.yMax, row.y)\n    }),\n    {xMin: Infinity, xMax: -Infinity, yMin: Infinity, yMax: -Infinity}\n  );\n}\n\nexport function transformToBinData(data, width, height) {\n  const targetPPP = 5e-3;\n  const binCount = ~~Math.sqrt(width * height * targetPPP);\n  const domains = generateDomain(data);\n  const xBin = scaleQuantize()\n    .domain([domains.xMin, domains.xMax])\n    .range(range(binCount));\n  const yBin = scaleQuantize()\n    .domain([domains.yMin, domains.yMax])\n    .range(range(binCount));\n\n  const binData = new Array(binCount * binCount).fill(0);\n  data.forEach(d => {\n    // compute the \"address\" of the bin in the binData hash\n    const index = xBin(d.x) + binCount * yBin(d.y);\n    binData[index]++;\n  });\n  const maxCount = max(binData);\n  const color = scaleSqrt()\n    .domain([0, maxCount])\n    .range(['#fff', '#12939A']);\n\n  return binData.map((d, index) => {\n    const x = index % binCount;\n    const y = ~~(index / binCount);\n    return {x, y, color: color(d), count: d, maxCount};\n  });\n}\n\nfunction transformColor(data, hovered = [], useRange = false) {\n  const samplePoint = data[0];\n  const color = useRange\n    ? scaleLinear()\n        .domain([0, samplePoint.maxCount])\n        .range(['#fff', '#EF5D28'])\n    : () => '#EF5D28';\n\n  const hoveredPoints = hovered.reduce((res, row) => {\n    res[useRange ? `${row.x}-${row.y}` : row.label] = true;\n    return res;\n  }, {});\n  return data.map(row => {\n    if (hoveredPoints[useRange ? `${row.x}-${row.y}` : row.label]) {\n      return {...row, color: color(row.count)};\n    }\n    return row;\n  });\n}\n\nexport function manicureData(data, hoveredPoint, selectedPoints, useRange) {\n  if (!hoveredPoint && selectedPoints.length === 0) {\n    return data;\n  }\n  const concatedData = !hoveredPoint\n    ? selectedPoints\n    : selectedPoints.concat([hoveredPoint]);\n  return transformColor(data, concatedData, useRange);\n}\n"
  },
  {
    "path": "packages/showcase/examples/responsive-vis/responsive-vis.scss",
    "content": ".responsive-vis-example {\n  display: flex;\n  flex-direction: column;\n\n  .responsive-controls {\n    display: flex;\n    flex-direction: column;\n    max-width: 400px;\n  }\n\n  .chart-type-selector {\n    display: flex;\n    justify-content: space-around;\n\n    * {\n      cursor: pointer;\n    }\n  }\n\n  .selected-chart-type {\n    font-weight: 600;\n    text-decoration: underline;\n  }\n\n  .responsive-vis {\n    display: flex;\n    justify-content: center;\n  }\n\n  .responsive-bar-chart {\n    display: flex;\n    justify-content: center;\n\n    .rv-hint {\n      color: #000;\n    }\n  }\n\n  .points-per-pixel-label {\n    font-size: 32px;\n    white-space: nowrap;\n  }\n\n  .features-label {\n    font-size: 24px;\n    white-space: nowrap;\n  }\n\n  .controls-wrapper {\n    align-items: center;\n    display: flex;\n    justify-content: center;\n    width: 100%;\n  }\n}\n"
  },
  {
    "path": "packages/showcase/examples/streamgraph/streamgraph-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport {stack as d3Stack, stackOffsetWiggle} from 'd3-shape';\nimport {range, transpose} from 'd3-array';\n\nimport {FlexibleWidthXYPlot, AreaSeries} from 'react-vis';\n\nimport './streamgraph-example.scss';\n\nconst NUMBER_OF_LAYERS = 20;\nconst SAMPLES_PER_LAYER = 200;\nconst BUMPS_PER_LAYER = 10;\n\nconst bump = (aggregatingData, samplesPerLayer) => {\n  const x = 1 / (0.1 + Math.random());\n  const y = 2 * Math.random() - 0.5;\n  const z = 10 / (0.1 + Math.random());\n\n  return aggregatingData.map((v, i) => {\n    const w = (i / samplesPerLayer - y) * z;\n    return v + x * Math.exp(-w * w);\n  });\n};\n\n// Inspired by Bostock's version of Lee Byron’s test data generator.\nfunction bumps(samplesPerLayer, bumpsPerLayer) {\n  const dataOutline = new Array(samplesPerLayer).fill(0);\n  return range(bumpsPerLayer).reduce(\n    res => bump(res, samplesPerLayer),\n    dataOutline\n  );\n}\n\nfunction generateData() {\n  const stack = d3Stack()\n    .keys(range(NUMBER_OF_LAYERS))\n    .offset(stackOffsetWiggle);\n  const transposed = transpose(\n    range(NUMBER_OF_LAYERS).map(() => bumps(SAMPLES_PER_LAYER, BUMPS_PER_LAYER))\n  );\n  return stack(transposed).map(series =>\n    series.map((row, x) => ({x, y0: row[0], y: row[1]}))\n  );\n}\n\nclass StreamgraphExample extends React.Component {\n  state = {\n    data: generateData(),\n    hoveredIndex: false\n  };\n\n  render() {\n    const {forFrontPage} = this.props;\n    const {data, hoveredIndex} = this.state;\n    return (\n      <div className=\"streamgraph-example\">\n        {!forFrontPage && (\n          <button\n            className=\"showcase-button\"\n            onClick={() => this.setState({data: generateData()})}\n          >\n            {'Click me!'}\n          </button>\n        )}\n        <div className=\"streamgraph\">\n          <FlexibleWidthXYPlot\n            animation\n            onMouseLeave={() => this.setState({hoveredIndex: false})}\n            height={300}\n          >\n            {data.map((series, index) => (\n              <AreaSeries\n                key={index}\n                curve=\"curveNatural\"\n                className={`${\n                  index === hoveredIndex ? 'highlighted-stream' : ''\n                }`}\n                onSeriesMouseOver={() => this.setState({hoveredIndex: index})}\n                data={series}\n              />\n            ))}\n          </FlexibleWidthXYPlot>\n        </div>\n      </div>\n    );\n  }\n}\n\nStreamgraphExample.propTypes = {\n  forFrontPage: PropTypes.bool\n};\n\nexport default StreamgraphExample;\n"
  },
  {
    "path": "packages/showcase/examples/streamgraph/streamgraph-example.scss",
    "content": ".highlighted-stream {\n  stroke: #fff !important;\n  stroke-width: 5px;\n}\n\n.streamgraph .rv-xy-plot__series--line {\n  cursor: pointer;\n}\n\n.markdown-example .streamgraph-example {\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n}\n\n.streamgraph-example {\n  min-width: 400px;\n  width: 100%;\n}\n"
  },
  {
    "path": "packages/showcase/flexible/flexible-examples.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the 'Software'), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  VerticalBarSeries,\n  FlexibleWidthXYPlot,\n  FlexibleHeightXYPlot,\n  FlexibleXYPlot\n} from 'react-vis';\n\nconst data = [\n  {x: 0, y: 8},\n  {x: 1, y: 5},\n  {x: 2, y: 4},\n  {x: 3, y: 9},\n  {x: 4, y: 1},\n  {x: 5, y: 7},\n  {x: 6, y: 6},\n  {x: 7, y: 3},\n  {x: 8, y: 2}\n];\n\nconst defaultProps = {\n  margin: {top: 10, left: 10, right: 10, bottom: 10}\n};\n\nexport const FlexibleCharts = ({height, width}) => (\n  <div>\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'space-between',\n        position: 'relative',\n        width: width || '60vw'\n      }}\n    >\n      <div style={{width: '30%'}}>Flexible width - fixed height</div>\n      <div style={{width: '30%'}}>Flexible height - fixed width</div>\n      <div style={{width: '30%'}}>Flexible width and height</div>\n    </div>\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'space-between',\n        position: 'relative',\n        width: width || '60vw',\n        height: height || '30vh'\n      }}\n    >\n      <div\n        className=\"flexible-width\"\n        style={{width: '30%', height: '100%', border: '1px solid #ccc'}}\n      >\n        <FlexibleWidthXYPlot {...defaultProps} height={100}>\n          <VerticalBarSeries data={data} />\n        </FlexibleWidthXYPlot>\n      </div>\n      <div\n        className=\"flexible-height\"\n        style={{width: '30%', height: '100%', border: '1px solid #ccc'}}\n      >\n        <FlexibleHeightXYPlot {...defaultProps} width={100}>\n          <VerticalBarSeries data={data} />\n        </FlexibleHeightXYPlot>\n      </div>\n      <div\n        className=\"flexible-vis\"\n        style={{width: '30%', height: '100%', border: '1px solid #ccc'}}\n      >\n        <FlexibleXYPlot {...defaultProps}>\n          <VerticalBarSeries data={data} />\n        </FlexibleXYPlot>\n      </div>\n    </div>\n  </div>\n);\n"
  },
  {
    "path": "packages/showcase/index.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>react-vis examples</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"https://fonts.googleapis.com/css?family=Sintony:400,700\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"./app.css\">\n  </head>\n  <body>\n    <script src=\"bundle.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "packages/showcase/index.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport sourceLinker from './showcase-components/source-linker';\nimport {SHOWCASE_LINKS} from './showcase-links';\n\nimport ComplexChart from './plot/complex-chart';\nimport LineChart from './plot/line-chart';\nimport LineChartManyColors from './color/line-chart-many-colors';\nimport LineChartCanvas from './plot/line-chart-canvas';\nimport LineChartWithStyle from './plot/line-chart-with-style';\nimport LineMarkChart from './plot/linemark-chart';\nimport LineSeriesCanvasNearestXYExample from './plot/line-series-canvas-nearest-xy-example';\nimport BarChart from './plot/bar-chart';\nimport BigBaseBarChart from './plot/big-base-bar-chart';\nimport DifferenceChart from './plot/difference-chart';\nimport StackedVerticalBarChart from './plot/stacked-vertical-bar-chart';\nimport LabeledStackedVerticalBarChart from './plot/labeled-stacked-vertical-bar-chart';\nimport StackedHorizontalBarChart from './plot/stacked-horizontal-bar-chart';\nimport ClusteredStackedVerticalBarChart from './plot/clustered-stacked-bar-chart';\nimport StackedHistogram from './plot/stacked-histogram';\nimport Histogram from './plot/histogram';\nimport AreaChart from './plot/area-chart';\nimport AreaChartElevated from './plot/area-chart-elevated';\nimport ScatterplotChart from './plot/scatterplot';\nimport WhiskerChart from './plot/whisker-chart.js';\nimport CustomSVGExample from './plot/custom-svg-example';\nimport CustomSVGRootLevel from './plot/custom-svg-root-level';\nimport CustomSVGAllTheMarks from './plot/custom-svg-all-the-marks';\nimport FauxScatterplotChart from './plot/faux-radial-scatterplot';\nimport ScatterplotCanvas from './plot/scatterplot-canvas';\nimport HeatmapChart from './plot/heatmap-chart';\nimport HexHeatmap from './plot/hex-heatmap';\nimport HexbinSizeExample from './plot/hexbin-size-example';\nimport LabeledHeatmap from './plot/labeled-heatmap';\nimport ContourSeriesExample from './plot/contour-series-example';\nimport WidthHeightMarginChart from './plot/width-height-margin';\nimport CustomScales from './plot/custom-scales';\nimport AxisWithTurnedLabels from './plot/axis-with-turned-labels';\nimport MixedStackedChart from './plot/mixed-stacked-chart';\nimport GridLinesChart from './plot/grid';\n\nimport EnergySankey from './sankey/energy-sankey';\nimport VornoiSankey from './sankey/voronoi';\nimport BasicSankey from './sankey/basic';\n\nimport {\n  SensibleDefaults,\n  ColorInXYPlot,\n  ColorSpecificity,\n  CategoryColorAtMarkLevel,\n  CategoryColorAtMarkLevelCustomPalette,\n  CategoryColorAtMarkLevelFixedStroke,\n  GradientCharts,\n  LinearColorAtMarkLevel,\n  LinearColorAtMarkLevelNoPalette,\n  LineSeriesMarkSeries,\n  LiteralColorAtMarkLevel,\n  CategoryColorAtSeriesLevel,\n  LinearColorAtSeriesLevel,\n  LiteralColorAtSeriesLevel,\n  ReactVis5,\n  ReactVis20,\n  Continuous,\n  CustomPalette\n} from './color/mini-color-examples';\n\nimport {MiniCharts} from './data/mini-data-examples';\n\nimport {\n  LineChartMouseOverSeries,\n  LineChartMouseOverXY,\n  LinkedCharts,\n  ScatterPlotOnNearestXY\n} from './interaction/interaction-examples';\n\nimport {FlexibleCharts} from './flexible/flexible-examples';\n\nimport AxisOn0 from './axes/axis-on-0';\nimport CustomAxesOrientation from './axes/custom-axes-orientation';\nimport CustomAxisChart from './axes/custom-axis';\nimport CustomAxisTickFormat from './axes/custom-axis-tick-format';\nimport CustomAxisTickElement from './axes/custom-axis-tick-element';\nimport CustomAxes from './axes/custom-axes';\nimport DecorativeAxisCrissCross from './axes/decorative-axes-criss-cross';\nimport EmptyChart from './axes/empty-chart';\nimport StaticHints from './axes/static-hints';\nimport DynamicHints from './axes/dynamic-hints';\nimport DynamicComplexEdgeHints from './axes/dynamic-complex-edge-hints';\nimport DynamicSimpleEdgeHints from './axes/dynamic-simple-edge-hints';\nimport DynamicSimpleTopEdgeHints from './axes/dynamic-simple-topedge-hints';\nimport DynamicProgrammaticRightEdgeHints from './axes/dynamic-programmatic-rightedge-hints';\nimport DynamicCrosshair from './axes/dynamic-crosshair';\nimport DynamicCrosshairScatterplot from './axes/dynamic-crosshair-scatterplot';\nimport PaddedAxis from './axes/padded-axis';\nimport ParallelCoordinatesExample from './axes/parallel-coordinates-example';\nimport StaticCrosshair from './axes/static-crosshair';\n\nimport VerticalDiscreteColorLegendExample from './legends/vertical-discrete-color';\nimport HorizontalDiscreteColorLegendExample from './legends/horizontal-discrete-color';\nimport SearchableDiscreteColorLegendExample from './legends/searchable-discrete-color';\nimport SearchableDiscreteColorLegendHoverExample from './legends/searchable-discrete-color-hover';\nimport ContinuousColorLegendExample from './legends/continuous-color';\nimport ContinuousSizeLegendExample from './legends/continuous-size';\nimport HorizontalDiscreteCustomPalette from './legends/horizontal-discrete-custom-palette';\n\nimport AnimationExample from './misc/animation-example';\nimport LabelSeriesExample from './misc/label-series-example';\nimport GradientExample from './misc/gradient-example';\nimport ClipExample from './misc/clip-example';\nimport NullDataExample from './misc/null-data-example';\nimport SyncedCharts from './misc/synced-charts';\nimport TimeChart from './misc/time-chart';\nimport TriangleExample from './misc/triangle-example';\nimport VoronoiLineChart from './misc/voronoi-line-chart';\nimport ZoomableChartExample from './misc/zoomable-chart-example';\nimport SelectionPlotExample from './misc/selection-plot-example';\nimport DragableChartExample from './misc/dragable-chart-example';\nimport BidirectionDragChart from './misc/2d-dragable-plot';\n\nimport SimpleRadialChart from './radial-chart/simple-radial-chart';\nimport DonutChartExample from './radial-chart/donut-chart';\nimport CustomRadiusRadialChart from './radial-chart/custom-radius-radial-chart';\nimport GradientPie from './radial-chart/gradient-pie';\nimport ArcSeriesExample from './radial-chart/arc-series-example';\n\nimport BasicRadarChart from './radar-chart/basic-radar-chart';\nimport AnimatedRadarChart from './radar-chart/animated-radar-chart';\nimport FourQuadrantRadarChart from './radar-chart/four-quadrant-radar-chart';\nimport RadarChartWithTooltips from './radar-chart/radar-chart-with-tooltips';\nimport RadarChartSeriesTooltips from './radar-chart/radar-chart-series-tooltips';\n\nimport BasicParallelCoordinates from './parallel-coordinates/basic-parallel-coordinates';\nimport AnimatedParallelCoordinates from './parallel-coordinates/animated-parallel-coordinates';\nimport BrushedParallelCoordinates from './parallel-coordinates/brushed-parallel-coordinates';\n\nimport BasicSunburst from './sunbursts/basic-sunburst';\nimport ClockExample from './sunbursts/clock-example';\nimport AnimatedSunburst from './sunbursts/animated-sunburst';\nimport SunburstWithTooltips from './sunbursts/sunburst-with-tooltips';\n\nimport BasicSankeyExample from './sankey/basic';\nimport VoronoiSankeyExample from './sankey/voronoi';\nimport EnergySankeyExample from './sankey/energy-sankey';\nimport LinkEventSankeyExample from './sankey/link-event';\nimport LinkHintSankeyExample from './sankey/link-hint';\n\nimport SimpleTreemap from './treemap/simple-treemap';\nimport TreemapExample from './treemap/dynamic-treemap';\n\nconst mainShowCase = {\n  AxisOn0,\n  ComplexChart,\n  LineChart,\n  LineChartManyColors,\n  LineChartCanvas,\n  LineChartWithStyle,\n  LineMarkChart,\n  LineSeriesCanvasNearestXYExample,\n  BarChart,\n  BigBaseBarChart,\n  DifferenceChart,\n  StackedVerticalBarChart,\n  LabeledStackedVerticalBarChart,\n  MixedStackedChart,\n  StackedHorizontalBarChart,\n  ClusteredStackedVerticalBarChart,\n  StackedHistogram,\n  Histogram,\n  AnimationExample,\n  AreaChart,\n  AreaChartElevated,\n  FauxScatterplotChart,\n  CustomSVGExample,\n  CustomSVGRootLevel,\n  CustomSVGAllTheMarks,\n  ScatterplotChart,\n  ScatterplotCanvas,\n  WhiskerChart,\n  HeatmapChart,\n  HexHeatmap,\n  HexbinSizeExample,\n  LabeledHeatmap,\n  ContourSeriesExample,\n  WidthHeightMarginChart,\n  CustomScales,\n  CustomAxesOrientation,\n  CustomAxisChart,\n  CustomAxisTickFormat,\n  CustomAxisTickElement,\n  AxisWithTurnedLabels,\n  GridLinesChart,\n  StaticHints,\n  DecorativeAxisCrissCross,\n  DynamicHints,\n  DynamicComplexEdgeHints,\n  DynamicSimpleEdgeHints,\n  DynamicSimpleTopEdgeHints,\n  DynamicProgrammaticRightEdgeHints,\n  EmptyChart,\n  StaticCrosshair,\n  DynamicCrosshair,\n  DynamicCrosshairScatterplot,\n  PaddedAxis,\n  ParallelCoordinatesExample,\n  SyncedCharts,\n  TimeChart,\n  TriangleExample,\n  VoronoiLineChart,\n  CustomAxes,\n  LabelSeriesExample,\n  GradientExample,\n  ClipExample,\n  NullDataExample,\n  ZoomableChartExample,\n  SelectionPlotExample,\n  DragableChartExample,\n  BidirectionDragChart,\n\n  SensibleDefaults,\n  ColorInXYPlot,\n  ColorSpecificity,\n  CategoryColorAtMarkLevel,\n  CategoryColorAtMarkLevelCustomPalette,\n  CategoryColorAtMarkLevelFixedStroke,\n  GradientCharts,\n  LinearColorAtMarkLevel,\n  LinearColorAtMarkLevelNoPalette,\n  LineSeriesMarkSeries,\n  LiteralColorAtMarkLevel,\n  CategoryColorAtSeriesLevel,\n  LinearColorAtSeriesLevel,\n  LiteralColorAtSeriesLevel,\n  ReactVis5,\n  ReactVis20,\n  Continuous,\n  CustomPalette,\n\n  MiniCharts,\n\n  FlexibleCharts,\n\n  LineChartMouseOverSeries,\n  LineChartMouseOverXY,\n  LinkedCharts,\n  ScatterPlotOnNearestXY,\n\n  SimpleTreemap,\n  TreemapExample,\n\n  AnimatedSunburst,\n  BasicSunburst,\n  ClockExample,\n  SunburstWithTooltips,\n\n  SimpleRadialChart,\n  DonutChartExample,\n  CustomRadiusRadialChart,\n  GradientPie,\n  ArcSeriesExample,\n\n  AnimatedRadarChart,\n  BasicRadarChart,\n  FourQuadrantRadarChart,\n  RadarChartWithTooltips,\n  RadarChartSeriesTooltips,\n\n  BasicParallelCoordinates,\n  AnimatedParallelCoordinates,\n  BrushedParallelCoordinates,\n\n  BasicSankeyExample,\n  VoronoiSankeyExample,\n  EnergySankeyExample,\n  LinkEventSankeyExample,\n  LinkHintSankeyExample,\n\n  VerticalDiscreteColorLegendExample,\n  HorizontalDiscreteColorLegendExample,\n  HorizontalDiscreteCustomPalette,\n  SearchableDiscreteColorLegendExample,\n  SearchableDiscreteColorLegendHoverExample,\n  ContinuousColorLegendExample,\n  ContinuousSizeLegendExample,\n\n  EnergySankey,\n  BasicSankey,\n  VornoiSankey\n};\n\nconst showCaseWithLinks = Object.keys(mainShowCase).reduce(\n  (acc, showCaseExample) => {\n    const link = SHOWCASE_LINKS[showCaseExample];\n    acc[`${showCaseExample}WithLink`] = sourceLinker(\n      mainShowCase[showCaseExample],\n      link\n    );\n    return acc;\n  },\n  {}\n);\n\nexport const showCase = {...mainShowCase, ...showCaseWithLinks};\n"
  },
  {
    "path": "packages/showcase/interaction/interaction-examples.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the 'Software'), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport {XYPlot, LineSeries, MarkSeries} from 'react-vis';\n\nconst scatterPlotData = [...Array(30).keys()].map(() => ({\n  x: Math.random() * 10,\n  y: Math.random() * 10\n}));\n\nconst lineData = [...Array(3).keys()].map(() =>\n  [...Array(10).keys()].map(x => ({x, y: Math.random() * 10}))\n);\n\nconst allData = lineData.reduce((prev, curr, i) => {\n  return [...prev, ...curr.map(d => ({...d, seriesNb: i}))];\n}, []);\n\nconst defaultProps = {\n  width: 400,\n  height: 200,\n  margin: {top: 5, left: 5, right: 5, bottom: 5}\n};\n\nexport class ScatterPlotOnNearestXY extends Component {\n  constructor() {\n    super();\n    this.state = {index: null};\n  }\n  render() {\n    const {index} = this.state;\n    const data = scatterPlotData.map((d, i) => ({\n      ...d,\n      color: i === index ? 1 : 0\n    }));\n    return (\n      <XYPlot\n        {...defaultProps}\n        xDomain={[-0.5, 9.5]}\n        yDomain={[-0.5, 9.5]}\n        size={5}\n        colorDomain={[0, 1]}\n        onMouseLeave={() => this.setState({index: null})}\n      >\n        <MarkSeries\n          data={data}\n          stroke=\"white\"\n          onNearestXY={(d, e) => this.setState({index: e.index})}\n        />\n      </XYPlot>\n    );\n  }\n}\n\nexport class LineChartMouseOverSeries extends Component {\n  constructor() {\n    super();\n    this.state = {index: null};\n  }\n  render() {\n    const {index} = this.state;\n    return (\n      <XYPlot\n        {...defaultProps}\n        onMouseLeave={() => this.setState({index: null})}\n      >\n        {lineData.map((d, i) => (\n          <LineSeries\n            data={d}\n            key={`${i}`}\n            stroke={i === index ? 'orange' : undefined}\n          />\n        ))}\n        {lineData.map((d, i) => (\n          <LineSeries\n            data={d}\n            key={`${i}-mouseover`}\n            onSeriesMouseOut={() => this.setState({index: null})}\n            onSeriesMouseOver={() => this.setState({index: i})}\n            strokeWidth={10}\n            stroke={index === i ? 'rgba(0,0,0,0.2)' : 'transparent'}\n          />\n        ))}\n      </XYPlot>\n    );\n  }\n}\n\nexport class LineChartMouseOverXY extends Component {\n  constructor() {\n    super();\n    this.state = {highlightedSeries: null, pointUsed: null};\n  }\n  render() {\n    const {pointUsed, highlightedSeries} = this.state;\n    const data = allData.map((d, i) => ({\n      ...d,\n      color: i === pointUsed ? 'rgba(0,0,0,0.2)' : 'transparent'\n    }));\n\n    return (\n      <XYPlot\n        {...defaultProps}\n        onMouseLeave={() =>\n          this.setState({\n            highlightedSeries: null,\n            pointUsed: null\n          })\n        }\n      >\n        {lineData.map((d, i) => (\n          <LineSeries\n            data={d}\n            key={`${i}`}\n            stroke={i === highlightedSeries ? 'orange' : undefined}\n          />\n        ))}\n        <MarkSeries\n          data={data}\n          colorType=\"literal\"\n          size={10}\n          onNearestXY={({seriesNb}, {index}) =>\n            this.setState({\n              highlightedSeries: seriesNb,\n              pointUsed: index\n            })\n          }\n        />\n      </XYPlot>\n    );\n  }\n}\n\nexport class LinkedCharts extends Component {\n  constructor() {\n    super();\n    this.state = {index: null};\n  }\n\n  handleMouseOver = index => {\n    this.setState({index});\n  };\n\n  render() {\n    const {index} = this.state;\n    return (\n      <div>\n        {lineData.map((d, i) => (\n          <div key={i}>\n            <LineChart\n              data={d}\n              index={index}\n              handleMouseOver={this.handleMouseOver}\n            />\n          </div>\n        ))}\n      </div>\n    );\n  }\n}\n\nfunction LineChart({data, index, handleMouseOver}) {\n  return (\n    <XYPlot\n      {...defaultProps}\n      height={80}\n      yDomain={[0, 10]}\n      onMouseLeave={() => handleMouseOver(null)}\n    >\n      <LineSeries data={data} onNearestX={(d, e) => handleMouseOver(e.index)} />\n      {index === null ? null : (\n        <LineSeries\n          data={[\n            {x: index, y: 0},\n            {x: index, y: 10}\n          ]}\n          opacity={0.5}\n        />\n      )}\n      {index === null ? null : (\n        <MarkSeries data={[data[index]]} stroke=\"white\" />\n      )}\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/legends/continuous-color.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport ContinuousColorLegend from 'react-vis/legends/continuous-color-legend';\n\nexport default class Example extends React.Component {\n  constructor(props) {\n    super(props);\n  }\n\n  render() {\n    return (\n      <ContinuousColorLegend\n        width={300}\n        startTitle=\"100\"\n        midTitle=\"150\"\n        endTitle=\"200\"\n      />\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/legends/continuous-size.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport ContinuousSizeLegend from 'react-vis/legends/continuous-size-legend';\n\nexport default class Example extends React.Component {\n  constructor(props) {\n    super(props);\n  }\n\n  render() {\n    return <ContinuousSizeLegend width={200} startTitle=\"100\" endTitle=\"200\" />;\n  }\n}\n"
  },
  {
    "path": "packages/showcase/legends/horizontal-discrete-color.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport DiscreteColorLegend from 'react-vis/legends/discrete-color-legend';\nimport GradientDefs from 'react-vis/plot/gradient-defs';\n\nconst ITEMS = [\n  {title: 'Dashed', color: '#45aeb1', strokeStyle: 'dashed'},\n  {title: 'Dasharray', color: '#f93', strokeDasharray: '1 2 3 4 5 6 7'},\n  {title: 'Dots', color: 'url(#circles)', strokeWidth: 9},\n  {title: 'Stripes', color: 'url(#stripes)'},\n  {title: 'Wide stripes', color: 'url(#stripes)', strokeWidth: 13},\n  {title: 'Normal', color: 'purple'},\n  {title: 'Wide', color: 'powderblue', strokeWidth: 6}\n];\n\nexport default function DiscreteColorExample() {\n  return (\n    <div>\n      <svg height={0} width={0}>\n        <GradientDefs>\n          <pattern\n            id=\"stripes\"\n            width=\"4\"\n            height=\"4\"\n            patternUnits=\"userSpaceOnUse\"\n          >\n            <path d=\"M 0, 0 l 5, 5\" stroke=\"#45aeb1\" strokeLinecap=\"square\" />\n          </pattern>\n          <pattern\n            id=\"circles\"\n            width=\"3\"\n            height=\"3\"\n            patternUnits=\"userSpaceOnUse\"\n          >\n            <circle cx=\"1.5\" cy=\"1.5\" r=\"0.8\" fill=\"magenta\" />\n          </pattern>\n        </GradientDefs>\n      </svg>\n      <DiscreteColorLegend orientation=\"horizontal\" width={300} items={ITEMS} />\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/legends/horizontal-discrete-custom-palette.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the 'Software'), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport DiscreteColorLegend from 'react-vis/legends/discrete-color-legend';\n\nconst ITEMS = [\n  'Options',\n  'Buttons',\n  'Select boxes',\n  'Date inputs',\n  'Password inputs',\n  'Forms',\n  'Other'\n];\n\nconst COLORS = [\n  '#6588cd',\n  '#66b046',\n  '#a361c7',\n  '#ad953f',\n  '#c75a87',\n  '#55a47b',\n  '#cb6141'\n];\n\nexport default class HorizontalDiscreteColorPalette extends Component {\n  state = {\n    hoveredItem: false\n  };\n  render() {\n    const {hoveredItem} = this.state;\n    return (\n      <DiscreteColorLegend\n        colors={COLORS}\n        onItemMouseEnter={i => this.setState({hoveredItem: i})}\n        onItemMouseLeave={() => this.setState({hoveredItem: false})}\n        orientation=\"horizontal\"\n        width={300}\n        items={ITEMS.map((item, key) =>\n          hoveredItem === item ? (\n            <div key={key}>\n              {item}\n              <br />\n              {'SELECTED'}\n            </div>\n          ) : (\n            item\n          )\n        )}\n      />\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/legends/searchable-discrete-color-hover.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport SearchableDiscreteColorLegend from 'react-vis/legends/searchable-discrete-color-legend';\n\nexport default class SearchableDiscreteColorLegendHoverExample extends Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      hoveredItem: false,\n      items: [\n        {title: 'Apples', color: '#3a3'},\n        {title: 'Bananas', color: '#fc0'},\n        {title: 'Blueberries', color: '#337'},\n        {title: 'Carrots', color: '#f93'},\n        {title: 'Eggplants', color: '#337'},\n        {title: 'Limes', color: '#cf3'},\n        {title: 'Potatoes', color: '#766'}\n      ],\n      searchText: ''\n    };\n  }\n\n  _clickHandler = (item, i) => {\n    const {items} = this.state;\n    items[i].disabled = !items[i].disabled;\n    this.setState({items});\n  };\n\n  _searchChangeHandler = searchText => {\n    this.setState({searchText});\n  };\n\n  render() {\n    const {items, hoveredItem, searchText} = this.state;\n    return (\n      <SearchableDiscreteColorLegend\n        height={200}\n        width={300}\n        onItemMouseEnter={i =>\n          this.setState({\n            hoveredItem: {\n              ...i,\n              title: `${i.title}:SELECTED`\n            }\n          })\n        }\n        onItemMouseLeave={() => this.setState({hoveredItem: false})}\n        onSearchChange={this._searchChangeHandler}\n        searchText={searchText}\n        onItemClick={this._clickHandler}\n        items={items.map(item =>\n          hoveredItem && hoveredItem.title.includes(item.title)\n            ? hoveredItem\n            : item\n        )}\n      />\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/legends/searchable-discrete-color.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport SearchableDiscreteColorLegend from 'react-vis/legends/searchable-discrete-color-legend';\n\nexport default class Example extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      items: [\n        {title: 'Apples', color: '#3a3'},\n        {title: 'Bananas', color: '#fc0'},\n        {title: 'Blueberries', color: '#337'},\n        {title: 'Carrots', color: '#f93'},\n        {title: 'Eggplants', color: '#337'},\n        {title: 'Limes', color: '#cf3'},\n        {title: 'Potatoes', color: '#766'}\n      ],\n      searchText: ''\n    };\n  }\n\n  _clickHandler = item => {\n    const {items} = this.state;\n    item.disabled = !item.disabled;\n    this.setState({items});\n  };\n\n  _searchChangeHandler = searchText => {\n    this.setState({searchText});\n  };\n\n  render() {\n    const {items, searchText} = this.state;\n    return (\n      <SearchableDiscreteColorLegend\n        height={200}\n        width={300}\n        onSearchChange={this._searchChangeHandler}\n        searchText={searchText}\n        onItemClick={this._clickHandler}\n        items={items}\n      />\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/legends/vertical-discrete-color.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport DiscreteColorLegend from 'react-vis/legends/discrete-color-legend';\n\nconst ITEMS = [\n  'Options',\n  'Buttons',\n  'Select boxes',\n  'Date inputs',\n  'Password inputs',\n  'Forms',\n  'Other'\n];\n\nexport default function DiscreteColorExample() {\n  return <DiscreteColorLegend height={200} width={300} items={ITEMS} />;\n}\n"
  },
  {
    "path": "packages/showcase/misc/2d-dragable-plot.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  MarkSeries,\n  Highlight,\n  Hint\n} from 'react-vis';\n\nimport {generateSeededRandom} from '../showcase-utils';\nconst seededRandom = generateSeededRandom(3);\n\n// randomly generated data\nconst data = [...new Array(30)].map(() => ({\n  x: seededRandom() * 5,\n  y: seededRandom() * 10\n}));\n\nexport default class BidirectionDragChart extends React.Component {\n  state = {\n    filter: null,\n    hovered: null,\n    highlighting: false\n  };\n\n  render() {\n    const {filter, hovered, highlighting} = this.state;\n\n    const highlightPoint = d => {\n      if (!filter) {\n        return false;\n      }\n      const leftRight = d.x <= filter.right && d.x >= filter.left;\n      const upDown = d.y <= filter.top && d.y >= filter.bottom;\n      return leftRight && upDown;\n    };\n\n    const numSelectedPoints = filter ? data.filter(highlightPoint).length : 0;\n    return (\n      <div>\n        <XYPlot width={300} height={300}>\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <Highlight\n            drag\n            onBrushStart={() => this.setState({highlighting: true})}\n            onBrush={area => this.setState({filter: area})}\n            onBrushEnd={area =>\n              this.setState({highlighting: false, filter: area})\n            }\n            onDragStart={() => this.setState({highlighting: true})}\n            onDrag={area => this.setState({filter: area})}\n            onDragEnd={area =>\n              this.setState({highlighting: false, filter: area})\n            }\n          />\n          <MarkSeries\n            className=\"mark-series-example\"\n            strokeWidth={2}\n            opacity=\"0.8\"\n            sizeRange={[5, 15]}\n            style={{pointerEvents: highlighting ? 'none' : ''}}\n            colorType=\"literal\"\n            getColor={d => (highlightPoint(d) ? '#EF5D28' : '#12939A')}\n            onValueMouseOver={d => this.setState({hovered: d})}\n            onValueMouseOut={() => this.setState({hovered: false})}\n            data={data}\n          />\n          {hovered && <Hint value={hovered} />}\n        </XYPlot>\n        <p>{`There are ${numSelectedPoints} selected points`}</p>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/misc/animation-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  MarkSeries\n} from 'react-vis';\n\nfunction generateData() {\n  return [...new Array(10)].map(() => ({\n    x: Math.random() * 5,\n    y: Math.random() * 10\n  }));\n}\n\nconst MODE = ['noWobble', 'gentle', 'wobbly', 'stiff'];\n\nexport default class Example extends React.Component {\n  state = {\n    data: generateData(),\n    modeIndex: 0\n  };\n\n  updateModeIndex = increment => () => {\n    const newIndex = this.state.modeIndex + (increment ? 1 : -1);\n    const modeIndex =\n      newIndex < 0 ? MODE.length - 1 : newIndex >= MODE.length ? 0 : newIndex;\n    this.setState({\n      modeIndex\n    });\n  };\n\n  render() {\n    const {modeIndex, data} = this.state;\n    return (\n      <div className=\"centered-and-flexed\">\n        <div className=\"centered-and-flexed-controls\">\n          <ShowcaseButton\n            onClick={this.updateModeIndex(false)}\n            buttonContent={'PREV'}\n          />\n          <div> {`ANIMATION TECHNIQUE: ${MODE[modeIndex]}`} </div>\n          <ShowcaseButton\n            onClick={this.updateModeIndex(true)}\n            buttonContent={'NEXT'}\n          />\n        </div>\n        <XYPlot width={300} height={300}>\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <MarkSeries animation={MODE[modeIndex]} data={data} />\n        </XYPlot>\n        <ShowcaseButton\n          onClick={() => this.setState({data: generateData()})}\n          buttonContent={'UPDATE DATA'}\n        />\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/misc/clip-example.js",
    "content": "import React, {useState} from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  AreaSeries,\n  ContentClipPath\n} from 'react-vis';\n\nexport default function ClipExample() {\n  const [clip, setClip] = useState(true);\n\n  return (\n    <>\n      <label style={{display: 'block'}}>\n        <input\n          type=\"checkbox\"\n          checked={clip}\n          onChange={e => setClip(e.currentTarget.checked)}\n        />\n        Enable Clipping\n      </label>\n      <XYPlot xDomain={[1.2, 3]} yDomain={[11, 26]} width={300} height={300}>\n        {clip && <ContentClipPath id=\"content\" />}\n\n        <VerticalGridLines />\n        <HorizontalGridLines />\n\n        <AreaSeries\n          data={[\n            {x: 1, y: 10, y0: 1},\n            {x: 2, y: 25, y0: 5},\n            {x: 3, y: 15, y0: 3}\n          ]}\n          style={{clipPath: 'url(#content)'}}\n        />\n        <XAxis />\n        <YAxis />\n        <AreaSeries\n          data={[\n            {x: 1, y: 5, y0: 6},\n            {x: 2, y: 20, y0: 11},\n            {x: 3, y: 10, y0: 9}\n          ]}\n          style={{clipPath: 'url(#content)'}}\n        />\n      </XYPlot>\n    </>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/misc/dragable-chart-example.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {XYPlot, XAxis, YAxis, VerticalRectSeries, Highlight} from 'react-vis';\n\nconst DATA = [\n  {x0: 0, x: 1, y: 1},\n  {x0: 1, x: 2, y: 2},\n  {x0: 2, x: 3, y: 10},\n  {x0: 3, x: 4, y: 6},\n  {x0: 4, x: 5, y: 5},\n  {x0: 5, x: 6, y: 3},\n  {x0: 6, x: 7, y: 1}\n];\n\nclass DragableChartExample extends React.Component {\n  state = {\n    selectionStart: null,\n    selectionEnd: null\n  };\n\n  render() {\n    const {selectionStart, selectionEnd} = this.state;\n    const updateDragState = area =>\n      this.setState({\n        selectionStart: area && area.left,\n        selectionEnd: area && area.right\n      });\n\n    return (\n      <div>\n        <XYPlot width={500} height={300}>\n          <XAxis />\n          <YAxis />\n          <VerticalRectSeries\n            data={DATA}\n            stroke=\"white\"\n            colorType=\"literal\"\n            getColor={d => {\n              if (selectionStart === null || selectionEnd === null) {\n                return '#1E96BE';\n              }\n              const inX = d.x >= selectionStart && d.x <= selectionEnd;\n              const inX0 = d.x0 >= selectionStart && d.x0 <= selectionEnd;\n              const inStart = selectionStart >= d.x0 && selectionStart <= d.x;\n              const inEnd = selectionEnd >= d.x0 && selectionEnd <= d.x;\n\n              return inStart || inEnd || inX || inX0 ? '#12939A' : '#1E96BE';\n            }}\n          />\n\n          <Highlight\n            color=\"#829AE3\"\n            drag\n            enableY={false}\n            onDrag={updateDragState}\n            onDragEnd={updateDragState}\n          />\n        </XYPlot>\n\n        <div>\n          <b>selectionStart:</b> {`${Math.floor(selectionStart * 100) / 100},`}\n          <b>selectionEnd:</b> {`${Math.floor(selectionEnd * 100) / 100},`}\n        </div>\n      </div>\n    );\n  }\n}\n\nexport default DragableChartExample;\n"
  },
  {
    "path": "packages/showcase/misc/gradient-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  AreaSeries,\n  GradientDefs,\n  Borders\n} from 'react-vis';\n\nexport default function GradientExample() {\n  return (\n    <XYPlot xDomain={[1.2, 3]} yDomain={[11, 26]} width={300} height={300}>\n      <GradientDefs>\n        <linearGradient id=\"CoolGradient\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n          <stop offset=\"0%\" stopColor=\"red\" stopOpacity={0.4} />\n          <stop offset=\"100%\" stopColor=\"blue\" stopOpacity={0.3} />\n        </linearGradient>\n      </GradientDefs>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n\n      <AreaSeries\n        color={'url(#CoolGradient)'}\n        data={[\n          {x: 1, y: 10, y0: 1},\n          {x: 2, y: 25, y0: 5},\n          {x: 3, y: 15, y0: 3}\n        ]}\n      />\n      <Borders\n        style={{\n          bottom: {fill: '#fff'},\n          left: {fill: 'url(#CoolGradient)', opacity: 0.3},\n          right: {fill: '#fff'},\n          top: {fill: '#fff'}\n        }}\n      />\n      <XAxis />\n      <YAxis />\n      <AreaSeries\n        data={[\n          {x: 1, y: 5, y0: 6},\n          {x: 2, y: 20, y0: 11},\n          {x: 3, y: 10, y0: 9}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/misc/label-series-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {XYPlot, XAxis, YAxis, MarkSeries, LabelSeries} from 'react-vis';\n\nfunction generateData() {\n  return [\n    {\n      x: Math.random() * 3,\n      y: Math.random() * 20,\n      label: 'Wigglytuff',\n      size: 30,\n      style: {fontSize: 20}\n    },\n    {x: Math.random() * 3, y: Math.random() * 20, label: 'Psyduck', size: 10},\n    {x: Math.random() * 3, y: Math.random() * 20, label: 'Geodude', size: 1},\n    {\n      x: Math.random() * 3,\n      y: Math.random() * 20,\n      label: 'red',\n      size: 12,\n      rotation: 45\n    },\n    {x: Math.random() * 3, y: Math.random() * 20, label: 'blue', size: 4}\n  ];\n}\n\nexport default class Example extends React.Component {\n  state = {\n    data: [\n      {\n        x: 3,\n        y: 7,\n        label: 'Wigglytuff',\n        size: 30,\n        style: {fontSize: 20},\n        rotation: 45\n      },\n      {x: 2, y: 4, label: 'Psyduck', size: 10},\n      {x: 1, y: 20, label: 'Geodude', size: 1},\n      {x: 4, y: 12, label: 'Ditto', size: 12, rotation: 45},\n      {x: 1, y: 14, label: 'Snorlax', size: 4}\n    ]\n  };\n  render() {\n    const {data} = this.state;\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({data: generateData()})}\n          buttonContent=\"UPDATE\"\n        />\n        <XYPlot yDomain={[-1, 22]} xDomain={[-1, 5]} width={300} height={300}>\n          <XAxis />\n          <YAxis />\n          <MarkSeries\n            className=\"mark-series-example\"\n            strokeWidth={2}\n            sizeRange={[5, 15]}\n            data={data}\n          />\n          <LabelSeries animation allowOffsetToBeReversed data={data} />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/misc/null-data-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  AreaSeries,\n  Crosshair,\n  XYPlot,\n  XAxis,\n  YAxis,\n  HorizontalGridLines,\n  VerticalGridLines,\n  LineMarkSeries\n} from 'react-vis';\n\nconst DATA = [\n  [\n    {x: 1, y: 10},\n    {x: 2, y: 10},\n    {x: 3, y: 13},\n    {x: 4, y: 7},\n    {x: 5, y: null}\n  ],\n  [\n    {x: 1, y: 30},\n    {x: 2, y: 0},\n    {x: 5, y: null},\n    {x: 4, y: 15},\n    {x: 5, y: null}\n  ]\n];\n\nexport default class NullDataExample extends React.Component {\n  state = {\n    crosshairValues: []\n  };\n\n  onMouseLeave = () => this.setState({crosshairValues: []});\n  onNearestX = (value, {index}) =>\n    this.setState({\n      crosshairValues: DATA.map(d => d[index].y !== null && d[index])\n    });\n\n  render() {\n    return (\n      <XYPlot width={300} height={300} onMouseLeave={this.onMouseLeave}>\n        <XAxis />\n        <YAxis />\n        <HorizontalGridLines />\n        <VerticalGridLines />\n        <AreaSeries\n          getNull={d => d.y !== null}\n          onNearestX={this.onNearestX}\n          data={DATA[0]}\n        />\n        <LineMarkSeries getNull={d => d.y !== null} data={DATA[1]} />\n        <Crosshair values={this.state.crosshairValues} />\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/misc/selection-plot-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  MarkSeries,\n  Highlight\n} from 'react-vis';\n\nimport {generateSeededRandom} from '../showcase-utils';\nconst seededRandom = generateSeededRandom(36);\n\n// randomly generated data\nconst data = [...new Array(10)].map(() => ({\n  x: seededRandom() * 3,\n  y: seededRandom() * 11 + 4,\n  size: seededRandom() * 30 + 1\n}));\n\nexport default class SelectionPlotExample extends React.Component {\n  state = {\n    filter: null\n  };\n  render() {\n    const {filter} = this.state;\n    const highlightPoint = d => {\n      if (!filter) {\n        return false;\n      }\n      return d.y <= filter.top && d.y >= filter.bottom;\n    };\n\n    const numSelectedPoints = filter ? data.filter(highlightPoint).length : 0;\n    return (\n      <div>\n        <XYPlot width={300} height={300}>\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n\n          <MarkSeries\n            className=\"mark-series-example\"\n            sizeRange={[5, 15]}\n            colorType=\"literal\"\n            getColor={d => (highlightPoint(d) ? '#EF5D28' : '#12939A')}\n            data={data}\n          />\n          <Highlight\n            enableX={false}\n            className=\"selection-example\"\n            onBrush={area => this.setState({filter: area})}\n            onBrushEnd={area => this.setState({filter: area})}\n          />\n        </XYPlot>\n        <p>{`There are ${numSelectedPoints} selected points`}</p>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/misc/synced-charts.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineSeries\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      selectedIndex: null\n    };\n    this._onSeriesMouseOvers = [\n      this._onSeriesMouseOver.bind(this, 0),\n      this._onSeriesMouseOver.bind(this, 1)\n    ];\n  }\n\n  _getSeriesColor(index) {\n    const {selectedIndex} = this.state;\n    if (selectedIndex !== null && selectedIndex !== index) {\n      return '#ddd';\n    }\n    return null;\n  }\n\n  _onChartMouseLeave = () => {\n    this.setState({selectedIndex: null});\n  };\n\n  _onSeriesMouseOver(selectedIndex) {\n    this.setState({selectedIndex});\n  }\n\n  render() {\n    return (\n      <div>\n        <XYPlot onMouseLeave={this._onChartMouseLeave} width={300} height={150}>\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <LineSeries\n            color={this._getSeriesColor(0)}\n            onSeriesMouseOver={this._onSeriesMouseOvers[0]}\n            data={[\n              {x: 1, y: 15},\n              {x: 2, y: 8},\n              {x: 3, y: 1}\n            ]}\n          />\n          <LineSeries\n            color={this._getSeriesColor(1)}\n            onSeriesMouseOver={this._onSeriesMouseOvers[1]}\n            data={[\n              {x: 1, y: 10},\n              {x: 2, y: 5},\n              {x: 3, y: 15}\n            ]}\n          />\n        </XYPlot>\n        <XYPlot onMouseLeave={this._onChartMouseLeave} width={300} height={150}>\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <LineSeries\n            color={this._getSeriesColor(0)}\n            onSeriesMouseOver={this._onSeriesMouseOvers[0]}\n            data={[\n              {x: 1, y: 4},\n              {x: 2, y: 11},\n              {x: 3, y: 9}\n            ]}\n          />\n          <LineSeries\n            color={this._getSeriesColor(1)}\n            onSeriesMouseOver={this._onSeriesMouseOvers[1]}\n            data={[\n              {x: 1, y: 2},\n              {x: 2, y: 3},\n              {x: 3, y: 11}\n            ]}\n          />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/misc/time-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  HorizontalGridLines,\n  VerticalGridLines,\n  LineSeries\n} from 'react-vis';\n\nconst MSEC_DAILY = 86400000;\n\nexport default function Example() {\n  const timestamp = new Date('September 9 2017').getTime();\n  return (\n    <XYPlot xType=\"time\" width={300} height={300}>\n      <HorizontalGridLines />\n      <VerticalGridLines />\n      <XAxis title=\"X Axis\" />\n      <YAxis title=\"Y Axis\" />\n      <LineSeries\n        data={[\n          {x: timestamp + MSEC_DAILY, y: 3},\n          {x: timestamp + MSEC_DAILY * 2, y: 5},\n          {x: timestamp + MSEC_DAILY * 3, y: 15},\n          {x: timestamp + MSEC_DAILY * 4, y: 12}\n        ]}\n      />\n      <LineSeries data={null} />\n      <LineSeries\n        data={[\n          {x: timestamp + MSEC_DAILY, y: 10},\n          {x: timestamp + MSEC_DAILY * 2, y: 4},\n          {x: timestamp + MSEC_DAILY * 3, y: 2},\n          {x: timestamp + MSEC_DAILY * 4, y: 15}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/misc/triangle-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {XYPlot, PolygonSeries, XAxis, YAxis, GradientDefs} from 'react-vis';\n\nfunction buildTriangle(sideWidth, lowerLeftCoord) {\n  const {x, y} = lowerLeftCoord;\n  const triangle = [\n    [\n      {x, y},\n      {x, y: y + sideWidth},\n      {x: x + sideWidth, y}\n    ]\n  ];\n  if (sideWidth < 0.5) {\n    return triangle;\n  }\n  const newWidth = sideWidth * 0.5;\n  const a = buildTriangle(newWidth, lowerLeftCoord);\n  const b = buildTriangle(newWidth, {x: x + sideWidth, y});\n  const c = buildTriangle(newWidth, {x, y: y + sideWidth});\n  return triangle\n    .concat(a)\n    .concat(b)\n    .concat(c);\n}\n\nconst triangles = buildTriangle(7, {x: 0, y: 0});\n\nexport default class Example extends React.Component {\n  state = {\n    hoveredIndex: false\n  };\n\n  render() {\n    const {hoveredIndex} = this.state;\n\n    return (\n      <XYPlot width={300} height={300}>\n        <GradientDefs>\n          <radialGradient\n            id=\"grad1\"\n            cx=\"50%\"\n            cy=\"50%\"\n            r=\"50%\"\n            fx=\"50%\"\n            fy=\"50%\"\n          >\n            <stop offset=\"0%\" stopColor=\"#829AE3\" stopOpacity=\"0\" />\n            <stop offset=\"100%\" stopColor=\"#12939A\" stopOpacity=\"1\" />\n          </radialGradient>\n        </GradientDefs>\n        <XAxis />\n        <YAxis />\n        {triangles.map((triangle, index) => {\n          return (\n            <PolygonSeries\n              key={`triangle-${index}`}\n              data={triangle}\n              onSeriesMouseOver={() => this.setState({hoveredIndex: index})}\n              onSeriesMouseOut={() => this.setState({hoveredIndex: false})}\n              color={index !== hoveredIndex ? 'url(#grad1)' : null}\n              style={{\n                strokeWidth: 0.5,\n                strokeOpacity: 1,\n                opacity: 0.5,\n                fill: index === hoveredIndex ? '#EF5D28' : null\n              }}\n            />\n          );\n        })}\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/misc/voronoi-line-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  HorizontalGridLines,\n  VerticalGridLines,\n  LineSeries,\n  MarkSeries,\n  Voronoi\n} from 'react-vis';\n\nconst lines = [\n  [\n    {x: 1, y: 3},\n    {x: 2, y: 5},\n    {x: 3, y: 15},\n    {x: 4, y: 12}\n  ],\n  [\n    {x: 1, y: 10},\n    {x: 2, y: 4},\n    {x: 3, y: 2},\n    {x: 4, y: 15}\n  ],\n  [\n    {x: 1, y: 7},\n    {x: 2, y: 11},\n    {x: 3, y: 9},\n    {x: 4, y: 2}\n  ]\n].map((p, i) => p.map(d => ({...d, line: i})));\nconst nodes = lines.reduce((acc, d) => [...acc, ...d], []);\n\nconst getDomain = (data, key) => {\n  const {min, max} = data.reduce(\n    (acc, row) => ({\n      min: Math.min(acc.min, row[key]),\n      max: Math.max(acc.max, row[key])\n    }),\n    {min: Infinity, max: -Infinity}\n  );\n  return [min, max];\n};\nconst xDomain = getDomain(nodes, 'x');\nconst yDomain = getDomain(nodes, 'y');\n\nexport default class Example extends React.Component {\n  state = {\n    hoveredNode: null,\n    showVoronoi: false\n  };\n\n  render() {\n    const {hoveredNode, showVoronoi} = this.state;\n    return (\n      <div>\n        <label style={{display: 'block'}}>\n          <input\n            type=\"checkbox\"\n            checked={showVoronoi}\n            onChange={() => this.setState({showVoronoi: !showVoronoi})}\n          />\n          Show Voronoi\n        </label>\n        <XYPlot\n          xDomain={xDomain}\n          yDomain={yDomain}\n          margin={{top: 10, left: 40, bottom: 40, right: 10}}\n          width={300}\n          height={300}\n        >\n          <HorizontalGridLines />\n          <VerticalGridLines />\n          <XAxis title=\"X Axis\" />\n          <YAxis title=\"Y Axis\" />\n          {lines.map((d, i) => (\n            <LineSeries\n              key={i}\n              opacity={hoveredNode && hoveredNode.line === i ? 1 : 0.5}\n              data={d}\n            />\n          ))}\n          {hoveredNode && <MarkSeries data={[hoveredNode]} />}\n          <Voronoi\n            nodes={lines.reduce((acc, d) => [...acc, ...d], [])}\n            onHover={node => this.setState({hoveredNode: node})}\n            onBlur={() => this.setState({hoveredNode: null})}\n            polygonStyle={{stroke: showVoronoi ? 'rgba(0, 0, 0, .2)' : null}}\n          />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/misc/zoomable-chart-example.js",
    "content": "// Copyright (c) 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XAxis,\n  YAxis,\n  HorizontalGridLines,\n  XYPlot,\n  LineSeries,\n  Highlight\n} from 'react-vis';\nimport {generateSeededRandom} from '../showcase-utils';\n\nconst seededRandom = generateSeededRandom(9);\nconst totalValues = 100;\n\n/**\n * Get the array of x and y pairs.\n * The function tries to avoid too large changes of the chart.\n * @param {number} total Total number of values.\n * @returns {Array} Array of data.\n * @private\n */\nfunction getRandomSeriesData(total) {\n  const result = [];\n  let lastY = seededRandom() * 40 - 20;\n  let y;\n  const firstY = lastY;\n  for (let i = 0; i < total; i++) {\n    y = seededRandom() * firstY - firstY / 2 + lastY;\n    result.push({\n      x: i,\n      y\n    });\n    lastY = y;\n  }\n  return result;\n}\n\nexport default class ZoomableChartExample extends React.Component {\n  state = {\n    lastDrawLocation: null,\n    series: [\n      {\n        data: getRandomSeriesData(totalValues),\n        disabled: false,\n        title: 'Apples'\n      },\n      {\n        data: getRandomSeriesData(totalValues),\n        disabled: false,\n        title: 'Bananas'\n      }\n    ]\n  };\n\n  render() {\n    const {series, lastDrawLocation} = this.state;\n    return (\n      <div>\n        <div>\n          <XYPlot\n            animation\n            xDomain={\n              lastDrawLocation && [\n                lastDrawLocation.left,\n                lastDrawLocation.right\n              ]\n            }\n            yDomain={\n              lastDrawLocation && [\n                lastDrawLocation.bottom,\n                lastDrawLocation.top\n              ]\n            }\n            width={500}\n            height={300}\n          >\n            <HorizontalGridLines />\n\n            <YAxis />\n            <XAxis />\n\n            {series.map(entry => (\n              <LineSeries key={entry.title} data={entry.data} />\n            ))}\n\n            <Highlight\n              onBrushEnd={area => this.setState({lastDrawLocation: area})}\n              onDrag={area => {\n                this.setState({\n                  lastDrawLocation: {\n                    bottom: lastDrawLocation.bottom + (area.top - area.bottom),\n                    left: lastDrawLocation.left - (area.right - area.left),\n                    right: lastDrawLocation.right - (area.right - area.left),\n                    top: lastDrawLocation.top + (area.top - area.bottom)\n                  }\n                });\n              }}\n            />\n          </XYPlot>\n        </div>\n\n        <button\n          className=\"showcase-button\"\n          onClick={() => this.setState({lastDrawLocation: null})}\n        >\n          Reset Zoom\n        </button>\n\n        <div>\n          <h4>\n            <b>Last Draw Area</b>\n          </h4>\n          {lastDrawLocation ? (\n            <ul style={{listStyle: 'none'}}>\n              <li>\n                <b>Top:</b> {lastDrawLocation.top}\n              </li>\n              <li>\n                <b>Right:</b> {lastDrawLocation.right}\n              </li>\n              <li>\n                <b>Bottom:</b> {lastDrawLocation.bottom}\n              </li>\n              <li>\n                <b>Left:</b> {lastDrawLocation.left}\n              </li>\n            </ul>\n          ) : (\n            <span>N/A</span>\n          )}\n        </div>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/package.json",
    "content": "{\n  \"name\": \"react-vis-showcase\",\n  \"description\": \"Showcase of react-vis components\",\n  \"version\": \"0.1.0\",\n  \"scripts\": {\n    \"start\": \"webpack-dev-server --progress --hot --port 3001\",\n    \"lint\": \"eslint .\",\n    \"build\": \"NODE_ENV=production webpack\",\n    \"build:windows\": \"set NODE_ENV=production&&.\\\\node_modules\\\\.bin\\\\webpack\"\n  },\n  \"devDependencies\": {\n    \"babel-loader\": \"^8.0.0\",\n    \"css-loader\": \"^0.26.1\",\n    \"mini-css-extract-plugin\": \"^0.9.0\",\n    \"sass-loader\": \"^8.0.2\",\n    \"style-loader\": \"^0.13.1\",\n    \"webpack\": \"^4.43.0\",\n    \"webpack-cli\": \"^3.3.11\",\n    \"webpack-dev-server\": \"^3.11.0\"\n  },\n  \"license\": \"MIT\",\n  \"private\": true,\n  \"dependencies\": {\n    \"d3-force\": \"^1.0.6\",\n    \"d3-random\": \"^1.1.0\",\n    \"react\": \"^17.0.2\",\n    \"react-dom\": \"^17.0.2\",\n    \"react-router\": \"^5.2.0\",\n    \"react-router-dom\": \"^5.2.0\",\n    \"react-vis\": \"^1.11.7\"\n  },\n  \"volta\": {\n    \"node\": \"14.18.0\",\n    \"yarn\": \"1.22.4\"\n  }\n}\n"
  },
  {
    "path": "packages/showcase/parallel-coordinates/animated-parallel-coordinates.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {ParallelCoordinates} from 'react-vis';\n\nconst DATA = [\n  {\n    explosions: 7,\n    wow: 10,\n    dog: 8,\n    sickMoves: 9,\n    nice: 7\n  }\n];\n\nconst DOMAIN = [\n  {name: 'nice', domain: [0, 100], tickFormat: t => t},\n  {name: 'explosions', domain: [6.9, 7.1]},\n  {name: 'wow', domain: [0, 11]},\n  {name: 'dog', domain: [0, 16]},\n  {name: 'sickMoves', domain: [0, 20]}\n];\n\nfunction generateData() {\n  return [\n    Object.keys(DATA[0]).reduce((acc, key) => {\n      acc[key] = DATA[0][key] + 5 * (Math.random() - 0.5);\n      return acc;\n    }, {})\n  ];\n}\n\nexport default class AnimatedParallelCoordinates extends Component {\n  state = {\n    data: DATA\n  };\n\n  render() {\n    const {data} = this.state;\n\n    return (\n      <div className=\"centered-and-flexed\">\n        <ParallelCoordinates\n          animation\n          data={data}\n          domains={DOMAIN}\n          style={{\n            lines: {\n              strokeWidth: 3,\n              strokeDasharray: '2, 2'\n            },\n            axes: {\n              text: {\n                opacity: 1\n              }\n            },\n            labels: {\n              textAnchor: 'right'\n            }\n          }}\n          margin={{\n            left: 30,\n            top: 30,\n            bottom: 40,\n            right: 50\n          }}\n          tickFormat={() => ''}\n          width={400}\n          height={300}\n        />\n        <ShowcaseButton\n          onClick={() => this.setState({data: generateData()})}\n          buttonContent={'UPDATE DATA'}\n        />\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/parallel-coordinates/basic-parallel-coordinates.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {format} from 'd3-format';\n\nimport {ParallelCoordinates} from 'react-vis';\n\nconst DATA = [\n  {\n    name: 'Mercedes',\n    mileage: 7,\n    price: 10,\n    safety: 8,\n    performance: 9,\n    interior: 7,\n    warranty: 7\n  },\n  {\n    name: 'Honda',\n    mileage: 8,\n    price: 6,\n    safety: 9,\n    performance: 6,\n    interior: 3,\n    warranty: 9,\n    style: {\n      strokeWidth: 3,\n      strokeDasharray: '2, 2'\n    }\n  },\n  {\n    name: 'Chevrolet',\n    mileage: 5,\n    price: 4,\n    safety: 6,\n    performance: 4,\n    interior: 5,\n    warranty: 6\n  }\n];\n\nconst basicFormat = format('.2r');\nconst wideFormat = format('.3r');\n\nexport default function BasicParallelCoordinates() {\n  return (\n    <ParallelCoordinates\n      data={DATA}\n      tickFormat={t => wideFormat(t)}\n      margin={50}\n      colorRange={['#172d47', '#911116', '#998965']}\n      domains={[\n        {name: 'mileage', domain: [0, 10]},\n        {\n          name: 'price',\n          domain: [2, 16],\n          tickFormat: t => `$${basicFormat(t)}`,\n          getValue: d => d.price\n        },\n        {name: 'safety', domain: [5, 10], getValue: d => d.safety},\n        {name: 'performance', domain: [0, 10], getValue: d => d.performance},\n        {name: 'interior', domain: [0, 7], getValue: d => d.interior},\n        {name: 'warranty', domain: [10, 2], getValue: d => d.warranty}\n      ]}\n      showMarks\n      width={400}\n      height={300}\n    />\n  );\n}\n"
  },
  {
    "path": "packages/showcase/parallel-coordinates/brushed-parallel-coordinates.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {ParallelCoordinates} from 'react-vis';\nimport IrisData from '../datasets/iris.json';\n\n// {\"sepal length\": 5.1, \"sepal width\": 3.5, \"petal length\": 1.4, \"petal width\": 0.2, \"species\": \"setosa\"},\n\nconst SPECIES_COLORS = {\n  setosa: '#12939A',\n  virginica: '#79C7E3',\n  versicolor: '#1A3177'\n};\n\nconst domainStructure = Object.keys(IrisData[0])\n  .filter(name => name !== 'species')\n  .map(name => ({name, domain: [Infinity, -Infinity]}));\n\nconst domains = IrisData.reduce((acc, row) => {\n  return acc.map(d => {\n    return {\n      name: d.name,\n      domain: [\n        Math.min(d.domain[0], row[d.name]),\n        Math.max(d.domain[1], row[d.name])\n      ]\n    };\n  });\n}, domainStructure);\n\nexport default function BrushedParallelCoordinates() {\n  return (\n    <ParallelCoordinates\n      animation\n      brushing\n      data={IrisData.map(d => ({...d, color: SPECIES_COLORS[d.species]}))}\n      domains={domains}\n      margin={60}\n      width={600}\n      height={400}\n    />\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/area-chart-elevated.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineMarkSeries,\n  AreaSeries\n} from 'react-vis';\n\nexport default function AreaChartElevated() {\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis />\n      <YAxis />\n      <AreaSeries\n        className=\"area-elevated-series-1\"\n        color=\"#79c7e3\"\n        data={[\n          {x: 1, y: 10, y0: 1},\n          {x: 2, y: 25, y0: 5},\n          {x: 3, y: 15, y0: 3}\n        ]}\n      />\n      <AreaSeries\n        className=\"area-elevated-series-2\"\n        color=\"#12939a\"\n        data={[\n          {x: 1, y: 5, y0: 6},\n          {x: 2, y: 20, y0: 11},\n          {x: 3, y: 10, y0: 9}\n        ]}\n      />\n      <LineMarkSeries\n        className=\"area-elevated-line-series\"\n        data={[\n          {x: 1, y: 5.5},\n          {x: 2, y: 15},\n          {x: 3, y: 9}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/area-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  AreaSeries\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis />\n      <YAxis />\n      <AreaSeries\n        className=\"area-series-example\"\n        curve=\"curveNatural\"\n        data={[\n          {x: 1, y: 10},\n          {x: 2, y: 5},\n          {x: 3, y: 15}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/axis-with-turned-labels.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  VerticalBarSeries\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot margin={{bottom: 70}} xType=\"ordinal\" width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis tickLabelAngle={-45} />\n      <YAxis />\n      <VerticalBarSeries\n        data={[\n          {x: 'Apples', y: 10},\n          {x: 'Bananas', y: 5},\n          {x: 'Cranberries', y: 15}\n        ]}\n      />\n      <VerticalBarSeries\n        data={[\n          {x: 'Apples', y: 12},\n          {x: 'Bananas', y: 2},\n          {x: 'Cranberries', y: 11}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/bar-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  VerticalBarSeries,\n  VerticalBarSeriesCanvas,\n  LabelSeries\n} from 'react-vis';\n\nconst greenData = [\n  {x: 'A', y: 10},\n  {x: 'B', y: 5},\n  {x: 'C', y: 15}\n];\n\nconst blueData = [\n  {x: 'A', y: 12},\n  {x: 'B', y: 2},\n  {x: 'C', y: 11}\n];\n\nconst labelData = greenData.map((d, idx) => ({\n  x: d.x,\n  y: Math.max(greenData[idx].y, blueData[idx].y)\n}));\n\nexport default class Example extends React.Component {\n  state = {\n    useCanvas: false\n  };\n\n  render() {\n    const {useCanvas} = this.state;\n    const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';\n    const BarSeries = useCanvas ? VerticalBarSeriesCanvas : VerticalBarSeries;\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({useCanvas: !useCanvas})}\n          buttonContent={content}\n        />\n        <XYPlot xType=\"ordinal\" width={300} height={300} xDistance={100}>\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <BarSeries className=\"vertical-bar-series-example\" data={greenData} />\n          <BarSeries data={blueData} />\n          <LabelSeries data={labelData} getLabel={d => d.x} />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/big-base-bar-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalBarSeries,\n  VerticalBarSeriesCanvas\n} from 'react-vis';\n\nconst myDATA = [\n  {id: '00036', y: 200400, x: 1504121437},\n  {id: '00036', y: 200350, x: 1504121156},\n  {id: '00036', y: 200310, x: 1504120874},\n  {id: '00036', y: 200260, x: 1504120590},\n  {id: '00036', y: 200210, x: 1504120306},\n  {id: '00036', y: 200160, x: 1504120024},\n  {id: '00036', y: 200120, x: 1504119740},\n  {id: '00036', y: 200070, x: 1504119458},\n  {id: '00036', y: 200020, x: 1504119177},\n  {id: '00036', y: 199980, x: 1504118893},\n  {id: '00036', y: 199930, x: 1504118611},\n  {id: '00036', y: 199880, x: 1504118330},\n  {id: '00036', y: 199830, x: 1504118048},\n  {id: '00036', y: 199790, x: 1504117763},\n  {id: '00036', y: 199740, x: 1504117481}\n];\n\nconst yDomain = myDATA.reduce(\n  (res, row) => {\n    return {\n      max: Math.max(res.max, row.y),\n      min: Math.min(res.min, row.y)\n    };\n  },\n  {max: -Infinity, min: Infinity}\n);\n\nexport default class Example extends React.Component {\n  state = {\n    useCanvas: false\n  };\n\n  render() {\n    const {useCanvas} = this.state;\n    const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';\n    const BarSeries = useCanvas ? VerticalBarSeriesCanvas : VerticalBarSeries;\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({useCanvas: !useCanvas})}\n          buttonContent={content}\n        />\n        <XYPlot\n          margin={{left: 75}}\n          xType=\"time\"\n          width={300}\n          height={300}\n          yDomain={[yDomain.min, yDomain.max]}\n        >\n          <BarSeries className=\"vertical-bar-series-example\" data={myDATA} />\n          <XAxis />\n          <YAxis />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/clustered-stacked-bar-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  VerticalBarSeries,\n  VerticalBarSeriesCanvas,\n  DiscreteColorLegend\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  state = {\n    useCanvas: false\n  };\n  render() {\n    const {useCanvas} = this.state;\n    const BarSeries = useCanvas ? VerticalBarSeriesCanvas : VerticalBarSeries;\n    const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';\n\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({useCanvas: !useCanvas})}\n          buttonContent={content}\n        />\n        <XYPlot\n          className=\"clustered-stacked-bar-chart-example\"\n          xType=\"ordinal\"\n          stackBy=\"y\"\n          width={300}\n          height={300}\n        >\n          <DiscreteColorLegend\n            style={{position: 'absolute', left: '50px', top: '10px'}}\n            orientation=\"horizontal\"\n            items={[\n              {\n                title: 'Apples',\n                color: '#12939A'\n              },\n              {\n                title: 'Oranges',\n                color: '#79C7E3'\n              }\n            ]}\n          />\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <BarSeries\n            cluster=\"2015\"\n            color=\"#12939A\"\n            data={[\n              {x: 'Q1', y: 10},\n              {x: 'Q2', y: 5},\n              {x: 'Q3', y: 15},\n              {x: 'Q4', y: 20}\n            ]}\n          />\n          <BarSeries\n            cluster=\"2015\"\n            color=\"#79C7E3\"\n            data={[\n              {x: 'Q1', y: 3},\n              {x: 'Q2', y: 7},\n              {x: 'Q3', y: 2},\n              {x: 'Q4', y: 1}\n            ]}\n          />\n          <BarSeries\n            cluster=\"2016\"\n            color=\"#12939A\"\n            data={[\n              {x: 'Q1', y: 3},\n              {x: 'Q2', y: 8},\n              {x: 'Q3', y: 11},\n              {x: 'Q4', y: 19}\n            ]}\n          />\n          <BarSeries\n            cluster=\"2016\"\n            color=\"#79C7E3\"\n            data={[\n              {x: 'Q1', y: 22},\n              {x: 'Q2', y: 2},\n              {x: 'Q3', y: 22},\n              {x: 'Q4', y: 18}\n            ]}\n          />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/complex-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XAxis,\n  YAxis,\n  FlexibleWidthXYPlot,\n  HorizontalGridLines,\n  LineSeries,\n  VerticalRectSeries,\n  DiscreteColorLegend,\n  Crosshair\n} from 'react-vis';\n\n/**\n * Get the array of x and y pairs.\n * The function tries to avoid too large changes of the chart.\n * @param {number} total Total number of values.\n * @returns {Array} Array of data.\n * @private\n */\nfunction getRandomSeriesData(total) {\n  const result = [];\n  let lastY = Math.random() * 40 - 20;\n  let y;\n  const firstY = lastY;\n  for (let i = 0; i < Math.max(total, 3); i++) {\n    y = Math.random() * firstY - firstY / 2 + lastY;\n    result.push({\n      left: i,\n      top: y\n    });\n    lastY = y;\n  }\n  return result;\n}\n\nexport default class Example extends React.Component {\n  constructor(props) {\n    super(props);\n    const totalValues = Math.random() * 50;\n    this.state = {\n      crosshairValues: [],\n      series: [\n        {\n          title: 'Apples',\n          disabled: false,\n          data: getRandomSeriesData(totalValues)\n        },\n        {\n          title: 'Bananas',\n          disabled: false,\n          data: getRandomSeriesData(totalValues)\n        }\n      ]\n    };\n  }\n\n  /**\n   * A callback to format the crosshair items.\n   * @param {Object} values Array of values.\n   * @returns {Array<Object>} Array of objects with titles and values.\n   * @private\n   */\n  _formatCrosshairItems = values => {\n    const {series} = this.state;\n    return values.map((v, i) => {\n      return {\n        title: series[i].title,\n        value: v.top\n      };\n    });\n  };\n\n  /**\n   * Format the title line of the crosshair.\n   * @param {Array} values Array of values.\n   * @returns {Object} The caption and the value of the title.\n   * @private\n   */\n  _formatCrosshairTitle = values => {\n    return {\n      title: 'X',\n      value: values[0].left\n    };\n  };\n\n  /**\n   * Click handler for the legend.\n   * @param {Object} item Clicked item of the legend.\n   * @param {number} i Index of the legend.\n   * @private\n   */\n  _legendClickHandler = (item, i) => {\n    const {series} = this.state;\n    series[i].disabled = !series[i].disabled;\n    this.setState({series});\n  };\n\n  /**\n   * Event handler for onMouseLeave.\n   * @private\n   */\n  _mouseLeaveHandler = () => {\n    this.setState({crosshairValues: []});\n  };\n\n  /**\n   * Event handler for onNearestX.\n   * @param {Object} value Selected value.\n   * @param {number} index Index of the series.\n   * @private\n   */\n  _nearestXHandler = (value, {index}) => {\n    const {series} = this.state;\n    this.setState({\n      crosshairValues: series.map(s => s.data[index])\n    });\n  };\n\n  _updateButtonClicked = () => {\n    const {series} = this.state;\n    const totalValues = Math.random() * 50;\n    series.forEach(s => {\n      s.data = getRandomSeriesData(totalValues);\n    });\n    this.setState({series});\n  };\n\n  render() {\n    const {series, crosshairValues} = this.state;\n    return (\n      <div className=\"example-with-click-me\">\n        <div className=\"legend\">\n          <DiscreteColorLegend\n            onItemClick={this._legendClickHandler}\n            width={180}\n            items={series}\n          />\n        </div>\n\n        <div className=\"chart\">\n          <FlexibleWidthXYPlot\n            animation\n            getX={d => d.left}\n            getY={d => d.top}\n            onMouseLeave={this._mouseLeaveHandler}\n            xDomain={[-0.5, series[0].data.length - 1]}\n            height={300}\n          >\n            <HorizontalGridLines />\n            <YAxis\n              className=\"cool-custom-name\"\n              tickSizeInner={0}\n              tickSizeOuter={8}\n            />\n            <XAxis\n              className=\"even-cooler-custom-name\"\n              tickSizeInner={0}\n              tickSizeOuter={8}\n            />\n            <VerticalRectSeries\n              data={series[0].data.map(({left, top}) => ({\n                x0: left - 0.5,\n                left: left + 0.5,\n                top\n              }))}\n              stroke=\"white\"\n              onNearestX={this._nearestXHandler}\n              {...(series[0].disabled ? {opacity: 0.2} : null)}\n            />\n            <LineSeries\n              data={series[1].data}\n              curve=\"curveMonotoneX\"\n              {...(series[1].disabled ? {opacity: 0.2} : null)}\n            />\n            <Crosshair\n              itemsFormat={this._formatCrosshairItems}\n              titleFormat={this._formatCrosshairTitle}\n              values={crosshairValues}\n            />\n          </FlexibleWidthXYPlot>\n        </div>\n\n        <button className=\"click-me\" onClick={this._updateButtonClicked}>\n          Click to update\n        </button>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/contour-series-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  ContourSeries,\n  MarkSeriesCanvas,\n  Borders\n} from 'react-vis';\n\nimport DATA from '../datasets/old-faithful.json';\n\nfunction updateData() {\n  return DATA.map(row => ({\n    waiting: row.waiting + (Math.random() - 0.5) * 10,\n    eruptions: row.eruptions + (Math.random() - 0.5) * 2\n  }));\n}\nexport default class ContourSeriesExample extends Component {\n  state = {\n    data: DATA\n  };\n  render() {\n    const {data} = this.state;\n    return (\n      <div>\n        <XYPlot\n          xDomain={[40, 100]}\n          yDomain={[1.5, 8]}\n          width={600}\n          getX={d => d.waiting}\n          getY={d => d.eruptions}\n          height={300}\n        >\n          <ContourSeries\n            animation\n            className=\"contour-series-example\"\n            style={{\n              stroke: '#125C77',\n              strokeLinejoin: 'round'\n            }}\n            colorRange={['#79C7E3', '#FF9833']}\n            data={data}\n          />\n          <MarkSeriesCanvas animation data={data} size={1} color={'#125C77'} />\n          <Borders style={{all: {fill: '#fff'}}} />\n          <XAxis />\n          <YAxis />\n        </XYPlot>\n        <ShowcaseButton\n          onClick={() => this.setState({data: updateData()})}\n          buttonContent={'UPDATE'}\n        />\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/custom-scales.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  HorizontalGridLines,\n  VerticalGridLines,\n  LineSeries\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot xType=\"linear\" width={300} height={300}>\n      <HorizontalGridLines />\n      <VerticalGridLines />\n      <XAxis title=\"X Axis\" />\n      <YAxis title=\"Y Axis\" />\n      <LineSeries\n        data={[\n          {x: 1, y: 3},\n          {x: 2, y: 5},\n          {x: 3, y: 15},\n          {x: 4, y: 12}\n        ]}\n      />\n      <LineSeries data={null} />\n      <LineSeries\n        data={[\n          {x: 1, y: 10},\n          {x: 2, y: 4},\n          {x: 4, y: 2},\n          {x: 5, y: 15}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/custom-svg-all-the-marks.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  CustomSVGSeries,\n  Hint\n} from 'react-vis';\n\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nfunction generateData(reversed) {\n  return ['star', 'square', 'circle', 'diamond'].reduce(\n    (acc, row, rowIndex) => {\n      const cellsInRow = [...new Array(5)].map((cell, index) => {\n        return {\n          x: index,\n          y: reversed ? (5 - rowIndex) * 5 : rowIndex * 5,\n          size: (index + 1) * 3,\n          customComponent: row\n        };\n      });\n\n      return acc.concat(cellsInRow);\n    },\n    []\n  );\n}\n\nconst DATA = generateData(false);\nconst REVERSED_DATA = generateData(true);\n\nconst tipStyle = {\n  display: 'flex',\n  color: '#fff',\n  background: '#000',\n  alignItems: 'center',\n  padding: '5px'\n};\n\nexport default class Example extends React.Component {\n  state = {\n    reverse: false\n  };\n  render() {\n    const {reverse, hoveredCell} = this.state;\n\n    return (\n      <div>\n        <ShowcaseButton\n          buttonContent=\"REVERSE\"\n          onClick={() => this.setState({reverse: !reverse})}\n        />\n        <XYPlot margin={50} width={300} height={300}>\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <CustomSVGSeries\n            animation\n            style={{stroke: 'red', fill: 'orange'}}\n            data={reverse ? REVERSED_DATA : DATA}\n            onValueMouseOver={v => {\n              this.setState({hoveredCell: v});\n            }}\n            onValueMouseOut={() => this.setState({hoveredCell: false})}\n          />\n          {hoveredCell && (\n            <Hint value={hoveredCell}>\n              <div style={tipStyle}>{hoveredCell.customComponent}</div>\n            </Hint>\n          )}\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/custom-svg-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  CustomSVGSeries\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis />\n      <YAxis />\n      <CustomSVGSeries\n        className=\"custom-marking\"\n        customComponent=\"square\"\n        data={[\n          {x: 1, y: 10, value: 10, customComponent: 'circle', size: 10},\n          {\n            x: 1.7,\n            y: 12,\n            value: 12,\n            size: 20,\n            style: {stroke: 'red', fill: 'orange'}\n          },\n          {x: 2, y: 5, value: 5},\n          {x: 3, y: 15, value: 15},\n          {\n            x: 2.5,\n            y: 7,\n            value: 7,\n            // eslint-disable-next-line react/display-name\n            customComponent: (_, positionInPixels) => {\n              return (\n                <g className=\"inner-inner-component\">\n                  <circle cx=\"0\" cy=\"0\" r={10} fill=\"green\" />\n                  <text x={0} y={0}>\n                    <tspan x=\"0\" y=\"0\">{`x: ${positionInPixels.x}`}</tspan>\n                    <tspan x=\"0\" y=\"1em\">{`y: ${positionInPixels.y}`}</tspan>\n                  </text>\n                </g>\n              );\n            }\n          }\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/custom-svg-root-level.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  CustomSVGSeries\n} from 'react-vis';\n\nexport default function CustomSVGRootLevelComponent() {\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis />\n      <YAxis />\n      <CustomSVGSeries\n        className=\"custom-marking\"\n        customComponent={(row, positionInPixels) => {\n          return (\n            <g className=\"inner-inner-component\">\n              <circle cx=\"0\" cy=\"0\" r={row.size || 10} fill=\"green\" />\n              <text x={0} y={0}>\n                <tspan x=\"0\" y=\"0\">{`x: ${positionInPixels.x}`}</tspan>\n                <tspan x=\"0\" y=\"1em\">{`y: ${positionInPixels.y}`}</tspan>\n              </text>\n            </g>\n          );\n        }}\n        data={[\n          {x: 1, y: 10, size: 3},\n          {x: 1.7, y: 12, size: 20, style: {stroke: 'red', fill: 'orange'}},\n          {x: 2, y: 5},\n          {x: 3, y: 15},\n          {x: 2.5, y: 7}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/difference-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalBarSeries,\n  VerticalBarSeriesCanvas\n} from 'react-vis';\n\n// When making a difference chart you are specifying in coordinates\n// where you want your bars to start and stop\nconst myDATA = [...new Array(15)].map((x, idx) => ({\n  x: idx,\n  // if the bars are above zero then we start them at zero\n  y0: idx - 4 < 0 ? idx - 4 : 0,\n  // if the bars are below zero then we stop them at zero\n  y: idx < 5 ? 0 : Math.abs(idx - 4)\n}));\n\nconst yDomain = myDATA.reduce(\n  (res, row) => ({\n    max: Math.max(res.max, row.y, row.y0),\n    min: Math.min(res.min, row.y, row.y0)\n  }),\n  {max: -Infinity, min: Infinity}\n);\n\nexport default class DifferenceChart extends React.Component {\n  state = {\n    useCanvas: false\n  };\n\n  render() {\n    const {useCanvas} = this.state;\n    const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';\n    const BarSeries = useCanvas ? VerticalBarSeriesCanvas : VerticalBarSeries;\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({useCanvas: !useCanvas})}\n          buttonContent={content}\n        />\n        <XYPlot width={300} height={300} yDomain={[yDomain.min, yDomain.max]}>\n          <BarSeries\n            className=\"difference-example\"\n            data={myDATA}\n            colorType=\"literal\"\n            getColor={d => {\n              return d.y0 < 0 ? '#EF5D28' : '#1A3177';\n            }}\n          />\n          <XAxis />\n          <YAxis />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/faux-radial-scatterplot.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {XYPlot, XAxis, YAxis, MarkSeries, CircularGridLines} from 'react-vis';\n\nconst data = [\n  {r: 1, theta: Math.PI / 3, size: 30},\n  {r: 1.7, theta: (2 * Math.PI) / 3, size: 10},\n  {r: 2, theta: Math.PI, size: 1},\n  {r: 3, theta: (3 * Math.PI) / 2, size: 12},\n  {r: 2.5, theta: Math.PI / 4, size: 4},\n  {r: 0, theta: Math.PI / 4, size: 1}\n];\n\nconst margin = {\n  top: 10,\n  bottom: 10,\n  left: 10,\n  right: 10\n};\n\nconst WIDTH = 300;\nconst HEIGHT = 300;\n\nexport default function Example() {\n  return (\n    <XYPlot\n      margin={margin}\n      xDomain={[-3, 3]}\n      yDomain={[-3, 3]}\n      width={WIDTH}\n      height={HEIGHT}\n    >\n      <CircularGridLines />\n      <XAxis top={(HEIGHT - margin.top) / 2} />\n      <YAxis left={(WIDTH - margin.left - margin.right) / 2} />\n      <MarkSeries\n        strokeWidth={2}\n        sizeRange={[5, 15]}\n        data={data.map(row => ({\n          ...row,\n          x: Math.cos(row.theta) * row.r,\n          y: Math.sin(row.theta) * row.r\n        }))}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/grid.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {XYPlot, XAxis, YAxis, VerticalGridLines, LineSeries} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines values={[2, 2.3, 2.7]} />\n      <XAxis />\n      <YAxis />\n      <LineSeries\n        data={[\n          {x: 1, y: 10},\n          {x: 2, y: 5},\n          {x: 3, y: 15}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/heatmap-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport {XYPlot, XAxis, YAxis, HeatmapSeries, Hint} from 'react-vis';\n\nexport default class HeatmapChart extends Component {\n  state = {\n    value: false\n  };\n\n  render() {\n    const {value} = this.state;\n    return (\n      <XYPlot width={300} height={300}>\n        <XAxis />\n        <YAxis />\n        <HeatmapSeries\n          className=\"heatmap-series-example\"\n          onValueMouseOver={v => this.setState({value: v})}\n          onSeriesMouseOut={() => this.setState({value: false})}\n          data={[\n            {x: 1, y: 0, color: 10},\n            {x: 1, y: 5, color: 10},\n            {x: 1, y: 10, color: 6},\n            {x: 1, y: 15, color: 7},\n            {x: 2, y: 0, color: 12},\n            {x: 2, y: 5, color: 2},\n            {x: 2, y: 10, color: 1},\n            {x: 2, y: 15, color: 12},\n            {x: 3, y: 0, color: 9},\n            {x: 3, y: 5, color: 2},\n            {x: 3, y: 10, color: 6},\n            {x: 3, y: 15, color: 12}\n          ]}\n        />\n        {value !== false && <Hint value={value} />}\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/hex-heatmap.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nimport {XYPlot, XAxis, YAxis, HexbinSeries, Borders, Hint} from 'react-vis';\n\nimport DATA from '../datasets/old-faithful.json';\n\nfunction updateData() {\n  return DATA.map(row => ({\n    waiting: row.waiting + (Math.random() - 0.5) * 10,\n    eruptions: row.eruptions + (Math.random() - 0.5) * 2\n  }));\n}\nexport default class HexHeatmap extends Component {\n  state = {\n    data: DATA,\n    hoveredNode: null,\n    radius: 10,\n    offset: 0\n  };\n  render() {\n    const {data, radius, hoveredNode, offset} = this.state;\n\n    return (\n      <div>\n        <XYPlot\n          xDomain={[40, 100]}\n          yDomain={[1.5, 8]}\n          width={300}\n          getX={d => d.waiting}\n          getY={d => d.eruptions}\n          onMouseLeave={() => this.setState({hoveredNode: null})}\n          height={300}\n        >\n          <HexbinSeries\n            animation\n            className=\"hexbin-example\"\n            style={{\n              stroke: '#125C77',\n              strokeLinejoin: 'round'\n            }}\n            onValueMouseOver={d => this.setState({hoveredNode: d})}\n            xOffset={offset}\n            yOffset={offset}\n            colorRange={['orange', 'cyan']}\n            radius={radius}\n            data={data}\n          />\n          <Borders style={{all: {fill: '#fff'}}} />\n          <XAxis />\n          <YAxis />\n          {hoveredNode && (\n            <Hint\n              xType=\"literal\"\n              yType=\"literal\"\n              getX={d => d.x}\n              getY={d => d.y}\n              value={{\n                x: hoveredNode.x,\n                y: hoveredNode.y,\n                value: hoveredNode.length\n              }}\n            />\n          )}\n        </XYPlot>\n        <ShowcaseButton\n          onClick={() => this.setState({data: updateData()})}\n          buttonContent={'UPDATE DATA'}\n        />\n        <ShowcaseButton\n          onClick={() =>\n            this.setState({radius: (Math.random() - 0.5) * 10 + 10})\n          }\n          buttonContent={'UPDATE RADIUS'}\n        />\n        <ShowcaseButton\n          onClick={() =>\n            this.setState({offset: (Math.random() - 0.5) * 10 + 10})\n          }\n          buttonContent={'UPDATE OFFSET'}\n        />\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/hexbin-size-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nimport {XYPlot, XAxis, YAxis, HexbinSeries, ChartLabel} from 'react-vis';\n\nimport DATA from '../datasets/car-data.json';\n\nconst DIMENSIONS = [\n  'economy (mpg)',\n  'cylinders',\n  'displacement (cc)',\n  'power (hp)',\n  'weight (lb)',\n  '0-60 mph (s)',\n  'year'\n];\n\nexport default class HexbinSizeExample extends Component {\n  state = {\n    xAxis: 0,\n    yAxis: 3\n  };\n\n  updateX(increment) {\n    this.setState({\n      xAxis: (this.state.xAxis + (increment ? 1 : -1)) % DIMENSIONS.length\n    });\n  }\n\n  updateY(increment) {\n    this.setState({\n      yAxis: (this.state.yAxis + (increment ? 1 : -1)) % DIMENSIONS.length\n    });\n  }\n\n  render() {\n    const {xAxis, yAxis} = this.state;\n    const data = DATA.map(d => ({\n      x: Number(d[DIMENSIONS[xAxis]]),\n      y: Number(d[DIMENSIONS[yAxis]])\n    }));\n\n    return (\n      <div className=\"centered-and-flexed\">\n        <div className=\"centered-and-flexed-controls\">\n          <ShowcaseButton\n            onClick={() => this.updateX(false)}\n            buttonContent={'PREV X'}\n          />\n          <div> {`X AXIS ${DIMENSIONS[xAxis]}`} </div>\n          <ShowcaseButton\n            onClick={() => this.updateX(true)}\n            buttonContent={'NEXT X'}\n          />\n        </div>\n        <div className=\"centered-and-flexed-controls\">\n          <ShowcaseButton\n            onClick={() => this.updateY(false)}\n            buttonContent={'PREV Y'}\n          />\n          <div> {`Y AXIS ${DIMENSIONS[yAxis]}`} </div>\n          <ShowcaseButton\n            onClick={() => this.updateY(true)}\n            buttonContent={'NEXT Y'}\n          />\n        </div>\n        <XYPlot\n          width={500}\n          onMouseLeave={() => this.setState({hoveredNode: null})}\n          height={300}\n          margin={50}\n        >\n          <HexbinSeries\n            animation\n            sizeHexagonsWithCount\n            className=\"hexbin-size-example\"\n            radius={15}\n            data={data}\n          />\n          <XAxis />\n          <YAxis />\n          <ChartLabel\n            text={DIMENSIONS[xAxis]}\n            className=\"alt-x-label\"\n            xPercent={0.9}\n            yPercent={0.65}\n            style={{\n              transform: 'rotate(90)',\n              textAnchor: 'end'\n            }}\n          />\n\n          <ChartLabel\n            text={DIMENSIONS[yAxis]}\n            className=\"alt-y-label\"\n            xPercent={0.1}\n            yPercent={0.0}\n            style={{\n              textAnchor: 'start'\n            }}\n          />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/histogram.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  VerticalRectSeries\n} from 'react-vis';\n\nconst timestamp = new Date('May 23 2017').getTime();\nconst ONE_DAY = 86400000;\n\nconst DATA = [\n  {x0: ONE_DAY * 2, x: ONE_DAY * 3, y: 1},\n  {x0: ONE_DAY * 7, x: ONE_DAY * 8, y: 1},\n  {x0: ONE_DAY * 8, x: ONE_DAY * 9, y: 1},\n  {x0: ONE_DAY * 9, x: ONE_DAY * 10, y: 2},\n  {x0: ONE_DAY * 10, x: ONE_DAY * 11, y: 2.2},\n  {x0: ONE_DAY * 19, x: ONE_DAY * 20, y: 1},\n  {x0: ONE_DAY * 20, x: ONE_DAY * 21, y: 2.5},\n  {x0: ONE_DAY * 21, x: ONE_DAY * 24, y: 1}\n].map(el => ({x0: el.x0 + timestamp, x: el.x + timestamp, y: el.y}));\n\nexport default function Example() {\n  return (\n    <XYPlot\n      xDomain={[timestamp - 2 * ONE_DAY, timestamp + 30 * ONE_DAY]}\n      yDomain={[0.1, 2.1]}\n      xType=\"time\"\n      width={300}\n      height={300}\n    >\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis />\n      <YAxis />\n      <VerticalRectSeries data={DATA} style={{stroke: '#fff'}} />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/labeled-heatmap.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\nimport {scaleLinear} from 'd3-scale';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  HeatmapSeries,\n  LabelSeries,\n  Hint\n} from 'react-vis';\n\nconst alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'];\nconst data = alphabet.reduce((acc, letter1, idx) => {\n  return acc.concat(\n    alphabet.map((letter2, jdx) => ({\n      x: `${letter1}1`,\n      y: `${letter2}2`,\n      color: (idx + jdx) % Math.floor(jdx / idx) || idx\n    }))\n  );\n}, []);\nconst {min, max} = data.reduce(\n  (acc, row) => ({\n    min: Math.min(acc.min, row.color),\n    max: Math.max(acc.max, row.color)\n  }),\n  {min: Infinity, max: -Infinity}\n);\n\nexport default class LabeledHeatmap extends Component {\n  state = {\n    value: false\n  };\n\n  render() {\n    const {value} = this.state;\n    const exampleColorScale = scaleLinear()\n      .domain([min, (min + max) / 2, max])\n      .range(['orange', 'white', 'cyan']);\n\n    return (\n      <XYPlot\n        xType=\"ordinal\"\n        xDomain={alphabet.map(letter => `${letter}1`)}\n        yType=\"ordinal\"\n        yDomain={alphabet.map(letter => `${letter}2`).reverse()}\n        margin={50}\n        width={500}\n        height={500}\n      >\n        <XAxis orientation=\"top\" />\n        <YAxis />\n        <HeatmapSeries\n          colorType=\"literal\"\n          getColor={d => exampleColorScale(d.color)}\n          style={{\n            stroke: 'white',\n            strokeWidth: '2px',\n            rectStyle: {\n              rx: 10,\n              ry: 10\n            }\n          }}\n          className=\"heatmap-series-example\"\n          data={data}\n          onValueMouseOver={v => this.setState({value: v})}\n          onSeriesMouseOut={() => this.setState({value: false})}\n        />\n        <LabelSeries\n          style={{pointerEvents: 'none'}}\n          data={data}\n          labelAnchorX=\"middle\"\n          labelAnchorY=\"baseline\"\n          getLabel={d => `${d.color}`}\n        />\n        {value !== false && <Hint value={value} />}\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/labeled-stacked-vertical-bar-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  VerticalBarSeries,\n  VerticalBarSeriesCanvas,\n  LabelSeries\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  state = {\n    useCanvas: false\n  };\n  render() {\n    const {useCanvas} = this.state;\n    const BarSeries = useCanvas ? VerticalBarSeriesCanvas : VerticalBarSeries;\n    const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';\n    const data = [\n      [\n        {x: 1, y: 8},\n        {x: 3, y: 5},\n        {x: 4, y: 15}\n      ],\n      [\n        {x: 3, y: 9},\n        {x: 4, y: 2},\n        {x: 5, y: 7}\n      ],\n      [\n        {x: 2, y: 11},\n        {x: 3, y: 7},\n        {x: 4, y: 9}\n      ]\n    ];\n    const labelsData = data.map(value =>\n      value.map(tuple => ({x: tuple.x, y: tuple.y, label: tuple.y.toString()}))\n    );\n\n    const bars = data.map((value, index) => (\n      <BarSeries data={value} key={index} />\n    ));\n    const labels = labelsData.map((value, index) => (\n      <LabelSeries\n        data={value}\n        key={index}\n        labelAnchorY=\"hanging\"\n        style={{fill: '#ff8c00'}}\n      />\n    ));\n\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({useCanvas: !useCanvas})}\n          buttonContent={content}\n        />\n        <XYPlot width={300} height={300} stackBy=\"y\">\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          {bars}\n          {labels}\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/line-chart-canvas.js",
    "content": "// Copyright (c) 2016 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineMarkSeriesCanvas,\n  LineMarkSeries,\n  LineSeriesCanvas,\n  LineSeries,\n  Crosshair\n} from 'react-vis';\n\nfunction getRandomData() {\n  return new Array(1000).fill(0).map((row, i) => ({\n    x: i,\n    y: Math.random() * 20,\n    color: Math.random() * 10\n  }));\n}\n\nconst randomData = getRandomData();\n\nconst colorRanges = {\n  typeA: ['#59E4EC', '#0D676C'],\n  typeB: ['#EFC1E3', '#B52F93']\n};\n\nconst nextType = {\n  typeA: 'typeB',\n  typeB: 'typeA'\n};\n\nconst nextModeContent = {\n  canvas: 'SWITCH TO SVG',\n  svg: 'SWITCH TO CANVAS'\n};\n\nconst drawModes = ['canvas', 'svg'];\n\nexport default class Example extends React.Component {\n  state = {\n    drawMode: 0,\n    data: randomData,\n    colorType: 'typeA',\n    strokeWidth: 1,\n    showMarks: true,\n    value: false,\n    hideComponent: false\n  };\n\n  render() {\n    const {\n      colorType,\n      drawMode,\n      data,\n      hideComponent,\n      strokeWidth,\n      showMarks,\n      value\n    } = this.state;\n    const lineSeriesProps = {\n      animation: true,\n      className: 'mark-series-example',\n      sizeRange: [5, 15],\n      color: colorType === 'typeA' ? '#0D676C' : '#B52F93',\n      colorRange: colorRanges[colorType],\n      opacityType: 'literal',\n      strokeWidth,\n      data,\n      onNearestX: d => this.setState({value: d})\n    };\n    const SVGComponent = showMarks ? LineMarkSeries : LineSeries;\n    const CanvasComponent = showMarks ? LineMarkSeriesCanvas : LineSeriesCanvas;\n\n    const mode = drawModes[drawMode];\n    return (\n      <div className=\"canvas-wrapper\">\n        <div className=\"canvas-example-controls\">\n          <div> {`Mode: ${mode}`} </div>\n          <ShowcaseButton\n            onClick={() => this.setState({drawMode: (drawMode + 1) % 2})}\n            buttonContent={nextModeContent[mode]}\n          />\n          <ShowcaseButton\n            onClick={() => this.setState({showMarks: !showMarks})}\n            buttonContent={showMarks ? 'HIDE MARKS' : 'SHOW MARKS'}\n          />\n          <ShowcaseButton\n            onClick={() => this.setState({data: getRandomData()})}\n            buttonContent={'UPDATE DATA'}\n          />\n          <ShowcaseButton\n            onClick={() => this.setState({colorType: nextType[colorType]})}\n            buttonContent={`TOGGLE COLOR to ${nextType[colorType]}`}\n          />\n          <ShowcaseButton\n            onClick={() =>\n              this.setState({strokeWidth: strokeWidth === 1 ? 2 : 1})\n            }\n            buttonContent={'TOGGLE STROKEWIDTH'}\n          />\n          <ShowcaseButton\n            onClick={() => this.setState({hideComponent: !hideComponent})}\n            buttonContent={hideComponent ? 'SHOW' : 'HIDE'}\n          />\n        </div>\n        {!hideComponent && (\n          <XYPlot\n            onMouseLeave={() => this.setState({value: false})}\n            width={600}\n            height={300}\n          >\n            <VerticalGridLines />\n            <HorizontalGridLines />\n            <XAxis />\n            <YAxis />\n            {mode === 'canvas' && <CanvasComponent {...lineSeriesProps} />}\n            {mode === 'svg' && <SVGComponent {...lineSeriesProps} />}\n            {value && <Crosshair values={[value]} />}\n          </XYPlot>\n        )}\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/line-chart-with-style.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {curveCatmullRom} from 'd3-shape';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  HorizontalGridLines,\n  VerticalGridLines,\n  LineSeries\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot width={300} height={300}>\n      <HorizontalGridLines style={{stroke: '#B7E9ED'}} />\n      <VerticalGridLines style={{stroke: '#B7E9ED'}} />\n      <XAxis\n        title=\"X Axis\"\n        style={{\n          line: {stroke: '#ADDDE1'},\n          ticks: {stroke: '#ADDDE1'},\n          text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}\n        }}\n      />\n      <YAxis title=\"Y Axis\" />\n      <LineSeries\n        className=\"first-series\"\n        data={[\n          {x: 1, y: 3},\n          {x: 2, y: 5},\n          {x: 3, y: 15},\n          {x: 4, y: 12}\n        ]}\n        style={{\n          strokeLinejoin: 'round',\n          strokeWidth: 4\n        }}\n      />\n      <LineSeries className=\"second-series\" data={null} />\n      <LineSeries\n        className=\"third-series\"\n        curve={'curveMonotoneX'}\n        data={[\n          {x: 1, y: 10},\n          {x: 2, y: 4},\n          {x: 3, y: 2},\n          {x: 4, y: 15}\n        ]}\n        strokeDasharray=\"7, 3\"\n      />\n      <LineSeries\n        className=\"fourth-series\"\n        curve={curveCatmullRom.alpha(0.5)}\n        data={[\n          {x: 1, y: 7},\n          {x: 2, y: 11},\n          {x: 3, y: 9},\n          {x: 4, y: 2}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/line-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {curveCatmullRom} from 'd3-shape';\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  ChartLabel,\n  HorizontalGridLines,\n  VerticalGridLines,\n  LineSeries,\n  LineSeriesCanvas\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  state = {\n    useCanvas: false\n  };\n  render() {\n    const {useCanvas} = this.state;\n    const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';\n    const Line = useCanvas ? LineSeriesCanvas : LineSeries;\n\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({useCanvas: !useCanvas})}\n          buttonContent={content}\n        />\n        <XYPlot width={300} height={300}>\n          <HorizontalGridLines />\n          <VerticalGridLines />\n          <XAxis />\n          <YAxis />\n          <ChartLabel\n            text=\"X Axis\"\n            className=\"alt-x-label\"\n            includeMargin={false}\n            xPercent={0.025}\n            yPercent={1.01}\n          />\n\n          <ChartLabel\n            text=\"Y Axis\"\n            className=\"alt-y-label\"\n            includeMargin={false}\n            xPercent={0.06}\n            yPercent={0.06}\n            style={{\n              transform: 'rotate(-90)',\n              textAnchor: 'end'\n            }}\n          />\n          <Line\n            className=\"first-series\"\n            data={[\n              {x: 1, y: 3},\n              {x: 2, y: 5},\n              {x: 3, y: 15},\n              {x: 4, y: 12}\n            ]}\n          />\n          <Line className=\"second-series\" data={null} />\n          <Line\n            className=\"third-series\"\n            curve={'curveMonotoneX'}\n            data={[\n              {x: 1, y: 10},\n              {x: 2, y: 4},\n              {x: 3, y: 2},\n              {x: 4, y: 15}\n            ]}\n            strokeDasharray={useCanvas ? [7, 3] : '7, 3'}\n          />\n          <Line\n            className=\"fourth-series\"\n            curve={curveCatmullRom.alpha(0.5)}\n            style={{\n              // note that this can not be translated to the canvas version\n              strokeDasharray: '2 2'\n            }}\n            data={[\n              {x: 1, y: 7},\n              {x: 2, y: 11},\n              {x: 3, y: 9},\n              {x: 4, y: 2}\n            ]}\n          />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/line-series-canvas-nearest-xy-example.js",
    "content": "// Copyright (c) 2016-2018 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nimport React from 'react';\nimport {XYPlot, LineSeriesCanvas, MarkSeriesCanvas} from 'react-vis';\nconst k = 100;\nconst data = Array(k)\n  .fill(0)\n  .map((n, x) => ({x, y: x % 2 ? 180 : -180}));\n\nexport default class LineSeriesCanvasNearestXYExample extends React.Component {\n  state = {\n    nearestXY: data[0]\n  };\n\n  render() {\n    const {nearestXY} = this.state;\n    return (\n      <XYPlot\n        width={500}\n        height={300}\n        domainX={[0, 2 * k]}\n        domainY={[-200, 200]}\n      >\n        {\n          <LineSeriesCanvas\n            onNearestXY={point => this.setState({nearestXY: point})}\n            data={data}\n          />\n        }\n        {\n          <MarkSeriesCanvas\n            size={5}\n            fill={'yellow'}\n            stroke={'red'}\n            style={{pointerEvents: 'none'}}\n            data={[nearestXY]}\n          />\n        }\n      </XYPlot>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/linemark-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  LineMarkSeries\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis />\n      <YAxis />\n      <LineMarkSeries\n        className=\"linemark-series-example\"\n        style={{\n          strokeWidth: '3px'\n        }}\n        lineStyle={{stroke: 'red'}}\n        markStyle={{stroke: 'blue'}}\n        data={[\n          {x: 1, y: 10},\n          {x: 2, y: 5},\n          {x: 3, y: 15}\n        ]}\n      />\n      <LineMarkSeries\n        className=\"linemark-series-example-2\"\n        curve={'curveMonotoneX'}\n        data={[\n          {x: 1, y: 11},\n          {x: 1.5, y: 29},\n          {x: 3, y: 7}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/mixed-stacked-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  VerticalBarSeries,\n  VerticalBarSeriesCanvas,\n  LineSeries\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  state = {\n    useCanvas: false\n  };\n  render() {\n    const {useCanvas} = this.state;\n    const BarSeries = useCanvas ? VerticalBarSeriesCanvas : VerticalBarSeries;\n    const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({useCanvas: !useCanvas})}\n          buttonContent={content}\n        />\n        <XYPlot width={300} height={300} stackBy=\"y\">\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <BarSeries\n            data={[\n              {x: 2, y: 10},\n              {x: 4, y: 5},\n              {x: 5, y: 15}\n            ]}\n            stack\n          />\n          <BarSeries\n            data={[\n              {x: 2, y: 12},\n              {x: 4, y: 2},\n              {x: 5, y: 11}\n            ]}\n            stack\n          />\n          <LineSeries\n            className=\"fourth-series\"\n            data={[\n              {x: 2, y: 26},\n              {x: 4, y: 8},\n              {x: 5, y: 30}\n            ]}\n          />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/scatterplot-canvas.js",
    "content": "// Copyright (c) 2016 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  MarkSeries,\n  MarkSeriesCanvas,\n  Hint\n} from 'react-vis';\n\nfunction getRandomData() {\n  return new Array(100).fill(0).map(() => ({\n    x: Math.random() * 10,\n    y: Math.random() * 20,\n    size: Math.random() * 10,\n    color: Math.random() * 10,\n    opacity: Math.random() * 0.5 + 0.5\n  }));\n}\nconst colorRanges = {\n  typeA: ['#59E4EC', '#0D676C'],\n  typeB: ['#EFC1E3', '#B52F93']\n};\n\nconst randomData = getRandomData();\nconst nextType = {\n  typeA: 'typeB',\n  typeB: 'typeA'\n};\n\nconst nextModeContent = {\n  canvas: 'SWITCH TO SVG',\n  svg: 'SWITCH TO CANVAS'\n};\n\nconst drawModes = ['canvas', 'svg'];\n\nexport default class Example extends React.Component {\n  state = {\n    drawMode: 0,\n    data: randomData,\n    colorType: 'typeA',\n    value: false\n  };\n\n  render() {\n    const {drawMode, data, colorType} = this.state;\n    const markSeriesProps = {\n      animation: true,\n      className: 'mark-series-example',\n      sizeRange: [5, 15],\n      seriesId: 'my-example-scatterplot',\n      colorRange: colorRanges[colorType],\n      opacityType: 'literal',\n      data,\n      onNearestXY: value => this.setState({value})\n    };\n\n    const mode = drawModes[drawMode];\n    return (\n      <div className=\"canvas-wrapper\">\n        <div className=\"canvas-example-controls\">\n          <div>{`MODE: ${mode}`}</div>\n          <ShowcaseButton\n            onClick={() => this.setState({drawMode: (drawMode + 1) % 2})}\n            buttonContent={nextModeContent[mode]}\n          />\n          <ShowcaseButton\n            onClick={() => this.setState({data: getRandomData()})}\n            buttonContent={'UPDATE DATA'}\n          />\n          <ShowcaseButton\n            onClick={() => this.setState({colorType: nextType[colorType]})}\n            buttonContent={'UPDATE COLOR'}\n          />\n        </div>\n        <XYPlot\n          onMouseLeave={() => this.setState({value: false})}\n          width={600}\n          height={300}\n        >\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          {mode === 'canvas' && <MarkSeriesCanvas {...markSeriesProps} />}\n          {mode === 'svg' && <MarkSeries {...markSeriesProps} />}\n          {this.state.value ? <Hint value={this.state.value} /> : null}\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/scatterplot.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  MarkSeries\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis />\n      <YAxis />\n      <MarkSeries\n        className=\"mark-series-example\"\n        strokeWidth={2}\n        opacity=\"0.8\"\n        sizeRange={[5, 15]}\n        data={[\n          {x: 1, y: 10, size: 30},\n          {x: 1.7, y: 12, size: 10},\n          {x: 2, y: 5, size: 1},\n          {x: 3, y: 15, size: 12},\n          {x: 2.5, y: 7, size: 4}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/stacked-histogram.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  VerticalRectSeries,\n  VerticalRectSeriesCanvas\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  state = {\n    useCanvas: false\n  };\n  render() {\n    const {useCanvas} = this.state;\n    const RectSeries = useCanvas\n      ? VerticalRectSeriesCanvas\n      : VerticalRectSeries;\n    const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({useCanvas: !useCanvas})}\n          buttonContent={content}\n        />\n        <XYPlot xDomain={[0, 7]} width={300} height={300} stackBy=\"y\">\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <RectSeries\n            data={[\n              {x0: 1, x: 2, y: 10},\n              {x0: 2, x: 4, y: 5},\n              {x0: 5, x: 6, y: 15}\n            ]}\n          />\n          <RectSeries\n            data={[\n              {x0: 1, x: 2, y: 12},\n              {x0: 2, x: 4, y: 2},\n              {x0: 5, x: 6, y: 15}\n            ]}\n          />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/stacked-horizontal-bar-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  HorizontalBarSeries,\n  HorizontalBarSeriesCanvas\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  state = {\n    useCanvas: false\n  };\n  render() {\n    const {useCanvas} = this.state;\n    const BarSeries = useCanvas\n      ? HorizontalBarSeriesCanvas\n      : HorizontalBarSeries;\n    const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({useCanvas: !useCanvas})}\n          buttonContent={content}\n        />\n        <XYPlot width={300} height={300} stackBy=\"x\">\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <BarSeries\n            data={[\n              {y: 2, x: 10},\n              {y: 4, x: 5},\n              {y: 5, x: 15}\n            ]}\n          />\n          <BarSeries\n            data={[\n              {y: 2, x: 12},\n              {y: 4, x: 2},\n              {y: 5, x: 11}\n            ]}\n          />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/stacked-vertical-bar-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  VerticalBarSeries,\n  VerticalBarSeriesCanvas\n} from 'react-vis';\n\nexport default class Example extends React.Component {\n  state = {\n    useCanvas: false\n  };\n  render() {\n    const {useCanvas} = this.state;\n    const BarSeries = useCanvas ? VerticalBarSeriesCanvas : VerticalBarSeries;\n    const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() => this.setState({useCanvas: !useCanvas})}\n          buttonContent={content}\n        />\n        <XYPlot width={300} height={300} stackBy=\"y\">\n          <VerticalGridLines />\n          <HorizontalGridLines />\n          <XAxis />\n          <YAxis />\n          <BarSeries\n            data={[\n              {x: 2, y: 10},\n              {x: 4, y: 5},\n              {x: 5, y: 15}\n            ]}\n          />\n          <BarSeries\n            data={[\n              {x: 2, y: 12},\n              {x: 4, y: 2},\n              {x: 5, y: 11}\n            ]}\n          />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/plot/whisker-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {\n  XYPlot,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines,\n  WhiskerSeries\n} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot width={300} height={300}>\n      <VerticalGridLines />\n      <HorizontalGridLines />\n      <XAxis />\n      <YAxis />\n      <WhiskerSeries\n        className=\"whisker-series-example\"\n        data={[\n          {x: 1, y: 10, xVariance: 0.2, yVariance: 4},\n          {x: 1.7, y: 12, xVariance: 0.3, yVariance: 7},\n          {x: 2, y: 5, xVariance: 0.1, yVariance: 3},\n          {x: 3, y: 15, xVariance: 0.4, yVariance: 10},\n          {x: 2.5, y: 7, xVariance: 0.3, yVariance: 4}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/plot/width-height-margin.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {XYPlot, XAxis, YAxis, VerticalGridLines, LineSeries} from 'react-vis';\n\nexport default function Example() {\n  return (\n    <XYPlot margin={50} width={200} height={200}>\n      <VerticalGridLines />\n      <XAxis />\n      <YAxis />\n      <LineSeries\n        data={[\n          {x: 1, y: 10},\n          {x: 2, y: 5},\n          {x: 3, y: 15}\n        ]}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/radar-chart/animated-radar-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport RadarChart from 'react-vis/radar-chart';\nimport CircularGridLines from 'react-vis/plot/circular-grid-lines';\n\nconst DATA = [\n  {\n    explosions: 7,\n    wow: 10,\n    dog: 8,\n    sickMoves: 9,\n    nice: 7\n  }\n];\n\nconst DOMAIN = [\n  {name: 'nice', domain: [0, 100], tickFormat: t => t},\n  {name: 'explosions', domain: [6.9, 7.1]},\n  {name: 'wow', domain: [0, 11]},\n  {name: 'dog', domain: [0, 16]},\n  {name: 'sickMoves', domain: [0, 20]}\n];\n\nfunction generateData() {\n  return [\n    Object.keys(DATA[0]).reduce((acc, key) => {\n      acc[key] = DATA[0][key] + 5 * (Math.random() - 0.5);\n      return acc;\n    }, {})\n  ];\n}\n\nexport default class AnimatedRadar extends Component {\n  state = {\n    data: DATA\n  };\n\n  render() {\n    const {data} = this.state;\n\n    return (\n      <div className=\"centered-and-flexed\">\n        <RadarChart\n          animation\n          data={data}\n          domains={DOMAIN}\n          style={{\n            polygons: {\n              fillOpacity: 0,\n              strokeWidth: 3\n            },\n            axes: {\n              text: {\n                opacity: 1\n              }\n            },\n            labels: {\n              textAnchor: 'middle'\n            }\n          }}\n          margin={{\n            left: 30,\n            top: 30,\n            bottom: 40,\n            right: 50\n          }}\n          tickFormat={() => ''}\n          width={400}\n          height={300}\n        >\n          <CircularGridLines\n            tickValues={[...new Array(10)].map((v, i) => i / 10 - 1)}\n          />\n        </RadarChart>\n        <ShowcaseButton\n          onClick={() => this.setState({data: generateData()})}\n          buttonContent={'UPDATE DATA'}\n        />\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/radar-chart/basic-radar-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport {format} from 'd3-format';\n\nimport RadarChart from 'react-vis/radar-chart';\n\nconst DATA = [\n  {\n    name: 'Mercedes',\n    mileage: 7,\n    price: 10,\n    safety: 8,\n    performance: 9,\n    interior: 7,\n    warranty: 7\n  },\n  {\n    name: 'Honda',\n    mileage: 8,\n    price: 6,\n    safety: 9,\n    performance: 6,\n    interior: 3,\n    warranty: 9\n  },\n  {\n    name: 'Chevrolet',\n    mileage: 5,\n    price: 4,\n    safety: 6,\n    performance: 4,\n    interior: 5,\n    warranty: 6\n  }\n];\n\nconst basicFormat = format('.2r');\nconst wideFormat = format('.3r');\n\nexport default function BasicRadarChart() {\n  return (\n    <RadarChart\n      data={DATA}\n      tickFormat={t => wideFormat(t)}\n      startingAngle={0}\n      domains={[\n        {name: 'mileage', domain: [0, 10]},\n        {\n          name: 'price',\n          domain: [2, 16],\n          tickFormat: t => `$${basicFormat(t)}`,\n          getValue: d => d.price\n        },\n        {name: 'safety', domain: [5, 10], getValue: d => d.safety},\n        {name: 'performance', domain: [0, 10], getValue: d => d.performance},\n        {name: 'interior', domain: [0, 7], getValue: d => d.interior},\n        {name: 'warranty', domain: [10, 2], getValue: d => d.warranty}\n      ]}\n      width={400}\n      height={300}\n    />\n  );\n}\n"
  },
  {
    "path": "packages/showcase/radar-chart/four-quadrant-radar-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport RadarChart from 'react-vis/radar-chart';\n\nconst RADAR_PROPS = {\n  data: [\n    {\n      C: 30,\n      VisualBasics: 60,\n      Excel: 40,\n      Access: 40\n    }\n  ],\n  domains: [\n    {name: 'C', domain: [0, 100]},\n    {name: 'VisualBasics', domain: [0, 100]},\n    {name: 'Excel', domain: [0, 100]},\n    {name: 'Access', domain: [0, 100]}\n  ],\n  height: 300,\n  width: 400\n};\n\nexport default function FourQuadrantRadarChart() {\n  return (\n    <RadarChart\n      data={RADAR_PROPS.data}\n      domains={RADAR_PROPS.domains}\n      height={RADAR_PROPS.height}\n      width={RADAR_PROPS.width}\n      startingAngle={Math.PI / 7}\n      className=\"overflow-okay horizontally-centered\"\n      style={{\n        labels: {\n          fontSize: 13\n        },\n        polygons: {\n          fillOpacity: 0.1,\n          strokeOpacity: 1,\n          strokeWidth: 0.5\n        }\n      }}\n    />\n  );\n}\n"
  },
  {
    "path": "packages/showcase/radar-chart/radar-chart-series-tooltips.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\nimport {format} from 'd3-format';\n\nimport RadarChart from 'react-vis/radar-chart';\nimport {Hint} from 'react-vis';\n\nconst DATA = [\n  {\n    name: 'Mercedes',\n    mileage: 7,\n    price: 10,\n    safety: 8,\n    performance: 9,\n    interior: 7,\n    warranty: 7\n  },\n  {\n    name: 'Honda',\n    mileage: 8,\n    price: 6,\n    safety: 9,\n    performance: 6,\n    interior: 3,\n    warranty: 9\n  },\n  {\n    name: 'Chevrolet',\n    mileage: 5,\n    price: 4,\n    safety: 6,\n    performance: 4,\n    interior: 5,\n    warranty: 6\n  }\n];\n\nconst basicFormat = format('.2r');\nconst wideFormat = format('.3r');\n\nconst tipStyle = {\n  display: 'flex',\n  color: '#fff',\n  background: '#000',\n  alignItems: 'center',\n  padding: '5px'\n};\n\nexport default class BasicRadarChart extends Component {\n  state = {\n    hoveredCell: false\n  };\n\n  render() {\n    const {hoveredCell} = this.state;\n\n    return (\n      <RadarChart\n        data={DATA}\n        tickFormat={t => wideFormat(t)}\n        startingAngle={0}\n        domains={[\n          {name: 'mileage', domain: [0, 10]},\n          {\n            name: 'price',\n            domain: [2, 16],\n            tickFormat: t => `$${basicFormat(t)}`,\n            getValue: d => d.price\n          },\n          {name: 'safety', domain: [5, 10], getValue: d => d.safety},\n          {name: 'performance', domain: [0, 10], getValue: d => d.performance},\n          {name: 'interior', domain: [0, 7], getValue: d => d.interior},\n          {name: 'warranty', domain: [10, 2], getValue: d => d.warranty}\n        ]}\n        width={400}\n        height={300}\n        onSeriesMouseOver={data => {\n          this.setState({hoveredCell: data.event[0]});\n        }}\n        onSeriesMouseOut={() => this.setState({hoveredCell: false})}\n      >\n        {hoveredCell && (\n          <Hint value={{x: 0, y: 0}}>\n            <div style={tipStyle}>{hoveredCell.name}</div>\n          </Hint>\n        )}\n      </RadarChart>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/radar-chart/radar-chart-with-tooltips.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\nimport RadarChart from 'react-vis/radar-chart';\nimport {Hint} from 'react-vis';\n\n// The first 6 data elements here are to simulate a 'spider' type of radar chart -\n// similar to CircularGridLines, but straight edges instead.\nconst DATA = [\n  {\n    name: 'Spider5',\n    mileage: 5,\n    price: 5,\n    safety: 5,\n    performance: 5,\n    interior: 5,\n    warranty: 5,\n    fill: '#f8f8f8',\n    stroke: '#cccccc'\n  },\n  {\n    name: 'Spider4',\n    mileage: 4,\n    price: 4,\n    safety: 4,\n    performance: 4,\n    interior: 4,\n    warranty: 4,\n    fill: 'white',\n    stroke: '#cccccc'\n  },\n  {\n    name: 'Spider3',\n    mileage: 3,\n    price: 3,\n    safety: 3,\n    performance: 3,\n    interior: 3,\n    warranty: 3,\n    fill: '#f8f8f8',\n    stroke: '#cccccc'\n  },\n  {\n    name: 'Spider2',\n    mileage: 2,\n    price: 2,\n    safety: 2,\n    performance: 2,\n    interior: 2,\n    warranty: 2,\n    fill: 'white',\n    stroke: '#cccccc'\n  },\n  {\n    name: 'Spider1',\n    mileage: 1,\n    price: 1,\n    safety: 1,\n    performance: 1,\n    interior: 1,\n    warranty: 1,\n    fill: '#f8f8f8',\n    stroke: '#cccccc'\n  },\n  {\n    name: 'Spider0',\n    mileage: 0.1,\n    price: 0.1,\n    safety: 0.1,\n    performance: 0.1,\n    interior: 0.1,\n    warranty: 0.1,\n    fill: '#f8f8f8',\n    stroke: '#cccccc'\n  },\n  {\n    name: 'Mercedes',\n    mileage: 3,\n    price: 4,\n    safety: 5,\n    performance: 1.5,\n    interior: 4,\n    warranty: 4.5,\n    fill: 'rgba(114,172,240,0.5)',\n    stroke: 'rgba(114,172,240,0.2)'\n  }\n];\n\nconst tipStyle = {\n  display: 'flex',\n  color: '#fff',\n  background: '#000',\n  alignItems: 'center',\n  padding: '5px'\n};\n\nexport default class RadarChartWithTooltips extends Component {\n  state = {\n    hoveredCell: false\n  };\n\n  render() {\n    const {hoveredCell} = this.state;\n\n    return (\n      <RadarChart\n        data={DATA}\n        tickFormat={() => {\n          return '';\n        }}\n        domains={[\n          {\n            name: 'mileage',\n            domain: [0, 5],\n            tickFormat: t => {\n              if (t < 5 && t > 0) {\n                return Math.round(t);\n              }\n              return '';\n            }\n          },\n          {\n            name: 'price',\n            domain: [0, 5],\n            getValue: d => d.price\n          },\n          {name: 'safety', domain: [0, 5], getValue: d => d.safety},\n          {name: 'performance', domain: [0, 5], getValue: d => d.performance},\n          {name: 'interior', domain: [0, 5], getValue: d => d.interior},\n          {name: 'warranty', domain: [0, 5], getValue: d => d.warranty}\n        ]}\n        width={300}\n        height={300}\n        onValueMouseOver={v => {\n          this.setState({hoveredCell: v});\n        }}\n        onValueMouseOut={() => this.setState({hoveredCell: false})}\n        style={{\n          polygons: {\n            strokeWidth: 1,\n            strokeOpacity: 0.8,\n            fillOpacity: 0.8\n          },\n          labels: {\n            textAnchor: 'middle'\n          },\n          axes: {\n            line: {\n              fillOpacity: 0.8,\n              strokeWidth: 0.5,\n              strokeOpacity: 0.8\n            },\n            ticks: {\n              fillOpacity: 0,\n              strokeOpacity: 0\n            },\n            text: {}\n          }\n        }}\n        colorRange={['transparent']}\n        hideInnerMostValues={false}\n        renderAxesOverPolygons={true}\n      >\n        {hoveredCell && hoveredCell.dataName === 'Mercedes' && (\n          <Hint value={hoveredCell}>\n            <div style={tipStyle}>\n              {hoveredCell.domain}: {hoveredCell.value}\n            </div>\n          </Hint>\n        )}\n      </RadarChart>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/radial-chart/arc-series-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport ShowcaseButton from '../showcase-components/showcase-button';\nimport {XYPlot, ArcSeries, XAxis, YAxis} from 'react-vis';\n\nimport {EXTENDED_DISCRETE_COLOR_RANGE as COLORS} from 'react-vis/theme';\n\nconst PI = Math.PI;\n\nfunction updateData() {\n  const divider = Math.floor(Math.random() * 8 + 3);\n  const newData = [...new Array(5)].map((row, index) => {\n    return {\n      color: index,\n      radius0: Math.random() > 0.8 ? Math.random() + 1 : 0,\n      radius: Math.random() * 3 + 1,\n      angle: ((index + 1) * PI) / divider,\n      angle0: (index * PI) / divider\n    };\n  });\n  return newData.concat([\n    {angle0: 0, angle: PI * 2 * Math.random(), radius: 1.1, radius0: 0.8}\n  ]);\n}\n\nfunction updateLittleData() {\n  const portion = Math.random();\n  return [\n    {\n      angle0: 0,\n      angle: portion * PI * 2,\n      radius0: 0,\n      radius: 10,\n      color: COLORS[13]\n    },\n    {\n      angle0: portion * PI * 2,\n      angle: 2 * PI,\n      radius0: 0,\n      radius: 10,\n      color: COLORS[12]\n    }\n  ];\n}\n\nexport default class Example extends React.Component {\n  state = {\n    data: updateData(),\n    littleData: updateLittleData(),\n    value: false\n  };\n  render() {\n    return (\n      <div>\n        <ShowcaseButton\n          onClick={() =>\n            this.setState({\n              data: updateData(),\n              littleData: updateLittleData()\n            })\n          }\n          buttonContent={'UPDATE'}\n        />\n        <XYPlot xDomain={[-5, 5]} yDomain={[-5, 5]} width={300} height={300}>\n          <XAxis />\n          <YAxis />\n          <ArcSeries\n            animation\n            radiusDomain={[0, 4]}\n            data={this.state.data.map(row => {\n              if (this.state.value && this.state.value.color === row.color) {\n                return {...row, style: {stroke: 'black', strokeWidth: '5px'}};\n              }\n              return row;\n            })}\n            colorRange={COLORS}\n            onValueMouseOver={row => this.setState({value: row})}\n            onSeriesMouseOut={() => this.setState({value: false})}\n            colorType={'category'}\n          />\n          <ArcSeries\n            animation\n            radiusType={'literal'}\n            center={{x: -2, y: 2}}\n            data={this.state.littleData}\n            colorType={'literal'}\n          />\n        </XYPlot>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/radial-chart/custom-radius-radial-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport {CircularGridLines, RadialChart} from 'react-vis';\n\nconst DATA = [\n  {\n    angle: 1,\n    id: 1,\n    radius: 10\n  },\n  {\n    angle: 2,\n    label: 'Super Custom label',\n    subLabel: 'With annotation',\n    id: 2,\n    radius: 20\n  },\n  {\n    angle: 5,\n    id: 3,\n    radius: 5,\n    label: 'Alt Label'\n  },\n  {\n    angle: 3,\n    id: 4,\n    radius: 14\n  },\n  {\n    angle: 5,\n    id: 5,\n    radius: 12,\n    subLabel: 'Sub Label only'\n  }\n];\n\nfunction mapData(hoveredSection) {\n  return DATA.map((row, index) => {\n    return {\n      ...row,\n      innerRadius: hoveredSection === index + 1 ? row.radius - 1 : null,\n      opacity: !hoveredSection || hoveredSection === index + 1 ? 1 : 0.6\n    };\n  });\n}\n\nexport default class SimpleRadialChart extends Component {\n  state = {\n    hoveredSection: false\n  };\n\n  render() {\n    const {hoveredSection} = this.state;\n    return (\n      <RadialChart\n        animation\n        showLabels\n        radiusDomain={[0, 20]}\n        data={mapData(hoveredSection)}\n        labelsAboveChildren\n        onValueMouseOver={row => this.setState({hoveredSection: row.id})}\n        onMouseLeave={() => this.setState({hoveredSection: false})}\n        width={600}\n        height={300}\n      >\n        <CircularGridLines tickTotal={20} rRange={[0, 150]} />\n      </RadialChart>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/radial-chart/donut-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {Component} from 'react';\n\nimport {RadialChart, Hint} from 'react-vis';\n\nexport default class SimpleRadialChart extends Component {\n  state = {\n    value: false\n  };\n  render() {\n    const {value} = this.state;\n    return (\n      <RadialChart\n        className={'donut-chart-example'}\n        innerRadius={100}\n        radius={140}\n        getAngle={d => d.theta}\n        data={[\n          {theta: 2, className: 'custom-class'},\n          {theta: 6},\n          {theta: 2},\n          {theta: 3},\n          {theta: 1}\n        ]}\n        onValueMouseOver={v => this.setState({value: v})}\n        onSeriesMouseOut={() => this.setState({value: false})}\n        width={300}\n        height={300}\n        padAngle={0.04}\n      >\n        {value !== false && <Hint value={value} />}\n      </RadialChart>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/radial-chart/gradient-pie.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {GradientDefs, RadialChart} from 'react-vis';\n\nexport default function GradientPie() {\n  return (\n    <RadialChart\n      colorType={'literal'}\n      colorDomain={[0, 100]}\n      colorRange={[0, 10]}\n      margin={{top: 100}}\n      getColor={d => `url(#${d.gradientLabel})`}\n      data={[\n        {angle: 1, gradientLabel: 'grad1'},\n        {angle: 2, gradientLabel: 'grad2'},\n        {angle: 5, gradientLabel: 'grad3'}\n      ]}\n      labelsRadiusMultiplier={1.1}\n      labelsStyle={{fontSize: 16, fill: '#222'}}\n      showLabels\n      style={{stroke: '#fff', strokeWidth: 2}}\n      width={400}\n      height={300}\n    >\n      <GradientDefs>\n        <linearGradient id=\"grad1\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n          <stop offset=\"0%\" stopColor=\"red\" stopOpacity={0.4} />\n          <stop offset=\"100%\" stopColor=\"blue\" stopOpacity={0.3} />\n        </linearGradient>\n        <linearGradient id=\"grad2\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n          <stop offset=\"0%\" stopColor=\"blue\" stopOpacity={0.4} />\n          <stop offset=\"100%\" stopColor=\"green\" stopOpacity={0.3} />\n        </linearGradient>\n        <linearGradient id=\"grad3\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n          <stop offset=\"0%\" stopColor=\"yellow\" stopOpacity={0.4} />\n          <stop offset=\"100%\" stopColor=\"green\" stopOpacity={0.3} />\n        </linearGradient>\n      </GradientDefs>\n    </RadialChart>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/radial-chart/simple-radial-chart.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport RadialChart from 'react-vis/radial-chart';\n\nexport default function SimpleRadialChart() {\n  return (\n    <RadialChart\n      colorType={'literal'}\n      colorDomain={[0, 100]}\n      colorRange={[0, 10]}\n      margin={{top: 100}}\n      getLabel={d => d.name}\n      data={[\n        {angle: 1, color: '#89DAC1', name: 'green', opacity: 0.2},\n        {angle: 2, color: '#F6D18A', name: 'yellow'},\n        {angle: 5, color: '#1E96BE', name: 'cyan'},\n        {angle: 3, color: '#DA70BF', name: 'magenta'},\n        {angle: 5, color: '#F6D18A', name: 'yellow again'}\n      ]}\n      labelsRadiusMultiplier={1.1}\n      labelsStyle={{fontSize: 16, fill: '#222'}}\n      showLabels\n      style={{stroke: '#fff', strokeWidth: 2}}\n      width={400}\n      height={300}\n    />\n  );\n}\n"
  },
  {
    "path": "packages/showcase/sankey/basic.js",
    "content": "import React from 'react';\n\nimport Sankey from 'react-vis/sankey';\n\nconst nodes = [{name: 'a', rotation: 0}, {name: 'b'}, {name: 'c'}];\nconst links = [\n  {source: 0, target: 1, value: 10, opacity: 0.2},\n  {source: 0, target: 2, value: 20},\n  {source: 1, target: 2, value: 20}\n];\n\nexport default function BasicSankeyExample() {\n  return (\n    <Sankey\n      nodes={nodes}\n      links={links}\n      width={200}\n      height={200}\n      labelRotation={45}\n    />\n  );\n}\n"
  },
  {
    "path": "packages/showcase/sankey/energy-sankey.js",
    "content": "import React from 'react';\n\nimport Sankey from 'react-vis/sankey';\n\nimport Energy from '../datasets/energy.json';\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nconst MODE = ['justify', 'center', 'left', 'right'];\n\nexport default class EnergySankey extends React.Component {\n  state = {\n    modeIndex: 0\n  };\n\n  updateModeIndex = increment => () => {\n    const newIndex = this.state.modeIndex + (increment ? 1 : -1);\n    const modeIndex =\n      newIndex < 0 ? MODE.length - 1 : newIndex >= MODE.length ? 0 : newIndex;\n    this.setState({modeIndex});\n  };\n  render() {\n    const {modeIndex} = this.state;\n\n    return (\n      <div className=\"centered-and-flexed\">\n        <div className=\"centered-and-flexed-controls\">\n          <ShowcaseButton\n            onClick={this.updateModeIndex(false)}\n            buttonContent={'PREV MODE'}\n          />\n          <div> {MODE[modeIndex]} </div>\n          <ShowcaseButton\n            onClick={this.updateModeIndex(true)}\n            buttonContent={'NEXT MODE'}\n          />\n        </div>\n        <Sankey\n          animation\n          margin={50}\n          nodes={Energy.nodes}\n          links={Energy.links}\n          width={960}\n          align={MODE[modeIndex]}\n          height={500}\n          layout={24}\n          nodeWidth={15}\n          nodePadding={10}\n          style={{\n            links: {\n              opacity: 0.3\n            },\n            labels: {\n              fontSize: '8px'\n            },\n            rects: {\n              strokeWidth: 2,\n              stroke: '#1A3177'\n            }\n          }}\n        />\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/sankey/link-event.js",
    "content": "import React from 'react';\n\nimport Sankey from 'react-vis/sankey';\n\nconst BLURRED_LINK_OPACITY = 0.3;\nconst FOCUSED_LINK_OPACITY = 0.6;\n\nconst nodes = [{name: 'a'}, {name: 'b'}, {name: 'c'}];\nconst links = [\n  {source: 0, target: 1, value: 10},\n  {source: 0, target: 2, value: 20},\n  {source: 1, target: 2, value: 20}\n];\n\nexport default class LinkEventSankeyExample extends React.Component {\n  state = {\n    activeLink: null\n  };\n\n  render() {\n    const {activeLink} = this.state;\n\n    // Note: d3.sankey currently mutates the `nodes` and `links` arrays, which doesn't play nice\n    // with React's single-direction data flow. We create a copy of each before we pass to the sankey\n    // component, just to be sure.\n    return (\n      <div>\n        <div>\n          {`${\n            activeLink\n              ? `${nodes[activeLink.source.index].name} -> ${\n                  nodes[activeLink.target.index].name\n                }`\n              : 'None'\n          } selected`}\n        </div>\n        <Sankey\n          nodes={nodes.map(d => ({...d}))}\n          links={links.map((d, i) => ({\n            ...d,\n            opacity:\n              activeLink && i === activeLink.index\n                ? FOCUSED_LINK_OPACITY\n                : BLURRED_LINK_OPACITY\n          }))}\n          width={200}\n          height={200}\n          onLinkMouseOver={node => this.setState({activeLink: node})}\n          onLinkMouseOut={() => this.setState({activeLink: null})}\n        />\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/sankey/link-hint.js",
    "content": "import React from 'react';\n\nimport Sankey from 'react-vis/sankey';\nimport Hint from 'react-vis/plot/hint';\n\nconst BLURRED_LINK_OPACITY = 0.3;\nconst FOCUSED_LINK_OPACITY = 0.6;\n\nconst nodes = [{name: 'a'}, {name: 'b'}, {name: 'c'}];\nconst links = [\n  {source: 0, target: 1, value: 10},\n  {source: 0, target: 2, value: 20},\n  {source: 1, target: 2, value: 20}\n];\n\nexport default class LinkHintSankeyExample extends React.Component {\n  state = {\n    activeLink: null\n  };\n\n  _renderHint() {\n    const {activeLink} = this.state;\n\n    // calculate center x,y position of link for positioning of hint\n    const x =\n      activeLink.source.x1 + (activeLink.target.x0 - activeLink.source.x1) / 2;\n    const y = activeLink.y0 - (activeLink.y0 - activeLink.y1) / 2;\n\n    const hintValue = {\n      [`${activeLink.source.name} ➞ ${activeLink.target.name}`]: activeLink.value\n    };\n\n    return <Hint x={x} y={y} value={hintValue} />;\n  }\n\n  render() {\n    const {activeLink} = this.state;\n\n    // Note: d3.sankey currently mutates the `nodes` and `links` arrays, which doesn't play nice\n    // with React's single-direction data flow. We create a copy of each before we pass to the sankey\n    // component, just to be sure.\n    return (\n      <div>\n        <Sankey\n          nodes={nodes.map(d => ({...d}))}\n          links={links.map((d, i) => ({\n            ...d,\n            opacity:\n              activeLink && i === activeLink.index\n                ? FOCUSED_LINK_OPACITY\n                : BLURRED_LINK_OPACITY\n          }))}\n          width={200}\n          height={200}\n          // do not use voronoi in combination with link mouse over\n          hasVoronoi={false}\n          onLinkMouseOver={node => this.setState({activeLink: node})}\n          onLinkMouseOut={() => this.setState({activeLink: null})}\n        >\n          {activeLink && this._renderHint()}\n        </Sankey>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/sankey/voronoi.js",
    "content": "import React from 'react';\n\nimport Sankey from 'react-vis/sankey';\n\nconst BLURRED_NODE_OPACITY = 0.8;\nconst FOCUSED_NODE_OPACITY = 1;\n\nconst nodes = [{name: 'a'}, {name: 'b'}, {name: 'c'}];\nconst links = [\n  {source: 0, target: 1, value: 10},\n  {source: 0, target: 2, value: 20},\n  {source: 1, target: 2, value: 20}\n];\n\nexport default class VoronoiSankeyExample extends React.Component {\n  state = {\n    activeNode: null\n  };\n\n  render() {\n    const {activeNode} = this.state;\n\n    // Note: d3.sankey currently mutates the `nodes` and `links` arrays, which doesn't play nice\n    // with React's single-direction data flow. We create a copy of each before we pass to the sankey\n    // component, just to be sure.\n    return (\n      <div>\n        <div>{`${activeNode ? activeNode.name : 'None'} selected`}</div>\n        <Sankey\n          nodes={nodes.map(d => {\n            const isActiveNode = activeNode && d.name === activeNode.name;\n            return {\n              ...d,\n              opacity: isActiveNode\n                ? FOCUSED_NODE_OPACITY\n                : BLURRED_NODE_OPACITY,\n              name: isActiveNode ? `!${d.name}!` : d.name\n            };\n          })}\n          links={links.map(d => ({...d}))}\n          width={200}\n          height={200}\n          hasVoronoi\n          onValueMouseOver={node => this.setState({activeNode: node})}\n          onValueMouseOut={() => this.setState({activeNode: null})}\n        />\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/showcase-app.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport ShowcaseDropdown from './showcase-components/showcase-dropdown';\n\nimport {\n  AxesShowcase,\n  PlotsShowcase,\n  SunburstSection,\n  RadialShowcase,\n  RadarShowcase,\n  LegendsShowcase,\n  SankeysShowcase,\n  TreemapShowcase,\n  ParallelCoordinatesShowcase,\n  MiscShowcase,\n  Candlestick,\n  ForceDirectedGraph,\n  ResponsiveVis,\n  StreamgraphExample,\n  IrisDashboard\n} from './showcase-index';\n\nconst sectionNames = [\n  {root: true, link: '', name: 'RETURN TO ROOT'},\n  // basic examples\n  {label: true, name: 'BASIC EXAMPLES'},\n  {showByDefault: true, link: 'plots', name: 'Plots', showcase: PlotsShowcase},\n  {showByDefault: true, link: 'axes', name: 'Axes', showcase: AxesShowcase},\n  {\n    showByDefault: true,\n    link: 'radial-charts',\n    name: 'Radial Charts',\n    showcase: RadialShowcase\n  },\n  {\n    showByDefault: true,\n    link: 'radar-charts',\n    name: 'Radar Charts',\n    showcase: RadarShowcase\n  },\n  {\n    showByDefault: true,\n    link: 'treemaps',\n    name: 'Treemaps',\n    showcase: TreemapShowcase\n  },\n  {\n    showByDefault: true,\n    link: 'legends',\n    name: 'Legends',\n    showcase: LegendsShowcase\n  },\n  {\n    showByDefault: true,\n    link: 'sunbursts',\n    name: 'Sunbursts',\n    showcase: SunburstSection\n  },\n  {\n    showByDefault: true,\n    link: 'sankeys',\n    name: 'Sankeys',\n    showcase: SankeysShowcase\n  },\n  {\n    showByDefault: true,\n    link: 'parallel-coordinates',\n    name: 'Parallel Coordinates',\n    showcase: ParallelCoordinatesShowcase\n  },\n  {showByDefault: true, link: 'misc', name: 'Misc', showcase: MiscShowcase},\n\n  // in depth examples\n  {label: true, name: 'ADVANCED EXAMPLES'},\n  {\n    showByDefault: false,\n    link: 'candlestick',\n    name: 'Candlestick',\n    showcase: Candlestick\n  },\n  {\n    showByDefault: false,\n    link: 'force-directed',\n    name: 'ForceDirectedGraph',\n    showcase: ForceDirectedGraph\n  },\n  {\n    showByDefault: false,\n    link: 'streamgraph',\n    name: 'Streamgraph',\n    showcase: StreamgraphExample\n  },\n  {\n    showByDefault: false,\n    link: 'irisdashboard',\n    name: 'IrisDashboard',\n    showcase: IrisDashboard\n  },\n  {\n    showByDefault: false,\n    link: 'responsive',\n    name: 'ResponsiveVis',\n    showcase: ResponsiveVis\n  }\n];\n\nfunction App(props) {\n  const {forExample} = props;\n  const linkedSection = location.href.split('/#')[1];\n  const foundSection = sectionNames.find(\n    section => section.link === linkedSection\n  );\n\n  const filteredSections = sectionNames\n    .filter(section => {\n      // if at http://localhost:3001/, just return everything\n      if (!linkedSection) {\n        return section.showByDefault;\n      }\n      const showThisSection =\n        foundSection && section.link === foundSection.link;\n      const showDefaultSections =\n        (!foundSection || foundSection.root) && section.showByDefault;\n\n      return showThisSection || showDefaultSections;\n    })\n    .map(section => {\n      if (section.label || section.root) {\n        return <div key={`${section.name}-showcase`} />;\n      }\n      return <section.showcase key={`${section.name}-showcase`} />;\n    });\n  return (\n    <main>\n      {!forExample && (\n        <header>\n          <div className=\"header-contents\">\n            <a className=\"header-logo\" href=\"#\">\n              react-vis\n            </a>\n            <ShowcaseDropdown\n              items={sectionNames.map(section => {\n                const {label, link, name} = section;\n                const content = label ? (\n                  <div className=\"subsection-label\">{name}</div>\n                ) : (\n                  <a href={`#${link}`}>{name}</a>\n                );\n\n                return <li key={name}>{content}</li>;\n              })}\n            />\n          </div>\n        </header>\n      )}\n      {filteredSections}\n    </main>\n  );\n}\n\nApp.propTypes = {\n  forExample: PropTypes.bool\n};\n\nexport default App;\n"
  },
  {
    "path": "packages/showcase/showcase-components/showcase-button.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nfunction ShowcaseButton(props) {\n  const {buttonContent, onClick} = props;\n  return (\n    <button className=\"showcase-button\" onClick={onClick}>\n      {buttonContent}\n    </button>\n  );\n}\n\nShowcaseButton.propTypes = {\n  buttonContent: PropTypes.string.isRequired,\n  onClick: PropTypes.func.isRequired\n};\n\nexport default ShowcaseButton;\n"
  },
  {
    "path": "packages/showcase/showcase-components/showcase-dropdown.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nclass ShowcaseDropdown extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      open: false\n    };\n  }\n\n  toggleState = () => {\n    this.setState({open: !this.state.open});\n  };\n\n  render() {\n    const {items} = this.props;\n    const {open} = this.state;\n    return (\n      <div className=\"dropdown-wrapper\">\n        <div className=\"dropdown-button\" onClick={this.toggleState}>\n          {'SELECT SECTION'}\n        </div>\n        {open && (\n          <div className=\"background-overlay\" onClick={this.toggleState} />\n        )}\n        {open && <ul className=\"dropdown-inner-wrapper\">{items}</ul>}\n      </div>\n    );\n  }\n}\n\nShowcaseDropdown.propTypes = {\n  items: PropTypes.arrayOf(PropTypes.component)\n};\n\nexport default ShowcaseDropdown;\n"
  },
  {
    "path": "packages/showcase/showcase-components/showcase-utils.js",
    "content": "import React from 'react';\n\nimport {SHOWCASE_LINKS} from '../showcase-links';\n\nexport function mapSection(section) {\n  const {docsLink, comment, name, componentName} = section;\n  const SectionComponent = section.component;\n  const linkProps = {\n    className: 'docs-link',\n    target: '_blank',\n    rel: 'noopener noreferrer'\n  };\n  const exampleLink = SHOWCASE_LINKS[componentName];\n  return (\n    <section key={`${name}-index`}>\n      <div className=\"section-header\">\n        <h3 className=\"section-title\">{name}</h3>\n        <div className=\"flex\">\n          {exampleLink && (\n            <a {...linkProps} href={exampleLink}>\n              {' '}\n              View Code\n            </a>\n          )}\n          {docsLink && (\n            <a {...linkProps} href={docsLink}>\n              {' '}\n              Documentation{' '}\n            </a>\n          )}\n        </div>\n      </div>\n      {comment && <p className=\"docs-comment\">{comment}</p>}\n      <SectionComponent />\n    </section>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/showcase-components/source-linker.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nexport default function sourceLinker(ShowcaseComponent, link) {\n  return function renderExample() {\n    return (\n      <div\n        style={{\n          alignItem: 'center',\n          display: 'flex',\n          flexDirection: 'column',\n          height: '100%',\n          width: '100%'\n        }}\n      >\n        {ShowcaseComponent && <ShowcaseComponent />}\n        {link && (\n          <a\n            {...{\n              className: 'docs-link',\n              target: '_blank',\n              rel: 'noopener noreferrer'\n            }}\n            href={link}\n          >\n            {'> View Code'}\n          </a>\n        )}\n      </div>\n    );\n  };\n}\n"
  },
  {
    "path": "packages/showcase/showcase-index.js",
    "content": "export AxesShowcase from './showcase-sections/axes-showcase';\nexport PlotsShowcase from './showcase-sections/plots-showcase';\nexport SunburstSection from './showcase-sections/sunburst-showcase';\nexport RadialShowcase from './showcase-sections/radial-showcase';\nexport RadarShowcase from './showcase-sections/radar-showcase';\nexport LegendsShowcase from './showcase-sections/legends-showcase';\nexport SankeysShowcase from './showcase-sections/sankeys-showcase';\nexport TreemapShowcase from './showcase-sections/treemap-showcase';\nexport ParallelCoordinatesShowcase from './showcase-sections/parallel-coordinates-showcase';\nexport MiscShowcase from './showcase-sections/misc-showcase';\n\nexport Candlestick from './examples/candlestick/candlestick-example';\nexport ForceDirectedGraph from './examples/force-directed-graph/force-directed-example';\nexport ResponsiveVis from './examples/responsive-vis/responsive-vis-example';\nexport StreamgraphExample from './examples/streamgraph/streamgraph-example';\nexport IrisDashboard from './examples/iris-dashboard/iris-dashboard';\n"
  },
  {
    "path": "packages/showcase/showcase-links.js",
    "content": "export const REACTVIS_BASE_URL =\n  'https://github.com/uber/react-vis/blob/master/packages/react-vis';\n\nexport const SHOWCASE_BASE_URL =\n  'https://github.com/uber/react-vis/blob/master/packages/showcase';\n\nexport const SHOWCASE_LINKS = {\n  // AXES SHOW CASE LINKS\n  AxisOn0: `${SHOWCASE_BASE_URL}/axes/axis-on-0.js`,\n  CustomAxesOrientation: `${SHOWCASE_BASE_URL}/axes/custom-axes-orientation.js`,\n  CustomAxisChart: `${SHOWCASE_BASE_URL}/axes/custom-axis.js`,\n  CustomAxes: `${SHOWCASE_BASE_URL}/axes/custom-axes.js`,\n  AxisWithTurnedLabels: `${SHOWCASE_BASE_URL}/plot/axis-with-turned-labels.js`,\n  PaddedAxis: `${SHOWCASE_BASE_URL}/axes/padded-axis.js`,\n  // AXES - TOOLTIPS SHOW CASE LINKS\n  StaticHints: `${SHOWCASE_BASE_URL}/axes/static-hints.js`,\n  DynamicHints: `${SHOWCASE_BASE_URL}/axes/dynamic-hints.js`,\n  DynamicSimpleEdgeHints: `${SHOWCASE_BASE_URL}/axes/dynamic-simple-edge-hints.js`,\n  DynamicSimpleTopEdgeHints: `${SHOWCASE_BASE_URL}/axes/dynamic-simple-topedge-hints.js`,\n  DynamicProgrammaticRightEdgeHints: `${SHOWCASE_BASE_URL}/axes/dynamic-programmatic-rightedge-hints.js`,\n  DynamicComplexEdgeHints: `${SHOWCASE_BASE_URL}/axes/dynamic-complex-edge-hints.js`,\n  StaticCrosshair: `${SHOWCASE_BASE_URL}/axes/static-crosshair.js`,\n  DynamicCrosshair: `${SHOWCASE_BASE_URL}/axes/dynamic-crosshair.js`,\n  DynamicCrosshairScatterplot: `${SHOWCASE_BASE_URL}/axes/dynamic-crosshair-scatterplot.js`,\n  // AXES - DECORATIVE_AXES SHOWCASE LINKS\n  DecorativeAxisCrissCross: `${SHOWCASE_BASE_URL}/axes/decorative-axes-criss-cross.js`,\n  ParallelCoordinatesExample: `${SHOWCASE_BASE_URL}/axes/parallel-coordinates-example.js`,\n  // MISC SHOWCASE LINKS\n  SyncedCharts: `${SHOWCASE_BASE_URL}/misc/synced-charts.js`,\n  TimeChart: `${SHOWCASE_BASE_URL}/misc/time-chart.js`,\n  TriangleExample: `${SHOWCASE_BASE_URL}/misc/triangle-example.js`,\n  VoronoiLineChart: `${SHOWCASE_BASE_URL}/misc/voronoi-line-chart.js`,\n  GradientExample: `${SHOWCASE_BASE_URL}/misc/gradient-example.js`,\n  ClipExample: `${SHOWCASE_BASE_URL}/misc/clip-example.js`,\n  AnimationExample: `${SHOWCASE_BASE_URL}/misc/animation-example.js`,\n  LabelSeriesExample: `${SHOWCASE_BASE_URL}/misc/label-series-example.js`,\n  NullDataExample: `${SHOWCASE_BASE_URL}/misc/null-data-example.js`,\n  ZoomableChartExample: `${SHOWCASE_BASE_URL}/misc/zoomable-chart-example.js`,\n  SelectionPlotExample: `${SHOWCASE_BASE_URL}/misc/selection-plot-example.js`,\n  DragableChartExample: `${SHOWCASE_BASE_URL}/misc/dragable-chart-example.js`,\n  BidirectionDragChart: `${SHOWCASE_BASE_URL}/misc/2d-dragable-plot.js`,\n  // PARALLEL COORDS LINKS\n  BasicParallelCoordinates: `${SHOWCASE_BASE_URL}/parallel-coordinates/animated-parallel-coordinates.js`,\n  AnimatedParallelCoordinates: `${SHOWCASE_BASE_URL}/parallel-coordinates/basic-parallel-coordinates.js`,\n  // PLOTS SHOWCASE LINKES\n  LineChart: `${SHOWCASE_BASE_URL}/plot/line-chart.js`,\n  LineChartWithStyle: `${SHOWCASE_BASE_URL}/plot/line-chart-with-style.js`,\n  LineMarkChart: `${SHOWCASE_BASE_URL}/plot/linemark-chart.js`,\n  LineChartCanvas: `${SHOWCASE_BASE_URL}/plot/line-chart-canvas.js`,\n  LineChartManyColors: `${SHOWCASE_BASE_URL}/color/line-chart-many-colors.js`,\n  ScatterplotChart: `${SHOWCASE_BASE_URL}/plot/scatterplot.js`,\n  ScatterplotCanvas: `${SHOWCASE_BASE_URL}/plot/scatterplot-canvas.js`,\n  WhiskerChart: `${SHOWCASE_BASE_URL}/plot/whisker-chart.js`,\n  AreaChart: `${SHOWCASE_BASE_URL}/plot/area-chart.js`,\n  AreaChartElevated: `${SHOWCASE_BASE_URL}/plot/area-chart-elevated.js`,\n  BarChart: `${SHOWCASE_BASE_URL}/plot/bar-chart.js`,\n  BigBaseBarChart: `${SHOWCASE_BASE_URL}/plot/big-base-bar-chart.js`,\n  StackedHorizontalBarChart: `${SHOWCASE_BASE_URL}/plot/stacked-horizontal-bar-chart.js`,\n  StackedVerticalBarChart: `${SHOWCASE_BASE_URL}/plot/stacked-vertical-bar-chart.js`,\n  ClusteredStackedVerticalBarChart: `${SHOWCASE_BASE_URL}/plot/clustered-stacked-bar-chart.js`,\n  StackedHistogram: `${SHOWCASE_BASE_URL}/plot/stacked-histogram.js`,\n  Histogram: `${SHOWCASE_BASE_URL}/plot/histogram.js`,\n  HeatmapChart: `${SHOWCASE_BASE_URL}/plot/heatmap-chart.js`,\n  HexHeatmap: `${SHOWCASE_BASE_URL}/plot/hex-heatmap.js`,\n  HexbinSizeExample: `${SHOWCASE_BASE_URL}/plot/hexbin-size-example.js`,\n  LabeledHeatmap: `${SHOWCASE_BASE_URL}/plot/labeled-heatmap.js`,\n  ContourSeriesExample: `${SHOWCASE_BASE_URL}/plot/contour-series-example.js`,\n  CustomSVGExample: `${SHOWCASE_BASE_URL}/plot/custom-svg-example.js`,\n  CustomSVGAllTheMarks: `${SHOWCASE_BASE_URL}/plot/custom-svg-all-the-marks.js`,\n  CustomSVGRootLevel: `${SHOWCASE_BASE_URL}/plot/custom-svg-root-level.js`,\n  // BASIC COMPONENTS SHOWCASE LINKS\n  WidthHeightMarginChart: `${SHOWCASE_BASE_URL}/plot/width-height-margin.js`,\n  CustomScales: `${SHOWCASE_BASE_URL}/plot/custom-scales.js`,\n  GridLinesChart: `${SHOWCASE_BASE_URL}/plot/grid.js`,\n  FauxScatterplotChart: `${SHOWCASE_BASE_URL}/plot/faux-radial-scatterplot.js`,\n  EmptyChart: `${SHOWCASE_BASE_URL}/axes/empty-chart.js`,\n  // RADAR CHART SHOWCASE LINKS\n  AnimatedRadarChart: `${SHOWCASE_BASE_URL}/radar-chart/animated-radar-chart.js`,\n  BasicRadarChart: `${SHOWCASE_BASE_URL}/radar-chart/basic-radar-chart.js`,\n  FourQuadrantRadarChart: `${SHOWCASE_BASE_URL}/radar-chart/four-quadrant-radar-chart.js`,\n  RadarChartWithTooltips: `${SHOWCASE_BASE_URL}/radar-chart/radar-chart-with-tooltips.js`,\n  RadarChartSeriesTooltips: `${SHOWCASE_BASE_URL}/radar-chart/radar-chart-series-tooltips.js`,\n\n  // RADIAL CHART SHOWCASE LINKS\n  SimpleRadialChart: `${SHOWCASE_BASE_URL}/radial-chart/simple-radial-chart.js`,\n  GradientPie: `${SHOWCASE_BASE_URL}/radial-chart/gradient-pie.js`,\n  DonutChartExample: `${SHOWCASE_BASE_URL}/radial-chart/donut-chart.js`,\n  CustomRadiusRadialChart: `${SHOWCASE_BASE_URL}/radial-chart/custom-radius-radial-chart.js`,\n  // SANKEY SHOWCASE LINKS\n  BasicSankeyExample: `${SHOWCASE_BASE_URL}/sankey/basic.js`,\n  VoronoiSankeyExample: `${SHOWCASE_BASE_URL}/sankey/voronoi.js`,\n  LinkEventSankeyExample: `${SHOWCASE_BASE_URL}/sankey/link-event.js`,\n  LinkHintSankeyExample: `${SHOWCASE_BASE_URL}/sankey/link-hint.js`,\n  EnergySankeyExample: `${SHOWCASE_BASE_URL}/sankey/energy-sankey.js`,\n  // SUNBURST SHOWCASE LINKS\n  ArcSeriesExample: `${SHOWCASE_BASE_URL}/radial-chart/arc-series-example.js`,\n  BasicSunburst: `${SHOWCASE_BASE_URL}/sunbursts/basic-sunburst.js`,\n  ClockExample: `${SHOWCASE_BASE_URL}/sunbursts/clock-example.js`,\n  AnimatedSunburst: `${SHOWCASE_BASE_URL}/sunbursts/animated-sunburst.js`,\n  SunburstWithTooltips: `${SHOWCASE_BASE_URL}/sunbursts/sunburst-with-tooltips.js`,\n  // TREEMAP SHOWCASE LINKS\n  SimpleTreemap: `${SHOWCASE_BASE_URL}/treemap/simple-treemap.js`,\n  TreemapExample: `${SHOWCASE_BASE_URL}/treemap/dynamic-treemap.js`,\n  // LEGENDS SHOWCASE LINKS\n  VerticalDiscreteColorLegendExample: `${SHOWCASE_BASE_URL}/legends/vertical-discrete-color.js`,\n  HorizontalDiscreteColorLegendExample: `${SHOWCASE_BASE_URL}/legends/horizontal-discrete-color.js`,\n  HorizontalDiscreteCustomPalette: `${SHOWCASE_BASE_URL}/legends/horizontal-discrete-custom-palette.js`,\n  SearchableDiscreteColorLegendExample: `${SHOWCASE_BASE_URL}/legends/searchable-discrete-color.js`,\n  // eslint-disable-next-line max-len\n  SearchableDiscreteColorLegendHoverExample: `${SHOWCASE_BASE_URL}/legends/searchable-discrete-color-hover.js`,\n  ContinuousColorLegendExample: `${SHOWCASE_BASE_URL}/legends/continuous-color.js`,\n  ContinuousSizeLegendExample: `${SHOWCASE_BASE_URL}/legends/continuous-size.js'`\n};\n"
  },
  {
    "path": "packages/showcase/showcase-sections/axes-showcase.js",
    "content": "import React from 'react';\n\nimport {mapSection} from '../showcase-components/showcase-utils';\nimport {showCase} from '../index';\nconst {\n  AxisOn0,\n  AxisWithTurnedLabels,\n  CustomAxes,\n  CustomAxisChart,\n  CustomAxesOrientation,\n  CustomAxisTickFormat,\n  CustomAxisTickElement,\n  DecorativeAxisCrissCross,\n  DynamicComplexEdgeHints,\n  DynamicCrosshair,\n  DynamicCrosshairScatterplot,\n  DynamicHints,\n  DynamicProgrammaticRightEdgeHints,\n  DynamicSimpleEdgeHints,\n  DynamicSimpleTopEdgeHints,\n  PaddedAxis,\n  ParallelCoordinatesExample,\n  StaticCrosshair,\n  StaticHints\n} = showCase;\n\n/* eslint-disable max-len */\nconst AXES = [\n  {\n    name: 'Axis on 0',\n    component: AxisOn0,\n    componentName: 'AxisOn0'\n  },\n  {\n    name: 'Custom Axes Orientation',\n    component: CustomAxesOrientation,\n    componentName: 'CustomAxesOrientation'\n  },\n  {\n    name: 'Custom Axis',\n    component: CustomAxisChart,\n    componentName: 'CustomAxisChart'\n  },\n  {\n    name: 'Custom axis tick format',\n    component: CustomAxisTickFormat\n  },\n  {\n    name: 'Custom axis tick label element',\n    component: CustomAxisTickElement\n  },\n  {\n    name: 'Even more Custom Axes',\n    component: CustomAxes,\n    componentName: 'CustomAxes'\n  },\n  {\n    name: 'Turned axis labels',\n    component: AxisWithTurnedLabels,\n    componentName: 'AxisWithTurnedLabels'\n  },\n  {\n    name: 'Unpadded Axis vs Padded Axis',\n    component: PaddedAxis,\n    componentName: 'PaddedAxis'\n  }\n];\n\nconst TOOLTIPS = [\n  {\n    name: 'Static Hints',\n    component: StaticHints,\n    componentName: 'StaticHints'\n  },\n  {\n    name: 'Dynamic Hints',\n    comment: 'Move mouse over the point to see the hint.',\n    component: DynamicHints,\n    componentName: 'DynamicHints'\n  },\n  {\n    name: 'Dynamic Simple Edge Hints',\n    comment:\n      'Mouse over point. Hint appears on different edges. Left margin enables first point to show w/o break.',\n    component: DynamicSimpleEdgeHints,\n    componentName: 'DynamicSimpleEdgeHints'\n  },\n  {\n    name: 'Dynamic Simple Top Edge Hints',\n    comment:\n      'Mouse over point. horizontalAlign=ALIGN.AUTO, verticalAlign=ALIGN.TOP_EDGE  Hint pinned to top edge, pole moves along edge, hint box on right of pole for first 2 data points and left otherwise.',\n    component: DynamicSimpleTopEdgeHints,\n    componentName: 'DynamicSimpleTopEdgeHints'\n  },\n  {\n    name: 'Dynamic Programmatic Right Edge Hints',\n    comment:\n      'Mouse over point. getAlignStyle method returns style object with right and top CSS props set (pinned right edge and at y position)',\n    component: DynamicProgrammaticRightEdgeHints,\n    componentName: 'DynamicProgrammaticRightEdgeHints'\n  },\n  {\n    name: 'Dynamic Complex Edge Hints',\n    comment:\n      'Mouse over point. Hint uses flex, css to show hint and pole from point to outside plot edge (css for margin values).',\n    component: DynamicComplexEdgeHints,\n    componentName: 'DynamicComplexEdgeHints'\n  },\n  {\n    name: 'Static Crosshair',\n    component: StaticCrosshair,\n    componentName: 'StaticCrosshair'\n  },\n  {\n    name: 'Dynamic Crosshair',\n    comment: 'Move your mouse over the chart to see the point.',\n    component: DynamicCrosshair,\n    componentName: 'DynamicCrosshair'\n  },\n  {\n    name: 'Dynamic Crosshair Scatterplot',\n    comment: 'Move your mouse over the chart to see the point.',\n    component: DynamicCrosshairScatterplot,\n    componentName: 'DynamicCrosshairScatterplot'\n  }\n];\n/* eslint-enable max-len */\nconst DECORATIVE_AXES = [\n  {\n    name: 'Diagonal Axes',\n    component: DecorativeAxisCrissCross,\n    componentName: 'DecorativeAxisCrissCross'\n  },\n  {\n    name: 'Parallel Coordinates',\n    component: ParallelCoordinatesExample,\n    componentName: 'ParallelCoordinatesExample'\n  }\n];\n\nfunction AxesShowcase() {\n  return (\n    <article id=\"axes\">\n      <h2>Axes</h2>\n      {AXES.map(mapSection)}\n      <h2>Tooltips</h2>\n      {TOOLTIPS.map(mapSection)}\n      <h2>DecorativeAxis</h2>\n      {DECORATIVE_AXES.map(mapSection)}\n    </article>\n  );\n}\n\nexport default AxesShowcase;\n"
  },
  {
    "path": "packages/showcase/showcase-sections/legends-showcase.js",
    "content": "import React from 'react';\nimport {mapSection} from '../showcase-components/showcase-utils';\nimport {showCase} from '../index';\nconst {\n  ContinuousColorLegendExample,\n  ContinuousSizeLegendExample,\n  HorizontalDiscreteColorLegendExample,\n  HorizontalDiscreteCustomPalette,\n  SearchableDiscreteColorLegendExample,\n  SearchableDiscreteColorLegendHoverExample,\n  VerticalDiscreteColorLegendExample\n} = showCase;\n/* eslint-disable max-len */\nconst DISCRETE_LEGENDS = [\n  {\n    name: 'Vertical legend',\n    component: VerticalDiscreteColorLegendExample,\n    componentName: 'VerticalDiscreteColorLegendExample'\n  },\n  {\n    name: 'Horizontal legend with stroke styles',\n    component: HorizontalDiscreteColorLegendExample,\n    componentName: 'HorizontalDiscreteColorLegendExample'\n  },\n  {\n    name: 'Custom palette with hover interaction',\n    component: HorizontalDiscreteCustomPalette,\n    componentName: 'HorizontalDiscreteCustomPalette'\n  },\n  {\n    name: 'Discrete color legend with search',\n    component: SearchableDiscreteColorLegendExample,\n    componentName: 'SearchableDiscreteColorLegendExample'\n  },\n  {\n    name: 'Discrete color legend with search and hover',\n    component: SearchableDiscreteColorLegendHoverExample,\n    componentName: 'SearchableDiscreteColorLegendHoverExample'\n  }\n];\n/* eslint-enable max-len */\n\nconst CONTINOUS_COLOR_LEGEND = [\n  {\n    name: 'Default legend',\n    component: ContinuousColorLegendExample,\n    componentName: 'ContinuousColorLegendExample'\n  }\n];\n\nconst CONTINOUS_SIZE_LEGEND = [\n  {\n    name: 'Default legend',\n    component: ContinuousSizeLegendExample,\n    componentName: 'ContinuousSizeLegendExample'\n  }\n];\n\nfunction LegendsExample() {\n  return (\n    <article id=\"legends\">\n      <h1>Legends</h1>\n      <h2>Discrete color legend</h2>\n      {DISCRETE_LEGENDS.map(mapSection)}\n      <h2>Continuous color legend</h2>\n      {CONTINOUS_COLOR_LEGEND.map(mapSection)}\n      <h2>Continuous size legend</h2>\n      {CONTINOUS_SIZE_LEGEND.map(mapSection)}\n    </article>\n  );\n}\n\nexport default LegendsExample;\n"
  },
  {
    "path": "packages/showcase/showcase-sections/misc-showcase.js",
    "content": "import React from 'react';\nimport {mapSection} from '../showcase-components/showcase-utils';\nimport {showCase} from '../index';\nimport {SHOWCASE_BASE_URL, REACTVIS_BASE_URL} from '../showcase-links';\nconst {\n  AnimationExample,\n  LabelSeriesExample,\n  GradientExample,\n  NullDataExample,\n  SyncedCharts,\n  TimeChart,\n  TriangleExample,\n  VoronoiLineChart,\n  ZoomableChartExample,\n  SelectionPlotExample,\n  DragableChartExample,\n  BidirectionDragChart,\n  ClipExample,\n  FlexibleCharts\n} = showCase;\n\nconst MISC = [\n  {\n    name: 'Synced Charts',\n    component: SyncedCharts,\n    componentName: 'SyncedCharts'\n  },\n  {\n    name: 'Time Chart',\n    component: TimeChart,\n    componentName: 'TimeChart'\n  },\n  {\n    name: 'Polygon Example',\n    component: TriangleExample,\n    componentName: 'TriangleExample',\n    sourceLink: `${REACTVIS_BASE_URL}/src/plot/series/polygon-series.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/polygon-series'\n  },\n  {\n    name: 'Voronoi Line Chart',\n    component: VoronoiLineChart,\n    componentName: 'VoronoiLineChart'\n  },\n  {\n    name: 'Gradient & Custom Border Example',\n    component: GradientExample,\n    componentName: 'GradientExample',\n    sourceLink: `${SHOWCASE_BASE_URL}/misc/gradient-example.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/api-reference/gradients'\n  },\n  {\n    name: 'Content Area Clipping',\n    component: ClipExample,\n    componentName: 'ClipExample',\n    sourceLink: `${SHOWCASE_BASE_URL}/misc/clip-example.js`,\n    docsLink: 'http://uber.github.io/react-vis/documentation/api-reference/clip'\n  },\n  {\n    name: 'Animation Example',\n    component: AnimationExample,\n    componentName: 'AnimationExample',\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/label-series'\n  },\n  {\n    name: 'Label Series Example',\n    component: LabelSeriesExample,\n    componentName: 'LabelSeriesExample',\n    sourceLink: `${SHOWCASE_BASE_URL}/src/plot/series/label-series.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/label-series'\n  },\n  {\n    name: 'Null Data Example',\n    component: NullDataExample,\n    componentName: 'NullDataExample'\n  },\n  {\n    name: 'Zoomable Chart example',\n    component: ZoomableChartExample,\n    componentName: 'ZoomableChartExample'\n  },\n  {\n    name: 'Selection plot example',\n    component: SelectionPlotExample,\n    componentName: 'SelectionPlotExample'\n  },\n  {\n    name: 'Dragable Chart Example',\n    component: DragableChartExample,\n    componentName: 'DragableChartExample'\n  },\n  {\n    name: '2d Dragable Chart',\n    component: BidirectionDragChart,\n    componentName: 'BidirectionDragChart'\n  },\n  {\n    name: 'Flexible Chart',\n    component: FlexibleCharts,\n    componentName: 'FlexibleCharts'\n  }\n];\n\nfunction MiscShowcase() {\n  return (\n    <article id=\"misc\">\n      <h2>Miscellaneous</h2>\n      {MISC.map(mapSection)}\n    </article>\n  );\n}\n\nexport default MiscShowcase;\n"
  },
  {
    "path": "packages/showcase/showcase-sections/parallel-coordinates-showcase.js",
    "content": "import React from 'react';\n\nimport {mapSection} from '../showcase-components/showcase-utils';\nimport {showCase} from '../index';\nimport {REACTVIS_BASE_URL} from '../showcase-links';\nconst {\n  AnimatedParallelCoordinates,\n  BasicParallelCoordinates,\n  BrushedParallelCoordinates\n} = showCase;\n\n/* eslint-disable max-len */\nconst PARALLEL_COORDINATES = [\n  {\n    name: 'Basic Parallel Coordinates',\n    component: BasicParallelCoordinates,\n    componentName: 'BasicParallelCoordinates',\n    sourceLink: `${REACTVIS_BASE_URL}/radar-chart/index.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/other-charts/radar-chart'\n  },\n  {\n    name: 'Animated Parallel Coordinates',\n    component: AnimatedParallelCoordinates,\n    componentName: 'AnimatedParallelCoordinates'\n  },\n  {\n    name: 'Brushed Parallel Coordinates',\n    component: BrushedParallelCoordinates,\n    componentName: 'BrushedParallelCoordinates'\n  }\n];\n\nfunction ParallelCoordinatesShowcase() {\n  return (\n    <article id=\"parallel-coordinates\">\n      <h1>Parallel Coordinates</h1>\n      {PARALLEL_COORDINATES.map(mapSection)}\n    </article>\n  );\n}\n\nexport default ParallelCoordinatesShowcase;\n"
  },
  {
    "path": "packages/showcase/showcase-sections/plots-showcase.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport {showCase} from '../index';\nimport {REACTVIS_BASE_URL} from '../showcase-links';\nimport {mapSection} from '../showcase-components/showcase-utils';\nconst {\n  AreaChart,\n  AreaChartElevated,\n  BarChart,\n  BigBaseBarChart,\n  ClusteredStackedVerticalBarChart,\n  ContourSeriesExample,\n  ComplexChart,\n  CustomScales,\n  CustomSVGExample,\n  CustomSVGAllTheMarks,\n  CustomSVGRootLevel,\n  DifferenceChart,\n  EmptyChart,\n  FauxScatterplotChart,\n  GridLinesChart,\n  HeatmapChart,\n  HexHeatmap,\n  HexbinSizeExample,\n  Histogram,\n  LabeledHeatmap,\n  LineChart,\n  LineChartManyColors,\n  LineChartWithStyle,\n  LineChartCanvas,\n  LineSeriesCanvasNearestXYExample,\n  LineMarkChart,\n  MixedStackedChart,\n  StackedVerticalBarChart,\n  LabeledStackedVerticalBarChart,\n  StackedHorizontalBarChart,\n  StackedHistogram,\n  ScatterplotChart,\n  ScatterplotCanvas,\n  WhiskerChart,\n  WidthHeightMarginChart\n} = showCase;\n\nconst PLOTS = [\n  {\n    component: LineChart,\n    componentName: 'LineChart',\n    name: 'Line Series',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/line-series.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/line-series'\n  },\n  {\n    component: LineChartWithStyle,\n    componentName: 'LineChartWithStyle',\n    name: 'Line Series with style',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/line-series.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/line-series'\n  },\n  {\n    component: LineMarkChart,\n    componentName: 'LineMarkChart',\n    name: 'LineMark Series',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/line-mark-series.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/line-mark-series'\n  },\n  {\n    component: LineChartCanvas,\n    componentName: 'LineChartCanvas',\n    name: 'Line Chart Canvas'\n  },\n  {\n    component: LineSeriesCanvasNearestXYExample,\n    componentName: 'LineSeriesCanvasNearestXYExample',\n    name: 'Line Series Canvas'\n  },\n  {\n    component: LineChartManyColors,\n    componentName: 'LineChartManyColors',\n    name: 'Line Series With Many Colors'\n  },\n  {\n    component: ScatterplotChart,\n    componentName: 'ScatterplotChart',\n    name: 'Mark Series',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/mark-series.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/mark-series'\n  },\n  {\n    component: ScatterplotCanvas,\n    componentName: 'ScatterplotCanvas',\n    name: 'Mark Series Canvas'\n  },\n  {\n    component: WhiskerChart,\n    componentName: 'WhiskerChart',\n    name: 'Whisker Series',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/whisker-series.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/whisker-series'\n  },\n  {\n    component: AreaChart,\n    componentName: 'AreaChart',\n    name: 'Area Series',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/area-serie.js`\n  },\n  {\n    component: AreaChartElevated,\n    componentName: 'AreaChartElevated',\n    name: 'Area Series With vertical offset',\n    sourceLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/area-series'\n  },\n  {\n    component: BarChart,\n    componentName: 'BarChart',\n    name: 'Bar Series',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/bar-series.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/bar-series'\n  },\n  {\n    component: BigBaseBarChart,\n    componentName: 'BigBaseBarChart',\n    name: 'Big Base Bar Series'\n  },\n  {\n    component: DifferenceChart,\n    componentName: 'DifferenceChart',\n    name: 'Difference Bar Series'\n  },\n  {\n    name: 'Stacked Horizontal Bar Series',\n    component: StackedHorizontalBarChart,\n    componentName: 'StackedHorizontalBarChart'\n  },\n  {\n    name: 'Stacked Vertical Bar Series',\n    component: StackedVerticalBarChart,\n    componentName: 'StackedVerticalBarChart'\n  },\n  {\n    name: 'Labeled Stacked Vertical Bar Series',\n    component: LabeledStackedVerticalBarChart,\n    componentName: 'LabeledStackedVerticalBarChart'\n  },\n  {\n    name: 'Mixed Stacked Series',\n    component: MixedStackedChart\n  },\n  {\n    name: 'Clustered Stacked Vertical Bar Series',\n    component: ClusteredStackedVerticalBarChart,\n    componentName: 'ClusteredStackedVerticalBarChart'\n  },\n  {\n    name: 'Stacked Vertical Rect Series (histogram)',\n    component: StackedHistogram,\n    componentName: 'StackedHistogram'\n  },\n  {\n    name: 'Horizontal Rect Series',\n    component: Histogram,\n    componentName: 'Histogram'\n  },\n  {\n    name: 'Heatmap Series',\n    component: HeatmapChart,\n    componentName: 'HeatmapChart',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/heatmap-series.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/heatmap-series'\n  },\n  {\n    name: 'Hexbin Series',\n    component: HexHeatmap,\n    componentName: 'HexHeatmap',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/hexbin-series.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/hexbin-series'\n  },\n  {\n    name: 'Hexbin Size',\n    component: HexbinSizeExample,\n    componentName: 'HexbinSizeExample'\n  },\n  {\n    name: 'Labeled Heatmap',\n    component: LabeledHeatmap,\n    componentName: 'LabeledHeatmap',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/heatmap-serie.js`\n  },\n  {\n    name: 'Contour Series',\n    component: ContourSeriesExample,\n    componentName: 'ContourSeriesExample'\n  },\n  {\n    name: 'Custom SVG Series',\n    component: CustomSVGExample,\n    componentName: 'CustomSVGExample'\n  },\n  {\n    name: 'Custom SVG - All The Marks (with tooltips)',\n    component: CustomSVGAllTheMarks,\n    componentName: 'CustomSVGAllTheMarks'\n  },\n  {\n    name: 'Custom SVG - Root Level Function Definition',\n    component: CustomSVGRootLevel,\n    componentName: 'CustomSVGRootLevel'\n  }\n];\n\nconst BASIC_COMPONENTS = [\n  {\n    name: 'Custom Size and Margin',\n    component: WidthHeightMarginChart,\n    componentName: 'WidthHeightMarginChart'\n  },\n  {\n    name: 'Custom scales',\n    component: CustomScales,\n    componentName: 'CustomScales'\n  },\n  {\n    name: 'Empty Chart',\n    component: EmptyChart,\n    componentName: 'EmptyChart'\n  },\n  {\n    name: 'Custom GridLines',\n    component: GridLinesChart,\n    componentName: 'GridLinesChart'\n  },\n  {\n    name: 'Circular Gridlines',\n    component: FauxScatterplotChart,\n    componentName: 'FauxScatterplotChart',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/circular-grid-lines.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/api-reference/grids'\n  }\n];\n\nfunction PlotsShowcase(props) {\n  const {forExample} = props;\n  return (\n    <article id=\"plots\">\n      <h1>Plots</h1>\n      {!forExample && (\n        <section>\n          <ComplexChart />\n        </section>\n      )}\n      <h2>Series Types</h2>\n\n      {PLOTS.map(mapSection)}\n      <h2>Basic Components</h2>\n      {BASIC_COMPONENTS.map(mapSection)}\n    </article>\n  );\n}\n\nPlotsShowcase.propTypes = {\n  forExample: PropTypes.bool\n};\n\nexport default PlotsShowcase;\n"
  },
  {
    "path": "packages/showcase/showcase-sections/radar-showcase.js",
    "content": "import React from 'react';\n\nimport {mapSection} from '../showcase-components/showcase-utils';\nimport {REACTVIS_BASE_URL} from '../showcase-links';\nimport {showCase} from '../index';\nconst {\n  AnimatedRadarChart,\n  BasicRadarChart,\n  FourQuadrantRadarChart,\n  RadarChartWithTooltips,\n  RadarChartSeriesTooltips\n} = showCase;\n\nconst RADAR = [\n  {\n    name: 'Basic Radar Chart',\n    component: BasicRadarChart,\n    componentName: 'BasicRadarChart',\n    sourceLink: `${REACTVIS_BASE_URL}/radar-chart/index.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/other-charts/radar-chart'\n  },\n  {\n    name: 'Animated Radar Chart',\n    component: AnimatedRadarChart,\n    componentName: 'AnimatedRadarChart'\n  },\n  {\n    name: 'Four Quadrant Radar Chart',\n    component: FourQuadrantRadarChart,\n    componentName: 'FourQuadrantRadarChart'\n  },\n  {\n    name: 'Radar Chart with Tooltips',\n    component: RadarChartWithTooltips,\n    componentName: 'RadarChartWithTooltips'\n  },\n  {\n    name: 'Radar Chart with Series Tooltips',\n    component: RadarChartSeriesTooltips,\n    componentName: 'RadarChartSeriesTooltips'\n  }\n];\n\nfunction RadarShowcase() {\n  return (\n    <article id=\"radar-charts\">\n      <h1>Radar Chart</h1>\n      {RADAR.map(mapSection)}\n    </article>\n  );\n}\n\nexport default RadarShowcase;\n"
  },
  {
    "path": "packages/showcase/showcase-sections/radial-showcase.js",
    "content": "import React from 'react';\n\nimport {mapSection} from '../showcase-components/showcase-utils';\nimport {REACTVIS_BASE_URL} from '../showcase-links';\nimport {showCase} from '../index';\nconst {\n  CustomRadiusRadialChart,\n  DonutChartExample,\n  SimpleRadialChart,\n  GradientPie\n} = showCase;\n/* eslint-disable max-len */\nconst RADIAL = [\n  {\n    name: 'Simple Radial Chart',\n    component: SimpleRadialChart,\n    componentName: SimpleRadialChart,\n    sourceLink: `${REACTVIS_BASE_URL}/radial-chart/index.js`,\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/other-charts/radial-chart'\n  },\n  {\n    name: 'Simple Donut Chart',\n    component: DonutChartExample,\n    componentName: DonutChartExample\n  },\n  {\n    name: 'Custom Radius',\n    component: CustomRadiusRadialChart,\n    componentName: CustomRadiusRadialChart\n  },\n  {\n    name: 'Gradient Pie',\n    component: GradientPie,\n    componentName: GradientPie\n  }\n];\n\nfunction RadialShowcase() {\n  return (\n    <article id=\"radial-charts\">\n      <h1>Radial Chart</h1>\n      {RADIAL.map(mapSection)}\n    </article>\n  );\n}\n\nexport default RadialShowcase;\n"
  },
  {
    "path": "packages/showcase/showcase-sections/sankeys-showcase.js",
    "content": "import React from 'react';\n\nimport {mapSection} from '../showcase-components/showcase-utils';\nimport {REACTVIS_BASE_URL} from '../showcase-links';\nimport {showCase} from '../index';\nconst {\n  BasicSankeyExample,\n  VoronoiSankeyExample,\n  EnergySankeyExample,\n  LinkEventSankeyExample,\n  LinkHintSankeyExample\n} = showCase;\n\nconst SANKEYS = [\n  {\n    name: 'Basic',\n    component: BasicSankeyExample,\n    componentName: 'BasicSankeyExample',\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/other-charts/sankey-diagram',\n    sourceLink: `${REACTVIS_BASE_URL}/sankey/index.js`\n  },\n  {\n    name: 'With Voronoi Selection',\n    component: VoronoiSankeyExample,\n    componentName: 'VoronoiSankeyExample'\n  },\n  {\n    name: 'With link selection',\n    component: LinkEventSankeyExample,\n    componentName: 'LinkEventSankeyExample'\n  },\n  {\n    name: 'With hint (for links)',\n    component: LinkHintSankeyExample,\n    componentName: 'LinkHintSankeyExample'\n  },\n  {\n    name: 'Energy Example',\n    component: EnergySankeyExample,\n    componentName: 'EnergySankeyExample'\n  }\n];\n\nfunction SankeysSection() {\n  return (\n    <article id=\"sankeys\">\n      <h1>Sankeys</h1>\n      {SANKEYS.map(mapSection)}\n    </article>\n  );\n}\n\nexport default SankeysSection;\n"
  },
  {
    "path": "packages/showcase/showcase-sections/sunburst-showcase.js",
    "content": "import React from 'react';\n\nimport {showCase} from '../index';\nimport {REACTVIS_BASE_URL} from '../showcase-links';\nimport {mapSection} from '../showcase-components/showcase-utils';\nconst {\n  AnimatedSunburst,\n  ArcSeriesExample,\n  BasicSunburst,\n  ClockExample,\n  SunburstWithTooltips\n} = showCase;\n\nconst SUNBURSTS = [\n  {\n    name: 'Arc Series Example',\n    component: ArcSeriesExample,\n    componentName: 'ArcSeriesExample',\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/series-reference/arc-series',\n    sourceLink: `${REACTVIS_BASE_URL}/plot/series/arc-series.js`\n  },\n  {\n    name: 'Basic Sunburst',\n    component: BasicSunburst,\n    componentName: 'BasicSunburst',\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/other-charts/sunburst-diagram',\n    sourceLink: `${REACTVIS_BASE_URL}/sunburst/index.js`\n  },\n  {\n    name: 'Clock',\n    component: ClockExample,\n    componentName: 'ClockExample'\n  },\n  {\n    name: 'Animated Sunburst',\n    component: AnimatedSunburst,\n    componentName: 'AnimatedSunburst'\n  },\n  {\n    name: 'Sunburst with tooltips',\n    component: SunburstWithTooltips,\n    componentName: 'SunburstWithTooltips'\n  }\n];\n\nfunction SunburstSection() {\n  return (\n    <article id=\"sunbursts\">\n      <h1>Sunbursts</h1>\n      {SUNBURSTS.map(mapSection)}\n    </article>\n  );\n}\n\nexport default SunburstSection;\n"
  },
  {
    "path": "packages/showcase/showcase-sections/treemap-showcase.js",
    "content": "import React from 'react';\n\nimport {showCase} from '../index';\nimport {REACTVIS_BASE_URL} from '../showcase-links';\nimport {mapSection} from '../showcase-components/showcase-utils';\n\nconst {SimpleTreemap, TreemapExample} = showCase;\n\nconst TREEMAPS = [\n  {\n    name: 'Simple Treemap',\n    component: SimpleTreemap,\n    componentName: 'SimpleTreemap',\n    docsLink:\n      'http://uber.github.io/react-vis/documentation/other-charts/treemap',\n    sourceLink: `${REACTVIS_BASE_URL}/treemap/index.js`\n  },\n  {\n    name: 'Animated Treemap',\n    component: TreemapExample,\n    componentName: 'TreemapExample'\n  }\n];\n\nfunction TreemapShowcase() {\n  return (\n    <article id=\"treemaps\">\n      <h1>Treemap</h1>\n      {TREEMAPS.map(mapSection)}\n    </article>\n  );\n}\n\nexport default TreemapShowcase;\n"
  },
  {
    "path": "packages/showcase/showcase-utils.js",
    "content": "// sourced from\n// http://indiegamr.com/generate-repeatable-random-numbers-in-js/\nexport function generateSeededRandom(baseSeed = 2) {\n  let seed = baseSeed;\n  return function seededRandom(max, min) {\n    max = max || 1;\n    min = min || 0;\n\n    seed = (seed * 9301 + 49297) % 233280;\n    const rnd = seed / 233280;\n\n    return min + rnd * (max - min);\n  };\n}\n"
  },
  {
    "path": "packages/showcase/sunbursts/animated-sunburst.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {Sunburst} from 'react-vis';\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nfunction randomLeaf() {\n  return {\n    size: Math.random() * 1000,\n    color: Math.random()\n  };\n}\n\nfunction updateData() {\n  const totalLeaves = Math.random() * 20;\n  const leaves = [];\n  for (let i = 0; i < totalLeaves; i++) {\n    const leaf = randomLeaf();\n    if (Math.random() > 0.8) {\n      leaf.children = [...new Array(3)].map(() => randomLeaf());\n    }\n    leaves.push(leaf);\n  }\n  return {\n    title: '',\n    color: 1,\n    children: leaves\n  };\n}\n\nconst DIVERGING_COLOR_SCALE = ['#00939C', '#85C4C8', '#EC9370', '#C22E00'];\n\nexport default class AnimatedSunburst extends React.Component {\n  state = {\n    data: updateData(),\n    hovering: false\n  };\n\n  render() {\n    const {data, hovering} = this.state;\n    return (\n      <div className=\"animated-sunburst-example-wrapper\">\n        <ShowcaseButton\n          onClick={() => this.setState({data: updateData()})}\n          buttonContent={'UPDATE'}\n        />\n        <div>{hovering ? 'CURRENTLY HOVERING' : 'NOT HOVERED'}</div>\n        <Sunburst\n          animation={{damping: 20, stiffness: 300}}\n          data={data}\n          colorType={'category'}\n          colorRange={DIVERGING_COLOR_SCALE}\n          style={{stroke: '#fff'}}\n          onValueMouseOver={() => this.setState({hovering: true})}\n          onValueMouseOut={() => this.setState({hovering: false})}\n          height={300}\n          width={350}\n        />\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/sunbursts/basic-sunburst.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport Sunburst from 'react-vis/sunburst';\nimport {EXTENDED_DISCRETE_COLOR_RANGE} from 'react-vis/theme';\nimport {LabelSeries} from 'react-vis';\n\nimport D3FlareData from '../datasets/d3-flare-example.json';\n\nconst LABEL_STYLE = {\n  fontSize: '8px',\n  textAnchor: 'middle'\n};\n\n/**\n * Recursively work backwards from highlighted node to find path of valud nodes\n * @param {Object} node - the current node being considered\n * @returns {Array} an array of strings describing the key route to the current node\n */\nfunction getKeyPath(node) {\n  if (!node.parent) {\n    return ['root'];\n  }\n\n  return [(node.data && node.data.name) || node.name].concat(\n    getKeyPath(node.parent)\n  );\n}\n\n/**\n * Recursively modify data depending on whether or not each cell has been selected by the hover/highlight\n * @param {Object} data - the current node being considered\n * @param {Object|Boolean} keyPath - a map of keys that are in the highlight path\n * if this is false then all nodes are marked as selected\n * @returns {Object} Updated tree structure\n */\nfunction updateData(data, keyPath) {\n  if (data.children) {\n    data.children.map(child => updateData(child, keyPath));\n  }\n  // add a fill to all the uncolored cells\n  if (!data.hex) {\n    data.style = {\n      fill: EXTENDED_DISCRETE_COLOR_RANGE[5]\n    };\n  }\n  data.style = {\n    ...data.style,\n    fillOpacity: keyPath && !keyPath[data.name] ? 0.2 : 1\n  };\n\n  return data;\n}\n\nconst decoratedData = updateData(D3FlareData, false);\n\nexport default class BasicSunburst extends React.Component {\n  state = {\n    pathValue: false,\n    data: decoratedData,\n    finalValue: 'SUNBURST',\n    clicked: false\n  };\n\n  render() {\n    const {clicked, data, finalValue, pathValue} = this.state;\n    return (\n      <div className=\"basic-sunburst-example-wrapper\">\n        <div>\n          {clicked ? 'click to unlock selection' : 'click to lock selection'}\n        </div>\n        <Sunburst\n          animation\n          className=\"basic-sunburst-example\"\n          hideRootNode\n          onValueMouseOver={node => {\n            if (clicked) {\n              return;\n            }\n            const path = getKeyPath(node).reverse();\n            const pathAsMap = path.reduce((res, row) => {\n              res[row] = true;\n              return res;\n            }, {});\n            this.setState({\n              finalValue: path[path.length - 1],\n              pathValue: path.join(' > '),\n              data: updateData(decoratedData, pathAsMap)\n            });\n          }}\n          onValueMouseOut={() =>\n            clicked\n              ? () => {}\n              : this.setState({\n                  pathValue: false,\n                  finalValue: false,\n                  data: updateData(decoratedData, false)\n                })\n          }\n          onValueClick={() => this.setState({clicked: !clicked})}\n          style={{\n            stroke: '#ddd',\n            strokeOpacity: 0.3,\n            strokeWidth: '0.5'\n          }}\n          colorType=\"literal\"\n          getSize={d => d.value}\n          getColor={d => d.hex}\n          data={data}\n          height={300}\n          width={350}\n        >\n          {finalValue && (\n            <LabelSeries\n              data={[{x: 0, y: 0, label: finalValue, style: LABEL_STYLE}]}\n            />\n          )}\n        </Sunburst>\n        <div className=\"basic-sunburst-example-path-name\">{pathValue}</div>\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/sunbursts/clock-example.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React, {useState, useEffect} from 'react';\n\nimport {XYPlot, ArcSeries} from 'react-vis';\n\nimport {EXTENDED_DISCRETE_COLOR_RANGE} from 'react-vis/theme';\n\nconst PI = Math.PI;\n\nfunction getSeconds() {\n  return Math.floor(new Date().getTime() / 1000);\n}\n\nexport default function ClockExample() {\n  const [time, setTime] = useState(getSeconds());\n  useEffect(() => {\n    const handle = setInterval(() => setTime(getSeconds()), 100);\n    return () => clearInterval(handle);\n  }, []);\n  const seconds = time % 60;\n  const minutes = (time / 60) % 60;\n  const hours = (time / (60 * 24)) % 24;\n  return (\n    <XYPlot\n      xDomain={[-3, 3]}\n      yDomain={[-3, 3]}\n      width={300}\n      getAngle={d => d.time}\n      getAngle0={() => 0}\n      height={300}\n    >\n      <ArcSeries\n        animation={{\n          damping: 9,\n          stiffness: 300\n        }}\n        radiusDomain={[0, 3]}\n        data={[\n          {time: (seconds / 60) * 2 * PI, radius0: 1, radius: 1.5, color: 0},\n          {\n            time: (minutes / 60) * 2 * PI,\n            radius0: 1.6,\n            radius: 2.1,\n            color: 1\n          },\n          {time: (hours / 24) * 2 * PI, radius0: 2.2, radius: 2.7, color: 2}\n        ]}\n        colorRange={EXTENDED_DISCRETE_COLOR_RANGE}\n      />\n    </XYPlot>\n  );\n}\n"
  },
  {
    "path": "packages/showcase/sunbursts/sunburst-with-tooltips.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport {Hint, Sunburst} from 'react-vis';\n\nimport {EXTENDED_DISCRETE_COLOR_RANGE as COLORS} from 'react-vis/theme';\n\nconst DATA = {\n  children: [\n    {\n      children: [\n        {bigness: 1, children: [], clr: COLORS[1], name: 'excellent'},\n        {bigness: 1, children: [], clr: COLORS[2], name: 'chart'}\n      ],\n      clr: COLORS[3]\n    },\n    {\n      bigness: 1,\n      children: [],\n      clr: COLORS[4],\n      name: 'cool',\n      labelStyle: {\n        fontSize: 15,\n        fontWeight: 'bold'\n      }\n    },\n    {bigness: 1, children: [], clr: COLORS[5], name: 'dogs'},\n    {bigness: 1, children: [], clr: COLORS[6], name: 'sunglasses'},\n    {\n      children: [\n        {bigness: 1, children: [], clr: COLORS[7], name: 'great'},\n        {bigness: 1, children: [], clr: COLORS[8], name: 'label'}\n      ],\n      clr: COLORS[9]\n    }\n  ]\n};\n\nconst tipStyle = {\n  display: 'flex',\n  color: '#fff',\n  background: '#000',\n  alignItems: 'center',\n  padding: '5px'\n};\nconst boxStyle = {height: '10px', width: '10px'};\n\nfunction buildValue(hoveredCell) {\n  const {radius, angle, angle0} = hoveredCell;\n  const truedAngle = (angle + angle0) / 2;\n  return {\n    x: radius * Math.cos(truedAngle),\n    y: radius * Math.sin(truedAngle)\n  };\n}\n\nexport default class SunburstWithTooltips extends React.Component {\n  state = {\n    hoveredCell: false\n  };\n  render() {\n    const {hoveredCell} = this.state;\n    return (\n      <Sunburst\n        data={DATA}\n        style={{stroke: '#fff'}}\n        onValueMouseOver={v =>\n          this.setState({hoveredCell: v.x && v.y ? v : false})\n        }\n        onValueMouseOut={() => this.setState({hoveredCell: false})}\n        height={300}\n        margin={{top: 50, bottom: 50, left: 50, right: 50}}\n        getLabel={d => d.name}\n        getSize={d => d.bigness}\n        getColor={d => d.clr}\n        width={350}\n        padAngle={() => 0.02}\n      >\n        {hoveredCell ? (\n          <Hint value={buildValue(hoveredCell)}>\n            <div style={tipStyle}>\n              <div style={{...boxStyle, background: hoveredCell.clr}} />\n              {hoveredCell.clr}\n            </div>\n          </Hint>\n        ) : null}\n      </Sunburst>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/treemap/dynamic-treemap.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport Treemap from 'react-vis/treemap';\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nfunction _getRandomData(total) {\n  const totalLeaves = total || Math.random() * 20;\n  const leaves = [];\n  for (let i = 0; i < totalLeaves; i++) {\n    leaves.push({\n      name: total ? total : String(Math.random()).slice(0, 3),\n      size: Math.random() * 1000,\n      color: Math.random(),\n      style: {\n        border: 'thin solid red'\n      }\n    });\n  }\n  return {\n    title: '',\n    color: 1,\n    children: leaves\n  };\n}\n\nexport default class DynamicTreemapExample extends React.Component {\n  state = {\n    hoveredNode: false,\n    treemapData: _getRandomData(20),\n    useCirclePacking: false\n  };\n\n  render() {\n    const {hoveredNode, useCirclePacking} = this.state;\n    const treeProps = {\n      animation: {\n        damping: 9,\n        stiffness: 300\n      },\n      data: this.state.treemapData,\n      onLeafMouseOver: x => this.setState({hoveredNode: x}),\n      onLeafMouseOut: () => this.setState({hoveredNode: false}),\n      onLeafClick: () => this.setState({treemapData: _getRandomData()}),\n      height: 300,\n      mode: this.state.useCirclePacking ? 'circlePack' : 'squarify',\n      getLabel: x => x.name,\n      width: 350\n    };\n    return (\n      <div className=\"dynamic-treemap-example\">\n        <ShowcaseButton\n          onClick={() => this.setState({useCirclePacking: !useCirclePacking})}\n          buttonContent={'TOGGLE CIRCLE PACK'}\n        />\n        <Treemap {...treeProps} />\n        click above to the update data\n        {hoveredNode && hoveredNode.value}\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/treemap/simple-treemap.js",
    "content": "// Copyright (c) 2016 - 2017 Uber Technologies, Inc.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport React from 'react';\n\nimport Treemap from 'react-vis/treemap';\n\nimport D3FlareData from '../datasets/d3-flare-example.json';\nimport ShowcaseButton from '../showcase-components/showcase-button';\n\nconst MODE = [\n  'circlePack',\n  'partition',\n  'partition-pivot',\n  'squarify',\n  'resquarify',\n  'slice',\n  'dice',\n  'slicedice',\n  'binary'\n];\n\nconst STYLES = {\n  SVG: {\n    stroke: '#ddd',\n    strokeWidth: '0.25',\n    strokeOpacity: 0.5\n  },\n  DOM: {\n    border: 'thin solid #ddd'\n  }\n};\n\nexport default class SimpleTreemapExample extends React.Component {\n  state = {\n    modeIndex: 0,\n    useSVG: true\n  };\n\n  updateModeIndex = increment => () => {\n    const newIndex = this.state.modeIndex + (increment ? 1 : -1);\n    const modeIndex =\n      newIndex < 0 ? MODE.length - 1 : newIndex >= MODE.length ? 0 : newIndex;\n    this.setState({modeIndex});\n  };\n\n  render() {\n    const {modeIndex, useSVG} = this.state;\n\n    return (\n      <div className=\"centered-and-flexed\">\n        <div className=\"centered-and-flexed-controls\">\n          <ShowcaseButton\n            onClick={() => this.setState({useSVG: !useSVG})}\n            buttonContent={useSVG ? 'USE DOM' : 'USE SVG'}\n          />\n        </div>\n        <div className=\"centered-and-flexed-controls\">\n          <ShowcaseButton\n            onClick={this.updateModeIndex(false)}\n            buttonContent={'PREV MODE'}\n          />\n          <div> {MODE[modeIndex]} </div>\n          <ShowcaseButton\n            onClick={this.updateModeIndex(true)}\n            buttonContent={'NEXT MODE'}\n          />\n        </div>\n        <Treemap\n          {...{\n            animation: true,\n            className: 'nested-tree-example',\n            colorType: 'literal',\n            colorRange: ['#88572C'],\n            data: D3FlareData,\n            mode: MODE[modeIndex],\n            renderMode: useSVG ? 'SVG' : 'DOM',\n            height: 300,\n            width: 350,\n            margin: 10,\n            getSize: d => d.value,\n            getColor: d => d.hex,\n            style: STYLES[useSVG ? 'SVG' : 'DOM']\n          }}\n        />\n      </div>\n    );\n  }\n}\n"
  },
  {
    "path": "packages/showcase/webpack.config.js",
    "content": "/* eslint-env node */\nconst process = require('process');\nconst path = require('path');\n\nconst MiniCssExtractPlugin = require('mini-css-extract-plugin');\n\nconst entry = {app: './app'};\nconst jsRule = {\n  test: /\\.js$/,\n  loader: 'babel-loader',\n  exclude: [/node_modules/],\n  options: {\n    rootMode: 'upward'\n  }\n};\nconst isProd = process.env.NODE_ENV === 'production';\nconst config = isProd\n  ? {\n      entry,\n      mode: 'production',\n      output: {\n        path: process.cwd(),\n        filename: 'bundle.js'\n      },\n\n      resolve: {\n        modules: [\n          'node_modules',\n          path.join(__dirname, '..', 'react-vis', 'src')\n        ]\n      },\n\n      module: {\n        rules: [\n          jsRule,\n          {\n            test: /\\.scss$/,\n            use: [\n              {\n                loader: MiniCssExtractPlugin.loader\n              },\n              'css-loader',\n              'sass-loader'\n            ]\n          }\n        ]\n      },\n      optimization: {\n        minimize: true\n      },\n      plugins: [new MiniCssExtractPlugin('bundle.css')]\n    }\n  : {\n      mode: 'development',\n      entry,\n      devtool: 'source-maps',\n      output: {\n        path: path.resolve(__dirname, './dist'),\n        filename: 'bundle.js'\n      },\n      plugins: [new MiniCssExtractPlugin()],\n\n      module: {\n        rules: [\n          jsRule,\n          {\n            test: /\\.(sa|sc|c)ss$/,\n            use: [\n              {\n                loader: MiniCssExtractPlugin.loader,\n                options: {\n                  hmr: true\n                }\n              },\n              'css-loader',\n              'sass-loader'\n            ]\n          }\n        ]\n      },\n\n      resolve: {\n        modules: [\n          'node_modules',\n          path.join(__dirname, '..', 'react-vis', 'src')\n        ]\n      }\n    };\n\nmodule.exports = config;\n"
  },
  {
    "path": "packages/website/.storybook/addons.js",
    "content": "import '@storybook/addon-knobs/register';\nimport 'storybook-addon-jsx/register';\n"
  },
  {
    "path": "packages/website/.storybook/config.js",
    "content": "import {configure, addParameters, setAddon} from '@storybook/react';\nimport JSXAddon, {jsxDecorator} from 'storybook-addon-jsx';\nimport {SimpleChartWrapper, jsxOptions} from '../storybook/storybook-utils';\n\nsetAddon(JSXAddon);\naddParameters({jsx: jsxOptions});\n\nfunction loadStories() {\n  require('../storybook/index.js');\n  // You can require as many stories as you need.\n}\n\nconfigure(loadStories, module);\n"
  },
  {
    "path": "packages/website/.storybook/storybook.css",
    "content": "html, body, #root {\n  height: 100%;\n}\n"
  },
  {
    "path": "packages/website/html.config.js",
    "content": "/* eslint-env node */\nmodule.exports = {\n  title: 'react-vis',\n\n  baseHref: process.env.NODE_ENV === 'production' ? 'website/dist/' : '/',\n\n  meta: [\n    {\n      name: 'description',\n      content: 'A composable charting library'\n    }\n  ],\n\n  scripts: ['https://uber.github.io/react-vis/redirect.js']\n};\n"
  },
  {
    "path": "packages/website/package.json",
    "content": "{\n  \"name\": \"@uber/react-vis-website\",\n  \"private\": true,\n  \"version\": \"1.0.0\",\n  \"description\": \"A composable charting library\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"ocular start\",\n    \"clean\": \"rm -rf dist/*{.js,.css,index.html,appcache,fonts,images}\",\n    \"build\": \"npm run clean && ocular build && npm run build-storybook\",\n    \"build-storybook\": \"build-storybook -c .storybook -o ./dist/storybook\",\n    \"lint\": \"ocular lint\",\n    \"storybook\": \"start-storybook -p 9001 -c .storybook\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"@storybook/addon-knobs\": \"^5.3.18\",\n    \"@storybook/react\": \"^5.3.18\",\n    \"storybook-addon-jsx\": \"^7.2.3\"\n  },\n  \"dependencies\": {\n    \"react\": \"^16.8.3\",\n    \"react-dom\": \"^16.8.3\",\n    \"d3-force\": \"^1.0.6\",\n    \"d3-random\": \"^1.1.0\",\n    \"ocular\": \"0.6.2\",\n    \"react-virtualized\": \"^9.18.5\",\n    \"react-vis\": \"^1.11.2\"\n  },\n  \"volta\": {\n    \"node\": \"10.20.1\",\n    \"yarn\": \"1.22.4\"\n  }\n}\n"
  },
  {
    "path": "packages/website/src/components/Hero.js",
    "content": "import React, {Component} from 'react';\n\nimport {PROJECT_NAME, PROJECT_DESC} from 'config';\n\nimport {\n  XYPlot,\n  AreaSeries,\n  LineSeries,\n  VerticalBarSeries,\n  MarkSeries,\n  Treemap,\n  RadialChart\n} from 'react-vis';\n\nconst palette = ['#12939A', '#17B8BE', '#1E96BE', '#FF991F', 'transparent'];\n\nconst MiniChart = props => {\n  const XYProps = {\n    colorType: 'literal',\n    height: 120,\n    margin: {left: 12, right: 12, top: 12, bottom: 12},\n    onMouseLeave: () => {\n      props.highlight(null);\n      props.scrub(null);\n    },\n    xDomain: [0, props.data[0].length - 1],\n    yDomain: [0, 20],\n    width: 120\n  };\n  switch (props.type) {\n    case 0: {\n      // bar charts\n      const barData = props.data.map((barseries, s) =>\n        barseries.map((d, i) => ({\n          ...d,\n          color: i === props.x ? palette[3] : palette[s]\n        }))\n      );\n      return (\n        <XYPlot {...XYProps} stackBy=\"y\" yDomain={[0, props.data.length * 10]}>\n          {barData.map((d, i) => (\n            <VerticalBarSeries\n              data={d}\n              key={i}\n              opacity={props.s !== null && props.s !== i ? 0.5 : 1}\n              onValueMouseOver={value => {\n                props.scrub(value.x);\n                props.highlight(value.s);\n              }}\n            />\n          ))}\n        </XYPlot>\n      );\n    }\n    case 1: {\n      // pie charts\n      const pieData = props.data\n        .reduce((prev, curr) => [...prev, ...curr], [])\n        .reduce(\n          (result, d, i) => {\n            result[i % 3].angle += d.y;\n            return result;\n          },\n          [\n            {angle: 0, s: 0, color: props.s === 0 ? palette[3] : palette[0]},\n            {angle: 0, s: 1, color: props.s === 1 ? palette[3] : palette[1]},\n            {angle: 0, s: 2, color: props.s === 2 ? palette[3] : palette[2]}\n          ]\n        );\n      return (\n        <RadialChart\n          data={pieData}\n          {...XYProps}\n          xDomain={[0, 20]}\n          center={{x: 10, y: 10}}\n          radius={45}\n          onValueMouseOver={value => props.highlight(value.s)}\n          onSeriesMouseOut={() => props.highlight(null)}\n        />\n      );\n    }\n    case 2:\n      // area charts\n      return (\n        <XYPlot {...XYProps} stackBy=\"y\" yDomain={[0, props.data.length * 20]}>\n          {props.data.map((d, i) => (\n            <AreaSeries\n              data={d}\n              key={i}\n              color={i === props.s ? palette[3] : palette[i]}\n              onSeriesMouseOver={() => props.highlight(i)}\n            />\n          ))}\n        </XYPlot>\n      );\n    case 3: {\n      // scatterplots\n      const scatterData = props.data.map((scatterseries, s) =>\n        scatterseries.map(d => ({\n          x: d.xS,\n          s,\n          y: d.yS,\n          size: d.size,\n          color: s === props.s ? palette[3] : palette[s]\n        }))\n      );\n      return (\n        <XYPlot {...XYProps} xDomain={[0, 20]}>\n          {scatterData.map((d, i) => (\n            <MarkSeries\n              data={d}\n              key={i}\n              onSeriesMouseOver={() => props.highlight(i)}\n              opacity={props.s === null || props.s === i ? 0.8 : 0.5}\n            />\n          ))}\n        </XYPlot>\n      );\n    }\n    case 4: {\n      // treemaps\n      const treeMapData = props.data.reduce(\n        (prev, treeseries, s) => {\n          prev.children.push(\n            treeseries.reduce(\n              (leaf, d) => {\n                leaf.children.push({\n                  size: d.yS,\n                  index: d.x,\n                  series: s,\n                  style: {background: props.x === d.x ? palette[3] : palette[s]}\n                });\n                return leaf;\n              },\n              {\n                title: '',\n                style: {background: 'white'},\n                children: []\n              }\n            )\n          );\n          return prev;\n        },\n        {\n          title: '',\n          children: []\n        }\n      );\n\n      return (\n        <Treemap\n          {...XYProps}\n          data={treeMapData}\n          animation={{\n            damping: 9,\n            stiffness: 300\n          }}\n          margin={{top: 6, bottom: 6, left: 6, right: 6}}\n          onLeafMouseOver={node => {\n            props.highlight(node.data.series);\n            props.scrub(node.data.index);\n          }}\n          style={{margin: '6px -6px -6px 6px'}}\n        />\n      );\n    }\n    default:\n      // Line charts\n      return (\n        <XYPlot {...XYProps}>\n          {props.data.map((d, i) => (\n            <LineSeries\n              data={d}\n              key={i}\n              stroke={i === props.s ? palette[3] : palette[i]}\n              strokeWidth={3}\n              onNearestXY={value => {\n                props.scrub(value.x);\n              }}\n            />\n          ))}\n          {props.data.map((d, i) => (\n            <LineSeries\n              data={d}\n              key={i}\n              stroke=\"transparent\"\n              strokeWidth={5}\n              onSeriesMouseOver={() => props.highlight(i)}\n            />\n          ))}\n          {props.x !== null && props.x < props.data[0].length ? (\n            <LineSeries\n              data={[\n                {x: props.x, y: 0},\n                {x: props.x, y: 20}\n              ]}\n              stroke=\"#125C77\"\n              strokeStyle=\"dashed\"\n              opacity={0.5}\n            />\n          ) : null}\n          {props.x !== null && props.x < props.data[0].length ? (\n            <MarkSeries\n              fillType=\"literal\"\n              data={props.data.map((markseries, s) => ({\n                x: props.x,\n                y: markseries[props.x].y,\n                fill: s === props.s ? palette[3] : palette[s]\n              }))}\n              size={5}\n              stroke=\"white\"\n            />\n          ) : null}\n        </XYPlot>\n      );\n  }\n};\n\nfunction makeData(nbSeries, nbPoints) {\n  return [...Array(nbSeries).keys()].map((d, s) => series(nbPoints, s));\n}\n\nfunction series(nbPoints, s) {\n  let previousPoint = random({scope: 3, rolls: 4});\n  return [...Array(nbPoints).keys()].map(d => {\n    const y =\n      previousPoint > 17.5\n        ? previousPoint - random({scope: 1, rolls: 3})\n        : previousPoint < 2.5\n        ? previousPoint + random({scope: 1, rolls: 3})\n        : previousPoint + random({scope: 1, rolls: 5}) - 2.5;\n    previousPoint = y;\n    return {\n      x: d,\n      s,\n      size: random({scope: 3, rolls: 3}),\n      xS: random({scope: 20, rolls: 1}),\n      yS: random({scope: 20, rolls: 1}),\n      y\n    };\n  });\n}\n\nfunction random({scope = 5, rolls = 1, integer = false}) {\n  let result = 0;\n  let i = 0;\n  for (i; i < rolls; i++) {\n    result += Math.random() * scope;\n  }\n  return integer ? Math.floor(result) : result;\n}\n\nclass Hero extends Component {\n  constructor() {\n    super();\n    this.state = {\n      x: null\n    };\n    this._resize = this._resize.bind(this);\n  }\n\n  componentDidMount() {\n    const chartsProps = this.generateData(100);\n    window.addEventListener('resize', this._resize);\n    this._resize();\n    this.setState({chartsProps});\n  }\n\n  componentWillUnmount() {\n    window.removeEventListener('resize', this._resize);\n  }\n\n  _resize = () => {\n    this.setState({\n      height: window.innerHeight,\n      width: window.innerWidth\n    });\n  };\n\n  changeType = i => {\n    const updatedChartsProps = [...this.state.chartsProps];\n    updatedChartsProps[i].type = (updatedChartsProps[i].type + 1) % 6;\n    updatedChartsProps[i].changes = updatedChartsProps[i].changes + 1;\n    this.setState({chartsProps: updatedChartsProps});\n  };\n\n  generateData = nb => {\n    return [...Array(nb).keys()].map(() => {\n      const nbPoints = 5 + random({scope: 5, rolls: 2, integer: true});\n      const nbSeries =\n        1 + Number(Math.random() > 0.2) + Number(Math.random() > 0.5);\n      const data = makeData(nbSeries, nbPoints);\n      const type = random({scope: 6, integer: true});\n      return {\n        changes: 0,\n        type,\n        data\n      };\n    });\n  };\n\n  highlight = s => this.setState({s});\n  scrub = x => this.setState({x});\n  render() {\n    const nbChartsInWidth = Math.floor((this.state.width - 24) / 132);\n    const nbChartsInHeight = Math.floor(\n      (0.65 * (this.state.height - 24)) / 132\n    );\n    const chartsToRender = nbChartsInWidth * nbChartsInHeight;\n\n    const chartsWidth = nbChartsInWidth * 132;\n    const chartsHeight = nbChartsInHeight * 132;\n    return (\n      <div\n        className=\"Hero\"\n        style={{\n          background: '#eeeeef',\n          height: '65vh',\n          padding: '14px 12px'\n        }}\n      >\n        <div\n          className=\"charts\"\n          style={{\n            height: chartsHeight,\n            width: chartsWidth,\n            margin: 'auto',\n            position: 'relative'\n          }}\n        >\n          {this.state.chartsProps\n            ? this.state.chartsProps.slice(0, chartsToRender).map((d, i) => (\n                <div\n                  key={i}\n                  className=\"mini-chart\"\n                  onClick={() => this.changeType(i)}\n                  style={{\n                    cursor: 'pointer',\n                    display: 'inline-block',\n                    background: 'white',\n                    margin: 6,\n                    boxShadow: '1px 1px 2px rgba(0,0,0,0.1)',\n                    transition: 'transform 0.5s',\n                    transform: `perspective(1000px) rotateY(${d.changes}turn)`\n                  }}\n                >\n                  <MiniChart\n                    highlight={this.highlight}\n                    scrub={this.scrub}\n                    s={this.state.s}\n                    x={this.state.x}\n                    {...d}\n                  />\n                </div>\n              ))\n            : null}\n          <a\n            className=\"container\"\n            style={{\n              top: `${6 + Math.floor(nbChartsInHeight / 2) * 138}px`,\n              left: `${6 + Math.max(nbChartsInHeight - 3, 1) * 132}px`\n            }}\n            href=\"/react-vis/documentation\"\n          >\n            <h1>{PROJECT_NAME}</h1>\n            <p id=\"project-desc\">{PROJECT_DESC}</p>\n            <p id=\"get-started\">Get started</p>\n          </a>\n        </div>\n      </div>\n    );\n  }\n}\n\nexport default Hero;\n"
  },
  {
    "path": "packages/website/src/config.js",
    "content": "export const PROJECT_TYPE = 'github';\n\nexport const PROJECT_NAME = 'react-vis';\nexport const PROJECT_ORG = 'uber';\nexport const PROJECT_URL = `https://github.com/${PROJECT_ORG}/${PROJECT_NAME}`;\nexport const PROJECT_DESC = 'A composable charting library';\n\nexport const PROJECTS = {};\n\nexport const HOME_HEADING = 'A composable charting library';\n\nexport const HOME_RIGHT = null;\n\nexport const HOME_BULLETS = [];\nexport const GA_TRACKING = 'UA-64694404-13';\nexport const ADDITIONAL_LINKS = [\n  {name: 'Storybook', href: './storybook/index.html'}\n];\n\nexport const BASENAME = '/react-vis';\nexport const HISTORY = 'browser';\n"
  },
  {
    "path": "packages/website/src/demos.js",
    "content": "import {showCase} from '../../showcase';\nimport * as ShowcaseIndex from '../../showcase/showcase-index';\n\nexport default {\n  ...showCase,\n  ...ShowcaseIndex\n};\n"
  },
  {
    "path": "packages/website/src/mdRoutes.js",
    "content": "import codepen from '../../docs/getting-started/react-vis-in-codepen.md';\nimport install from '../../docs/getting-started/installing-react-vis.md';\nimport newProject from '../../docs/getting-started/new-react-vis-project.md';\nimport first from '../../docs/getting-started/your-first-chart.md';\n\nimport otherThings from '../../docs/examples/building-things-other-than-charts.md';\nimport extensibility from '../../docs/examples/extensibility.md';\nimport responsiveVis from '../../docs/examples/responsive-vis.md';\nimport irisDashboard from '../../docs/examples/iris-dashboard.md';\nimport streamGraph from '../../docs/examples/stream-graph.md';\n\nimport axesShowcase from '../../docs/examples/showcases/axes-showcase.md';\nimport legendsShowcase from '../../docs/examples/showcases/legends-showcase.md';\nimport miscShowcase from '../../docs/examples/showcases/misc-showcase.md';\nimport plotsShowcase from '../../docs/examples/showcases/plots-showcase.md';\nimport radarShowcase from '../../docs/examples/showcases/radar-chart-showcase.md';\nimport radialShowcase from '../../docs/examples/showcases/radial-showcase.md';\nimport sankeysShowcase from '../../docs/examples/showcases/sankeys-showcase.md';\nimport sunburstShowcase from '../../docs/examples/showcases/sunburst-showcase.md';\nimport treemapsShowcase from '../../docs/examples/showcases/treemaps-showcase.md';\n\nimport animation from '../../docs/animation.md';\nimport arcSeries from '../../docs/arc-series.md';\nimport areaSeries from '../../docs/area-series.md';\nimport axes from '../../docs/axes.md';\nimport barSeries from '../../docs/bar-series.md';\nimport borders from '../../docs/borders.md';\nimport chartLabel from '../../docs/chart-label.md';\nimport colors from '../../docs/colors.md';\nimport contourSeries from '../../docs/contour-series.md';\nimport crosshair from '../../docs/crosshair.md';\nimport customSvgSeries from '../../docs/custom-svg-series.md';\nimport decorativeAxis from '../../docs/decorative-axis.md';\nimport flexiblePlots from '../../docs/flexible-plots.md';\nimport gradients from '../../docs/gradients.md';\nimport grids from '../../docs/grids.md';\nimport heatmapSeries from '../../docs/heatmap-series.md';\nimport hexbinSeries from '../../docs/hexbin-series.md';\nimport highlight from '../../docs/highlight.md';\nimport hint from '../../docs/hint.md';\nimport interaction from '../../docs/interaction.md';\nimport labelSeries from '../../docs/label-series.md';\nimport legends from '../../docs/legends.md';\nimport lineMarkSeries from '../../docs/line-mark-series.md';\nimport lineSeries from '../../docs/line-series.md';\nimport markSeries from '../../docs/mark-series.md';\nimport parallel from '../../docs/parallel-coordinates.md';\nimport polygonSeries from '../../docs/polygon-series.md';\nimport presentation from '../../docs/presentation.md';\nimport radar from '../../docs/radar-chart.md';\nimport radial from '../../docs/radial-chart.md';\nimport rectSeries from '../../docs/rect-series.md';\nimport sankey from '../../docs/sankey.md';\nimport scalesAndData from '../../docs/scales-and-data.md';\nimport series from '../../docs/series.md';\nimport style from '../../docs/style.md';\nimport sunburst from '../../docs/sunburst.md';\nimport treemap from '../../docs/treemap.md';\nimport voronoi from '../../docs/voronoi.md';\nimport whiskerSeries from '../../docs/whisker-series.md';\nimport xy from '../../docs/xy-plot.md';\nimport clip from '../../docs/clip.md';\n\nconst mdRoutes = [\n  {\n    name: 'Examples',\n    path: '/examples',\n    data: [\n      {\n        name: 'Showcases',\n        children: [\n          {\n            name: 'Plots',\n            markdown: plotsShowcase\n          },\n          {\n            name: 'Axes',\n            markdown: axesShowcase\n          },\n          {\n            name: 'Legends',\n            markdown: legendsShowcase\n          },\n          {\n            name: 'Sunbursts',\n            markdown: sunburstShowcase\n          },\n          {\n            name: 'Radial',\n            markdown: radialShowcase\n          },\n          {\n            name: 'Sankeys',\n            markdown: sankeysShowcase\n          },\n          {\n            name: 'Treemaps',\n            markdown: treemapsShowcase\n          },\n          {\n            name: 'Radar Charts',\n            markdown: radarShowcase\n          },\n          {\n            name: 'Misc',\n            markdown: miscShowcase\n          }\n        ]\n      },\n      {\n        name: 'Charts',\n        children: [\n          {\n            name: 'Candlestick',\n            markdown: extensibility\n          },\n          {\n            name: 'Force Directed Graph',\n            markdown: otherThings\n          },\n          {\n            name: 'Streamgraph',\n            markdown: streamGraph\n          },\n          {\n            name: 'Dynamic Dashboard',\n            markdown: irisDashboard\n          },\n          {\n            name: 'Responsive Vis',\n            markdown: responsiveVis\n          }\n        ]\n      }\n    ]\n  },\n  {\n    name: 'Documentation',\n    path: '/documentation',\n    data: [\n      {\n        name: 'Welcome to React-vis',\n        markdown: presentation\n      },\n      {\n        name: 'Getting Started',\n        children: [\n          {\n            name: 'React-vis in codepen',\n            markdown: codepen\n          },\n          {\n            name: 'Installing react-vis',\n            markdown: install\n          },\n          {\n            name: 'Creating a new react-vis project',\n            markdown: newProject\n          },\n          {\n            name: 'Your first chart',\n            markdown: first\n          }\n        ]\n      },\n      {\n        name: 'General principles',\n        children: [\n          {\n            name: 'Scales and data',\n            markdown: scalesAndData\n          },\n          {\n            name: 'Colors',\n            markdown: colors\n          },\n          {\n            name: 'Interaction',\n            markdown: interaction\n          },\n          {\n            name: 'Animation',\n            markdown: animation\n          },\n          {\n            name: 'Style',\n            markdown: style\n          }\n        ]\n      },\n      {\n        name: 'API Reference',\n        children: [\n          {\n            name: 'XY-Plot',\n            markdown: xy\n          },\n          {\n            name: 'Series',\n            markdown: series\n          },\n          {\n            name: 'Brushing and Dragging',\n            markdown: highlight\n          },\n          {\n            name: 'Legends',\n            markdown: legends\n          },\n          {\n            name: 'Crosshair',\n            markdown: crosshair\n          },\n          {\n            name: 'Grids',\n            markdown: grids\n          },\n          {\n            name: 'Hint',\n            markdown: hint\n          },\n          {\n            name: 'Axes',\n            markdown: axes\n          },\n          {\n            name: 'ChartLabel',\n            markdown: chartLabel\n          },\n          {\n            name: 'DecorativeAxis',\n            markdown: decorativeAxis\n          },\n          {\n            name: 'Gradients',\n            markdown: gradients\n          },\n          {\n            name: 'Flexible plots',\n            markdown: flexiblePlots\n          },\n          {name: 'Clipping', markdown: clip},\n          {\n            name: 'Borders',\n            markdown: borders\n          },\n          {\n            name: 'Voronoi',\n            markdown: voronoi\n          }\n        ]\n      },\n      {\n        name: 'Series reference',\n        children: [\n          {\n            name: 'Arc Series',\n            markdown: arcSeries\n          },\n          {\n            name: 'Area Series',\n            markdown: areaSeries\n          },\n          {\n            name: 'Bar Series',\n            markdown: barSeries\n          },\n          {\n            name: 'Contour Series',\n            markdown: contourSeries\n          },\n          {\n            name: 'Custom SVG Series',\n            markdown: customSvgSeries\n          },\n          {\n            name: 'Heatmap Series',\n            markdown: heatmapSeries\n          },\n          {\n            name: 'Hexbin Series',\n            markdown: hexbinSeries\n          },\n          {\n            name: 'Label Series',\n            markdown: labelSeries\n          },\n          {\n            name: 'Line Series',\n            markdown: lineSeries\n          },\n          {\n            name: 'Line-Mark Series',\n            markdown: lineMarkSeries\n          },\n          {\n            name: 'Mark Series',\n            markdown: markSeries\n          },\n          {\n            name: 'Polygon Series',\n            markdown: polygonSeries\n          },\n          {\n            name: 'Rect Series',\n            markdown: rectSeries\n          },\n          {\n            name: 'Whisker Series',\n            markdown: whiskerSeries\n          }\n        ]\n      },\n      {\n        name: 'Other Charts',\n        children: [\n          {\n            name: 'Parallel Coordinates',\n            markdown: parallel\n          },\n          {\n            name: 'Radar Chart',\n            markdown: radar\n          },\n          {\n            name: 'Radial Chart',\n            markdown: radial\n          },\n          {\n            name: 'Sankey Diagram',\n            markdown: sankey\n          },\n          {\n            name: 'Sunburst Diagram',\n            markdown: sunburst\n          },\n          {\n            name: 'Treemap',\n            markdown: treemap\n          }\n        ]\n      }\n    ]\n  }\n];\n\n// Ocular searches for links with at least one '/' and replaces them\n// with the first route it finds that includes the same markdown name\n// (that is error prone, and that's why current Axes links will all\n// point to Example Axes page instead of Documentation Axes page)\nconst fixMarkdownLinks = markdown => {\n  const markdownLinksRegex = /(?:\\(([^()/\\n]+\\.md)\\))/g;\n  return markdown.replace(markdownLinksRegex, '(/$1)');\n};\n\nmdRoutes.forEach(section => {\n  section.data.forEach(subsection => {\n    if (subsection.markdown) {\n      subsection.markdown = fixMarkdownLinks(subsection.markdown);\n    } else {\n      subsection.children.forEach(child => {\n        child.markdown = fixMarkdownLinks(child.markdown);\n      });\n    }\n  });\n});\n\nexport default mdRoutes;\n"
  },
  {
    "path": "packages/website/src/styles/_variables.scss",
    "content": "$primary: #00ADE6;\n$secondary: #05E3D5;\n$black: #041725;\n$black-20: #213746;\n$black-40: #5A666D;\n$white: #EDEDED;\n$white-40: #8D9BA3;\n\n$font-family: 'Source Sans Pro';\n\n$footer-height: 13rem;\n$topbar-height: 4rem;\n$topbar-maxheight: 8rem;\n$toc-width: 17rem;\n$mobile: 576px;\n\n$gradient-1: linear-gradient(to right, $primary 0%, $secondary 100%);\n$gradient-2: linear-gradient(to bottom, $primary 0%, $secondary 100%);"
  },
  {
    "path": "packages/website/src/styles/index.scss",
    "content": ".Hero .container {\n  position: absolute;\n  background: #fff;\n  box-shadow: 1px 1px 2px rgba(0,0,0,0.1);\n  cursor: pointer;\n  height: 120px;\n  overflow: hidden;\n  transition: background 0.5s;\n  padding: 12px;\n  width: 384px;\n  h1 {\n    margin-top: 0;\n    line-height: 84px;\n    letter-spacing: normal;\n    color: #494949;\n    margin-left: 24px;\n    transition: color 0.5s;\n  }\n  #get-started {\n    left: 400px;\n    opacity: 0;\n    color: white;\n    animation: pulse 2s infinite;\n  }\n\n  #project-desc {\n    opacity: 1;\n    left: 36px;\n  }\n  p {\n    transition: opacity 0.5s, left 0.5s;\n    font-size: 1rem;\n    line-height: 30px;\n    position: absolute;\n    bottom: 12px;\n  }\n  &:hover {\n    background: #17b8be;\n    h1 {\n      color: white;\n    }\n    #project-desc {\n      opacity: 0;\n      left: -100px;\n    }\n    #get-started {\n      opacity: 1;\n      left: 36px;\n    }\n  }\n}\n\n.container.f.fw {\n  display: none;\n}\n\n.container {\n\n  hr.short {\n    display: none;\n  }\n\n  &.markdown-body {\n    h2 + h4,\n    h2 + h5 {\n      margin-top: 0;\n    }\n\n    h4,\n    h5 {\n      margin-top: 2em;\n      font-size: 1.1em;\n      line-height: 1.5em;\n      font-weight: 600;\n      text-decoration: underline;\n\n      & ~ ul code,\n      & ~ p code {\n        background: rgba(#00ADE6, 0.1);\n      }\n\n      & ~ p,\n      & ~ pre,\n      & ~ ul {\n        margin-left: 2em;\n        font-size: 0.9em;\n        line-height: 1.5em;\n\n        @media (max-width: 400px) {\n          margin-left: 1em;\n        }\n\n        & + h2 {\n          margin-top: 2em;\n        }\n      }\n    }\n  }\n\n  .Contributors.m-top {\n    margin-top: 0;\n\n    .Contributor {\n      width: 8rem;\n      height: 10rem;\n      background: none;\n      margin: 10px;\n\n      img {\n        border-radius: 50%;\n        border: 4px solid #17b8be;\n        box-shadow: 0 0 0 #17b8be;\n        transition: border 0.5s, box-shadow 0.5s;\n      }\n\n      span {\n        display: block;\n        font-size: 1rem;\n        position: absolute;\n        margin-left: -8px;\n        bottom: 0;\n        color: #494949;\n        text-align: center;\n        text-shadow: none;\n        width: 8rem;\n      }\n    }\n\n    .Contributor:after {\n      content: '';\n      position: absolute;\n      left: 3px;\n      top: 3px;\n      width: calc(8rem - 10px);\n      height: calc(8rem - 10px);\n      border: 2px solid white;\n      border-radius: 50%;\n    }\n\n    .Contributor:hover {\n      img {\n        border-radius: 50%;\n        border: 4px solid white;\n        box-shadow: 0 0 20px #17b8be;\n      }\n    }\n  }\n}\n\n.inline-code.container > div {\n  align-items: center;\n  display: flex;\n  height: 100%;\n  justify-content: center;\n}\n\n@keyframes pulse {\n  0% {\n    font-size: 16px;\n    color: #ddd;\n  }\n  70% {\n    font-size: 17px;\n    color: white;\n  }\n  100% {\n    font-size: 16px;\n    color: #ddd;\n  }\n}\n"
  },
  {
    "path": "packages/website/static/.gitkeep",
    "content": ""
  },
  {
    "path": "packages/website/storybook/areaseries-story.js",
    "content": "/* eslint-env node */\nimport React from 'react';\n\nimport {storiesOf} from '@storybook/react';\n\nimport {\n  withKnobs,\n  color,\n  number,\n  object,\n  select\n} from '@storybook/addon-knobs/react';\n\nimport {AreaSeries, LineSeries} from 'react-vis';\n\nimport {generateLinearData, nonUniformX} from './storybook-data.js';\nimport {SimpleChartWrapper} from './storybook-utils.js';\n\nfunction styledAreaSeries(props) {\n  return (\n    <AreaSeries\n      data={props.data}\n      fill={color('fill', props.stroke || '#12939a', 'AreaSeries style')}\n      opacity={number(\n        'opacity',\n        props.opacity || 1,\n        {max: 1, min: 0, range: true, step: 0.01},\n        'AreaSeries style'\n      )}\n      stroke={color('stroke', props.stroke || '#12939a', 'AreaSeries style')}\n      style={object('style', props.style || {}, 'AreaSeries style')}\n    />\n  );\n}\n\nstoriesOf('Series/AreaSeries/Base', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('Single Area chart', () => {\n    return (\n      <SimpleChartWrapper>\n        <AreaSeries opacity={0.5} data={generateLinearData({key: 'area1'})} />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('Single Area chart paired with LineSeries', () => {\n    return (\n      <SimpleChartWrapper>\n        <AreaSeries\n          opacity={0.25}\n          data={generateLinearData({key: 'area1'})}\n          stroke=\"transparent\"\n        />\n        <LineSeries\n          stroke=\"#12939a\"\n          data={generateLinearData({key: 'area1'})}\n        />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('With negative numbers', () => {\n    return (\n      <SimpleChartWrapper yDomain={[-3, 3]}>\n        <AreaSeries\n          opacity={0.5}\n          data={generateLinearData({startValue: 0, key: 'area-neg'})}\n        />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('With non-uniform x numbers', () => {\n    return (\n      <SimpleChartWrapper>\n        <AreaSeries\n          opacity={0.5}\n          data={generateLinearData({\n            key: 'area-random-x',\n            extraParams: [['x', nonUniformX()]]\n          })}\n        />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('Multiple Area series', () => {\n    return (\n      <SimpleChartWrapper>\n        <AreaSeries opacity={0.25} data={generateLinearData({key: 'area1'})} />\n        <AreaSeries opacity={0.25} data={generateLinearData({key: 'area2'})} />\n        <AreaSeries opacity={0.25} data={generateLinearData({key: 'area3'})} />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('Multiple stacked Area series', () => {\n    return (\n      <SimpleChartWrapper stackBy=\"y\" yDomain={[0, 50]}>\n        <AreaSeries opacity={0.5} data={generateLinearData({key: 'area1'})} />\n        <AreaSeries opacity={0.5} data={generateLinearData({key: 'area2'})} />\n        <AreaSeries opacity={0.5} data={generateLinearData({key: 'area3'})} />\n      </SimpleChartWrapper>\n    );\n  });\n\nstoriesOf('Series/AreaSeries/Styling', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('opacity', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledAreaSeries({\n          data: generateLinearData({key: 'area1'}),\n          opacity: 0.75\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('stroke', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledAreaSeries({\n          data: generateLinearData({key: 'area1'}),\n          stroke: '#2c51be'\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('style object', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledAreaSeries({\n          data: generateLinearData({key: 'area1'}),\n          style: {\n            stroke: '#E48000',\n            strokeAreajoin: 'round',\n            strokeWidth: '3px'\n          }\n        })}\n      </SimpleChartWrapper>\n    );\n  });\n\nstoriesOf('Series/AreaSeries/Curve', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('Curve', () => {\n    return (\n      <SimpleChartWrapper>\n        <AreaSeries\n          opacity={0.5}\n          data={generateLinearData({key: 'area1'})}\n          curve={select(\n            'curve',\n            {\n              curveBasis: 'curveBasis',\n              curveCatmullRom: 'curveCatmullRom',\n              curveCardinal: 'curveCardinal',\n              curveAreaar: 'curveAreaar',\n              curveStep: 'curveStep',\n              curveStepAfter: 'curveStepAfter',\n              curveStepBefore: 'curveStepBefore',\n              none: null\n            },\n            'curveBasis',\n            'AreaSeries curve'\n          )}\n        />\n      </SimpleChartWrapper>\n    );\n  });\n"
  },
  {
    "path": "packages/website/storybook/axis-story.js",
    "content": "/* eslint-env node */\nimport React from 'react';\n\nimport {storiesOf} from '@storybook/react';\n\nimport {withKnobs, number, select} from '@storybook/addon-knobs/react';\n\nimport {LineSeries, VerticalBarSeries, XAxis, YAxis} from 'react-vis';\nimport {generateLinearData, getTime, getWord} from './storybook-data.js';\n\nimport {SimpleChartWrapperNoAxes} from './storybook-utils';\n\nstoriesOf('Axes and scales/Axis Formatting/Base', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('Axis orientation', () => {\n    const XAxisOrientation = select(\n      'XAxis.orientation',\n      {bottom: 'bottom', top: 'top'},\n      'bottom',\n      'XAxis'\n    );\n    const YAxisOrientation = select(\n      'YAxis.orientation',\n      {left: 'left', right: 'right'},\n      'left',\n      'YAxis'\n    );\n    return (\n      <SimpleChartWrapperNoAxes\n        margin={{\n          ...(XAxisOrientation === 'top' ? {bottom: 20, top: 40} : {}),\n          ...(YAxisOrientation === 'right' ? {left: 10, right: 40} : {})\n        }}\n      >\n        <XAxis orientation={XAxisOrientation} />\n        <YAxis orientation={YAxisOrientation} />\n        <LineSeries data={generateLinearData({key: 'line1'})} />\n      </SimpleChartWrapperNoAxes>\n    );\n  })\n  .addWithJSX('Axis titles', () => {\n    const XAxisPosition = select(\n      'XAxis.position',\n      {start: 'start', middle: 'middle', end: 'end'},\n      'end',\n      'XAxis'\n    );\n    const YAxisPosition = select(\n      'YAxis.position',\n      {start: 'start', middle: 'middle', end: 'end'},\n      'end',\n      'YAxis'\n    );\n\n    return (\n      <SimpleChartWrapperNoAxes>\n        <XAxis title=\"x-axis\" position={XAxisPosition} />\n        <YAxis title=\"y-axis\" position={YAxisPosition} />\n        <LineSeries data={generateLinearData({key: 'line1'})} />\n      </SimpleChartWrapperNoAxes>\n    );\n  })\n  .addWithJSX('Tick total', () => {\n    const xTickTotal = number(\n      'XAxis.tickTotal',\n      10,\n      {max: 20, min: 0, range: true},\n      'XAxis'\n    );\n    const yTickTotal = number(\n      'YAxis.tickTotal',\n      10,\n      {max: 20, min: 0, range: true},\n      'YAxis'\n    );\n\n    return (\n      <SimpleChartWrapperNoAxes>\n        <XAxis tickTotal={xTickTotal} />\n        <YAxis tickTotal={yTickTotal} />\n        <LineSeries data={generateLinearData({key: 'line1'})} />\n      </SimpleChartWrapperNoAxes>\n    );\n  })\n  .addWithJSX('Tick Size', () => {\n    const xTickSize = number(\n      'XAxis.tickSize',\n      6,\n      {max: 10, min: 0, range: true},\n      'XAxis'\n    );\n    const yTickSize = number(\n      'YAxis.tickSize',\n      6,\n      {max: 10, min: 0, range: true},\n      'YAxis'\n    );\n\n    return (\n      <SimpleChartWrapperNoAxes noHorizontalGridLines noVerticalGridLines>\n        <XAxis tickSize={xTickSize} />\n        <YAxis tickSize={yTickSize} />\n        <LineSeries data={generateLinearData({key: 'line1'})} />\n      </SimpleChartWrapperNoAxes>\n    );\n  })\n  .addWithJSX('Tick Size (Inner)', () => {\n    const xTickSize = number(\n      'XAxis.tickSizeInner',\n      6,\n      {max: 10, min: 0, range: true},\n      'XAxis'\n    );\n    const yTickSize = number(\n      'YAxis.tickSizeInner',\n      6,\n      {max: 10, min: 0, range: true},\n      'YAxis'\n    );\n\n    return (\n      <SimpleChartWrapperNoAxes noHorizontalGridLines noVerticalGridLines>\n        <XAxis tickSizeInner={xTickSize} />\n        <YAxis tickSizeInner={yTickSize} />\n        <LineSeries data={generateLinearData({key: 'line1'})} />\n      </SimpleChartWrapperNoAxes>\n    );\n  })\n  .addWithJSX('Tick Size (Outer)', () => {\n    const xTickSize = number(\n      'XAxis.tickSizeOuter',\n      6,\n      {max: 10, min: 0, range: true},\n      'XAxis'\n    );\n    const yTickSize = number(\n      'YAxis.tickSizeOuter',\n      6,\n      {max: 10, min: 0, range: true},\n      'YAxis'\n    );\n\n    return (\n      <SimpleChartWrapperNoAxes noHorizontalGridLines noVerticalGridLines>\n        <XAxis tickSizeOuter={xTickSize} />\n        <YAxis tickSizeOuter={yTickSize} />\n        <LineSeries data={generateLinearData({key: 'line1'})} />\n      </SimpleChartWrapperNoAxes>\n    );\n  })\n  .addWithJSX('Tick orientation', () => {\n    const tickLabelAngle = number(\n      'tickLabelAngle',\n      0,\n      {max: 90, min: -90, range: true},\n      'XAxis'\n    );\n    return (\n      <SimpleChartWrapperNoAxes margin={{bottom: 80}}>\n        <XAxis\n          tickFormat={d => new Date(d).toLocaleDateString()}\n          tickLabelAngle={tickLabelAngle}\n        />\n        <YAxis />\n        <LineSeries\n          data={generateLinearData({\n            key: 'line-with-time',\n            extraParams: [['x', getTime({})]]\n          })}\n        />\n      </SimpleChartWrapperNoAxes>\n    );\n  });\nstoriesOf('Axes and scales/Scales', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('time Scale', () => {\n    return (\n      <SimpleChartWrapperNoAxes margin={{right: 20}}>\n        <XAxis tickFormat={d => new Date(d).toLocaleDateString()} />\n        <YAxis />\n        <LineSeries\n          data={generateLinearData({\n            key: 'line-with-time',\n            extraParams: [['x', getTime({})]]\n          })}\n        />\n      </SimpleChartWrapperNoAxes>\n    );\n  })\n  .addWithJSX('category scale', () => {\n    const data = generateLinearData({\n      nbPoints: 8,\n      changeRatio: 0.4,\n      key: 'bar1'\n    });\n    return (\n      <SimpleChartWrapperNoAxes xType=\"ordinal\">\n        <XAxis />\n        <YAxis />\n        <VerticalBarSeries data={data} />\n      </SimpleChartWrapperNoAxes>\n    );\n  })\n  .addWithJSX('ordinal scale', () => {\n    const data = generateLinearData({\n      nbPoints: 8,\n      changeRatio: 0.4,\n      key: 'bar-with-words',\n      extraParams: [['x', getWord({})]]\n    });\n    return (\n      <SimpleChartWrapperNoAxes xType=\"ordinal\">\n        <XAxis />\n        <YAxis />\n        <VerticalBarSeries data={data} />\n      </SimpleChartWrapperNoAxes>\n    );\n  });\n"
  },
  {
    "path": "packages/website/storybook/barseries-story.js",
    "content": "/* eslint-env node */\nimport React from 'react';\n\nimport {storiesOf} from '@storybook/react';\n\nimport {\n  withKnobs,\n  color,\n  number,\n  object,\n  text\n} from '@storybook/addon-knobs/react';\n\nimport {HorizontalBarSeries, VerticalBarSeries} from 'react-vis';\n\nimport {generateLinearData, intRandom, random} from './storybook-data.js';\nimport {chooseColorScale, SimpleChartWrapper} from './storybook-utils.js';\n\nfunction addBarSeriesStory(isVertical = true) {\n  const seriesName = isVertical ? 'VerticalBarSeries' : 'HorizontalBarSeries';\n  const Series = isVertical ? VerticalBarSeries : HorizontalBarSeries;\n  function styledSeries(props) {\n    return (\n      <Series\n        color={color('color', props.color || null, 'style')}\n        data={props.data}\n        fill={(color('fill', props.fill || '#12939a'), 'style')}\n        opacity={number(\n          'opacity',\n          props.opacity || 1,\n          {max: 1, min: 0, range: true, step: 0.01},\n          'style'\n        )}\n        stroke={color('stroke', props.stroke || '#12939a', 'style')}\n        style={object('style', props.style || {}, 'style')}\n      />\n    );\n  }\n\n  const xyPlotParams = isVertical ? {} : {xDomain: [0, 20], yDomain: [0, 8]};\n  function dataGenerator(params) {\n    return generateLinearData({...params, flipXY: !isVertical});\n  }\n\n  storiesOf(`Series/${seriesName}/Base`, module)\n    .addDecorator(withKnobs)\n    .addWithJSX(`single ${seriesName}`, () => {\n      return (\n        <SimpleChartWrapper {...xyPlotParams}>\n          <Series\n            data={dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar1'})}\n          />\n        </SimpleChartWrapper>\n      );\n    })\n    .addWithJSX(`multiple ${seriesName} - clustered`, () => {\n      return (\n        <SimpleChartWrapper {...xyPlotParams}>\n          <Series\n            data={dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar1'})}\n          />\n          <Series\n            data={dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar2'})}\n          />\n          <Series\n            data={dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar3'})}\n          />\n        </SimpleChartWrapper>\n      );\n    })\n    .addWithJSX(`multiple ${seriesName} - stacked`, () => {\n      return (\n        <SimpleChartWrapper\n          {...(isVertical\n            ? {\n                stackBy: 'y',\n                xDomain: [0, 8],\n                yDomain: [0, 50]\n              }\n            : {\n                stackBy: 'x',\n                xDomain: [0, 50],\n                yDomain: [0, 8]\n              })}\n        >\n          <Series\n            cluster={text('BarSeries.1.cluster', 'stack 1')}\n            data={dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar1'})}\n          />\n          <Series\n            cluster={text('BarSeries.2.cluster', 'stack 1')}\n            data={dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar2'})}\n          />\n          <Series\n            cluster={text('BarSeries.3.cluster', 'stack 1')}\n            data={dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar3'})}\n          />\n        </SimpleChartWrapper>\n      );\n    });\n\n  storiesOf(`Series/${seriesName}/Styling/By datapoint`, module)\n    .addDecorator(withKnobs)\n    .addWithJSX('color', () => {\n      const {colorScale, colorRange} = chooseColorScale();\n\n      return (\n        <SimpleChartWrapper\n          {...xyPlotParams}\n          colorScale={colorScale}\n          colorRange={colorRange}\n        >\n          <Series\n            data={dataGenerator({\n              nbPoints: 8,\n              changeRatio: 0.4,\n              extraParams: [['color', intRandom({})]],\n              key: 'bar-color-1'\n            })}\n          />\n        </SimpleChartWrapper>\n      );\n    })\n    .addWithJSX('opacity', () => {\n      return (\n        <SimpleChartWrapper {...xyPlotParams}>\n          <Series\n            data={dataGenerator({\n              nbPoints: 8,\n              changeRatio: 0.4,\n              extraParams: [['opacity', random({min: 0.5, max: 1})]],\n              key: 'bar-opacity-1'\n            })}\n          />\n        </SimpleChartWrapper>\n      );\n    });\n\n  storiesOf(`Series/${seriesName}/Styling/At series level`, module)\n    .addDecorator(withKnobs)\n    .addWithJSX('fill', () => {\n      return (\n        <SimpleChartWrapper {...xyPlotParams}>\n          {styledSeries({\n            data: dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar1'}),\n            fill: '#2c51be'\n          })}\n        </SimpleChartWrapper>\n      );\n    })\n    .addWithJSX('opacity', () => {\n      return (\n        <SimpleChartWrapper {...xyPlotParams}>\n          {styledSeries({\n            data: dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar1'}),\n            opacity: 0.5\n          })}\n        </SimpleChartWrapper>\n      );\n    })\n    .addWithJSX('stroke', () => {\n      return (\n        <SimpleChartWrapper {...xyPlotParams}>\n          {styledSeries({\n            data: dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar1'}),\n            stroke: '#2c51be'\n          })}\n        </SimpleChartWrapper>\n      );\n    })\n    .addWithJSX('style', () => {\n      return (\n        <SimpleChartWrapper {...xyPlotParams}>\n          {styledSeries({\n            data: dataGenerator({nbPoints: 8, changeRatio: 0.4, key: 'bar1'}),\n            style: {\n              stroke: '#2c51be',\n              strokeWidth: '3px'\n            }\n          })}\n        </SimpleChartWrapper>\n      );\n    });\n}\naddBarSeriesStory();\naddBarSeriesStory(false);\n"
  },
  {
    "path": "packages/website/storybook/index.js",
    "content": "import '../../react-vis/dist/style.css';\nimport '../.storybook/storybook.css';\n\nimport './areaseries-story';\nimport './barseries-story';\nimport './lineseries-story';\nimport './markseries-story';\nimport './radial-story';\n\nimport './axis-story';\nimport './legend-story';\n\nimport './misc-story';\n"
  },
  {
    "path": "packages/website/storybook/legend-story.js",
    "content": "/* eslint-env node */\nimport React from 'react';\n\nimport {storiesOf} from '@storybook/react';\n\nimport {\n  withKnobs,\n  boolean,\n  color,\n  number,\n  select,\n  text\n} from '@storybook/addon-knobs/react';\n\nimport {\n  ContinuousColorLegend,\n  ContinuousSizeLegend,\n  DiscreteColorLegend,\n  SearchableDiscreteColorLegend\n} from 'react-vis';\n\nimport {CATEGORY_PALETTE, LINEAR_PALETTE} from './storybook-utils.js';\n\nstoriesOf('Legends', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('Discrete color legend', () => (\n    <DiscreteColorLegend\n      colors={CATEGORY_PALETTE.slice(0, 8)}\n      orientation={select(\n        'orientation',\n        {horizontal: 'horizontal', vertical: 'vertical'},\n        'vertical'\n      )}\n      items={[\n        'apples',\n        'bananas',\n        'carrots',\n        'dill',\n        'eggplant',\n        'fig',\n        'ginger'\n      ]}\n    />\n  ))\n  .addWithJSX('Searchable discrete color legend', () => (\n    <SearchableDiscreteColorLegend\n      colors={CATEGORY_PALETTE.slice(0, 8)}\n      orientation={select(\n        'orientation',\n        {horizontal: 'horizontal', vertical: 'vertical'},\n        'vertical'\n      )}\n      searchText={text('searchText', '')}\n      items={[\n        'apples',\n        'bananas',\n        'carrots',\n        'dill',\n        'eggplant',\n        'fig',\n        'ginger'\n      ]}\n    />\n  ))\n  .addWithJSX('Continuous Color Legend', () => {\n    const width = number('width', 300, {\n      max: 500,\n      min: 100,\n      range: true,\n      step: 1\n    });\n\n    const startTitle = number('startTitle', 0, {\n      max: 1000,\n      min: -1000,\n      range: true,\n      step: 1\n    });\n    const endTitle = number('endTitle', 100, {\n      max: 1000,\n      min: -1000,\n      range: true,\n      step: 1\n    });\n    const midTitle = number('midTitle', 50, {\n      max: 1000,\n      min: -1000,\n      range: true,\n      step: 1\n    });\n    const startColor = color('startColor', LINEAR_PALETTE[0]);\n    const midColor = color('midColor', '#DA854F');\n    const endColor = color('endColor', LINEAR_PALETTE[1]);\n    const useWidth = boolean('use Width?', true);\n    const useMidColor = boolean('use midColor?', false);\n    return (\n      <ContinuousColorLegend\n        width={useWidth ? width : null}\n        startTitle={startTitle}\n        midTitle={midTitle}\n        endTitle={endTitle}\n        startColor={startColor}\n        midColor={useMidColor ? midColor : null}\n        endColor={endColor}\n      />\n    );\n  })\n  .addWithJSX('Continuous Size Legend', () => {\n    const width = number('width', 300, {\n      max: 500,\n      min: 100,\n      range: true,\n      step: 1\n    });\n    const useWidth = boolean('use Width?', true);\n\n    const startTitle = number('startTitle', 0, {\n      max: 1000,\n      min: -1000,\n      range: true,\n      step: 1\n    });\n    const endTitle = number('endTitle', 100, {\n      max: 1000,\n      min: -1000,\n      range: true,\n      step: 1\n    });\n    const startSize = number('startSize', 2, {\n      max: 100,\n      min: 1,\n      range: true,\n      step: 1\n    });\n    const endSize = number('endSize', 20, {\n      max: 100,\n      min: 1,\n      range: true,\n      step: 1\n    });\n    const circlesTotal = number('circlesTotal', 10, {\n      max: 20,\n      min: 1,\n      range: true,\n      step: 1\n    });\n\n    return (\n      <ContinuousSizeLegend\n        circlesTotal={circlesTotal}\n        startSize={startSize}\n        endSize={endSize}\n        width={useWidth ? width : null}\n        startTitle={startTitle}\n        endTitle={endTitle}\n      />\n    );\n  });\n"
  },
  {
    "path": "packages/website/storybook/lineseries-story.js",
    "content": "/* eslint-env node */\nimport React from 'react';\n\nimport {storiesOf} from '@storybook/react';\n\nimport {\n  withKnobs,\n  color,\n  number,\n  object,\n  select,\n  text\n} from '@storybook/addon-knobs/react';\n\nimport {LineSeries} from 'react-vis';\n\nimport {generateLinearData, nonUniformX} from './storybook-data.js';\nimport {SimpleChartWrapper} from './storybook-utils.js';\n\nfunction styledLineSeries(props) {\n  return (\n    <LineSeries\n      data={props.data}\n      opacity={number(\n        'opacity',\n        props.opacity || 1,\n        {max: 1, min: 0, range: true, step: 0.01},\n        'style'\n      )}\n      stroke={color('stroke', props.stroke || '#12939a', 'style')}\n      strokeDasharray={text(\n        'strokeDasharray',\n        props.strokeDasharray || '',\n        'style'\n      )}\n      strokeStyle={select(\n        'strokeStyle',\n        {solid: 'solid', dashed: 'dashed'},\n        props.strokeStyle || 'solid',\n        'style'\n      )}\n      strokeWidth={text('strokeWidth', props.strokeWidth || '', 'style')}\n      style={object('style', props.style || {}, 'style')}\n    />\n  );\n}\n\nstoriesOf('Series/LineSeries/Base', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('Single Line chart', () => {\n    return (\n      <SimpleChartWrapper>\n        <LineSeries data={generateLinearData({key: 'line1'})} />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('With negative numbers', () => {\n    return (\n      <SimpleChartWrapper yDomain={[-3, 3]}>\n        <LineSeries\n          data={generateLinearData({startValue: 0, key: 'line-neg'})}\n        />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('With non-uniform x numbers', () => {\n    return (\n      <SimpleChartWrapper>\n        <LineSeries\n          data={generateLinearData({\n            key: 'line-random-x',\n            extraParams: [['x', nonUniformX()]]\n          })}\n        />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('Multiple Line series', () => {\n    return (\n      <SimpleChartWrapper>\n        <LineSeries data={generateLinearData({key: 'line1'})} />\n        <LineSeries data={generateLinearData({key: 'line2'})} />\n        <LineSeries data={generateLinearData({key: 'line3'})} />\n      </SimpleChartWrapper>\n    );\n  });\n\nstoriesOf('Series/LineSeries/Styling', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('opacity', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledLineSeries({\n          data: generateLinearData({key: 'line1'}),\n          opacity: 0.5\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('stroke', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledLineSeries({\n          data: generateLinearData({key: 'line1'}),\n          stroke: '#2c51be'\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('strokeDasharray', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledLineSeries({\n          data: generateLinearData({key: 'line1'}),\n          strokeDasharray: '5, 5, 1, 5'\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('strokeStyle', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledLineSeries({\n          data: generateLinearData({key: 'line1'}),\n          strokeStyle: 'dashed'\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('strokeWidth', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledLineSeries({\n          data: generateLinearData({key: 'line1'}),\n          strokeWidth: '5px'\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('style object', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledLineSeries({\n          data: generateLinearData({key: 'line1'}),\n          style: {\n            stroke: '#E48000',\n            strokeLinejoin: 'round',\n            strokeWidth: '3px'\n          }\n        })}\n      </SimpleChartWrapper>\n    );\n  });\n\nstoriesOf('Series/LineSeries/Curve', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('Curve', () => {\n    return (\n      <SimpleChartWrapper>\n        <LineSeries\n          data={generateLinearData({key: 'line1'})}\n          curve={select(\n            'curve',\n            {\n              curveBasis: 'curveBasis',\n              curveCatmullRom: 'curveCatmullRom',\n              curveCardinal: 'curveCardinal',\n              curveLinear: 'curveLinear',\n              curveStep: 'curveStep',\n              curveStepAfter: 'curveStepAfter',\n              curveStepBefore: 'curveStepBefore',\n              none: null\n            },\n            'curveBasis',\n            'LineSeries curve'\n          )}\n        />\n      </SimpleChartWrapper>\n    );\n  });\n"
  },
  {
    "path": "packages/website/storybook/markseries-story.js",
    "content": "/* eslint-env node */\nimport React from 'react';\n\nimport {storiesOf} from '@storybook/react';\n\nimport {\n  withKnobs,\n  color,\n  number,\n  object,\n  select\n} from '@storybook/addon-knobs/react';\n\nimport {MarkSeries} from 'react-vis';\n\nimport {generateScatterplotData, intRandom, random} from './storybook-data.js';\nimport {chooseColorScale, SimpleChartWrapper} from './storybook-utils.js';\n\nfunction styledMarkSeries(props) {\n  return (\n    <MarkSeries\n      data={props.data}\n      opacity={number(\n        'opacity',\n        props.opacity || 1,\n        {max: 1, min: 0, range: true, step: 0.01},\n        'style'\n      )}\n      fill={color('fill', props.fill || '#12939a', 'style')}\n      stroke={color('stroke', props.stroke || '#12939a', 'style')}\n      strokeStyle={select(\n        'strokeStyle',\n        {solid: 'solid', dashed: 'dashed'},\n        props.strokeStyle || 'solid',\n        'style'\n      )}\n      strokeWidth={number('strokeWidth', props.strokeWidth || 2, 'style')}\n      style={object('style', props.style || {}, 'style')}\n    />\n  );\n}\n\nstoriesOf('Series/MarkSeries/Base', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('Single scatterplot', () => {\n    return (\n      <SimpleChartWrapper>\n        <MarkSeries data={generateScatterplotData({key: 'scatter1'})} />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('Multiple MarkSeries', () => {\n    return (\n      <SimpleChartWrapper>\n        <MarkSeries data={generateScatterplotData({key: 'scatter1'})} />\n        <MarkSeries data={generateScatterplotData({key: 'scatter2'})} />\n        <MarkSeries data={generateScatterplotData({key: 'scatter3'})} />\n      </SimpleChartWrapper>\n    );\n  });\n\nstoriesOf('Series/MarkSeries/Styling/By Datapoint', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('color', () => {\n    const {colorScale, colorRange} = chooseColorScale();\n    return (\n      <SimpleChartWrapper colorScale={colorScale} colorRange={colorRange}>\n        <MarkSeries\n          data={generateScatterplotData({\n            key: 'scatter-color-1',\n            extraParams: [['color', intRandom({})]]\n          })}\n        />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('fill', () => {\n    const {colorScale, colorRange} = chooseColorScale();\n    return (\n      <SimpleChartWrapper fillScale={colorScale} fillRange={colorRange}>\n        <MarkSeries\n          data={generateScatterplotData({\n            key: 'scatter-fill-1',\n            extraParams: [['fill', intRandom({})]]\n          })}\n        />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('opacity', () => {\n    return (\n      <SimpleChartWrapper>\n        <MarkSeries\n          data={generateScatterplotData({\n            key: 'scatter-opacity-1',\n            extraParams: [['opacity', random({min: 0.5})]]\n          })}\n        />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('size', () => {\n    return (\n      <SimpleChartWrapper>\n        <MarkSeries\n          data={generateScatterplotData({\n            key: 'scatter-size-1',\n            extraParams: [['size', random({min: 5, max: 20})]]\n          })}\n        />\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('stroke', () => {\n    const {colorScale, colorRange} = chooseColorScale();\n    return (\n      <SimpleChartWrapper strokeScale={colorScale} strokeRange={colorRange}>\n        <MarkSeries\n          data={generateScatterplotData({\n            key: 'scatter-stroke-1',\n            extraParams: [['stroke', intRandom({})]]\n          })}\n          style={{strokeWidth: '2px'}}\n        />\n      </SimpleChartWrapper>\n    );\n  });\n\nstoriesOf('Series/MarkSeries/Styling/At series level', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('fill', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledMarkSeries({\n          data: generateScatterplotData({key: 'scatter1'}),\n          fill: '#2c51be'\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('opacity', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledMarkSeries({\n          data: generateScatterplotData({key: 'scatter1'}),\n          opacity: 0.5\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('stroke', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledMarkSeries({\n          data: generateScatterplotData({key: 'scatter1'}),\n          stroke: '#2c51be'\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('strokeWidth', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledMarkSeries({\n          data: generateScatterplotData({key: 'scatter1'}),\n          strokeWidth: '3px'\n        })}\n      </SimpleChartWrapper>\n    );\n  })\n  .addWithJSX('style', () => {\n    return (\n      <SimpleChartWrapper>\n        {styledMarkSeries({\n          data: generateScatterplotData({key: 'scatter1'}),\n          style: {\n            stroke: '#E48000',\n            strokeOpacity: 0.5,\n            strokeWidth: '3px'\n          }\n        })}\n      </SimpleChartWrapper>\n    );\n  });\n"
  },
  {
    "path": "packages/website/storybook/misc-story.js",
    "content": "/* eslint-env node */\n\nimport React from 'react';\n\nimport {storiesOf} from '@storybook/react';\n\nimport {withKnobs, boolean} from '@storybook/addon-knobs/react';\nimport {SimpleChartWrapper} from './storybook-utils';\nimport {generateLinearData} from './storybook-data';\n\nimport {LineSeries, ContentClipPath} from 'react-vis';\n\nconst data = generateLinearData({randomFactor: 10});\n\nstoriesOf('Misc', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('Clip Content', () => {\n    const margin = {left: 40, top: 40, bottom: 40, right: 40};\n    const xDomain = [data[1].x, data[data.length - 2].x];\n    const shouldClip = boolean(\n      'Enable Clipping',\n      false,\n      'General chart options'\n    );\n    return (\n      <SimpleChartWrapper xDomain={xDomain} yDomain={[0, 20]} margin={margin}>\n        {shouldClip && <ContentClipPath id=\"clip\" />}\n        <LineSeries data={data} style={{clipPath: 'url(#clip)'}} />\n      </SimpleChartWrapper>\n    );\n  });\n"
  },
  {
    "path": "packages/website/storybook/radial-story.js",
    "content": "/* eslint-env node */\nimport React from 'react';\n\nimport {storiesOf} from '@storybook/react';\n\nimport {withKnobs, boolean, number, object} from '@storybook/addon-knobs/react';\n\nimport {generateRadialData} from './storybook-data.js';\nimport {SimpleRadialChartWrapper} from './storybook-utils.js';\n\nfunction labelProps() {\n  const showLabels = boolean('showLabels', true, 'Labels');\n  const labelsRadiusMultiplier = number(\n    'labelsRadiusMultiplier',\n    1.1,\n    {max: 2, min: 0, range: true, step: 0.1},\n    'Labels'\n  );\n  const labelsStyle = object('labelStyle', {fontSize: 12}, 'Labels');\n  return {labelsRadiusMultiplier, labelsStyle, showLabels};\n}\n\nstoriesOf('Series/RadialCharts/Pie Chart', module)\n  .addDecorator(withKnobs)\n  .addWithJSX('Single Pie Chart', () => {\n    const nbSlices = number(\n      'nbSlices',\n      5,\n      {max: 8, min: 1, range: true, step: 1},\n      'Pie Chart'\n    );\n    return (\n      <SimpleRadialChartWrapper\n        data={generateRadialData({key: 'radial-1'}).slice(0, nbSlices)}\n      />\n    );\n  })\n  .addWithJSX('Single Pie Chart with Labels', () => {\n    const nbSlices = number(\n      'nbSlices',\n      5,\n      {max: 8, min: 1, range: true, step: 1},\n      'Pie Chart'\n    );\n    return (\n      <SimpleRadialChartWrapper\n        data={generateRadialData({key: 'radial-1'}).slice(0, nbSlices)}\n        {...labelProps()}\n      />\n    );\n  });\n"
  },
  {
    "path": "packages/website/storybook/storybook-data.js",
    "content": "const data = {};\nconst DEC23 = 1513987200000;\nconst DAY_IN_MS = 86400000;\nexport function generateLinearData({\n  nbPoints = 20,\n  randomFactor = 1,\n  startValue = 10,\n  changeRatio = 0.1,\n  extraParams = [],\n  flipXY,\n  key\n}) {\n  if (data[key]) {\n    return flipXY ? xyFlip(data[key]) : data[key];\n  }\n  const result = new Array(nbPoints).fill(0).reduce(\n    (series, curr, i) => [\n      ...series,\n      enrich({\n        extraParams,\n        datapoint: {\n          x: i + 1,\n          y:\n            series[i].y * (1 + (Math.random() - 0.5) * changeRatio) +\n            (Math.random() - 0.5) * randomFactor\n        },\n        nbPoints,\n        series,\n        i\n      })\n    ],\n    [\n      enrich({\n        extraParams,\n        datapoint: {x: 0, y: startValue},\n        nbPoints,\n        series: [],\n        i: 0\n      })\n    ]\n  );\n  if (key !== undefined) {\n    data[key] = result;\n  }\n  return flipXY ? xyFlip(result) : result;\n}\n\nexport function generateScatterplotData(args) {\n  const extraParams = [\n    ['x', random({max: 20})],\n    ['y', random({max: 20})]\n  ].concat(args.extraParams || []);\n  return generateLinearData({...args, extraParams});\n}\n\nexport function generateRadialData(args) {\n  return generateScatterplotData(args).map(({x, y, ...d}, i) => {\n    return {\n      angle: Math.round(x + y),\n      label: getWord()({i}),\n      ...d\n    };\n  });\n}\n\nexport function xyFlip(arr) {\n  return arr.map(d => ({\n    ...d,\n    x: d.y,\n    y: d.x\n  }));\n}\n\nexport function enrich({datapoint, extraParams, nbPoints, series, i}) {\n  return extraParams.reduce((result, param) => {\n    result[param[0]] = param[1]({...datapoint, series, nbPoints, i});\n    return result;\n  }, datapoint);\n}\n\nexport function nonUniformX() {\n  return ({x, series, i}) => {\n    if (!i) {\n      return x;\n    }\n    return series[i].x + Math.random() + Math.random() + Math.random();\n  };\n}\n\nexport function random({max = 1, min = 0}) {\n  return () => min + Math.random() * (max - min);\n}\n\nexport function intRandom({max = 10, min = 0}) {\n  return () => Math.floor(min + Math.random() * (max - min));\n}\n\nexport function getTime({startTime = DEC23}) {\n  return ({i}) => startTime + i * DAY_IN_MS;\n}\n\nexport function getWord() {\n  return ({i}) =>\n    [\n      'deck.gl',\n      'math.gl',\n      'probe.gl',\n      'vis.gl',\n      'react-map-gl',\n      'vis-academy',\n      'luma.gl',\n      'kepler.gl'\n    ][i % 8];\n}\n"
  },
  {
    "path": "packages/website/storybook/storybook-utils.js",
    "content": "import React from 'react';\nimport {AutoSizer} from 'react-virtualized';\nimport {\n  XYPlot,\n  RadialChart,\n  XAxis,\n  YAxis,\n  VerticalGridLines,\n  HorizontalGridLines\n} from 'react-vis';\nimport {boolean, select} from '@storybook/addon-knobs/react';\n\nexport const CATEGORY_PALETTE = [\n  '#19CDD7',\n  '#DDB27C',\n  '#88572C',\n  '#FF991F',\n  '#F15C17',\n  '#223F9A',\n  '#DA70BF',\n  '#125C77',\n  '#4DC19C',\n  '#776E57',\n  '#12939A',\n  '#17B8BE',\n  '#F6D18A',\n  '#B7885E',\n  '#FFCB99',\n  '#F89570',\n  '#829AE3',\n  '#E79FD5',\n  '#1E96BE',\n  '#89DAC1',\n  '#B3AD9E'\n];\n\nexport const LINEAR_PALETTE = ['#EF5D28', '#FF9833'];\n\nexport function SimpleChartWrapper(props) {\n  return (\n    <AutoSizer>\n      {({height, width}) => (\n        <XYPlot\n          height={height}\n          width={width}\n          colorRange={props.colorRange}\n          colorScale={props.colorType}\n          fillRange={props.fillRange}\n          fillScale={props.fillScale}\n          margin={props.margin}\n          strokeRange={props.strokeRange}\n          strokeType={props.strokeType}\n          xDomain={props.xDomain}\n          xType={props.xType}\n          yDomain={props.yDomain || [0, 20]}\n          stackBy={props.stackBy}\n        >\n          {props.noXAxis\n            ? null\n            : boolean('X Axis', true, 'General chart options') && <XAxis />}\n          {props.noYAxis\n            ? null\n            : boolean('Y Axis', true, 'General chart options') && <YAxis />}\n          {props.noVerticalGridLines\n            ? null\n            : boolean('vertical gridlines', true, 'General chart options') && (\n                <VerticalGridLines />\n              )}\n          {props.noHorizontalGridLines\n            ? null\n            : boolean(\n                'horizontal gridlines',\n                true,\n                'General chart options'\n              ) && <HorizontalGridLines />}\n          {props.children}\n        </XYPlot>\n      )}\n    </AutoSizer>\n  );\n}\n\nexport function SimpleRadialChartWrapper(props) {\n  return (\n    <AutoSizer>\n      {({height, width}) => (\n        <RadialChart height={height} width={width} {...props} />\n      )}\n    </AutoSizer>\n  );\n}\n\nexport function SimpleChartWrapperNoAxes(props) {\n  return SimpleChartWrapper({...props, noXAxis: true, noYAxis: true});\n}\n\nexport function chooseColorScale() {\n  const colorScale = select(\n    'colorScale',\n    {linear: 'linear', category: 'category'},\n    'category'\n  );\n  const colorRange = {\n    category: CATEGORY_PALETTE,\n    linear: LINEAR_PALETTE\n  }[colorScale];\n  return {colorRange, colorScale};\n}\n\nexport const jsxOptions = {\n  defaultProps: false,\n  displayName: component => {\n    if (\n      component.type.name === 'SimpleChartWrapper' ||\n      component.type.name === 'SimpleChartWrapperNoAxes'\n    ) {\n      return 'XYPlot';\n    }\n    if (component.type.name === 'SimpleRadialChartWrapper') {\n      return 'RadialChart';\n    }\n    return component.type.displayName;\n  },\n  filterProps: ['className', 'getNull', 'nullAccessor', 'stack']\n};\n"
  },
  {
    "path": "packages/website/webpack.config.js",
    "content": "/* eslint-env node */\nconst {resolve} = require('path');\n\nmodule.exports = {\n  module: {\n    rules: [\n      {\n        test: /\\.js$/,\n        loader: 'babel-loader',\n        exclude: [/node_modules/],\n        options: {\n          rootMode: 'upward'\n        }\n      }\n    ]\n  },\n  resolve: {\n    alias: {\n      react: resolve(__dirname, './node_modules/react')\n    }\n  }\n};\n"
  },
  {
    "path": "publish-docs.sh",
    "content": "#!/bin/bash\ncd website &&\nnpm run build &&\nrm -rf /tmp/dist-vis &&\nmv dist /tmp/dist-vis &&\ngit checkout gh-pages &&\nrm -rf dist &&\nmv /tmp/dist-vis dist &&\nmv dist/index.html .. &&\ncd .. &&\ngit add . &&\ngit commit -m 'Upgrade docs' &&\ngit push && git checkout master\n"
  },
  {
    "path": "publish.sh",
    "content": "#!/bin/bash\nDRY_RUN=0\n\nwhile true; do\n  case $1 in\n    -v | --version ) VERSION=$2; shift 2 ;;\n    -t | --tag ) TAG=$2; shift 2 ;;\n    -r | --registry ) REGISTRY=$2; shift 2 ;;\n    --dry-run ) DRY_RUN=1; shift ;;\n    -- ) shift; break ;;\n    * ) break ;;\n  esac\ndone\n\nif [ -z $VERSION ]\nthen\n    echo \"Error: must specify version, with the -v option.\"\n    exit 0\nfi\n\nif [ -z $REGISTRY ]\nthen\n    echo \"Registry unset, use the default npm registry https://registry.npmjs.org.\"\n    REGISTRY=\"https://registry.npmjs.org\"\nfi\n\ncp CHANGELOG.md README.md LICENSE packages/react-vis\n\ncd packages/react-vis\n\nnpm version $VERSION\n\npublish_command=\"npm publish\"\n\nif [ -z $TAG ]\nthen\n    publish_command+=\" --tag ${TAG} --registry ${REGISTRY}\"\nelse\n    publish_command+=\" --registry ${REGISTRY}\"\nfi\n\nif [ $DRY_RUN -eq 1 ]\nthen\n    publish_command+=\" --dry-run\"\nfi\n\neval $publish_command\n\nrm CHANGELOG.md README.md LICENSE\n"
  },
  {
    "path": "remove-refs-to-unpm.pl",
    "content": "#!/bin/bash\n\nperl -pi -e 's/unpm\\.uberinternal\\.com/registry\\.yarnpkg\\.com/g' `find . -name yarn.lock`\n"
  }
]